From 065c37d3f5eed86dc218c9722e245fa5fda9bd75 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sun, 17 Jul 2022 23:42:04 -0400 Subject: [PATCH] xwayland: Process move-only client configure requests more quickly For a move-only client configure request, treat it similarly to view_move() by updating the scene-graph immediately, rather than waiting for handle_commit(). Move-and-resize requests are handled the same as before. This (mostly?) fixes the glitchiness that was noticeable when dragging an undecorated XWayland window (e.g. Audacious in Winamp mode). Also: - Reduce some code duplication in handle_request_configure() by simply calling configure(), as suggested by @johanmalm in #428. - Factor out common logic after a move and/or resize into view_moved(). --- include/labwc.h | 1 + src/view.c | 7 +++-- src/xdg.c | 8 ++--- src/xwayland.c | 77 +++++++++++++++++++------------------------------ 4 files changed, 38 insertions(+), 55 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index 0af693ea..cae25f31 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -419,6 +419,7 @@ void view_close(struct view *view); */ void view_move_resize(struct view *view, struct wlr_box geo); void view_move(struct view *view, double x, double y); +void view_moved(struct view *view); void view_minimize(struct view *view, bool minimized); /* view_wlr_output - return the output that a view is mostly on */ struct wlr_output *view_wlr_output(struct view *view); diff --git a/src/view.c b/src/view.c index b3f5dcad..3ac1a698 100644 --- a/src/view.c +++ b/src/view.c @@ -124,6 +124,11 @@ view_move(struct view *view, double x, double y) if (view->impl->move) { view->impl->move(view, x, y); } +} + +void +view_moved(struct view *view) +{ view_discover_output(view); wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); ssd_update_geometry(view); @@ -136,8 +141,6 @@ view_move_resize(struct view *view, struct wlr_box geo) if (view->impl->configure) { view->impl->configure(view, geo); } - ssd_update_title(view); - view_discover_output(view); } #define MIN_VIEW_WIDTH (100) diff --git a/src/xdg.c b/src/xdg.c index b7c9edf3..f2b9b6b8 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -57,8 +57,7 @@ handle_commit(struct wl_listener *listener, void *data) view->pending_move_resize.configure_serial = 0; } } - wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); - ssd_update_geometry(view); + view_moved(view); } static void @@ -182,9 +181,7 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo) } else if (view->pending_move_resize.configure_serial == 0) { view->x = geo.x; view->y = geo.y; - wlr_scene_node_set_position(&view->scene_tree->node, - view->x, view->y); - ssd_update_geometry(view); + view_moved(view); } } @@ -193,6 +190,7 @@ xdg_toplevel_view_move(struct view *view, double x, double y) { view->x = x; view->y = y; + view_moved(view); } static void diff --git a/src/xwayland.c b/src/xwayland.c index aa89ce19..beb21ec0 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -15,37 +15,22 @@ handle_commit(struct wl_listener *listener, void *data) struct wlr_surface_state *state = &view->surface->current; struct view_pending_move_resize *pending = &view->pending_move_resize; - bool move_pending = pending->update_x || pending->update_y; - bool size_changed = view->w != state->width || view->h != state->height; - - if (!move_pending && !size_changed) { + if (view->w == state->width && view->h == state->height) { return; } view->w = state->width; view->h = state->height; - if (pending->update_x) { + if (view->x != pending->x) { /* Adjust x for queued up configure events */ view->x = pending->x + pending->width - view->w; } - if (pending->update_y) { + if (view->y != pending->y) { /* Adjust y for queued up configure events */ view->y = pending->y + pending->height - view->h; } - if (move_pending) { - wlr_scene_node_set_position(&view->scene_tree->node, - view->x, view->y); - } - if ((int)pending->width == view->w && (int)pending->height == view->h) { - /* - * We reached the end of all queued size changing configure - * events - */ - pending->update_x = false; - pending->update_y = false; - } - ssd_update_geometry(view); + view_moved(view); } static void @@ -134,6 +119,27 @@ handle_destroy(struct wl_listener *listener, void *data) view_destroy(view); } +static void +configure(struct view *view, struct wlr_box geo) +{ + assert(view->xwayland_surface); + + view->pending_move_resize.x = geo.x; + view->pending_move_resize.y = geo.y; + view->pending_move_resize.width = geo.width; + view->pending_move_resize.height = geo.height; + + wlr_xwayland_surface_configure(view->xwayland_surface, geo.x, geo.y, + geo.width, geo.height); + + /* If not resizing, process the move immediately */ + if (view->w == geo.width && view->h == geo.height) { + view->x = geo.x; + view->y = geo.y; + view_moved(view); + } +} + static void handle_request_configure(struct wl_listener *listener, void *data) { @@ -144,16 +150,7 @@ handle_request_configure(struct wl_listener *listener, void *data) int height = event->height; view_adjust_size(view, &width, &height); - view->pending_move_resize.update_x = event->x != view->x; - view->pending_move_resize.update_y = event->y != view->y; - view->pending_move_resize.x = event->x; - view->pending_move_resize.y = event->y; - view->pending_move_resize.width = width; - view->pending_move_resize.height = height; - - wlr_scene_node_set_position(&view->scene_tree->node, event->x, event->y); - wlr_xwayland_surface_configure(view->xwayland_surface, - event->x, event->y, width, height); + configure(view, (struct wlr_box){event->x, event->y, width, height}); } static void @@ -206,38 +203,22 @@ handle_set_class(struct wl_listener *listener, void *data) view_update_app_id(view); } -static void -configure(struct view *view, struct wlr_box geo) -{ - if (!view->xwayland_surface) { - wlr_log(WLR_ERROR, "Not configuring view without xwayland_surface"); - return; - } - view->pending_move_resize.update_x = geo.x != view->x; - view->pending_move_resize.update_y = geo.y != view->y; - view->pending_move_resize.x = geo.x; - view->pending_move_resize.y = geo.y; - view->pending_move_resize.width = geo.width; - view->pending_move_resize.height = geo.height; - wlr_xwayland_surface_configure(view->xwayland_surface, (int16_t)geo.x, - (int16_t)geo.y, (uint16_t)geo.width, (uint16_t)geo.height); -} - static void move(struct view *view, double x, double y) { + assert(view->xwayland_surface); + view->x = x; view->y = y; /* override any previous pending move */ - view->pending_move_resize.update_x = false; - view->pending_move_resize.update_y = false; view->pending_move_resize.x = x; view->pending_move_resize.y = y; struct wlr_xwayland_surface *s = view->xwayland_surface; wlr_xwayland_surface_configure(s, (int16_t)x, (int16_t)y, (uint16_t)s->width, (uint16_t)s->height); + view_moved(view); } static void