diff options
Diffstat (limited to 'sway/xdg_decoration.c')
-rw-r--r-- | sway/xdg_decoration.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/sway/xdg_decoration.c b/sway/xdg_decoration.c new file mode 100644 index 00000000..2e7e4bd0 --- /dev/null +++ b/sway/xdg_decoration.c | |||
@@ -0,0 +1,73 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include "sway/desktop/transaction.h" | ||
3 | #include "sway/server.h" | ||
4 | #include "sway/tree/arrange.h" | ||
5 | #include "sway/tree/view.h" | ||
6 | #include "sway/xdg_decoration.h" | ||
7 | #include "log.h" | ||
8 | |||
9 | static void xdg_decoration_handle_destroy(struct wl_listener *listener, | ||
10 | void *data) { | ||
11 | struct sway_xdg_decoration *deco = | ||
12 | wl_container_of(listener, deco, destroy); | ||
13 | deco->view->xdg_decoration = NULL; | ||
14 | wl_list_remove(&deco->destroy.link); | ||
15 | wl_list_remove(&deco->surface_commit.link); | ||
16 | wl_list_remove(&deco->link); | ||
17 | free(deco); | ||
18 | } | ||
19 | |||
20 | static void xdg_decoration_handle_surface_commit(struct wl_listener *listener, | ||
21 | void *data) { | ||
22 | struct sway_xdg_decoration *decoration = | ||
23 | wl_container_of(listener, decoration, surface_commit); | ||
24 | |||
25 | bool csd = decoration->wlr_xdg_decoration->current_mode == | ||
26 | WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; | ||
27 | struct sway_view *view = decoration->view; | ||
28 | |||
29 | view_set_csd_from_client(view, csd); | ||
30 | |||
31 | arrange_container(view->container); | ||
32 | transaction_commit_dirty(); | ||
33 | } | ||
34 | |||
35 | void handle_xdg_decoration(struct wl_listener *listener, void *data) { | ||
36 | struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data; | ||
37 | struct sway_xdg_shell_view *xdg_shell_view = wlr_deco->surface->data; | ||
38 | struct wlr_xdg_surface *wlr_xdg_surface = | ||
39 | xdg_shell_view->view.wlr_xdg_surface; | ||
40 | |||
41 | struct sway_xdg_decoration *deco = calloc(1, sizeof(*deco)); | ||
42 | if (deco == NULL) { | ||
43 | return; | ||
44 | } | ||
45 | |||
46 | deco->view = &xdg_shell_view->view; | ||
47 | deco->view->xdg_decoration = deco; | ||
48 | deco->wlr_xdg_decoration = wlr_deco; | ||
49 | |||
50 | wl_signal_add(&wlr_deco->events.destroy, &deco->destroy); | ||
51 | deco->destroy.notify = xdg_decoration_handle_destroy; | ||
52 | |||
53 | // Note: We don't listen to the request_mode signal here, effectively | ||
54 | // ignoring any modes the client asks to set. The client can still force a | ||
55 | // mode upon us, in which case we get upset but live with it. | ||
56 | |||
57 | deco->surface_commit.notify = xdg_decoration_handle_surface_commit; | ||
58 | wl_signal_add(&wlr_xdg_surface->surface->events.commit, | ||
59 | &deco->surface_commit); | ||
60 | |||
61 | wl_list_insert(&server.xdg_decorations, &deco->link); | ||
62 | } | ||
63 | |||
64 | struct sway_xdg_decoration *xdg_decoration_from_surface( | ||
65 | struct wlr_surface *surface) { | ||
66 | struct sway_xdg_decoration *deco; | ||
67 | wl_list_for_each(deco, &server.xdg_decorations, link) { | ||
68 | if (deco->wlr_xdg_decoration->surface->surface == surface) { | ||
69 | return deco; | ||
70 | } | ||
71 | } | ||
72 | return NULL; | ||
73 | } | ||