diff options
| -rw-r--r-- | include/rootston/view.h | 15 | ||||
| -rw-r--r-- | rootston/xdg_shell_v6.c | 37 | ||||
| -rw-r--r-- | 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); | 
