diff options
| -rw-r--r-- | include/sway/decoration.h | 17 | ||||
| -rw-r--r-- | include/sway/server.h | 11 | ||||
| -rw-r--r-- | include/sway/tree/view.h | 4 | ||||
| -rw-r--r-- | sway/decoration.c | 71 | ||||
| -rw-r--r-- | sway/desktop/xdg_shell.c | 19 | ||||
| -rw-r--r-- | sway/desktop/xdg_shell_v6.c | 25 | ||||
| -rw-r--r-- | sway/meson.build | 5 | ||||
| -rw-r--r-- | sway/server.c | 12 | 
8 files changed, 153 insertions, 11 deletions
| diff --git a/include/sway/decoration.h b/include/sway/decoration.h new file mode 100644 index 00000000..7916746e --- /dev/null +++ b/include/sway/decoration.h @@ -0,0 +1,17 @@ +#ifndef _SWAY_DECORATION_H +#define _SWAY_DECORATION_H + +#include <wlr/types/wlr_server_decoration.h> + +struct sway_server_decoration { +	struct wlr_server_decoration *wlr_server_decoration; +	struct wl_list link; + +	struct wl_listener destroy; +	struct wl_listener mode; +}; + +struct sway_server_decoration *decoration_from_surface( +	struct wlr_surface *surface); + +#endif diff --git a/include/sway/server.h b/include/sway/server.h index a3782f91..b93584b6 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -4,12 +4,13 @@  #include <wayland-server.h>  #include <wlr/backend.h>  #include <wlr/backend/session.h> +#include <wlr/render/wlr_renderer.h>  #include <wlr/types/wlr_compositor.h>  #include <wlr/types/wlr_data_device.h>  #include <wlr/types/wlr_layer_shell.h> +#include <wlr/types/wlr_server_decoration.h>  #include <wlr/types/wlr_xdg_shell_v6.h>  #include <wlr/types/wlr_xdg_shell.h> -#include <wlr/render/wlr_renderer.h>  // TODO WLR: make Xwayland optional  #include "list.h"  #include "config.h" @@ -42,11 +43,17 @@ struct sway_server {  	struct wlr_xdg_shell *xdg_shell;  	struct wl_listener xdg_shell_surface; +  #ifdef HAVE_XWAYLAND  	struct sway_xwayland xwayland;  	struct wl_listener xwayland_surface;  	struct wl_listener xwayland_ready;  #endif + +	struct wlr_server_decoration_manager *server_decoration_manager; +	struct wl_listener server_decoration; +	struct wl_list decorations; // sway_server_decoration::link +  	bool debug_txn_timings;  	list_t *transactions; @@ -71,4 +78,6 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data);  #ifdef HAVE_XWAYLAND  void handle_xwayland_surface(struct wl_listener *listener, void *data);  #endif +void handle_server_decoration(struct wl_listener *listener, void *data); +  #endif diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 4a3f01e7..c2225bcb 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -118,6 +118,8 @@ struct sway_view {  struct sway_xdg_shell_v6_view {  	struct sway_view view; +	enum wlr_server_decoration_manager_mode deco_mode; +  	struct wl_listener commit;  	struct wl_listener request_move;  	struct wl_listener request_resize; @@ -134,6 +136,8 @@ struct sway_xdg_shell_v6_view {  struct sway_xdg_shell_view {  	struct sway_view view; +	enum wlr_server_decoration_manager_mode deco_mode; +  	struct wl_listener commit;  	struct wl_listener request_move;  	struct wl_listener request_resize; diff --git a/sway/decoration.c b/sway/decoration.c new file mode 100644 index 00000000..0e3e67ac --- /dev/null +++ b/sway/decoration.c @@ -0,0 +1,71 @@ +#include <stdlib.h> +#include "sway/decoration.h" +#include "sway/server.h" +#include "sway/tree/view.h" +#include "log.h" + +static void server_decoration_handle_destroy(struct wl_listener *listener, +		void *data) { +	struct sway_server_decoration *deco = +		wl_container_of(listener, deco, destroy); +	wl_list_remove(&deco->destroy.link); +	wl_list_remove(&deco->mode.link); +	wl_list_remove(&deco->link); +	free(deco); +} + +static void server_decoration_handle_mode(struct wl_listener *listener, +		void *data) { +	struct sway_server_decoration *deco = +		wl_container_of(listener, deco, mode); +	struct sway_view *view = +		view_from_wlr_surface(deco->wlr_server_decoration->surface); +	if (view == NULL || view->surface != deco->wlr_server_decoration->surface) { +		return; +	} + +	switch (view->type) { +	case SWAY_VIEW_XDG_SHELL_V6:; +		struct sway_xdg_shell_v6_view *xdg_shell_v6_view = +			(struct sway_xdg_shell_v6_view *)view; +		xdg_shell_v6_view->deco_mode = deco->wlr_server_decoration->mode; +		break; +	case SWAY_VIEW_XDG_SHELL:; +		struct sway_xdg_shell_view *xdg_shell_view = +			(struct sway_xdg_shell_view *)view; +		xdg_shell_view->deco_mode = deco->wlr_server_decoration->mode; +		break; +	default: +		break; +	} +} + +void handle_server_decoration(struct wl_listener *listener, void *data) { +	struct wlr_server_decoration *wlr_deco = data; + +	struct sway_server_decoration *deco = calloc(1, sizeof(*deco)); +	if (deco == NULL) { +		return; +	} + +	deco->wlr_server_decoration = wlr_deco; + +	wl_signal_add(&wlr_deco->events.destroy, &deco->destroy); +	deco->destroy.notify = server_decoration_handle_destroy; + +	wl_signal_add(&wlr_deco->events.mode, &deco->mode); +	deco->mode.notify = server_decoration_handle_mode; + +	wl_list_insert(&server.decorations, &deco->link); +} + +struct sway_server_decoration *decoration_from_surface( +		struct wlr_surface *surface) { +	struct sway_server_decoration *deco; +	wl_list_for_each(deco, &server.decorations, link) { +		if (deco->wlr_server_decoration->surface == surface) { +			return deco; +		} +	} +	return NULL; +} diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index b364663d..3b73f99c 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -6,6 +6,7 @@  #include <wlr/types/wlr_xdg_shell.h>  #include <wlr/util/edges.h>  #include "log.h" +#include "sway/decoration.h"  #include "sway/input/input-manager.h"  #include "sway/input/seat.h"  #include "sway/server.h" @@ -170,6 +171,15 @@ static bool wants_floating(struct sway_view *view) {  		|| toplevel->parent;  } +static bool has_client_side_decorations(struct sway_view *view) { +	struct sway_xdg_shell_view *xdg_shell_view = +		xdg_shell_view_from_view(view); +	if (xdg_shell_view == NULL) { +		return true; +	} +	return xdg_shell_view->deco_mode != WLR_SERVER_DECORATION_MANAGER_MODE_SERVER; +} +  static void for_each_surface(struct sway_view *view,  		wlr_surface_iterator_func_t iterator, void *user_data) {  	if (xdg_shell_view_from_view(view) == NULL) { @@ -226,6 +236,7 @@ static const struct sway_view_impl view_impl = {  	.set_tiled = set_tiled,  	.set_fullscreen = set_fullscreen,  	.wants_floating = wants_floating, +	.has_client_side_decorations = has_client_side_decorations,  	.for_each_surface = for_each_surface,  	.for_each_popup = for_each_popup,  	.close = _close, @@ -357,6 +368,14 @@ static void handle_map(struct wl_listener *listener, void *data) {  		view->natural_height = view->wlr_xdg_surface->surface->current.height;  	} +	struct sway_server_decoration *deco = +		decoration_from_surface(xdg_surface->surface); +	if (deco != NULL) { +		xdg_shell_view->deco_mode = deco->wlr_server_decoration->mode; +	} else { +		xdg_shell_view->deco_mode = WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; +	} +  	view_map(view, view->wlr_xdg_surface->surface);  	if (xdg_surface->toplevel->client_pending.fullscreen) { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index ffea03ad..a947fb35 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -4,14 +4,15 @@  #include <stdlib.h>  #include <wayland-server.h>  #include <wlr/types/wlr_xdg_shell_v6.h> +#include "log.h" +#include "sway/decoration.h" +#include "sway/input/input-manager.h" +#include "sway/input/seat.h"  #include "sway/server.h"  #include "sway/tree/arrange.h"  #include "sway/tree/container.h"  #include "sway/tree/layout.h"  #include "sway/tree/view.h" -#include "sway/input/seat.h" -#include "sway/input/input-manager.h" -#include "log.h"  static const struct sway_view_child_impl popup_impl; @@ -166,6 +167,15 @@ static bool wants_floating(struct sway_view *view) {  		|| toplevel->parent;  } +static bool has_client_side_decorations(struct sway_view *view) { +	struct sway_xdg_shell_v6_view *xdg_shell_v6_view = +		xdg_shell_v6_view_from_view(view); +	if (xdg_shell_v6_view == NULL) { +		return true; +	} +	return xdg_shell_v6_view->deco_mode != WLR_SERVER_DECORATION_MANAGER_MODE_SERVER; +} +  static void for_each_surface(struct sway_view *view,  		wlr_surface_iterator_func_t iterator, void *user_data) {  	if (xdg_shell_v6_view_from_view(view) == NULL) { @@ -223,6 +233,7 @@ static const struct sway_view_impl view_impl = {  	.set_tiled = set_tiled,  	.set_fullscreen = set_fullscreen,  	.wants_floating = wants_floating, +	.has_client_side_decorations = has_client_side_decorations,  	.for_each_surface = for_each_surface,  	.for_each_popup = for_each_popup,  	.close = _close, @@ -353,6 +364,14 @@ static void handle_map(struct wl_listener *listener, void *data) {  		view->natural_height = view->wlr_xdg_surface_v6->surface->current.height;  	} +	struct sway_server_decoration *deco = +		decoration_from_surface(xdg_surface->surface); +	if (deco != NULL) { +		xdg_shell_v6_view->deco_mode = deco->wlr_server_decoration->mode; +	} else { +		xdg_shell_v6_view->deco_mode = WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; +	} +  	view_map(view, view->wlr_xdg_surface_v6->surface);  	if (xdg_surface->toplevel->client_pending.fullscreen) { diff --git a/sway/meson.build b/sway/meson.build index c18fb6e2..2a457270 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -1,13 +1,14 @@  sway_sources = files( -	'main.c', -	'server.c',  	'commands.c',  	'config.c',  	'criteria.c',  	'debug-tree.c', +	'decoration.c',  	'ipc-json.c',  	'ipc-server.c', +	'main.c',  	'security.c', +	'server.c',  	'swaynag.c',  	'desktop/desktop.c', diff --git a/sway/server.c b/sway/server.c index e8755360..e8dc63be 100644 --- a/sway/server.c +++ b/sway/server.c @@ -19,7 +19,6 @@  #include <wlr/types/wlr_xcursor_manager.h>  #include <wlr/types/wlr_xdg_output.h>  #include <wlr/util/log.h> -// TODO WLR: make Xwayland optional  #include "list.h"  #include "sway/config.h"  #include "sway/desktop/idle_inhibit_v1.h" @@ -85,7 +84,6 @@ bool server_init(struct sway_server *server) {  		&server->xdg_shell_surface);  	server->xdg_shell_surface.notify = handle_xdg_shell_surface; -	// TODO make xwayland optional  #ifdef HAVE_XWAYLAND  	server->xwayland.wlr_xwayland =  		wlr_xwayland_create(server->wl_display, server->compositor, true); @@ -109,11 +107,15 @@ bool server_init(struct sway_server *server) {  	}  #endif -	// TODO: Integration with sway borders -	struct wlr_server_decoration_manager *deco_manager = +	server->server_decoration_manager =  		wlr_server_decoration_manager_create(server->wl_display);  	wlr_server_decoration_manager_set_default_mode( -		deco_manager, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); +		server->server_decoration_manager, +		WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); +	wl_signal_add(&server->server_decoration_manager->events.new_decoration, +		&server->server_decoration); +	server->server_decoration.notify = handle_server_decoration; +	wl_list_init(&server->decorations);  	wlr_linux_dmabuf_v1_create(server->wl_display, renderer);  	wlr_export_dmabuf_manager_v1_create(server->wl_display); | 
