tSupport xdg-decoration v1 protocol to enforce SSD - spkp - Stacking wayland compositor
 (HTM) git clone git://git.z3bra.org/spkp.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit bdb94039d9d277179778aa36b086ce8c9d4f90f7
 (DIR) parent 9937532ed873f3f1b1da2e28fc7b2fa1ab2a50cb
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Tue, 10 Nov 2020 16:20:56 +0100
       
       Support xdg-decoration v1 protocol to enforce SSD
       
       Diffstat:
         M compositor.c                        |      78 ++++++++++++++++++++++++++++++-
         M mkfile                              |      10 ++++++++--
       
       2 files changed, 85 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/compositor.c b/compositor.c
       t@@ -19,11 +19,13 @@
        #include <wlr/types/wlr_primary_selection_v1.h>
        #include <wlr/types/wlr_screencopy_v1.h>
        #include <wlr/types/wlr_xcursor_manager.h>
       +#include <wlr/types/wlr_xdg_decoration_v1.h>
        #include <wlr/types/wlr_xdg_shell.h>
        
        #include <linux/input-event-codes.h>
        
        #include "xdg-shell-protocol.h"
       +#include "xdg-decoration-unstable-v1-protocol.h"
        
        #include "arg.h"
        
       t@@ -49,10 +51,12 @@ struct state {
        
                struct wlr_cursor *cursor;
                struct wlr_xcursor_manager *cursor_mgr;
       +        struct wlr_xdg_decoration_manager_v1 *chrome_mgr;
        
                struct wl_listener new_input;
                struct wl_listener new_output;
                struct wl_listener new_window;
       +        struct wl_listener new_chrome;
        
                /* cursor related events */
                struct wl_listener req_cursor;
       t@@ -84,7 +88,7 @@ struct output {
        struct window {
                struct state *server;
                struct wlr_xdg_surface *toplevel;
       -
       +        struct wlr_xdg_toplevel_decoration_v1 decoration;
                double x, y;
        
                int mapped;
       t@@ -112,6 +116,14 @@ struct keyboard {
                struct wl_list link;
        };
        
       +struct chrome {
       +        struct state *server;
       +        struct wlr_xdg_toplevel_decoration_v1 *decoration;
       +
       +        struct wl_listener destroy;
       +        struct wl_listener mode;
       +};
       +
        /* Optional argument to pass down to a keybinding function */
        union keyarg {
                int i;
       t@@ -144,10 +156,13 @@ static void cb_new_output(struct wl_listener *, void *);
        static void cb_destroy_output(struct wl_listener *, void *);
        static void cb_frame_output(struct wl_listener *, void *);
        static void cb_new_window(struct wl_listener *, void *);
       +static void cb_new_decoration(struct wl_listener *, void *);
        
        static void cb_map_window(struct wl_listener *, void *);
        static void cb_unmap_window(struct wl_listener *, void *);
        static void cb_destroy_window(struct wl_listener *, void *);
       +static void cb_set_chrome(struct wl_listener *, void *);
       +static void cb_destroy_chrome(struct wl_listener *, void *);
        
        static void cb_kb_mod(struct wl_listener *, void *);
        static void cb_kb_key(struct wl_listener *, void *);
       t@@ -370,6 +385,33 @@ cb_new_window(struct wl_listener *listener, void *data)
        }
        
        /*
       + * Top level window request to add decorations
       + */
       +void
       +cb_new_decoration(struct wl_listener *listener, void *data)
       +{
       +        struct state *server;
       +        struct chrome *chrome;
       +        struct wlr_xdg_toplevel_decoration_v1 *decoration;
       +
       +        server = wl_container_of(listener, server, new_chrome);
       +        decoration = data;
       +
       +        chrome = calloc(1, sizeof(*chrome));
       +        if (!chrome)
       +                return;
       +
       +        chrome->decoration = decoration;
       +        chrome->server = server;
       +
       +        chrome->mode.notify = cb_set_chrome;
       +        chrome->destroy.notify = cb_destroy_chrome;
       +
       +        wl_signal_add(&decoration->events.request_mode, &chrome->mode);
       +        wl_signal_add(&decoration->events.destroy, &chrome->destroy);
       +}
       +
       +/*
         * Request from a client to be mapped on-screen.
         */
        void
       t@@ -412,6 +454,37 @@ cb_destroy_window(struct wl_listener *listener, void *data)
        }
        
        /*
       + * Ask wether to use client-side or server-side decorations.
       + * We always to server-side.
       + */
       +void
       +cb_set_chrome(struct wl_listener *listener, void *data)
       +{
       +        (void)data;
       +        struct chrome *chrome;
       +
       +        chrome = wl_container_of(listener, chrome, mode);
       +        wlr_xdg_toplevel_decoration_v1_set_mode(chrome->decoration,
       +                WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
       +}
       +
       +/*
       + * Destroy chrome associated to a window
       + */
       +void
       +cb_destroy_chrome(struct wl_listener *listener, void *data)
       +{
       +        (void)data;
       +        struct chrome *chrome;
       +
       +        chrome = wl_container_of(listener, chrome, destroy);
       +
       +        wl_list_remove(&chrome->destroy.link);
       +        wl_list_remove(&chrome->mode.link);
       +        free(chrome);
       +}
       +
       +/*
         * A modifier key is pressed, or depressed.
         */
        void
       t@@ -870,6 +943,7 @@ main(int argc, char *argv[])
                server.layout = wlr_output_layout_create();
                server.backend = wlr_backend_autocreate(server.dpy, NULL);
                server.renderer = wlr_backend_get_renderer(server.backend);
       +        server.chrome_mgr = wlr_xdg_decoration_manager_v1_create(server.dpy);
        
                server.cursor = wlr_cursor_create();
                server.cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
       t@@ -898,6 +972,7 @@ main(int argc, char *argv[])
                server.new_window.notify = cb_new_window;
                server.new_input.notify = cb_new_input;
                server.new_output.notify = cb_new_output;
       +        server.new_chrome.notify = cb_new_decoration;
        
                server.click.notify = cb_click;
                server.scroll.notify = cb_scroll;
       t@@ -909,6 +984,7 @@ main(int argc, char *argv[])
                wl_signal_add(&server.backend->events.new_output, &server.new_output);
                wl_signal_add(&server.shell->events.new_surface, &server.new_window);
                wl_signal_add(&server.backend->events.new_input, &server.new_input);
       +        wl_signal_add(&server.chrome_mgr->events.new_toplevel_decoration, &server.new_chrome);
        
                wl_signal_add(&server.cursor->events.button, &server.click);
                wl_signal_add(&server.cursor->events.axis, &server.scroll);
 (DIR) diff --git a/mkfile b/mkfile
       t@@ -2,10 +2,10 @@
        
        all:V: compositor
        
       -compositor: compositor.o proto/xdg-shell-protocol.o
       +compositor: compositor.o proto/xdg-shell-protocol.o proto/xdg-decoration-unstable-v1-protocol.o
                ${LD} ${LDFLAGS} $prereq ${WL_LIBS} -o $target
        
       -compositor.o: config.h proto/xdg-shell-protocol.h
       +compositor.o: config.h proto/xdg-shell-protocol.h proto/xdg-decoration-unstable-v1-protocol.h
        %.o: %.c
                ${CC} ${CPPFLAGS} ${CFLAGS} ${WL_CFLAGS} -c $stem.c -o $stem.o
        
       t@@ -18,6 +18,12 @@ proto/xdg-shell-protocol.c: ${WL_PROTO}/stable/xdg-shell/xdg-shell.xml
        proto/xdg-shell-protocol.h: ${WL_PROTO}/stable/xdg-shell/xdg-shell.xml
                wayland-scanner server-header < $prereq > $target
        
       +proto/xdg-decoration-unstable-v1-protocol.c: ${WL_PROTO}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
       +        wayland-scanner public-code < $prereq > $target
       +
       +proto/xdg-decoration-unstable-v1-protocol.h: ${WL_PROTO}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
       +        wayland-scanner server-header < $prereq > $target
       +
        clean:V:
                rm -f compositor *.o proto/*