aboutsummaryrefslogtreecommitdiffstats
path: root/sway/xdg_decoration.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/xdg_decoration.c')
-rw-r--r--sway/xdg_decoration.c73
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
9static 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
20static 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
35void 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
64struct 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}