diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-08-06 11:32:17 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-06 11:32:17 -0400 |
commit | d8b65193c493e5826383a08593395a598ce4b503 (patch) | |
tree | 97a1da416928ad8d7d3cca2e3e7dd72c39f924b6 | |
parent | Merge pull request #2392 from ianyfan/commands (diff) | |
parent | Handle views created after decoration mode is sent for xdg-shell-v6 (diff) | |
download | sway-d8b65193c493e5826383a08593395a598ce4b503.tar.gz sway-d8b65193c493e5826383a08593395a598ce4b503.tar.zst sway-d8b65193c493e5826383a08593395a598ce4b503.zip |
Merge pull request #2268 from emersion/server-decoration-borders
Enable borders on floating SSD xdg-shell views
-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 @@ | |||
1 | #ifndef _SWAY_DECORATION_H | ||
2 | #define _SWAY_DECORATION_H | ||
3 | |||
4 | #include <wlr/types/wlr_server_decoration.h> | ||
5 | |||
6 | struct sway_server_decoration { | ||
7 | struct wlr_server_decoration *wlr_server_decoration; | ||
8 | struct wl_list link; | ||
9 | |||
10 | struct wl_listener destroy; | ||
11 | struct wl_listener mode; | ||
12 | }; | ||
13 | |||
14 | struct sway_server_decoration *decoration_from_surface( | ||
15 | struct wlr_surface *surface); | ||
16 | |||
17 | #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 @@ | |||
4 | #include <wayland-server.h> | 4 | #include <wayland-server.h> |
5 | #include <wlr/backend.h> | 5 | #include <wlr/backend.h> |
6 | #include <wlr/backend/session.h> | 6 | #include <wlr/backend/session.h> |
7 | #include <wlr/render/wlr_renderer.h> | ||
7 | #include <wlr/types/wlr_compositor.h> | 8 | #include <wlr/types/wlr_compositor.h> |
8 | #include <wlr/types/wlr_data_device.h> | 9 | #include <wlr/types/wlr_data_device.h> |
9 | #include <wlr/types/wlr_layer_shell.h> | 10 | #include <wlr/types/wlr_layer_shell.h> |
11 | #include <wlr/types/wlr_server_decoration.h> | ||
10 | #include <wlr/types/wlr_xdg_shell_v6.h> | 12 | #include <wlr/types/wlr_xdg_shell_v6.h> |
11 | #include <wlr/types/wlr_xdg_shell.h> | 13 | #include <wlr/types/wlr_xdg_shell.h> |
12 | #include <wlr/render/wlr_renderer.h> | ||
13 | // TODO WLR: make Xwayland optional | 14 | // TODO WLR: make Xwayland optional |
14 | #include "list.h" | 15 | #include "list.h" |
15 | #include "config.h" | 16 | #include "config.h" |
@@ -42,11 +43,17 @@ struct sway_server { | |||
42 | 43 | ||
43 | struct wlr_xdg_shell *xdg_shell; | 44 | struct wlr_xdg_shell *xdg_shell; |
44 | struct wl_listener xdg_shell_surface; | 45 | struct wl_listener xdg_shell_surface; |
46 | |||
45 | #ifdef HAVE_XWAYLAND | 47 | #ifdef HAVE_XWAYLAND |
46 | struct sway_xwayland xwayland; | 48 | struct sway_xwayland xwayland; |
47 | struct wl_listener xwayland_surface; | 49 | struct wl_listener xwayland_surface; |
48 | struct wl_listener xwayland_ready; | 50 | struct wl_listener xwayland_ready; |
49 | #endif | 51 | #endif |
52 | |||
53 | struct wlr_server_decoration_manager *server_decoration_manager; | ||
54 | struct wl_listener server_decoration; | ||
55 | struct wl_list decorations; // sway_server_decoration::link | ||
56 | |||
50 | bool debug_txn_timings; | 57 | bool debug_txn_timings; |
51 | 58 | ||
52 | list_t *transactions; | 59 | list_t *transactions; |
@@ -71,4 +78,6 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data); | |||
71 | #ifdef HAVE_XWAYLAND | 78 | #ifdef HAVE_XWAYLAND |
72 | void handle_xwayland_surface(struct wl_listener *listener, void *data); | 79 | void handle_xwayland_surface(struct wl_listener *listener, void *data); |
73 | #endif | 80 | #endif |
81 | void handle_server_decoration(struct wl_listener *listener, void *data); | ||
82 | |||
74 | #endif | 83 | #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 { | |||
118 | struct sway_xdg_shell_v6_view { | 118 | struct sway_xdg_shell_v6_view { |
119 | struct sway_view view; | 119 | struct sway_view view; |
120 | 120 | ||
121 | enum wlr_server_decoration_manager_mode deco_mode; | ||
122 | |||
121 | struct wl_listener commit; | 123 | struct wl_listener commit; |
122 | struct wl_listener request_move; | 124 | struct wl_listener request_move; |
123 | struct wl_listener request_resize; | 125 | struct wl_listener request_resize; |
@@ -134,6 +136,8 @@ struct sway_xdg_shell_v6_view { | |||
134 | struct sway_xdg_shell_view { | 136 | struct sway_xdg_shell_view { |
135 | struct sway_view view; | 137 | struct sway_view view; |
136 | 138 | ||
139 | enum wlr_server_decoration_manager_mode deco_mode; | ||
140 | |||
137 | struct wl_listener commit; | 141 | struct wl_listener commit; |
138 | struct wl_listener request_move; | 142 | struct wl_listener request_move; |
139 | struct wl_listener request_resize; | 143 | 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 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include "sway/decoration.h" | ||
3 | #include "sway/server.h" | ||
4 | #include "sway/tree/view.h" | ||
5 | #include "log.h" | ||
6 | |||
7 | static void server_decoration_handle_destroy(struct wl_listener *listener, | ||
8 | void *data) { | ||
9 | struct sway_server_decoration *deco = | ||
10 | wl_container_of(listener, deco, destroy); | ||
11 | wl_list_remove(&deco->destroy.link); | ||
12 | wl_list_remove(&deco->mode.link); | ||
13 | wl_list_remove(&deco->link); | ||
14 | free(deco); | ||
15 | } | ||
16 | |||
17 | static void server_decoration_handle_mode(struct wl_listener *listener, | ||
18 | void *data) { | ||
19 | struct sway_server_decoration *deco = | ||
20 | wl_container_of(listener, deco, mode); | ||
21 | struct sway_view *view = | ||
22 | view_from_wlr_surface(deco->wlr_server_decoration->surface); | ||
23 | if (view == NULL || view->surface != deco->wlr_server_decoration->surface) { | ||
24 | return; | ||
25 | } | ||
26 | |||
27 | switch (view->type) { | ||
28 | case SWAY_VIEW_XDG_SHELL_V6:; | ||
29 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | ||
30 | (struct sway_xdg_shell_v6_view *)view; | ||
31 | xdg_shell_v6_view->deco_mode = deco->wlr_server_decoration->mode; | ||
32 | break; | ||
33 | case SWAY_VIEW_XDG_SHELL:; | ||
34 | struct sway_xdg_shell_view *xdg_shell_view = | ||
35 | (struct sway_xdg_shell_view *)view; | ||
36 | xdg_shell_view->deco_mode = deco->wlr_server_decoration->mode; | ||
37 | break; | ||
38 | default: | ||
39 | break; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | void handle_server_decoration(struct wl_listener *listener, void *data) { | ||
44 | struct wlr_server_decoration *wlr_deco = data; | ||
45 | |||
46 | struct sway_server_decoration *deco = calloc(1, sizeof(*deco)); | ||
47 | if (deco == NULL) { | ||
48 | return; | ||
49 | } | ||
50 | |||
51 | deco->wlr_server_decoration = wlr_deco; | ||
52 | |||
53 | wl_signal_add(&wlr_deco->events.destroy, &deco->destroy); | ||
54 | deco->destroy.notify = server_decoration_handle_destroy; | ||
55 | |||
56 | wl_signal_add(&wlr_deco->events.mode, &deco->mode); | ||
57 | deco->mode.notify = server_decoration_handle_mode; | ||
58 | |||
59 | wl_list_insert(&server.decorations, &deco->link); | ||
60 | } | ||
61 | |||
62 | struct sway_server_decoration *decoration_from_surface( | ||
63 | struct wlr_surface *surface) { | ||
64 | struct sway_server_decoration *deco; | ||
65 | wl_list_for_each(deco, &server.decorations, link) { | ||
66 | if (deco->wlr_server_decoration->surface == surface) { | ||
67 | return deco; | ||
68 | } | ||
69 | } | ||
70 | return NULL; | ||
71 | } | ||
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 @@ | |||
6 | #include <wlr/types/wlr_xdg_shell.h> | 6 | #include <wlr/types/wlr_xdg_shell.h> |
7 | #include <wlr/util/edges.h> | 7 | #include <wlr/util/edges.h> |
8 | #include "log.h" | 8 | #include "log.h" |
9 | #include "sway/decoration.h" | ||
9 | #include "sway/input/input-manager.h" | 10 | #include "sway/input/input-manager.h" |
10 | #include "sway/input/seat.h" | 11 | #include "sway/input/seat.h" |
11 | #include "sway/server.h" | 12 | #include "sway/server.h" |
@@ -170,6 +171,15 @@ static bool wants_floating(struct sway_view *view) { | |||
170 | || toplevel->parent; | 171 | || toplevel->parent; |
171 | } | 172 | } |
172 | 173 | ||
174 | static bool has_client_side_decorations(struct sway_view *view) { | ||
175 | struct sway_xdg_shell_view *xdg_shell_view = | ||
176 | xdg_shell_view_from_view(view); | ||
177 | if (xdg_shell_view == NULL) { | ||
178 | return true; | ||
179 | } | ||
180 | return xdg_shell_view->deco_mode != WLR_SERVER_DECORATION_MANAGER_MODE_SERVER; | ||
181 | } | ||
182 | |||
173 | static void for_each_surface(struct sway_view *view, | 183 | static void for_each_surface(struct sway_view *view, |
174 | wlr_surface_iterator_func_t iterator, void *user_data) { | 184 | wlr_surface_iterator_func_t iterator, void *user_data) { |
175 | if (xdg_shell_view_from_view(view) == NULL) { | 185 | if (xdg_shell_view_from_view(view) == NULL) { |
@@ -226,6 +236,7 @@ static const struct sway_view_impl view_impl = { | |||
226 | .set_tiled = set_tiled, | 236 | .set_tiled = set_tiled, |
227 | .set_fullscreen = set_fullscreen, | 237 | .set_fullscreen = set_fullscreen, |
228 | .wants_floating = wants_floating, | 238 | .wants_floating = wants_floating, |
239 | .has_client_side_decorations = has_client_side_decorations, | ||
229 | .for_each_surface = for_each_surface, | 240 | .for_each_surface = for_each_surface, |
230 | .for_each_popup = for_each_popup, | 241 | .for_each_popup = for_each_popup, |
231 | .close = _close, | 242 | .close = _close, |
@@ -357,6 +368,14 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
357 | view->natural_height = view->wlr_xdg_surface->surface->current.height; | 368 | view->natural_height = view->wlr_xdg_surface->surface->current.height; |
358 | } | 369 | } |
359 | 370 | ||
371 | struct sway_server_decoration *deco = | ||
372 | decoration_from_surface(xdg_surface->surface); | ||
373 | if (deco != NULL) { | ||
374 | xdg_shell_view->deco_mode = deco->wlr_server_decoration->mode; | ||
375 | } else { | ||
376 | xdg_shell_view->deco_mode = WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; | ||
377 | } | ||
378 | |||
360 | view_map(view, view->wlr_xdg_surface->surface); | 379 | view_map(view, view->wlr_xdg_surface->surface); |
361 | 380 | ||
362 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 381 | 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 @@ | |||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <wayland-server.h> | 5 | #include <wayland-server.h> |
6 | #include <wlr/types/wlr_xdg_shell_v6.h> | 6 | #include <wlr/types/wlr_xdg_shell_v6.h> |
7 | #include "log.h" | ||
8 | #include "sway/decoration.h" | ||
9 | #include "sway/input/input-manager.h" | ||
10 | #include "sway/input/seat.h" | ||
7 | #include "sway/server.h" | 11 | #include "sway/server.h" |
8 | #include "sway/tree/arrange.h" | 12 | #include "sway/tree/arrange.h" |
9 | #include "sway/tree/container.h" | 13 | #include "sway/tree/container.h" |
10 | #include "sway/tree/layout.h" | 14 | #include "sway/tree/layout.h" |
11 | #include "sway/tree/view.h" | 15 | #include "sway/tree/view.h" |
12 | #include "sway/input/seat.h" | ||
13 | #include "sway/input/input-manager.h" | ||
14 | #include "log.h" | ||
15 | 16 | ||
16 | static const struct sway_view_child_impl popup_impl; | 17 | static const struct sway_view_child_impl popup_impl; |
17 | 18 | ||
@@ -166,6 +167,15 @@ static bool wants_floating(struct sway_view *view) { | |||
166 | || toplevel->parent; | 167 | || toplevel->parent; |
167 | } | 168 | } |
168 | 169 | ||
170 | static bool has_client_side_decorations(struct sway_view *view) { | ||
171 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | ||
172 | xdg_shell_v6_view_from_view(view); | ||
173 | if (xdg_shell_v6_view == NULL) { | ||
174 | return true; | ||
175 | } | ||
176 | return xdg_shell_v6_view->deco_mode != WLR_SERVER_DECORATION_MANAGER_MODE_SERVER; | ||
177 | } | ||
178 | |||
169 | static void for_each_surface(struct sway_view *view, | 179 | static void for_each_surface(struct sway_view *view, |
170 | wlr_surface_iterator_func_t iterator, void *user_data) { | 180 | wlr_surface_iterator_func_t iterator, void *user_data) { |
171 | if (xdg_shell_v6_view_from_view(view) == NULL) { | 181 | if (xdg_shell_v6_view_from_view(view) == NULL) { |
@@ -223,6 +233,7 @@ static const struct sway_view_impl view_impl = { | |||
223 | .set_tiled = set_tiled, | 233 | .set_tiled = set_tiled, |
224 | .set_fullscreen = set_fullscreen, | 234 | .set_fullscreen = set_fullscreen, |
225 | .wants_floating = wants_floating, | 235 | .wants_floating = wants_floating, |
236 | .has_client_side_decorations = has_client_side_decorations, | ||
226 | .for_each_surface = for_each_surface, | 237 | .for_each_surface = for_each_surface, |
227 | .for_each_popup = for_each_popup, | 238 | .for_each_popup = for_each_popup, |
228 | .close = _close, | 239 | .close = _close, |
@@ -353,6 +364,14 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
353 | view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; | 364 | view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; |
354 | } | 365 | } |
355 | 366 | ||
367 | struct sway_server_decoration *deco = | ||
368 | decoration_from_surface(xdg_surface->surface); | ||
369 | if (deco != NULL) { | ||
370 | xdg_shell_v6_view->deco_mode = deco->wlr_server_decoration->mode; | ||
371 | } else { | ||
372 | xdg_shell_v6_view->deco_mode = WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; | ||
373 | } | ||
374 | |||
356 | view_map(view, view->wlr_xdg_surface_v6->surface); | 375 | view_map(view, view->wlr_xdg_surface_v6->surface); |
357 | 376 | ||
358 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 377 | 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 @@ | |||
1 | sway_sources = files( | 1 | sway_sources = files( |
2 | 'main.c', | ||
3 | 'server.c', | ||
4 | 'commands.c', | 2 | 'commands.c', |
5 | 'config.c', | 3 | 'config.c', |
6 | 'criteria.c', | 4 | 'criteria.c', |
7 | 'debug-tree.c', | 5 | 'debug-tree.c', |
6 | 'decoration.c', | ||
8 | 'ipc-json.c', | 7 | 'ipc-json.c', |
9 | 'ipc-server.c', | 8 | 'ipc-server.c', |
9 | 'main.c', | ||
10 | 'security.c', | 10 | 'security.c', |
11 | 'server.c', | ||
11 | 'swaynag.c', | 12 | 'swaynag.c', |
12 | 13 | ||
13 | 'desktop/desktop.c', | 14 | '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 @@ | |||
19 | #include <wlr/types/wlr_xcursor_manager.h> | 19 | #include <wlr/types/wlr_xcursor_manager.h> |
20 | #include <wlr/types/wlr_xdg_output.h> | 20 | #include <wlr/types/wlr_xdg_output.h> |
21 | #include <wlr/util/log.h> | 21 | #include <wlr/util/log.h> |
22 | // TODO WLR: make Xwayland optional | ||
23 | #include "list.h" | 22 | #include "list.h" |
24 | #include "sway/config.h" | 23 | #include "sway/config.h" |
25 | #include "sway/desktop/idle_inhibit_v1.h" | 24 | #include "sway/desktop/idle_inhibit_v1.h" |
@@ -85,7 +84,6 @@ bool server_init(struct sway_server *server) { | |||
85 | &server->xdg_shell_surface); | 84 | &server->xdg_shell_surface); |
86 | server->xdg_shell_surface.notify = handle_xdg_shell_surface; | 85 | server->xdg_shell_surface.notify = handle_xdg_shell_surface; |
87 | 86 | ||
88 | // TODO make xwayland optional | ||
89 | #ifdef HAVE_XWAYLAND | 87 | #ifdef HAVE_XWAYLAND |
90 | server->xwayland.wlr_xwayland = | 88 | server->xwayland.wlr_xwayland = |
91 | wlr_xwayland_create(server->wl_display, server->compositor, true); | 89 | wlr_xwayland_create(server->wl_display, server->compositor, true); |
@@ -109,11 +107,15 @@ bool server_init(struct sway_server *server) { | |||
109 | } | 107 | } |
110 | #endif | 108 | #endif |
111 | 109 | ||
112 | // TODO: Integration with sway borders | 110 | server->server_decoration_manager = |
113 | struct wlr_server_decoration_manager *deco_manager = | ||
114 | wlr_server_decoration_manager_create(server->wl_display); | 111 | wlr_server_decoration_manager_create(server->wl_display); |
115 | wlr_server_decoration_manager_set_default_mode( | 112 | wlr_server_decoration_manager_set_default_mode( |
116 | deco_manager, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); | 113 | server->server_decoration_manager, |
114 | WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); | ||
115 | wl_signal_add(&server->server_decoration_manager->events.new_decoration, | ||
116 | &server->server_decoration); | ||
117 | server->server_decoration.notify = handle_server_decoration; | ||
118 | wl_list_init(&server->decorations); | ||
117 | 119 | ||
118 | wlr_linux_dmabuf_v1_create(server->wl_display, renderer); | 120 | wlr_linux_dmabuf_v1_create(server->wl_display, renderer); |
119 | wlr_export_dmabuf_manager_v1_create(server->wl_display); | 121 | wlr_export_dmabuf_manager_v1_create(server->wl_display); |