diff options
author | emersion <contact@emersion.fr> | 2017-11-20 12:05:21 +0100 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2017-11-20 12:05:21 +0100 |
commit | 0153a0ed8fb934333505ee7793b1c493d8d0cd35 (patch) | |
tree | fa4ee9935976ad04b14b23abb57d735d8b38f842 /rootston | |
parent | ac6385689f8a4895888f069afeae037edc7c7e19 (diff) |
Fix laggy move-resize for xwayland views
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/xdg_shell_v6.c | 37 | ||||
-rw-r--r-- | rootston/xwayland.c | 50 |
2 files changed, 64 insertions, 23 deletions
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); |