From 3e3209cba22c9a5a562acc5e543946408a36e2f4 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 5 Nov 2017 10:22:42 +0100 Subject: [PATCH 1/9] Fix laggy move-resize in xdg-shell --- include/rootston/view.h | 6 ++++ rootston/xdg_shell_v6.c | 76 ++++++++++++++++++++++++----------------- rootston/xwayland.c | 22 ++++++------ 3 files changed, 62 insertions(+), 42 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 0913b42e..adfbe6e0 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -26,6 +26,12 @@ struct roots_xdg_surface_v6 { struct wl_listener destroy; struct wl_listener request_move; struct wl_listener request_resize; + + struct { + bool needs_move; + double x, y; + uint32_t width, height; + } move_resize; }; struct roots_xwayland_surface { diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ca33c582..38341922 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -12,27 +12,26 @@ static void get_size(struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); - struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; - // TODO: surf->geometry can be NULL - memcpy(box, surf->geometry, sizeof(struct wlr_box)); + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + // TODO: surface->geometry can be NULL + memcpy(box, surface->geometry, sizeof(struct wlr_box)); } static void activate(struct roots_view *view, bool active) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); - struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; - if (surf->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { - wlr_xdg_toplevel_v6_set_activated(surf, active); + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + if (surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + wlr_xdg_toplevel_v6_set_activated(surface, active); } } -static void apply_size_constraints(struct wlr_xdg_surface_v6 *surf, +static void apply_size_constraints(struct wlr_xdg_surface_v6 *surface, uint32_t width, uint32_t height, uint32_t *dest_width, uint32_t *dest_height) { *dest_width = width; *dest_height = height; - struct wlr_xdg_toplevel_v6_state *state = - &surf->toplevel_state->current; + struct wlr_xdg_toplevel_v6_state *state = &surface->toplevel_state->current; if (width < state->min_width) { *dest_width = state->min_width; } else if (state->max_width > 0 && @@ -49,46 +48,50 @@ static void apply_size_constraints(struct wlr_xdg_surface_v6 *surf, static void resize(struct roots_view *view, uint32_t width, uint32_t height) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); - struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; - if (surf->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { return; } - uint32_t contrained_width, contrained_height; - apply_size_constraints(surf, width, height, &contrained_width, - &contrained_height); + uint32_t constrained_width, constrained_height; + apply_size_constraints(surface, width, height, &constrained_width, + &constrained_height); - wlr_xdg_toplevel_v6_set_size(surf, contrained_width, contrained_height); + wlr_xdg_toplevel_v6_set_size(surface, constrained_width, + constrained_height); } static void move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); - struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; - if (surf->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + struct roots_xdg_surface_v6 *roots_surface = view->roots_xdg_surface_v6; + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { return; } - uint32_t contrained_width, contrained_height; - apply_size_constraints(surf, width, height, &contrained_width, - &contrained_height); + uint32_t constrained_width, constrained_height; + apply_size_constraints(surface, width, height, &constrained_width, + &constrained_height); - x = x + width - contrained_width; - y = y + height - contrained_height; + x = x + width - constrained_width; + y = y + height - constrained_height; - // TODO: we should wait for an ack_configure event before updating the - // position - view->x = x; - view->y = y; + roots_surface->move_resize.needs_move = true; + roots_surface->move_resize.x = x; + roots_surface->move_resize.y = y; + roots_surface->move_resize.width = constrained_width; + roots_surface->move_resize.height = constrained_height; - wlr_xdg_toplevel_v6_set_size(surf, contrained_width, contrained_height); + wlr_xdg_toplevel_v6_set_size(surface, constrained_width, + constrained_height); } static void close(struct roots_view *view) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); - struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; - if (surf->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { - wlr_xdg_toplevel_v6_send_close(surf); + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + if (surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + wlr_xdg_toplevel_v6_send_close(surface); } } @@ -119,7 +122,18 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { } static void handle_commit(struct wl_listener *listener, void *data) { - // TODO is there anything we need to do here? + struct roots_xdg_surface_v6 *roots_surface = + wl_container_of(listener, roots_surface, commit); + struct roots_view *view = roots_surface->view; + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + + if (roots_surface->move_resize.needs_move) { + view->x = roots_surface->move_resize.x + + roots_surface->move_resize.width - surface->geometry->width; + view->y = roots_surface->move_resize.y + + roots_surface->move_resize.height - surface->geometry->height; + roots_surface->move_resize.needs_move = false; + } } static void handle_destroy(struct wl_listener *listener, void *data) { diff --git a/rootston/xwayland.c b/rootston/xwayland.c index e3fc1c84..76cdf05a 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -52,13 +52,13 @@ static void resize(struct roots_view *view, uint32_t width, uint32_t height) { assert(view->type == ROOTS_XWAYLAND_VIEW); struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; - uint32_t contrained_width, contrained_height; - apply_size_constraints(xwayland_surface, width, height, &contrained_width, - &contrained_height); + uint32_t constrained_width, constrained_height; + apply_size_constraints(xwayland_surface, width, height, &constrained_width, + &constrained_height); wlr_xwayland_surface_configure(view->desktop->xwayland, xwayland_surface, - xwayland_surface->x, xwayland_surface->y, contrained_width, - contrained_height); + xwayland_surface->x, xwayland_surface->y, constrained_width, + constrained_height); } static void move_resize(struct roots_view *view, double x, double y, @@ -66,18 +66,18 @@ static void move_resize(struct roots_view *view, double x, double y, assert(view->type == ROOTS_XWAYLAND_VIEW); struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; - uint32_t contrained_width, contrained_height; - apply_size_constraints(xwayland_surface, width, height, &contrained_width, - &contrained_height); + uint32_t constrained_width, constrained_height; + apply_size_constraints(xwayland_surface, width, height, &constrained_width, + &constrained_height); - x = x + width - contrained_width; - y = y + height - contrained_height; + x = x + width - constrained_width; + y = y + height - constrained_height; view->x = x; view->y = y; wlr_xwayland_surface_configure(view->desktop->xwayland, xwayland_surface, - x, y, contrained_width, contrained_height); + x, y, constrained_width, constrained_height); } static void close(struct roots_view *view) { From e2843d87c868341869cf905f6c77531e78d997ad Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 17 Nov 2017 23:52:42 +0100 Subject: [PATCH 2/9] Ensure to move the view when configured --- include/rootston/view.h | 2 +- include/wlr/types/wlr_xdg_shell_v6.h | 24 ++++++++++------- rootston/xdg_shell_v6.c | 10 +++---- types/wlr_xdg_shell_v6.c | 40 ++++++++++++++-------------- 4 files changed, 40 insertions(+), 36 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 9df2ee08..66616207 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -30,7 +30,7 @@ struct roots_xdg_surface_v6 { struct wl_listener request_maximize; struct { - bool needs_move; + uint32_t configure_serial; double x, y; uint32_t width, height; } move_resize; diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index e3982003..d0e7957b 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -107,7 +107,9 @@ struct wlr_xdg_surface_v6 { bool configured; bool added; + uint32_t configure_serial; struct wl_event_source *configure_idle; + uint32_t configure_next_serial; struct wl_list configure_list; char *title; @@ -171,37 +173,38 @@ void wlr_xdg_shell_v6_destroy(struct wlr_xdg_shell_v6 *xdg_shell); void wlr_xdg_surface_v6_ping(struct wlr_xdg_surface_v6 *surface); /** - * Request that this toplevel surface be the given size. + * Request that this toplevel surface be the given size. Returns the associated + * configure serial. */ -void wlr_xdg_toplevel_v6_set_size(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_size(struct wlr_xdg_surface_v6 *surface, uint32_t width, uint32_t height); /** * Request that this toplevel surface show itself in an activated or deactivated - * state. + * state. Returns the associated configure serial. */ -void wlr_xdg_toplevel_v6_set_activated(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_activated(struct wlr_xdg_surface_v6 *surface, bool activated); /** * Request that this toplevel surface consider itself maximized or not - * maximized. + * maximized. Returns the associated configure serial. */ -void wlr_xdg_toplevel_v6_set_maximized(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_maximized(struct wlr_xdg_surface_v6 *surface, bool maximized); /** * Request that this toplevel surface consider itself fullscreen or not - * fullscreen. + * fullscreen. Returns the associated configure serial. */ -void wlr_xdg_toplevel_v6_set_fullscreen(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_fullscreen(struct wlr_xdg_surface_v6 *surface, bool fullscreen); /** * Request that this toplevel surface consider itself to be resizing or not - * resizing. + * resizing. Returns the associated configure serial. */ -void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface, bool resizing); /** @@ -223,4 +226,5 @@ void wlr_xdg_surface_v6_popup_get_position(struct wlr_xdg_surface_v6 *surface, struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( struct wlr_xdg_surface_v6 *surface, double sx, double sy, double *popup_sx, double *popup_sy); + #endif diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index f9c905dd..d91fc2d9 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -83,14 +83,13 @@ static void move_resize(struct roots_view *view, double x, double y, x = x + width - constrained_width; y = y + height - constrained_height; - roots_surface->move_resize.needs_move = true; roots_surface->move_resize.x = x; roots_surface->move_resize.y = y; roots_surface->move_resize.width = constrained_width; roots_surface->move_resize.height = constrained_height; - wlr_xdg_toplevel_v6_set_size(surface, constrained_width, - constrained_height); + roots_surface->move_resize.configure_serial = wlr_xdg_toplevel_v6_set_size( + surface, constrained_width, constrained_height); } static void maximize(struct roots_view *view, bool maximized) { @@ -159,12 +158,13 @@ static void handle_commit(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; - if (roots_surface->move_resize.needs_move) { + if (roots_surface->move_resize.configure_serial == + surface->configure_serial) { view->x = roots_surface->move_resize.x + roots_surface->move_resize.width - surface->geometry->width; view->y = roots_surface->move_resize.y + roots_surface->move_resize.height - surface->geometry->height; - roots_surface->move_resize.needs_move = false; + roots_surface->move_resize.configure_serial = 0; } } diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 429baa70..dfe5ddc5 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -812,6 +812,7 @@ static void xdg_surface_ack_configure(struct wl_client *client, } surface->configured = true; + surface->configure_serial = serial; wl_signal_emit(&surface->events.ack_configure, surface); @@ -941,7 +942,6 @@ static void wlr_xdg_toplevel_v6_send_configure( static void wlr_xdg_surface_send_configure(void *user_data) { struct wlr_xdg_surface_v6 *surface = user_data; - struct wl_display *display = wl_client_get_display(surface->client->client); surface->configure_idle = NULL; @@ -953,7 +953,7 @@ static void wlr_xdg_surface_send_configure(void *user_data) { } wl_list_insert(surface->configure_list.prev, &configure->link); - configure->serial = wl_display_next_serial(display); + configure->serial = surface->configure_next_serial; switch (surface->role) { case WLR_XDG_SURFACE_V6_ROLE_NONE: @@ -974,7 +974,7 @@ static void wlr_xdg_surface_send_configure(void *user_data) { zxdg_surface_v6_send_configure(surface->resource, configure->serial); } -static void wlr_xdg_surface_v6_schedule_configure( +static uint32_t wlr_xdg_surface_v6_schedule_configure( struct wlr_xdg_surface_v6 *surface) { struct wl_display *display = wl_client_get_display(surface->client->client); struct wl_event_loop *loop = wl_display_get_event_loop(display); @@ -995,23 +995,23 @@ static void wlr_xdg_surface_v6_schedule_configure( if (surface->configure_idle != NULL) { if (!pending_same) { // configure request already scheduled - return; + return surface->configure_next_serial; } // configure request not necessary anymore wl_event_source_remove(surface->configure_idle); surface->configure_idle = NULL; + return 0; } else { if (pending_same) { // configure request not necessary - return; + return 0; } - surface->configure_idle = - wl_event_loop_add_idle( - loop, - wlr_xdg_surface_send_configure, - surface); + surface->configure_next_serial = wl_display_next_serial(display); + surface->configure_idle = wl_event_loop_add_idle(loop, + wlr_xdg_surface_send_configure, surface); + return surface->configure_next_serial; } } @@ -1304,45 +1304,45 @@ void wlr_xdg_surface_v6_ping(struct wlr_xdg_surface_v6 *surface) { surface->client->ping_serial); } -void wlr_xdg_toplevel_v6_set_size(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_size(struct wlr_xdg_surface_v6 *surface, uint32_t width, uint32_t height) { assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL); surface->toplevel_state->pending.width = width; surface->toplevel_state->pending.height = height; - wlr_xdg_surface_v6_schedule_configure(surface); + return wlr_xdg_surface_v6_schedule_configure(surface); } -void wlr_xdg_toplevel_v6_set_activated(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_activated(struct wlr_xdg_surface_v6 *surface, bool activated) { assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL); surface->toplevel_state->pending.activated = activated; - wlr_xdg_surface_v6_schedule_configure(surface); + return wlr_xdg_surface_v6_schedule_configure(surface); } -void wlr_xdg_toplevel_v6_set_maximized(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_maximized(struct wlr_xdg_surface_v6 *surface, bool maximized) { assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL); surface->toplevel_state->pending.maximized = maximized; - wlr_xdg_surface_v6_schedule_configure(surface); + return wlr_xdg_surface_v6_schedule_configure(surface); } -void wlr_xdg_toplevel_v6_set_fullscreen(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_fullscreen(struct wlr_xdg_surface_v6 *surface, bool fullscreen) { assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL); surface->toplevel_state->pending.fullscreen = fullscreen; - wlr_xdg_surface_v6_schedule_configure(surface); + return wlr_xdg_surface_v6_schedule_configure(surface); } -void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface, +uint32_t wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface, bool resizing) { assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL); surface->toplevel_state->pending.resizing = resizing; - wlr_xdg_surface_v6_schedule_configure(surface); + return wlr_xdg_surface_v6_schedule_configure(surface); } void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface) { From a3a8b7bfd8d1616cdf9f7ba911616ca0baeedc67 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 18 Nov 2017 09:09:23 +0100 Subject: [PATCH 3/9] Fixed a bug with move-resize, removed xdg-shell ack_configure event Fixed move-resizing a view when only one coordinate changes. --- include/rootston/view.h | 1 + include/wlr/types/wlr_xdg_shell_v6.h | 1 - rootston/cursor.c | 8 +------ rootston/desktop.c | 5 +++++ rootston/xdg_shell_v6.c | 31 +++++++++++++++++++++------- types/wlr_xdg_shell_v6.c | 3 --- 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 66616207..058dc73e 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -32,6 +32,7 @@ struct roots_xdg_surface_v6 { struct { uint32_t configure_serial; double x, y; + bool update_x, update_y; uint32_t width, height; } move_resize; }; diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index d0e7957b..6ac84cef 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -125,7 +125,6 @@ struct wlr_xdg_surface_v6 { struct { struct wl_signal commit; struct wl_signal destroy; - struct wl_signal ack_configure; struct wl_signal ping_timeout; struct wl_signal request_maximize; diff --git a/rootston/cursor.c b/rootston/cursor.c index 5949a364..d4c4510a 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -98,13 +98,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t height = 0; } - if (active_x != seat->focus->x || - active_y != seat->focus->y) { - view_move_resize(seat->focus, active_x, active_y, - width, height); - } else { - view_resize(seat->focus, width, height); - } + view_move_resize(seat->focus, active_x, active_y, width, height); } break; case ROOTS_CURSOR_ROTATE: diff --git a/rootston/desktop.c b/rootston/desktop.c index 1695d007..be63d7f5 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -103,6 +103,11 @@ void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { void view_move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height) { + if (x == view->x == x && y == view->y) { + view_resize(view, width, height); + return; + } + if (view->move_resize) { view->move_resize(view, x, y, width, height); return; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index d91fc2d9..5a55b8c4 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -76,15 +76,24 @@ static void move_resize(struct roots_view *view, double x, double y, return; } + bool update_x = x != view->x; + bool update_y = y != view->y; + uint32_t constrained_width, constrained_height; apply_size_constraints(surface, width, height, &constrained_width, &constrained_height); - x = x + width - constrained_width; - y = y + height - constrained_height; + if (update_x) { + x = x + width - constrained_width; + } + if (update_y) { + y = y + height - constrained_height; + } roots_surface->move_resize.x = x; roots_surface->move_resize.y = y; + roots_surface->move_resize.update_x = update_x; + roots_surface->move_resize.update_y = update_y; roots_surface->move_resize.width = constrained_width; roots_surface->move_resize.height = constrained_height; @@ -158,12 +167,20 @@ static void handle_commit(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; - if (roots_surface->move_resize.configure_serial == + if (roots_surface->move_resize.configure_serial > 0 && + roots_surface->move_resize.configure_serial == surface->configure_serial) { - view->x = roots_surface->move_resize.x + - roots_surface->move_resize.width - surface->geometry->width; - view->y = roots_surface->move_resize.y + - roots_surface->move_resize.height - surface->geometry->height; + struct wlr_box size; + get_size(view, &size); + + if (roots_surface->move_resize.update_x) { + view->x = roots_surface->move_resize.x + + roots_surface->move_resize.width - size.width; + } + if (roots_surface->move_resize.update_y) { + view->y = roots_surface->move_resize.y + + roots_surface->move_resize.height - size.height; + } roots_surface->move_resize.configure_serial = 0; } } diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index dfe5ddc5..8bb48a24 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -814,8 +814,6 @@ static void xdg_surface_ack_configure(struct wl_client *client, surface->configured = true; surface->configure_serial = serial; - wl_signal_emit(&surface->events.ack_configure, surface); - free(configure); } @@ -1155,7 +1153,6 @@ static void xdg_shell_get_xdg_surface(struct wl_client *wl_client, wl_signal_init(&surface->events.request_show_window_menu); wl_signal_init(&surface->events.commit); wl_signal_init(&surface->events.destroy); - wl_signal_init(&surface->events.ack_configure); wl_signal_init(&surface->events.ping_timeout); wl_signal_add(&surface->surface->events.destroy, From 8693bbd6b11b2519747fe3efcd6376a9736aef6f Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 18 Nov 2017 09:13:31 +0100 Subject: [PATCH 4/9] Update view coords when no configure is required --- rootston/xdg_shell_v6.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 5a55b8c4..8819ebdd 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -97,8 +97,14 @@ static void move_resize(struct roots_view *view, double x, double y, roots_surface->move_resize.width = constrained_width; roots_surface->move_resize.height = constrained_height; - roots_surface->move_resize.configure_serial = wlr_xdg_toplevel_v6_set_size( - surface, constrained_width, constrained_height); + uint32_t serial = wlr_xdg_toplevel_v6_set_size(surface, constrained_width, + constrained_height); + if (serial > 0) { + roots_surface->move_resize.configure_serial = serial; + } else { + view->x = x; + view->y = y; + } } static void maximize(struct roots_view *view, bool maximized) { From 7375931686e6a58c08a7727ce2f5d88e0be9adfa Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 18 Nov 2017 09:15:48 +0100 Subject: [PATCH 5/9] Fix typo making GCC build fail --- rootston/desktop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index be63d7f5..fca801bb 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -103,7 +103,7 @@ void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { void view_move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height) { - if (x == view->x == x && y == view->y) { + if (x == view->x && y == view->y) { view_resize(view, width, height); return; } From c0e2dc6f7875a3dc5ad7ca49444e068f15c001ed Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 19 Nov 2017 22:55:44 +0100 Subject: [PATCH 6/9] Update view position for previous configure_ack too --- rootston/xdg_shell_v6.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 8819ebdd..ca011d49 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -174,7 +174,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; if (roots_surface->move_resize.configure_serial > 0 && - roots_surface->move_resize.configure_serial == + roots_surface->move_resize.configure_serial >= surface->configure_serial) { struct wlr_box size; get_size(view, &size); @@ -187,7 +187,11 @@ static void handle_commit(struct wl_listener *listener, void *data) { view->y = roots_surface->move_resize.y + roots_surface->move_resize.height - size.height; } - roots_surface->move_resize.configure_serial = 0; + + if (roots_surface->move_resize.configure_serial == + surface->configure_serial) { + roots_surface->move_resize.configure_serial = 0; + } } } From ac6385689f8a4895888f069afeae037edc7c7e19 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 20 Nov 2017 11:10:43 +0100 Subject: [PATCH 7/9] Set min view size to 1x1 --- rootston/cursor.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/rootston/cursor.c b/rootston/cursor.c index db2a414c..93ee03d4 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -69,37 +69,37 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, if (seat->focus) { double dx = cursor->cursor->x - cursor->offs_x; double dy = cursor->cursor->y - cursor->offs_y; - double active_x = seat->focus->x; - double active_y = seat->focus->y; + double x = seat->focus->x; + double y = seat->focus->y; int width = cursor->view_width; int height = cursor->view_height; if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { - active_y = cursor->view_y + dy; + y = cursor->view_y + dy; height -= dy; - if (height < 0) { - active_y += height; + if (height < 1) { + y += height; } } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { height += dy; } if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { - active_x = cursor->view_x + dx; + x = cursor->view_x + dx; width -= dx; - if (width < 0) { - active_x += width; + if (width < 1) { + x += width; } } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { width += dx; } - if (width < 0) { - width = 0; + if (width < 1) { + width = 1; } - if (height < 0) { - height = 0; + if (height < 1) { + height = 1; } - view_move_resize(seat->focus, active_x, active_y, width, height); + view_move_resize(seat->focus, x, y, width, height); } break; case ROOTS_CURSOR_ROTATE: From 0153a0ed8fb934333505ee7793b1c493d8d0cd35 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 20 Nov 2017 12:05:21 +0100 Subject: [PATCH 8/9] Fix laggy move-resize for xwayland views --- include/rootston/view.h | 15 ++++++++----- rootston/xdg_shell_v6.c | 37 +++++++++++++++--------------- rootston/xwayland.c | 50 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 29 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 058dc73e..66fc88bc 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -29,12 +29,7 @@ struct roots_xdg_surface_v6 { struct wl_listener request_resize; struct wl_listener request_maximize; - struct { - uint32_t configure_serial; - double x, y; - bool update_x, update_y; - uint32_t width, height; - } move_resize; + uint32_t pending_move_resize_configure_serial; }; struct roots_xwayland_surface { @@ -48,6 +43,8 @@ struct roots_xwayland_surface { struct wl_listener request_maximize; struct wl_listener map_notify; struct wl_listener unmap_notify; + + struct wl_listener surface_commit; }; enum roots_view_type { @@ -69,6 +66,12 @@ struct roots_view { float rotation; } saved; + struct { + bool update_x, update_y; + double x, y; + uint32_t width, height; + } pending_move_resize; + // TODO: Something for roots-enforced width/height enum roots_view_type type; union { diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ca011d49..95df36a2 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -90,17 +90,17 @@ static void move_resize(struct roots_view *view, double x, double y, y = y + height - constrained_height; } - roots_surface->move_resize.x = x; - roots_surface->move_resize.y = y; - roots_surface->move_resize.update_x = update_x; - roots_surface->move_resize.update_y = update_y; - roots_surface->move_resize.width = constrained_width; - roots_surface->move_resize.height = constrained_height; + view->pending_move_resize.update_x = update_x; + view->pending_move_resize.update_y = update_y; + view->pending_move_resize.x = x; + view->pending_move_resize.y = y; + view->pending_move_resize.width = constrained_width; + view->pending_move_resize.height = constrained_height; uint32_t serial = wlr_xdg_toplevel_v6_set_size(surface, constrained_width, constrained_height); if (serial > 0) { - roots_surface->move_resize.configure_serial = serial; + roots_surface->pending_move_resize_configure_serial = serial; } else { view->x = x; view->y = y; @@ -173,24 +173,23 @@ static void handle_commit(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; - if (roots_surface->move_resize.configure_serial > 0 && - roots_surface->move_resize.configure_serial >= - surface->configure_serial) { + uint32_t pending_serial = + roots_surface->pending_move_resize_configure_serial; + if (pending_serial > 0 && pending_serial >= surface->configure_serial) { struct wlr_box size; get_size(view, &size); - if (roots_surface->move_resize.update_x) { - view->x = roots_surface->move_resize.x + - roots_surface->move_resize.width - size.width; + if (view->pending_move_resize.update_x) { + view->x = view->pending_move_resize.x + + view->pending_move_resize.width - size.width; } - if (roots_surface->move_resize.update_y) { - view->y = roots_surface->move_resize.y + - roots_surface->move_resize.height - size.height; + if (view->pending_move_resize.update_y) { + view->y = view->pending_move_resize.y + + view->pending_move_resize.height - size.height; } - if (roots_surface->move_resize.configure_serial == - surface->configure_serial) { - roots_surface->move_resize.configure_serial = 0; + if (pending_serial == surface->configure_serial) { + roots_surface->pending_move_resize_configure_serial = 0; } } } diff --git a/rootston/xwayland.c b/rootston/xwayland.c index f1093552..372fd951 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -66,15 +66,26 @@ static void move_resize(struct roots_view *view, double x, double y, assert(view->type == ROOTS_XWAYLAND_VIEW); struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; + bool update_x = x != view->x; + bool update_y = y != view->y; + uint32_t constrained_width, constrained_height; apply_size_constraints(xwayland_surface, width, height, &constrained_width, &constrained_height); - x = x + width - constrained_width; - y = y + height - constrained_height; + if (update_x) { + x = x + width - constrained_width; + } + if (update_y) { + y = y + height - constrained_height; + } - view->x = x; - view->y = y; + view->pending_move_resize.update_x = update_x; + view->pending_move_resize.update_y = update_y; + view->pending_move_resize.x = x; + view->pending_move_resize.y = y; + view->pending_move_resize.width = constrained_width; + view->pending_move_resize.height = constrained_height; wlr_xwayland_surface_configure(view->desktop->xwayland, xwayland_surface, x, y, constrained_width, constrained_height); @@ -171,6 +182,27 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) { view_maximize(view, maximized); } +static void handle_surface_commit(struct wl_listener *listener, void *data) { + struct roots_xwayland_surface *roots_surface = + wl_container_of(listener, roots_surface, surface_commit); + struct roots_view *view = roots_surface->view; + struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; + + int width = xwayland_surface->surface->current->width; + int height = xwayland_surface->surface->current->height; + + if (view->pending_move_resize.update_x) { + view->x = view->pending_move_resize.x + + view->pending_move_resize.width - width; + view->pending_move_resize.update_x = false; + } + if (view->pending_move_resize.update_y) { + view->y = view->pending_move_resize.y + + view->pending_move_resize.height - height; + view->pending_move_resize.update_y = false; + } +} + static void handle_map_notify(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, map_notify); @@ -182,6 +214,10 @@ static void handle_map_notify(struct wl_listener *listener, void *data) { view->x = (double)xsurface->x; view->y = (double)xsurface->y; + roots_surface->surface_commit.notify = handle_surface_commit; + wl_signal_add(&xsurface->surface->events.commit, + &roots_surface->surface_commit); + wlr_list_push(desktop->views, roots_surface->view); } @@ -191,6 +227,8 @@ static void handle_unmap_notify(struct wl_listener *listener, void *data) { struct roots_desktop *desktop = roots_surface->view->desktop; roots_surface->view->wlr_surface = NULL; + wl_list_remove(&roots_surface->surface_commit.link); + for (size_t i = 0; i < desktop->views->length; i++) { if (desktop->views->items[i] == roots_surface->view) { wlr_list_del(desktop->views, i); @@ -231,6 +269,10 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { wl_signal_add(&surface->events.request_maximize, &roots_surface->request_maximize); + roots_surface->surface_commit.notify = handle_surface_commit; + wl_signal_add(&surface->surface->events.commit, + &roots_surface->surface_commit); + struct roots_view *view = calloc(1, sizeof(struct roots_view)); if (view == NULL) { free(roots_surface); From 272e0858e49bf341b363fdbe59a5f669ba678ce2 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 20 Nov 2017 12:16:10 +0100 Subject: [PATCH 9/9] Fix laggy move-resize for wl-shell views --- rootston/desktop.c | 12 ++++++++++-- rootston/wl_shell.c | 19 ++++++++++++++++++- rootston/xwayland.c | 6 +++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index b3287ed0..c6a1957c 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -103,7 +103,9 @@ void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { void view_move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height) { - if (x == view->x && y == view->y) { + bool update_x = x != view->x; + bool update_y = y != view->y; + if (!update_x && !update_y) { view_resize(view, width, height); return; } @@ -113,7 +115,13 @@ void view_move_resize(struct roots_view *view, double x, double y, return; } - view_move(view, x, y); + view->pending_move_resize.update_x = update_x; + view->pending_move_resize.update_y = update_y; + view->pending_move_resize.x = x; + view->pending_move_resize.y = y; + view->pending_move_resize.width = width; + view->pending_move_resize.height = height; + view_resize(view, width, height); } diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 96f461fe..0043219f 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -71,7 +71,24 @@ static void handle_set_state(struct wl_listener *listener, void *data) { } static void handle_surface_commit(struct wl_listener *listener, void *data) { - // TODO do we need to do anything here? + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, surface_commit); + struct roots_view *view = roots_surface->view; + struct wlr_surface *wlr_surface = view->wlr_surface; + + int width = wlr_surface->current->width; + int height = wlr_surface->current->height; + + if (view->pending_move_resize.update_x) { + view->x = view->pending_move_resize.x + + view->pending_move_resize.width - width; + view->pending_move_resize.update_x = false; + } + if (view->pending_move_resize.update_y) { + view->y = view->pending_move_resize.y + + view->pending_move_resize.height - height; + view->pending_move_resize.update_y = false; + } } static void handle_destroy(struct wl_listener *listener, void *data) { diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 372fd951..b2f64879 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -186,10 +186,10 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, surface_commit); struct roots_view *view = roots_surface->view; - struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; + struct wlr_surface *wlr_surface = view->wlr_surface; - int width = xwayland_surface->surface->current->width; - int height = xwayland_surface->surface->current->height; + int width = wlr_surface->current->width; + int height = wlr_surface->current->height; if (view->pending_move_resize.update_x) { view->x = view->pending_move_resize.x +