aboutsummaryrefslogtreecommitdiff
path: root/rootston/xdg_shell.c
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-06-10 11:15:26 +0100
committeremersion <contact@emersion.fr>2018-07-28 22:48:07 +0100
commit555721f7142e1e363c17820657fb1e2b004e7c54 (patch)
tree61bf9363d2b60a2b62f4e853cf32d960f3a08a1e /rootston/xdg_shell.c
parentb6ed1f29a4dbba93eb53c32ec5492db8ee1d9343 (diff)
Add xdg-decoration-unstable-v1 support
Diffstat (limited to 'rootston/xdg_shell.c')
-rw-r--r--rootston/xdg_shell.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c
index d04d37e1..e63eed85 100644
--- a/rootston/xdg_shell.c
+++ b/rootston/xdg_shell.c
@@ -263,6 +263,7 @@ static void destroy(struct roots_view *view) {
wl_list_remove(&roots_xdg_surface->request_resize.link);
wl_list_remove(&roots_xdg_surface->request_maximize.link);
wl_list_remove(&roots_xdg_surface->request_fullscreen.link);
+ roots_xdg_surface->view->xdg_surface->data = NULL;
free(roots_xdg_surface);
}
@@ -437,6 +438,7 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
&roots_surface->request_fullscreen);
roots_surface->new_popup.notify = handle_new_popup;
wl_signal_add(&surface->events.new_popup, &roots_surface->new_popup);
+ surface->data = roots_surface;
struct roots_view *view = view_create(desktop);
if (!view) {
@@ -463,3 +465,71 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
view_set_fullscreen(view, true, NULL);
}
}
+
+
+
+static void decoration_handle_destroy(struct wl_listener *listener,
+ void *data) {
+ struct roots_xdg_toplevel_decoration *decoration =
+ wl_container_of(listener, decoration, destroy);
+
+ view_update_decorated(decoration->surface->view, false);
+ wl_list_remove(&decoration->destroy.link);
+ wl_list_remove(&decoration->request_mode.link);
+ wl_list_remove(&decoration->surface_commit.link);
+ free(decoration);
+}
+
+static void decoration_handle_request_mode(struct wl_listener *listener,
+ void *data) {
+ struct roots_xdg_toplevel_decoration *decoration =
+ wl_container_of(listener, decoration, request_mode);
+
+ enum wlr_xdg_toplevel_decoration_v1_mode mode =
+ decoration->wlr_decoration->client_pending_mode;
+ if (mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_NONE) {
+ mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
+ }
+ wlr_xdg_toplevel_decoration_v1_set_mode(decoration->wlr_decoration, mode);
+}
+
+static void decoration_handle_surface_commit(struct wl_listener *listener,
+ void *data) {
+ struct roots_xdg_toplevel_decoration *decoration =
+ wl_container_of(listener, decoration, surface_commit);
+
+ bool decorated = decoration->wlr_decoration->current_mode ==
+ WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
+ view_update_decorated(decoration->surface->view, decorated);
+}
+
+void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data) {
+ struct roots_desktop *desktop =
+ wl_container_of(listener, desktop, xdg_toplevel_decoration);
+ struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration = data;
+
+ wlr_log(WLR_DEBUG, "new xdg toplevel decoration");
+
+ struct roots_xdg_surface *xdg_surface = wlr_decoration->surface->data;
+ assert(xdg_surface != NULL);
+ struct wlr_xdg_surface *wlr_xdg_surface = xdg_surface->view->xdg_surface;
+
+ struct roots_xdg_toplevel_decoration *decoration =
+ calloc(1, sizeof(struct roots_xdg_toplevel_decoration));
+ if (decoration == NULL) {
+ return;
+ }
+ decoration->wlr_decoration = wlr_decoration;
+ decoration->surface = xdg_surface;
+
+ decoration->destroy.notify = decoration_handle_destroy;
+ wl_signal_add(&wlr_decoration->events.destroy, &decoration->destroy);
+ decoration->request_mode.notify = decoration_handle_request_mode;
+ wl_signal_add(&wlr_decoration->events.request_mode,
+ &decoration->request_mode);
+ decoration->surface_commit.notify = decoration_handle_surface_commit;
+ wl_signal_add(&wlr_xdg_surface->surface->events.commit,
+ &decoration->surface_commit);
+
+ decoration_handle_request_mode(&decoration->request_mode, wlr_decoration);
+}