fix animation architecture: delegate slide/move to backend vtable
Core code must not call backend directly. misc.c:slide_windows and move_window now delegate to wm_backend->slide_windows/move_window. Wayland backend implements both using scene node moves + event_flush.
This commit is contained in:
parent
1331103ce7
commit
b9c37c6629
|
|
@ -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,
|
||||
|
|
|
|||
22
src/misc.c
22
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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue