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().
This commit is contained in:
John Lindgren 2022-07-17 23:42:04 -04:00 committed by Johan Malm
parent a0a5cf706e
commit 065c37d3f5
4 changed files with 38 additions and 55 deletions

View file

@ -419,6 +419,7 @@ void view_close(struct view *view);
*/ */
void view_move_resize(struct view *view, struct wlr_box geo); void view_move_resize(struct view *view, struct wlr_box geo);
void view_move(struct view *view, double x, double y); void view_move(struct view *view, double x, double y);
void view_moved(struct view *view);
void view_minimize(struct view *view, bool minimized); void view_minimize(struct view *view, bool minimized);
/* view_wlr_output - return the output that a view is mostly on */ /* view_wlr_output - return the output that a view is mostly on */
struct wlr_output *view_wlr_output(struct view *view); struct wlr_output *view_wlr_output(struct view *view);

View file

@ -124,6 +124,11 @@ view_move(struct view *view, double x, double y)
if (view->impl->move) { if (view->impl->move) {
view->impl->move(view, x, y); view->impl->move(view, x, y);
} }
}
void
view_moved(struct view *view)
{
view_discover_output(view); view_discover_output(view);
wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y);
ssd_update_geometry(view); ssd_update_geometry(view);
@ -136,8 +141,6 @@ view_move_resize(struct view *view, struct wlr_box geo)
if (view->impl->configure) { if (view->impl->configure) {
view->impl->configure(view, geo); view->impl->configure(view, geo);
} }
ssd_update_title(view);
view_discover_output(view);
} }
#define MIN_VIEW_WIDTH (100) #define MIN_VIEW_WIDTH (100)

View file

@ -57,8 +57,7 @@ handle_commit(struct wl_listener *listener, void *data)
view->pending_move_resize.configure_serial = 0; view->pending_move_resize.configure_serial = 0;
} }
} }
wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); view_moved(view);
ssd_update_geometry(view);
} }
static void 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) { } else if (view->pending_move_resize.configure_serial == 0) {
view->x = geo.x; view->x = geo.x;
view->y = geo.y; view->y = geo.y;
wlr_scene_node_set_position(&view->scene_tree->node, view_moved(view);
view->x, view->y);
ssd_update_geometry(view);
} }
} }
@ -193,6 +190,7 @@ xdg_toplevel_view_move(struct view *view, double x, double y)
{ {
view->x = x; view->x = x;
view->y = y; view->y = y;
view_moved(view);
} }
static void static void

View file

@ -15,37 +15,22 @@ handle_commit(struct wl_listener *listener, void *data)
struct wlr_surface_state *state = &view->surface->current; struct wlr_surface_state *state = &view->surface->current;
struct view_pending_move_resize *pending = &view->pending_move_resize; struct view_pending_move_resize *pending = &view->pending_move_resize;
bool move_pending = pending->update_x || pending->update_y; if (view->w == state->width && view->h == state->height) {
bool size_changed = view->w != state->width || view->h != state->height;
if (!move_pending && !size_changed) {
return; return;
} }
view->w = state->width; view->w = state->width;
view->h = state->height; view->h = state->height;
if (pending->update_x) { if (view->x != pending->x) {
/* Adjust x for queued up configure events */ /* Adjust x for queued up configure events */
view->x = pending->x + pending->width - view->w; view->x = pending->x + pending->width - view->w;
} }
if (pending->update_y) { if (view->y != pending->y) {
/* Adjust y for queued up configure events */ /* Adjust y for queued up configure events */
view->y = pending->y + pending->height - view->h; view->y = pending->y + pending->height - view->h;
} }
if (move_pending) { view_moved(view);
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);
} }
static void static void
@ -134,6 +119,27 @@ handle_destroy(struct wl_listener *listener, void *data)
view_destroy(view); 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 static void
handle_request_configure(struct wl_listener *listener, void *data) 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; int height = event->height;
view_adjust_size(view, &width, &height); view_adjust_size(view, &width, &height);
view->pending_move_resize.update_x = event->x != view->x; configure(view, (struct wlr_box){event->x, event->y, width, height});
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);
} }
static void static void
@ -206,38 +203,22 @@ handle_set_class(struct wl_listener *listener, void *data)
view_update_app_id(view); 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 static void
move(struct view *view, double x, double y) move(struct view *view, double x, double y)
{ {
assert(view->xwayland_surface);
view->x = x; view->x = x;
view->y = y; view->y = y;
/* override any previous pending move */ /* 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.x = x;
view->pending_move_resize.y = y; view->pending_move_resize.y = y;
struct wlr_xwayland_surface *s = view->xwayland_surface; struct wlr_xwayland_surface *s = view->xwayland_surface;
wlr_xwayland_surface_configure(s, (int16_t)x, (int16_t)y, wlr_xwayland_surface_configure(s, (int16_t)x, (int16_t)y,
(uint16_t)s->width, (uint16_t)s->height); (uint16_t)s->width, (uint16_t)s->height);
view_moved(view);
} }
static void static void