mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Fix laggy move-resize for xwayland views
This commit is contained in:
		
							parent
							
								
									ac6385689f
								
							
						
					
					
						commit
						0153a0ed8f
					
				
					 3 changed files with 73 additions and 29 deletions
				
			
		| 
						 | 
					@ -29,12 +29,7 @@ struct roots_xdg_surface_v6 {
 | 
				
			||||||
	struct wl_listener request_resize;
 | 
						struct wl_listener request_resize;
 | 
				
			||||||
	struct wl_listener request_maximize;
 | 
						struct wl_listener request_maximize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
						uint32_t pending_move_resize_configure_serial;
 | 
				
			||||||
		uint32_t configure_serial;
 | 
					 | 
				
			||||||
		double x, y;
 | 
					 | 
				
			||||||
		bool update_x, update_y;
 | 
					 | 
				
			||||||
		uint32_t width, height;
 | 
					 | 
				
			||||||
	} move_resize;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_xwayland_surface {
 | 
					struct roots_xwayland_surface {
 | 
				
			||||||
| 
						 | 
					@ -48,6 +43,8 @@ struct roots_xwayland_surface {
 | 
				
			||||||
	struct wl_listener request_maximize;
 | 
						struct wl_listener request_maximize;
 | 
				
			||||||
	struct wl_listener map_notify;
 | 
						struct wl_listener map_notify;
 | 
				
			||||||
	struct wl_listener unmap_notify;
 | 
						struct wl_listener unmap_notify;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener surface_commit;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum roots_view_type {
 | 
					enum roots_view_type {
 | 
				
			||||||
| 
						 | 
					@ -69,6 +66,12 @@ struct roots_view {
 | 
				
			||||||
		float rotation;
 | 
							float rotation;
 | 
				
			||||||
	} saved;
 | 
						} saved;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							bool update_x, update_y;
 | 
				
			||||||
 | 
							double x, y;
 | 
				
			||||||
 | 
							uint32_t width, height;
 | 
				
			||||||
 | 
						} pending_move_resize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: Something for roots-enforced width/height
 | 
						// TODO: Something for roots-enforced width/height
 | 
				
			||||||
	enum roots_view_type type;
 | 
						enum roots_view_type type;
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,17 +90,17 @@ static void move_resize(struct roots_view *view, double x, double y,
 | 
				
			||||||
		y = y + height - constrained_height;
 | 
							y = y + height - constrained_height;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	roots_surface->move_resize.x = x;
 | 
						view->pending_move_resize.update_x = update_x;
 | 
				
			||||||
	roots_surface->move_resize.y = y;
 | 
						view->pending_move_resize.update_y = update_y;
 | 
				
			||||||
	roots_surface->move_resize.update_x = update_x;
 | 
						view->pending_move_resize.x = x;
 | 
				
			||||||
	roots_surface->move_resize.update_y = update_y;
 | 
						view->pending_move_resize.y = y;
 | 
				
			||||||
	roots_surface->move_resize.width = constrained_width;
 | 
						view->pending_move_resize.width = constrained_width;
 | 
				
			||||||
	roots_surface->move_resize.height = constrained_height;
 | 
						view->pending_move_resize.height = constrained_height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint32_t serial = wlr_xdg_toplevel_v6_set_size(surface, constrained_width,
 | 
						uint32_t serial = wlr_xdg_toplevel_v6_set_size(surface, constrained_width,
 | 
				
			||||||
		constrained_height);
 | 
							constrained_height);
 | 
				
			||||||
	if (serial > 0) {
 | 
						if (serial > 0) {
 | 
				
			||||||
		roots_surface->move_resize.configure_serial = serial;
 | 
							roots_surface->pending_move_resize_configure_serial = serial;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		view->x = x;
 | 
							view->x = x;
 | 
				
			||||||
		view->y = y;
 | 
							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 roots_view *view = roots_surface->view;
 | 
				
			||||||
	struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6;
 | 
						struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (roots_surface->move_resize.configure_serial > 0 &&
 | 
						uint32_t pending_serial =
 | 
				
			||||||
			roots_surface->move_resize.configure_serial >=
 | 
							roots_surface->pending_move_resize_configure_serial;
 | 
				
			||||||
			surface->configure_serial) {
 | 
						if (pending_serial > 0 && pending_serial >= surface->configure_serial) {
 | 
				
			||||||
		struct wlr_box size;
 | 
							struct wlr_box size;
 | 
				
			||||||
		get_size(view, &size);
 | 
							get_size(view, &size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (roots_surface->move_resize.update_x) {
 | 
							if (view->pending_move_resize.update_x) {
 | 
				
			||||||
			view->x = roots_surface->move_resize.x +
 | 
								view->x = view->pending_move_resize.x +
 | 
				
			||||||
				roots_surface->move_resize.width - size.width;
 | 
									view->pending_move_resize.width - size.width;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (roots_surface->move_resize.update_y) {
 | 
							if (view->pending_move_resize.update_y) {
 | 
				
			||||||
			view->y = roots_surface->move_resize.y +
 | 
								view->y = view->pending_move_resize.y +
 | 
				
			||||||
				roots_surface->move_resize.height - size.height;
 | 
									view->pending_move_resize.height - size.height;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (roots_surface->move_resize.configure_serial ==
 | 
							if (pending_serial == surface->configure_serial) {
 | 
				
			||||||
				surface->configure_serial) {
 | 
								roots_surface->pending_move_resize_configure_serial = 0;
 | 
				
			||||||
			roots_surface->move_resize.configure_serial = 0;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,15 +66,26 @@ static void move_resize(struct roots_view *view, double x, double y,
 | 
				
			||||||
	assert(view->type == ROOTS_XWAYLAND_VIEW);
 | 
						assert(view->type == ROOTS_XWAYLAND_VIEW);
 | 
				
			||||||
	struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface;
 | 
						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;
 | 
						uint32_t constrained_width, constrained_height;
 | 
				
			||||||
	apply_size_constraints(xwayland_surface, width, height, &constrained_width,
 | 
						apply_size_constraints(xwayland_surface, width, height, &constrained_width,
 | 
				
			||||||
		&constrained_height);
 | 
							&constrained_height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (update_x) {
 | 
				
			||||||
		x = x + width - constrained_width;
 | 
							x = x + width - constrained_width;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (update_y) {
 | 
				
			||||||
		y = y + height - constrained_height;
 | 
							y = y + height - constrained_height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	view->x = x;
 | 
						view->pending_move_resize.update_x = update_x;
 | 
				
			||||||
	view->y = y;
 | 
						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,
 | 
						wlr_xwayland_surface_configure(view->desktop->xwayland, xwayland_surface,
 | 
				
			||||||
		x, y, constrained_width, constrained_height);
 | 
							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);
 | 
						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) {
 | 
					static void handle_map_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct roots_xwayland_surface *roots_surface =
 | 
						struct roots_xwayland_surface *roots_surface =
 | 
				
			||||||
		wl_container_of(listener, roots_surface, map_notify);
 | 
							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->x = (double)xsurface->x;
 | 
				
			||||||
	view->y = (double)xsurface->y;
 | 
						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);
 | 
						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;
 | 
						struct roots_desktop *desktop = roots_surface->view->desktop;
 | 
				
			||||||
	roots_surface->view->wlr_surface = NULL;
 | 
						roots_surface->view->wlr_surface = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_remove(&roots_surface->surface_commit.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (size_t i = 0; i < desktop->views->length; i++) {
 | 
						for (size_t i = 0; i < desktop->views->length; i++) {
 | 
				
			||||||
		if (desktop->views->items[i] == roots_surface->view) {
 | 
							if (desktop->views->items[i] == roots_surface->view) {
 | 
				
			||||||
			wlr_list_del(desktop->views, i);
 | 
								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,
 | 
						wl_signal_add(&surface->events.request_maximize,
 | 
				
			||||||
		&roots_surface->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));
 | 
						struct roots_view *view = calloc(1, sizeof(struct roots_view));
 | 
				
			||||||
	if (view == NULL) {
 | 
						if (view == NULL) {
 | 
				
			||||||
		free(roots_surface);
 | 
							free(roots_surface);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue