tAdd function to cycle windows - spkp - Stacking wayland compositor
 (HTM) git clone git://git.z3bra.org/spkp.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit eb601d97f773fb0de0f3200b802e6d65a84f1f4b
 (DIR) parent fb861150ce5d1fc35b2b420d5d572a4d3ce206c9
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Thu, 12 Nov 2020 17:03:34 +0100
       
       Add function to cycle windows
       
       Diffstat:
         M compositor.c                        |      46 +++++++++++++++++++++++++------
         M config.def.h                        |       1 +
       
       2 files changed, 39 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/compositor.c b/compositor.c
       t@@ -182,11 +182,12 @@ static void add_keyboard(struct state *, struct wlr_input_device *);
        static void add_pointer(struct state *, struct wlr_input_device *);
        static void render(struct wlr_surface *, int, int, void *);
        static void focus(struct window *);
       -static int keybinding(struct state *, uint32_t, uint32_t);
       +static int keybinding(struct state *, uint32_t, uint32_t, enum wlr_key_state);
        static struct window *underneath(struct state *, double, double);
        
        /* keybinding functions, see config.h */
        static void kb_terminate(struct state *, union keyarg *);
       +static void kb_alttab(struct state *, union keyarg *);
        
        #include "config.h"
        
       t@@ -384,7 +385,6 @@ cb_new_window(struct wl_listener *listener, void *data)
                wl_signal_add(&surface->events.destroy, &window->destroy);
        
                wl_list_insert(&server->windows, &window->link);
       -
        }
        
        /*
       t@@ -529,7 +529,7 @@ cb_kb_key(struct wl_listener *listener, void *data)
        
                mod = wlr_keyboard_get_modifiers(kb->device->keyboard);
                for (int i = 0; i < nsym; i++) {
       -                if (keybinding(server, mod, syms[i]))
       +                if (keybinding(server, mod, syms[i], ev->state))
                                continue;
        
                        /* pass it onto the underlying client */
       t@@ -868,16 +868,18 @@ focus(struct window *window)
         * Execute specific functions when an modifier/key combination is pressed.
         */
        int
       -keybinding(struct state *server, uint32_t mod, uint32_t key)
       +keybinding(struct state *server, uint32_t mod, uint32_t key, enum wlr_key_state state)
        {
                ssize_t i, nkey;
        
                nkey = sizeof(keys)/sizeof(*keys);
        
                for (i=0; i<nkey; i++) {
       -                if (keys[i].mod == mod \
       -                 && keys[i].key == key)
       -                        keys[i].func(server, NULL);
       +                if (keys[i].mod == mod && keys[i].key == key) {
       +                        if (state == WLR_KEY_PRESSED)
       +                                keys[i].func(server, NULL);
       +                        return 1;
       +                }
                }
        
                return 0;
       t@@ -929,12 +931,40 @@ underneath(struct state *server, double x, double y)
        /*
         * Keybind: Terminate the wayland compositor
         */
       -void kb_terminate(struct state *server, union keyarg *arg)
       +void
       +kb_terminate(struct state *server, union keyarg *arg)
        {
                (void)arg;
                wl_display_terminate(server->dpy);
        }
        
       +/*
       + * Cycle windows.
       + */
       +void
       +kb_alttab(struct state *server, union keyarg *arg)
       +{
       +        (void)arg;
       +        struct window *w;
       +        struct wl_list *elm;
       +
       +        if (wl_list_empty(&server->windows))
       +                return;
       +
       +        elm = server->windows.prev;
       +
       +        if (elm == &server->windows)
       +                elm = server->windows.next;
       +
       +        w = wl_container_of(elm, w, link);
       +
       +        /* re-insert last window on top of the stack */
       +        wl_list_remove(elm);
       +        wl_list_insert(&server->windows, elm);
       +
       +        focus(w);
       +}
       +
        int
        main(int argc, char *argv[])
        {
 (DIR) diff --git a/config.def.h b/config.def.h
       t@@ -7,4 +7,5 @@ int bordersize = 2;
        
        struct key keys[] = {
                { WLR_MODIFIER_LOGO, XKB_KEY_Escape, kb_terminate, {0} },
       +        { WLR_MODIFIER_ALT , XKB_KEY_Tab   , kb_alttab   , {0} },
        };