This replaces view.using_csd with a new border mode: B_CSD. This also
removes sway_xdg_shell{_v6}_view.deco_mode and
view->has_client_side_decorations as we can now get these from the
border.
You can use `border toggle` to cycle through the modes including CSD, or
use `border csd` to set it directly. The client must support the
xdg-decoration protocol, and the only client I know of that does is the
example in wlroots.
If the client switches from SSD to CSD without us expecting it (via the
server-decoration protocol), we stash the previous border type into
view.saved_border so we can restore it if the client returns to SSD. I
haven't found a way to test this though.
			
			
				master
			
			
		
							parent
							
								
									58af001517
								
							
						
					
					
						commit
						7b138e5ef0
					
				| @ -0,0 +1,19 @@ | ||||
| #ifndef _SWAY_XDG_DECORATION_H | ||||
| #define _SWAY_XDG_DECORATION_H | ||||
| 
 | ||||
| #include <wlr/types/wlr_xdg_decoration_v1.h> | ||||
| 
 | ||||
| struct sway_xdg_decoration { | ||||
| 	struct wlr_xdg_toplevel_decoration_v1 *wlr_xdg_decoration; | ||||
| 	struct wl_list link; | ||||
| 
 | ||||
| 	struct sway_view *view; | ||||
| 
 | ||||
| 	struct wl_listener destroy; | ||||
| 	struct wl_listener surface_commit; | ||||
| }; | ||||
| 
 | ||||
| struct sway_xdg_decoration *xdg_decoration_from_surface( | ||||
| 	struct wlr_surface *surface); | ||||
| 
 | ||||
| #endif | ||||
| @ -0,0 +1,73 @@ | ||||
| #include <stdlib.h> | ||||
| #include "sway/desktop/transaction.h" | ||||
| #include "sway/server.h" | ||||
| #include "sway/tree/arrange.h" | ||||
| #include "sway/tree/view.h" | ||||
| #include "sway/xdg_decoration.h" | ||||
| #include "log.h" | ||||
| 
 | ||||
| static void xdg_decoration_handle_destroy(struct wl_listener *listener, | ||||
| 		void *data) { | ||||
| 	struct sway_xdg_decoration *deco = | ||||
| 		wl_container_of(listener, deco, destroy); | ||||
| 	deco->view->xdg_decoration = NULL; | ||||
| 	wl_list_remove(&deco->destroy.link); | ||||
| 	wl_list_remove(&deco->surface_commit.link); | ||||
| 	wl_list_remove(&deco->link); | ||||
| 	free(deco); | ||||
| } | ||||
| 
 | ||||
| static void xdg_decoration_handle_surface_commit(struct wl_listener *listener, | ||||
| 		void *data) { | ||||
| 	struct sway_xdg_decoration *decoration = | ||||
| 		wl_container_of(listener, decoration, surface_commit); | ||||
| 
 | ||||
| 	bool csd = decoration->wlr_xdg_decoration->current_mode == | ||||
| 		WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; | ||||
| 	struct sway_view *view = decoration->view; | ||||
| 
 | ||||
| 	view_set_csd_from_client(view, csd); | ||||
| 
 | ||||
| 	arrange_container(view->container); | ||||
| 	transaction_commit_dirty(); | ||||
| } | ||||
| 
 | ||||
| void handle_xdg_decoration(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data; | ||||
| 	struct sway_xdg_shell_view *xdg_shell_view = wlr_deco->surface->data; | ||||
| 	struct wlr_xdg_surface *wlr_xdg_surface = | ||||
| 		xdg_shell_view->view.wlr_xdg_surface; | ||||
| 
 | ||||
| 	struct sway_xdg_decoration *deco = calloc(1, sizeof(*deco)); | ||||
| 	if (deco == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	deco->view = &xdg_shell_view->view; | ||||
| 	deco->view->xdg_decoration = deco; | ||||
| 	deco->wlr_xdg_decoration = wlr_deco; | ||||
| 
 | ||||
| 	wl_signal_add(&wlr_deco->events.destroy, &deco->destroy); | ||||
| 	deco->destroy.notify = xdg_decoration_handle_destroy; | ||||
| 
 | ||||
| 	// Note: We don't listen to the request_mode signal here, effectively
 | ||||
| 	// ignoring any modes the client asks to set. The client can still force a
 | ||||
| 	// mode upon us, in which case we get upset but live with it.
 | ||||
| 
 | ||||
| 	deco->surface_commit.notify = xdg_decoration_handle_surface_commit; | ||||
| 	wl_signal_add(&wlr_xdg_surface->surface->events.commit, | ||||
| 		&deco->surface_commit); | ||||
| 
 | ||||
| 	wl_list_insert(&server.xdg_decorations, &deco->link); | ||||
| } | ||||
| 
 | ||||
| struct sway_xdg_decoration *xdg_decoration_from_surface( | ||||
| 		struct wlr_surface *surface) { | ||||
| 	struct sway_xdg_decoration *deco; | ||||
| 	wl_list_for_each(deco, &server.xdg_decorations, link) { | ||||
| 		if (deco->wlr_xdg_decoration->surface->surface == surface) { | ||||
| 			return deco; | ||||
| 		} | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue