tTeleport windows with middle click - spkp - Stacking wayland compositor
 (HTM) git clone git://git.z3bra.org/spkp.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit 13990de6158e0d499c413cb104bd0b511fb447f1
 (DIR) parent 281b3e0dd100d20ef731764cf0db1a87227d8fc1
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Fri, 13 Nov 2020 17:11:38 +0100
       
       Teleport windows with middle click
       
       Diffstat:
         M compositor.c                        |      41 +++++++++++++++++++------------
       
       1 file changed, 25 insertions(+), 16 deletions(-)
       ---
 (DIR) diff --git a/compositor.c b/compositor.c
       t@@ -36,7 +36,7 @@ enum {
                NORMAL,
                MOVE,
                RESIZE,
       -        DRAW,
       +        TELEPORT,
        };
        
        enum {
       t@@ -600,9 +600,9 @@ cb_motion(struct state *server, uint32_t time)
                        return; /* NOTREACHED */;
                        break;
                case RESIZE: /* FALLTHROUGH */
       -        case DRAW:
       -                server->grabbox.width = MAX(server->cursor->x - server->grabbox.x, 100);
       -                server->grabbox.height = MAX(server->cursor->y - server->grabbox.y, 100);
       +        case TELEPORT:
       +                server->grabbox.width = MAX(server->cursor->x - server->grabbox.x, 1);
       +                server->grabbox.height = MAX(server->cursor->y - server->grabbox.y, 1);
                        return;
                }
        
       t@@ -685,9 +685,12 @@ cb_click(struct wl_listener *listener, void *data)
                if (ev->state == WLR_BUTTON_RELEASED) {
                        switch(server->grabmode) {
                        case MOVE:
       +                case TELEPORT:
                                server->grabbed->x = server->grabbox.x;
                                server->grabbed->y = server->grabbox.y;
       -                        break;
       +                        if (server->grabmode == MOVE)
       +                                break;
       +                        /* FALLTHROUGH */
                        case RESIZE:
                                geom.width = server->grabbox.width;
                                geom.height = server->grabbox.height;
       t@@ -703,21 +706,20 @@ cb_click(struct wl_listener *listener, void *data)
                        return;
                }
        
       -        w = underneath(server, server->cursor->x, server->cursor->y);
        
       -        /* don't enter grab mode when there is no window under the pointer */
       -        if (!w) {
       -                if (ev->state == WLR_BUTTON_PRESSED) {
       -                        server->grabmode = DRAW;
       -                        server->grabbed = NULL;
       -                        server->grabbox.x = server->cursor->x;
       -                        server->grabbox.y = server->cursor->y;
       -                        server->grabbox.width = 1;
       -                        server->grabbox.height = 1;
       -                }
       +        if (kb->modifiers.depressed & WLR_MODIFIER_LOGO && ev->button == BTN_MIDDLE) {
       +                server->grabmode = TELEPORT;
       +                server->grabbox.x = server->cursor->x;
       +                server->grabbox.y = server->cursor->y;
       +                server->grabbox.width = 1;
       +                server->grabbox.height = 1;
                        return;
                }
        
       +        /* stop processing if no window is under the cursor */
       +        if (!(w = underneath(server, server->cursor->x, server->cursor->y)))
       +                return;
       +
                if ((w->area == BORDER || (kb->modifiers.depressed & WLR_MODIFIER_LOGO))
                 && ev->state == WLR_BUTTON_PRESSED
                 && server->grabmode == NORMAL) {
       t@@ -747,6 +749,11 @@ cb_click(struct wl_listener *listener, void *data)
                        }
                }
        
       +        /* pass down event when not grabbing a window */
       +        if (server->grabmode == NORMAL)
       +                wlr_seat_pointer_notify_button(server->seat,
       +                        ev->time_msec, ev->button, ev->state);
       +
                /* bring window to the front */
                wl_list_remove(&w->link);
                wl_list_insert(&server->windows, &w->link);
       t@@ -932,6 +939,8 @@ focus(struct window *window)
                        wlr_xdg_toplevel_set_activated(toplevel, false);
                }
        
       +        server->grabbed = window;
       +
                /* give keyboard focus to the toplevel window */
                wlr_seat_keyboard_notify_enter(seat, window->toplevel->surface,
                        kb->keycodes, kb->num_keycodes, &kb->modifiers);