Support pointer constraints protocol

This commit is contained in:
John Doe 2023-12-02 13:36:05 -05:00
parent 2b3504e439
commit 23bbacea42
2 changed files with 85 additions and 2 deletions

View File

@ -16,7 +16,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS)
all: dwl all: dwl
dwl: dwl.o util.o dwl: dwl.o util.o
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@ $(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h pointer-constraints-unstable-v1-protocol.h
util.o: util.c util.h util.o: util.c util.h
# wayland-scanner is a tool which generates C headers and rigging for Wayland # wayland-scanner is a tool which generates C headers and rigging for Wayland
@ -28,6 +28,9 @@ WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols`
xdg-shell-protocol.h: xdg-shell-protocol.h:
$(WAYLAND_SCANNER) server-header \ $(WAYLAND_SCANNER) server-header \
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
pointer-constraints-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) server-header \
$(WAYLAND_PROTOCOLS)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@
wlr-layer-shell-unstable-v1-protocol.h: wlr-layer-shell-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) server-header \ $(WAYLAND_SCANNER) server-header \
protocols/wlr-layer-shell-unstable-v1.xml $@ protocols/wlr-layer-shell-unstable-v1.xml $@

82
dwl.c
View File

@ -1,6 +1,7 @@
/* /*
* See LICENSE file for copyright and license details. * See LICENSE file for copyright and license details.
*/ */
#include <assert.h>
#include <getopt.h> #include <getopt.h>
#include <libinput.h> #include <libinput.h>
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
@ -35,8 +36,10 @@
#include <wlr/types/wlr_output_management_v1.h> #include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_pointer.h> #include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_presentation_time.h> #include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_primary_selection.h> #include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_primary_selection_v1.h> #include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_relative_pointer_v1.h>
#include <wlr/types/wlr_scene.h> #include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_screencopy_v1.h> #include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_seat.h> #include <wlr/types/wlr_seat.h>
@ -209,6 +212,13 @@ typedef struct {
int x, y; int x, y;
} MonitorRule; } MonitorRule;
struct pointer_constraint {
struct wlr_pointer_constraint_v1 *constraint;
struct wl_listener set_region;
struct wl_listener destroy;
};
typedef struct { typedef struct {
const char *id; const char *id;
const char *title; const char *title;
@ -251,6 +261,7 @@ static void createlocksurface(struct wl_listener *listener, void *data);
static void createmon(struct wl_listener *listener, void *data); static void createmon(struct wl_listener *listener, void *data);
static void createnotify(struct wl_listener *listener, void *data); static void createnotify(struct wl_listener *listener, void *data);
static void createpointer(struct wlr_pointer *pointer); static void createpointer(struct wlr_pointer *pointer);
static void createpointerconstraint(struct wl_listener *listener, void *data);
static void cursorframe(struct wl_listener *listener, void *data); static void cursorframe(struct wl_listener *listener, void *data);
static void destroydragicon(struct wl_listener *listener, void *data); static void destroydragicon(struct wl_listener *listener, void *data);
static void destroyidleinhibitor(struct wl_listener *listener, void *data); static void destroyidleinhibitor(struct wl_listener *listener, void *data);
@ -260,12 +271,14 @@ static void destroylocksurface(struct wl_listener *listener, void *data);
static void destroynotify(struct wl_listener *listener, void *data); static void destroynotify(struct wl_listener *listener, void *data);
static void destroysessionlock(struct wl_listener *listener, void *data); static void destroysessionlock(struct wl_listener *listener, void *data);
static void destroysessionmgr(struct wl_listener *listener, void *data); static void destroysessionmgr(struct wl_listener *listener, void *data);
static void destroypointerconstraint(struct wl_listener *listener, void *data);
static Monitor *dirtomon(enum wlr_direction dir); static Monitor *dirtomon(enum wlr_direction dir);
static void focusclient(Client *c, int lift); static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg); static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg); static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m); static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data); static void fullscreennotify(struct wl_listener *listener, void *data);
static void handleconstraintcommit(struct wl_listener *listener, void *data);
static void handlesig(int signo); static void handlesig(int signo);
static void incnmaster(const Arg *arg); static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data); static void inputdevice(struct wl_listener *listener, void *data);
@ -377,6 +390,11 @@ static struct wlr_box sgeom;
static struct wl_list mons; static struct wl_list mons;
static Monitor *selmon; static Monitor *selmon;
struct wlr_pointer_constraints_v1 *pointer_constraints;
struct wlr_pointer_constraint_v1 *active_constraint;
static struct wl_listener constraint_commit;
struct wlr_relative_pointer_manager_v1 *relative_pointer_manager;
#ifdef XWAYLAND #ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data); static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data); static void associatex11(struct wl_listener *listener, void *data);
@ -930,6 +948,30 @@ createmon(struct wl_listener *listener, void *data)
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
} }
void
createpointerconstraint(struct wl_listener *listener, void *data)
{
if (focustop(selmon)) {
struct wlr_pointer_constraint_v1 *constraint = data;
struct pointer_constraint *pointer_constraint = calloc(1, sizeof(struct pointer_constraint));
pointer_constraint->constraint = constraint;
pointer_constraint->destroy.notify = destroypointerconstraint;
wl_signal_add(&constraint->events.destroy, &pointer_constraint->destroy);
if (client_surface(focustop(selmon)) == constraint->surface) {
if (active_constraint == constraint)
return;
active_constraint = constraint;
wlr_pointer_constraint_v1_send_activated(constraint);
constraint_commit.notify = handleconstraintcommit;
wl_signal_add(&constraint->surface->events.commit, &constraint_commit);
}
}
}
void void
createnotify(struct wl_listener *listener, void *data) createnotify(struct wl_listener *listener, void *data)
{ {
@ -1022,6 +1064,25 @@ createpointer(struct wlr_pointer *pointer)
wlr_cursor_attach_input_device(cursor, &pointer->base); wlr_cursor_attach_input_device(cursor, &pointer->base);
} }
void
destroypointerconstraint(struct wl_listener *listener, void *data)
{
struct wlr_pointer_constraint_v1 *constraint = data;
struct pointer_constraint *pointer_constraint = wl_container_of(listener, pointer_constraint, destroy);
wl_list_remove(&pointer_constraint->destroy.link);
if (active_constraint == constraint) {
if (constraint_commit.link.next != NULL) {
wl_list_remove(&constraint_commit.link);
}
wl_list_init(&constraint_commit.link);
active_constraint = NULL;
}
free(pointer_constraint);
}
void void
cursorframe(struct wl_listener *listener, void *data) cursorframe(struct wl_listener *listener, void *data)
{ {
@ -1295,6 +1356,12 @@ fullscreennotify(struct wl_listener *listener, void *data)
setfullscreen(c, client_wants_fullscreen(c)); setfullscreen(c, client_wants_fullscreen(c));
} }
void
handleconstraintcommit(struct wl_listener *listener, void *data)
{
assert(active_constraint->surface == data);
}
void void
handlesig(int signo) handlesig(int signo)
{ {
@ -1676,7 +1743,15 @@ motionrelative(struct wl_listener *listener, void *data)
* special configuration applied for the specific input device which * special configuration applied for the specific input device which
* generated the event. You can pass NULL for the device if you want to move * generated the event. You can pass NULL for the device if you want to move
* the cursor around without any input. */ * the cursor around without any input. */
wlr_cursor_move(cursor, &event->pointer->base, event->delta_x, event->delta_y); wlr_relative_pointer_manager_v1_send_relative_motion(
relative_pointer_manager,
seat, (uint64_t)event->time_msec * 1000,
event->delta_x, event->delta_y, event->unaccel_dx, event->unaccel_dy);
if (!active_constraint) {
wlr_cursor_move(cursor, &event->pointer->base,
event->delta_x, event->delta_y);
}
motionnotify(event->time_msec); motionnotify(event->time_msec);
} }
@ -2282,6 +2357,11 @@ setup(void)
xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy); xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy);
LISTEN_STATIC(&xdg_decoration_mgr->events.new_toplevel_decoration, createdecoration); LISTEN_STATIC(&xdg_decoration_mgr->events.new_toplevel_decoration, createdecoration);
pointer_constraints = wlr_pointer_constraints_v1_create(dpy);
LISTEN_STATIC(&pointer_constraints->events.new_constraint, createpointerconstraint);
relative_pointer_manager = wlr_relative_pointer_manager_v1_create(dpy);
/* /*
* Creates a cursor, which is a wlroots utility for tracking the cursor * Creates a cursor, which is a wlroots utility for tracking the cursor
* image shown on screen. * image shown on screen.