tAdd basic move and resize feature with the mouse - spkp - Stacking wayland compositor
 (HTM) git clone git://git.z3bra.org/spkp.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit 04b58256de532860bd83b89a2137732da40f057b
 (DIR) parent 2226711ec174f0a3b4efcb46cd57daad2fca92a2
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Mon,  9 Nov 2020 20:02:56 +0100
       
       Add basic move and resize feature with the mouse
       
       Diffstat:
         M compositor.c                        |      74 ++++++++++++++++++++++++++-----
       
       1 file changed, 63 insertions(+), 11 deletions(-)
       ---
 (DIR) diff --git a/compositor.c b/compositor.c
       t@@ -21,11 +21,19 @@
        #include <wlr/types/wlr_xcursor_manager.h>
        #include <wlr/types/wlr_xdg_shell.h>
        
       +#include <linux/input-event-codes.h>
       +
        #include "xdg-shell-protocol.h"
        
        #include "arg.h"
        #include "config.h"
        
       +enum {
       +        NORMAL,
       +        MOVE,
       +        RESIZE,
       +};
       +
        /* keep track of internal compositor state */
        struct state {
                struct wl_display *dpy;
       t@@ -36,6 +44,9 @@ struct state {
        
                struct wlr_seat *seat;
        
       +        int grabmode;
       +        struct window *grabbed;
       +
                struct wlr_cursor *cursor;
                struct wlr_xcursor_manager *cursor_mgr;
        
       t@@ -414,7 +425,8 @@ cb_kb_key(struct wl_listener *listener, void *data)
                }
        }
        
       -void cb_req_cursor(struct wl_listener *listener, void *data)
       +void
       +cb_req_cursor(struct wl_listener *listener, void *data)
        {
                struct state *server;
                struct wlr_seat_pointer_request_set_cursor_event *ev;
       t@@ -429,7 +441,8 @@ void cb_req_cursor(struct wl_listener *listener, void *data)
        }
        
        
       -void cb_motion(struct state *server, uint32_t time)
       +void
       +cb_motion(struct state *server, uint32_t time)
        {
                double x, y, sx, sy;
                struct window *w;
       t@@ -438,6 +451,25 @@ void cb_motion(struct state *server, uint32_t time)
        
                seat = server->seat;
        
       +        w = server->grabbed;
       +
       +        struct wlr_box geom;
       +        switch(server->grabmode) {
       +        case MOVE:
       +                wlr_xdg_surface_get_geometry(w->surface, &geom);
       +                w->x = server->cursor->x - geom.width/2;
       +                w->y = server->cursor->y - geom.height/2;
       +                return; /* NOTREACHED */;
       +                break;
       +        case RESIZE:
       +                wlr_xdg_surface_get_geometry(w->surface, &geom);
       +                geom.width = server->cursor->x - w->x;
       +                geom.height = server->cursor->y - w->y;
       +                wlr_xdg_toplevel_set_size(w->surface, geom.width, geom.height);
       +                return; /* NOTREACHED */;
       +                break;
       +        }
       +
                /*
                 * reset focus and cursor image when no window is under the
                 * pointer
       t@@ -467,7 +499,8 @@ void cb_motion(struct state *server, uint32_t time)
        /*
         * Cursor moved, reporting relative coordinates.
         */
       -void cb_motion_relative(struct wl_listener *listener, void *data)
       +void
       +cb_motion_relative(struct wl_listener *listener, void *data)
        {
                struct state *server;
                struct wlr_event_pointer_motion *ev;
       t@@ -476,11 +509,11 @@ void cb_motion_relative(struct wl_listener *listener, void *data)
                ev = data;
        
                wlr_cursor_move(server->cursor, ev->device, ev->delta_x, ev->delta_y);
       -
                cb_motion(server, ev->time_msec);
        }
        
       -void cb_motion_absolute(struct wl_listener *listener, void *data)
       +void
       +cb_motion_absolute(struct wl_listener *listener, void *data)
        {
                struct state *server;
                struct wlr_event_pointer_motion_absolute *ev;
       t@@ -489,27 +522,44 @@ void cb_motion_absolute(struct wl_listener *listener, void *data)
                ev = data;
        
                wlr_cursor_warp_absolute(server->cursor, ev->device, ev->x, ev->y);
       -
                cb_motion(server, ev->time_msec);
        }
        
       -void cb_click(struct wl_listener *listener, void *data)
       +void
       +cb_click(struct wl_listener *listener, void *data)
        {
                double x, y, sx, sy;
                struct state *server;
                struct wlr_event_pointer_button *ev;
                struct window *w;
                struct wlr_surface *surface;
       +        struct wlr_keyboard *kb;
        
                server = wl_container_of(listener, server, click);
       +        kb = wlr_seat_get_keyboard(server->seat);
                ev = data;
        
       +        w = underneath(server, server->cursor->x, server->cursor->y);
       +        if (kb->modifiers.depressed & WLR_MODIFIER_LOGO && ev->state == WLR_BUTTON_PRESSED) {
       +                switch (ev->button) {
       +                case BTN_LEFT:
       +                        server->grabbed = w;
       +                        server->grabmode = MOVE;
       +                        break;
       +                case BTN_RIGHT:
       +                        server->grabbed = w;
       +                        server->grabmode = RESIZE;
       +                        break;
       +                }
       +        }
       +
                wlr_seat_pointer_notify_button(server->seat, ev->time_msec, ev->button, ev->state);
        
       -        if (ev->state == WLR_BUTTON_RELEASED)
       +        if (ev->state == WLR_BUTTON_RELEASED) {
       +                server->grabmode = NORMAL;
                        return;
       +        }
        
       -        w = underneath(server, server->cursor->x, server->cursor->y);
                if (!w) {
                        wlr_seat_pointer_clear_focus(server->seat);
                        return;
       t@@ -530,7 +580,8 @@ void cb_click(struct wl_listener *listener, void *data)
        
        }
        
       -void cb_scroll(struct wl_listener *listener, void *data)
       +void
       +cb_scroll(struct wl_listener *listener, void *data)
        {
                struct state *server;
                struct wlr_event_pointer_axis *ev;
       t@@ -542,7 +593,8 @@ void cb_scroll(struct wl_listener *listener, void *data)
                        ev->delta, ev->delta_discrete, ev->source);
        }
        
       -void cb_paint_cursor(struct wl_listener *listener, void *data)
       +void
       +cb_paint_cursor(struct wl_listener *listener, void *data)
        {
                struct state *server;