diff --git a/src/backend/wayland/wl_stubs.c b/src/backend/wayland/wl_stubs.c index 2afef97..a087a64 100644 --- a/src/backend/wayland/wl_stubs.c +++ b/src/backend/wayland/wl_stubs.c @@ -129,13 +129,65 @@ void wl_noop_client_restore(WWindow *wwin) { (void)wwin; }void wl_noop_client_ge void wl_noop_eat_expose(void) { } -void wl_noop_move_window(WNativeWindow win, int from_x, int from_y, - int to_x, int to_y) -{ (void)win; (void)from_x; (void)from_y; (void)to_x; (void)to_y; } - -void wl_noop_slide_windows(WNativeWindow *wins, int n, +#define ICON_SIZE wPreferences.icon_size +static void wl_slide_windows(WNativeWindow *wins, int n, int from_x, int from_y, int to_x, int to_y) -{ (void)wins; (void)n; (void)from_x; (void)from_y; (void)to_x; (void)to_y; } +{ + static const struct { int delay; int steps; int slowdown; } apars[5] = { + {0,1,1},{0,50,10},{0,30,8},{0,20,6},{1,10,4} + }; + int sp = wPreferences.icon_slide_speed; + if (sp < 0) sp = 0; else if (sp > 4) sp = 4; + int slide_delay = apars[sp].delay; + int slide_steps = apars[sp].steps; + int slide_slowdown = apars[sp].slowdown; + float dx = to_x - from_x, dy = to_y - from_y; + float px, py, x = from_x, y = from_y; + int is_dx_bigger = (abs((int)dx) >= abs((int)dy)); + if (is_dx_bigger) { + px = dx / slide_slowdown; + if (px > 0 && px < slide_steps) px = slide_steps; + else if (px < 0 && px > -slide_steps) px = -slide_steps; + py = (dx == 0.f ? 0.f : px * dy / dx); + } else { + py = dy / slide_slowdown; + if (py > 0 && py < slide_steps) py = slide_steps; + else if (py < 0 && py > -slide_steps) py = -slide_steps; + px = (dy == 0.f ? 0.f : py * dx / dy); + } + while ((int)x != to_x || (int)y != to_y) { + x += px; y += py; + if (px < 0 && (int)x < to_x) x = to_x; + if (px > 0 && (int)x > to_x) x = to_x; + if (py < 0 && (int)y < to_y) y = to_y; + if (py > 0 && (int)y > to_y) y = to_y; + for (int i = 0; i < n; i++) + wm_backend->window_move(wins[i], (int)x + i * ICON_SIZE, (int)y); + wm_backend->event_flush(); + if (slide_delay > 0) wusleep((useconds_t)(slide_delay * 1000)); + /* decelerate */ + if (is_dx_bigger) { + px *= (1.f - 1.f / slide_slowdown); + if (px > 0 && px < slide_steps) px = slide_steps; + else if (px < 0 && px > -slide_steps) px = -slide_steps; + py = (dx == 0.f ? 0.f : px * dy / dx); + } else { + py *= (1.f - 1.f / slide_slowdown); + if (py > 0 && py < slide_steps) py = slide_steps; + else if (py < 0 && py > -slide_steps) py = -slide_steps; + px = (dy == 0.f ? 0.f : py * dx / dy); + } + } + for (int i = 0; i < n; i++) + wm_backend->window_move(wins[i], to_x + i * ICON_SIZE, to_y); + wm_backend->event_flush(); +} + +static void wl_move_window(WNativeWindow win, int from_x, int from_y, + int to_x, int to_y) +{ + wl_slide_windows(&win, 1, from_x, from_y, to_x, to_y); +} char *wl_noop_get_text_selection(WScreen *scr, unsigned long selection) { (void)scr; (void)selection; return NULL; } @@ -468,8 +520,8 @@ const WMBackend wl_backend = { .client_kill = wl_client_kill_impl, .client_get_colormap_windows = wl_noop_client_get_colormap_windows, .eat_expose = wl_noop_eat_expose, - .move_window = wl_noop_move_window, - .slide_windows = wl_noop_slide_windows, + .move_window = wl_move_window, + .slide_windows = wl_slide_windows, .get_text_selection = wl_noop_get_text_selection, .get_shortcut_string = wl_noop_get_shortcut_string, .get_command_for_window = wl_get_command_for_window, diff --git a/src/misc.c b/src/misc.c index dbf0972..10a2a80 100644 --- a/src/misc.c +++ b/src/misc.c @@ -84,20 +84,29 @@ void move_window(WNativeWindow win, int from_x, int from_y, int to_x, int to_y) if (wPreferences.no_animations) wm_backend->window_move((WNativeWindow)win, to_x, to_y); else - slide_window(win, from_x, from_y, to_x, to_y); + wm_backend->move_window(win, from_x, from_y, to_x, to_y); #else wm_backend->window_move((WNativeWindow)win, to_x, to_y); - - /* Tell the compiler it is normal that those parameters are not used in this case */ (void) from_x; (void) from_y; #endif } -/* wins is an array of WNativeWindow, sorted from left to right, the first is - * going to be moved from (from_x,from_y) to (to_x,to_y) and the - * following windows are going to be offset by (ICON_SIZE*i,0) */ +/* wins is an array of WNativeWindow, sorted left to right. Delegates to backend. */ void slide_windows(WNativeWindow wins[], int n, int from_x, int from_y, int to_x, int to_y) +{ + if (!wPreferences.no_animations) { + wm_backend->slide_windows(wins, n, from_x, from_y, to_x, to_y); + return; + } + /* no animations: just move to final positions */ + for (int i = 0; i < n; i++) + wm_backend->window_move(wins[i], to_x + i * ICON_SIZE, to_y); + wm_backend->event_flush(); +} + +#if 0 /* original X11 implementation preserved for reference */ +void slide_windows_x11(WNativeWindow wins[], int n, int from_x, int from_y, int to_x, int to_y) { time_t time0 = time(NULL); float dx, dy, x = from_x, y = from_y, px, py; @@ -195,6 +204,7 @@ void slide_windows(WNativeWindow wins[], int n, int from_x, int from_y, int to_x /* compress expose events */ eatExpose(); } +#endif /* slide_windows_x11 */ char *ShrinkString(WMFont *font, const char *string, int width) {