aboutsummaryrefslogtreecommitdiff
path: root/rootston
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-08-02 09:33:10 -0400
committerGitHub <noreply@github.com>2018-08-02 09:33:10 -0400
commit5642c5cc8fd71103cb4805b1b9f1526311d544f8 (patch)
tree4a0be117fe52bc0266b00d4a0b2d211973b7484d /rootston
parenta3c33e93b80ffd3bd9f9c8dd9af9032ca578b726 (diff)
parent555721f7142e1e363c17820657fb1e2b004e7c54 (diff)
Merge pull request #1053 from emersion/xdg-decoration
Add xdg-decoration-unstable-v1 support
Diffstat (limited to 'rootston')
-rw-r--r--rootston/desktop.c23
-rw-r--r--rootston/xdg_shell.c70
2 files changed, 93 insertions, 0 deletions
diff --git a/rootston/desktop.c b/rootston/desktop.c
index 17bf7ec4..786ac99e 100644
--- a/rootston/desktop.c
+++ b/rootston/desktop.c
@@ -552,6 +552,23 @@ void view_update_size(struct roots_view *view, uint32_t width, uint32_t height)
view_damage_whole(view);
}
+void view_update_decorated(struct roots_view *view, bool decorated) {
+ if (view->decorated == decorated) {
+ return;
+ }
+
+ view_damage_whole(view);
+ view->decorated = decorated;
+ if (decorated) {
+ view->border_width = 4;
+ view->titlebar_height = 12;
+ } else {
+ view->border_width = 0;
+ view->titlebar_height = 0;
+ }
+ view_damage_whole(view);
+}
+
static bool view_at(struct roots_view *view, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy) {
if (view->type == ROOTS_WL_SHELL_VIEW &&
@@ -884,6 +901,12 @@ struct roots_desktop *desktop_create(struct roots_server *server,
desktop->screencopy = wlr_screencopy_manager_v1_create(server->wl_display);
+ desktop->xdg_decoration_manager =
+ wlr_xdg_decoration_manager_v1_create(server->wl_display);
+ wl_signal_add(&desktop->xdg_decoration_manager->events.new_toplevel_decoration,
+ &desktop->xdg_toplevel_decoration);
+ desktop->xdg_toplevel_decoration.notify = handle_xdg_toplevel_decoration;
+
return desktop;
}
diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c
index 0c438be4..e5ab9efd 100644
--- a/rootston/xdg_shell.c
+++ b/rootston/xdg_shell.c
@@ -265,6 +265,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);
}
@@ -439,6 +440,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) {
@@ -465,3 +467,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);
+}