]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Implement cursor-shape-v1 protocol
authorConsus <consus@ftml.net>
Sat, 2 Dec 2023 14:56:32 +0000 (17:56 +0300)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Tue, 5 Dec 2023 08:59:40 +0000 (09:59 +0100)
This protocol allows Wayland clients to request a buffer for a cursor
shape from a compositor.

Tested with foot.

include/labwc.h
protocols/meson.build
src/input/cursor.c

index f288de355d4662bf3ecc825e1ad49eb0eae20b34..86198a038a092b9b7bcf319b316fceeed621f15c 100644 (file)
@@ -175,6 +175,7 @@ struct seat {
        struct wl_listener swipe_end;
 
        struct wl_listener request_cursor;
+       struct wl_listener request_set_shape;
        struct wl_listener request_set_selection;
        struct wl_listener request_set_primary_selection;
 
index d2f7fc7ef7fe435dae46409853bfe6a8dabb3dc6..527f9d4cf10098e96d2537b3d24c39028e3873d7 100644 (file)
@@ -16,6 +16,7 @@ wayland_scanner_server = generator(
 server_protocols = [
        wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
        wl_protocol_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
+       wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
        wl_protocol_dir / 'staging/drm-lease/drm-lease-v1.xml',
        'wlr-layer-shell-unstable-v1.xml',
        'wlr-input-inhibitor-unstable-v1.xml',
index a98866dc397df9c0a2fb29f971b6072d60d838dc..cb3f67bc0c64e5a5188437ff8f9b9a23ef44e0c6 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/input-event-codes.h>
 #include <sys/time.h>
 #include <time.h>
+#include <wlr/types/wlr_cursor_shape_v1.h>
 #include <wlr/types/wlr_primary_selection.h>
 #include <wlr/util/region.h>
 #include "action.h"
@@ -22,6 +23,8 @@
 #include "ssd.h"
 #include "view.h"
 
+#define LAB_CURSOR_SHAPE_V1_VERSION 1
+
 static const char * const *cursor_names = NULL;
 
 /* Usual cursor names */
@@ -158,6 +161,33 @@ request_cursor_notify(struct wl_listener *listener, void *data)
        }
 }
 
+static void
+request_set_shape_notify(struct wl_listener *listener, void *data)
+{
+       struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data;
+       const char *shape_name = wlr_cursor_shape_v1_name(event->shape);
+       struct seat *seat = wl_container_of(listener, seat, request_set_shape);
+       struct wlr_seat_client *focused_client = seat->seat->pointer_state.focused_client;
+
+       /* Prevent setting a cursor image when moving or resizing */
+       if (seat->server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
+               return;
+       }
+
+       /*
+        * This can be sent by any client, so we check to make sure this one
+        * actually has pointer focus first.
+        */
+       if (event->seat_client != focused_client) {
+               wlr_log(WLR_INFO, "seat client %p != focused client %p",
+                       event->seat_client, focused_client);
+               return;
+       }
+
+       wlr_log(WLR_DEBUG, "set xcursor to shape %s", shape_name);
+       wlr_cursor_set_xcursor(seat->cursor, seat->xcursor_manager, shape_name);
+}
+
 static void
 request_set_selection_notify(struct wl_listener *listener, void *data)
 {
@@ -1225,6 +1255,18 @@ cursor_init(struct seat *seat)
        seat->request_cursor.notify = request_cursor_notify;
        wl_signal_add(&seat->seat->events.request_set_cursor,
                &seat->request_cursor);
+
+       struct wlr_cursor_shape_manager_v1 *cursor_shape_manager =
+               wlr_cursor_shape_manager_v1_create(seat->server->wl_display,
+                       LAB_CURSOR_SHAPE_V1_VERSION);
+       if (!cursor_shape_manager) {
+               wlr_log(WLR_ERROR, "unable to create cursor_shape interface");
+               exit(EXIT_FAILURE);
+       }
+       seat->request_set_shape.notify = request_set_shape_notify;
+       wl_signal_add(&cursor_shape_manager->events.request_set_shape,
+               &seat->request_set_shape);
+
        seat->request_set_selection.notify = request_set_selection_notify;
        wl_signal_add(&seat->seat->events.request_set_selection,
                &seat->request_set_selection);
@@ -1249,6 +1291,7 @@ void cursor_finish(struct seat *seat)
        touch_finish(seat);
 
        wl_list_remove(&seat->request_cursor.link);
+       wl_list_remove(&seat->request_set_shape.link);
        wl_list_remove(&seat->request_set_selection.link);
 
        wlr_xcursor_manager_destroy(seat->xcursor_manager);