commit 2b8fb38
dalem
·
2026-02-23 22:09:52 +0000 UTC
parent 1536be8
Add a protocol for interactive area selection This adds a new protocol "swc_select" to expose the internal overlay set box function to clients Behavior wise it sets appropriate cursors for the state of the operation, and starts the overlay box drawing operation after a click
6 files changed,
+155,
-0
M
Makefile
+6,
-0
1@@ -97,6 +97,7 @@ PROTO_EXTENSIONS= \
2 protocol/server-decoration.xml \
3 protocol/swc.xml \
4 protocol/swc_snap.xml \
5+ protocol/swc_select.xml \
6 protocol/swc_wallpaper.xml \
7 protocol/wayland-drm.xml \
8 ${WAYLAND_PROTOCOLS_DATADIR}/stable/xdg-shell/xdg-shell.xml \
9@@ -125,6 +126,7 @@ PROTO_GEN_C= \
10 protocol/server-decoration-protocol.c \
11 protocol/swc-protocol.c \
12 protocol/swc_snap-protocol.c \
13+ protocol/swc_select-protocol.c \
14 protocol/swc_wallpaper-protocol.c \
15 protocol/wayland-drm-protocol.c \
16 protocol/xdg-decoration-unstable-v1-protocol.c \
17@@ -139,6 +141,8 @@ PROTO_GEN_H= \
18 protocol/swc-client-protocol.h \
19 protocol/swc_snap-server-protocol.h \
20 protocol/swc_snap-client-protocol.h \
21+ protocol/swc_select-server-protocol.h \
22+ protocol/swc_select-client-protocol.h \
23 protocol/swc_wallpaper-server-protocol.h \
24 protocol/swc_wallpaper-client-protocol.h \
25 protocol/wayland-drm-server-protocol.h \
26@@ -205,6 +209,7 @@ SWC_SOURCES= \
27 libswc/subcompositor.c \
28 libswc/subsurface.c \
29 libswc/surface.c \
30+ libswc/select.c \
31 libswc/swc.c \
32 libswc/util.c \
33 libswc/view.c \
34@@ -217,6 +222,7 @@ SWC_SOURCES= \
35 protocol/server-decoration-protocol.c \
36 protocol/swc-protocol.c \
37 protocol/swc_snap-protocol.c \
38+ protocol/swc_select-protocol.c \
39 protocol/swc_wallpaper-protocol.c \
40 protocol/wayland-drm-protocol.c \
41 protocol/xdg-decoration-unstable-v1-protocol.c \
+1,
-0
1@@ -50,6 +50,7 @@ struct swc {
2 struct wl_global *panel_manager;
3 struct wl_global *shell;
4 struct wl_global *snap_manager;
5+ struct wl_global *select_manager;
6 struct wl_global *subcompositor;
7 struct wl_global *wallpaper_manager;
8 struct wl_global *xdg_decoration_manager;
+109,
-0
1@@ -0,0 +1,109 @@
2+#include <wayland-server.h>
3+
4+#include "select.h"
5+#include "swc_select-server-protocol.h"
6+
7+#include "compositor.h"
8+#include "pointer.h"
9+#include "seat.h"
10+#include "util.h"
11+
12+static struct wl_list select_resources;
13+static int32_t start_x, start_y;
14+static struct pointer_handler select_pointer_handler;
15+
16+enum select_state { STATE_WAIT, STATE_DRAG };
17+static enum select_state select_state;
18+
19+static bool
20+handle_motion(struct pointer_handler *h, uint32_t time, wl_fixed_t fx,
21+ wl_fixed_t fy)
22+{
23+ int32_t x = wl_fixed_to_int(fx);
24+ int32_t y = wl_fixed_to_int(fy);
25+ struct wl_resource *resource;
26+
27+ if (select_state != STATE_DRAG) {
28+ return false;
29+ }
30+
31+ /* TODO: customizable color, maybeee, idk idc */
32+ swc_overlay_set_box(start_x, start_y, x, y, 0xffffffff, 2);
33+
34+ wl_resource_for_each(resource, &select_resources)
35+ swc_select_send_update(resource, start_x, start_y, x, y);
36+
37+ return true;
38+}
39+
40+static bool
41+handle_button(struct pointer_handler *h, uint32_t time, struct button *button,
42+ uint32_t state)
43+{
44+ int32_t x = wl_fixed_to_int(swc.seat->pointer->x);
45+ int32_t y = wl_fixed_to_int(swc.seat->pointer->y);
46+ struct wl_resource *resource;
47+
48+ if (state == WL_POINTER_BUTTON_STATE_PRESSED &&
49+ select_state == STATE_WAIT) {
50+ start_x = x;
51+ start_y = y;
52+ select_state = STATE_DRAG;
53+ return true;
54+ }
55+
56+ if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
57+ select_state == STATE_DRAG) {
58+ swc_overlay_clear();
59+ wl_list_remove(&select_pointer_handler.link);
60+ select_state = STATE_WAIT;
61+ swc_set_cursor(SWC_CURSOR_DEFAULT);
62+
63+ wl_resource_for_each(resource, &select_resources)
64+ swc_select_send_done(resource, start_x, start_y, x, y);
65+
66+ return true;
67+ }
68+
69+ return false;
70+}
71+
72+static void
73+handle_grab(struct wl_client *client, struct wl_resource *resource)
74+{
75+ select_state = STATE_WAIT;
76+ select_pointer_handler.motion = handle_motion;
77+ select_pointer_handler.button = handle_button;
78+ wl_list_insert(&swc.seat->pointer->handlers, &select_pointer_handler.link);
79+ swc_set_cursor(SWC_CURSOR_CROSS);
80+}
81+
82+static const struct swc_select_interface select_impl = {
83+ .grab = handle_grab,
84+};
85+
86+static void
87+bind_select(struct wl_client *client, void *data, uint32_t version, uint32_t id)
88+{
89+ struct wl_resource *resource;
90+
91+ resource = wl_resource_create(client, &swc_select_interface, 1, id);
92+ if (!resource) {
93+ wl_client_post_no_memory(client);
94+ return;
95+ }
96+
97+ wl_resource_set_implementation(resource, &select_impl, NULL,
98+ remove_resource);
99+ wl_list_insert(&select_resources, wl_resource_get_link(resource));
100+}
101+
102+struct wl_global *
103+select_manager_create(struct wl_display *display)
104+{
105+ wl_list_init(&select_resources);
106+ select_pointer_handler.motion = handle_motion;
107+ select_pointer_handler.button = handle_button;
108+ return wl_global_create(display, &swc_select_interface, 1, NULL,
109+ &bind_select);
110+}
+4,
-0
1@@ -0,0 +1,4 @@
2+#include <wayland-server.h>
3+
4+struct wl_global *
5+select_manager_create(struct wl_display *display);
+9,
-0
1@@ -35,6 +35,7 @@
2 #include "pointer.h"
3 #include "screen.h"
4 #include "seat.h"
5+#include "select.h"
6 #include "shell.h"
7 #include "shm.h"
8 #include "snap.h"
9@@ -251,10 +252,18 @@ swc_initialize(struct wl_display *display, struct wl_event_loop *event_loop,
10 }
11 #endif
12
13+ swc.select_manager = select_manager_create(display);
14+ if (!swc.select_manager) {
15+ ERROR("Could not initialize select manager\n");
16+ goto error17;
17+ }
18+
19 setup_compositor();
20
21 return true;
22
23+error17:
24+ wl_global_destroy(swc.select_manager);
25 #ifdef ENABLE_XWAYLAND
26 error16:
27 wl_global_destroy(swc.wallpaper_manager);
+26,
-0
1@@ -0,0 +1,26 @@
2+<?xml version="1.0" encoding="UTF-8"?>
3+<protocol name="swc_select">
4+ <interface name="swc_select" version="1">
5+ <description summary="Get a selection box">
6+ Allows clients to get an interactive selction box.
7+ </description>
8+
9+ <request name="grab" />
10+ <event name="update" >
11+ <arg name="x1" type="int" />
12+ <arg name="y1" type="int" />
13+ <arg name="x2" type="int" />
14+ <arg name="y2" type="int" />
15+ </event>
16+
17+ <event name="done" >
18+ <arg name="x1" type="int" />
19+ <arg name="y1" type="int" />
20+ <arg name="x2" type="int" />
21+ <arg name="y2" type="int" />
22+ </event>
23+
24+ <event name="cancelled" />
25+ <request name="destroy" type="destructor" />
26+ </interface>
27+</protocol>