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;