Compare commits

..

5 Commits

Author SHA1 Message Date
Dhruva Sambrani a44a71ab0f add gamepad-bindings patch 2026-07-18 23:04:54 +02:00
A Frederick Christensen c9f31f29ea simpleborders: Update for 0.8 and for wlroots-next-f4249db
Abandoned simpleborders patch updated by @fauxmight
2026-07-16 06:09:31 +02:00
Viktor Woloszczuk 8085c4759f inputdevicerules: update for v0.8 dwl
addresses issue #623
2026-07-12 20:19:16 +01:00
skeetamine 514ad37ea9 per-app-cast: prefix var with ext_ for compatibility with other patches 2026-07-02 17:43:32 +03:00
nshan651 fd64a18e6f namedscratchpads: update for v0.8 dwl. 2026-06-29 12:37:42 +02:00
10 changed files with 928 additions and 46 deletions
+8
View File
@@ -0,0 +1,8 @@
### Description
Gamepad bindings to dwl. Press `LB + RB` toggle gamepad bindings.
### Download
- [2026-07-18](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/gamepad-bindings/gamepad-bindings.patch)
### Authors
- [dhruva_sambrani](https://codeberg.org/dhruva_sambrani)
@@ -0,0 +1,423 @@
diff --git a/Makefile b/Makefile
index 578194f..601c70e 100644
--- a/Makefile
+++ b/Makefile
@@ -12,16 +12,17 @@ DWLDEVCFLAGS = -g -Wpedantic -Wall -Wextra -Wdeclaration-after-statement \
-Wfloat-conversion
# CFLAGS / LDFLAGS
-PKGS = wayland-server xkbcommon libinput $(XLIBS)
+PKGS = wayland-server xkbcommon libinput libevdev libudev $(XLIBS)
DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(WLR_INCS) $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS)
LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(WLR_LIBS) -lm $(LIBS)
all: dwl
-dwl: dwl.o util.o
- $(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
-dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \
+dwl: dwl.o gamepad.o util.o
+ $(CC) dwl.o gamepad.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
+dwl.o: dwl.c client.h gamepad.h config.h config.mk cursor-shape-v1-protocol.h \
pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \
wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h
+gamepad.o: gamepad.c gamepad.h
util.o: util.c util.h
# wayland-scanner is a tool which generates C headers and rigging for Wayland
@@ -54,7 +55,7 @@ clean:
dist: clean
mkdir -p dwl-$(VERSION)
cp -R LICENSE* Makefile CHANGELOG.md README.md client.h config.def.h \
- config.mk protocols dwl.1 dwl.c util.c util.h dwl.desktop \
+ config.mk protocols dwl.1 dwl.c gamepad.c gamepad.h util.c util.h dwl.desktop \
dwl-$(VERSION)
tar -caf dwl-$(VERSION).tar.gz dwl-$(VERSION)
rm -rf dwl-$(VERSION)
diff --git a/config.def.h b/config.def.h
index 8a6eda0..48270f6 100644
--- a/config.def.h
+++ b/config.def.h
@@ -165,6 +165,22 @@ static const Key keys[] = {
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
};
+static const GamepadButton gamepadbuttons[] = {
+ { BTN_DPAD_DOWN, focusstack, {.i = +1} },
+ { BTN_DPAD_UP, focusstack, {.i = -1} },
+ { BTN_DPAD_LEFT, setmfact, {.f = -0.05f} },
+ { BTN_DPAD_RIGHT, setmfact, {.f = +0.05f} },
+ { BTN_SOUTH, zoom, {0} },
+ { BTN_EAST, setlayout, {.v = &layouts[0]} },
+ { BTN_NORTH, setlayout, {.v = &layouts[1]} },
+ { BTN_WEST, setlayout, {.v = &layouts[2]} },
+ { ABS_Z, focusmon, {.i = WLR_DIRECTION_LEFT} },
+ { ABS_RZ, focusmon, {.i = WLR_DIRECTION_RIGHT} },
+ { BTN_START, spawn, SHCMD("wmenu-run") },
+ { BTN_SELECT, winview, {0} },
+ { BTN_MODE, spawn, { "steam", NULL }},
+};
+
static const Button buttons[] = {
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
diff --git a/dwl.c b/dwl.c
index 101a45f..96e1c01 100644
--- a/dwl.c
+++ b/dwl.c
@@ -63,6 +63,7 @@
#include <wlr/util/log.h>
#include <wlr/util/region.h>
#include <xkbcommon/xkbcommon.h>
+#include "gamepad.h"
#ifdef XWAYLAND
#include <wlr/xwayland.h>
#include <xcb/xcb.h>
@@ -149,6 +150,12 @@ typedef struct {
const Arg arg;
} Key;
+typedef struct {
+ unsigned int button;
+ void (*func)(const Arg *);
+ const Arg arg;
+} GamepadButton;
+
typedef struct {
struct wlr_keyboard_group *wlr_group;
@@ -289,6 +296,7 @@ static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void gpureset(struct wl_listener *listener, void *data);
+static void gamepadbutton(unsigned int button, int state);
static void handlesig(int signo);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
@@ -398,6 +406,7 @@ static struct wlr_session_lock_v1 *cur_lock;
static struct wlr_seat *seat;
static KeyboardGroup *kb_group;
+static struct gamepad *gamepad;
static unsigned int cursor_mode;
static Client *grabc;
static int grabcx, grabcy; /* client-relative */
@@ -713,6 +722,7 @@ cleanup(void)
wlr_xcursor_manager_destroy(cursor_mgr);
destroykeyboardgroup(&kb_group->destroy, NULL);
+ gamepad_destroy(gamepad);
/* If it's not destroyed manually, it will cause a use-after-free of wlr_seat.
* Destroy it until it's fixed on the wlroots side */
@@ -1558,6 +1568,21 @@ gpureset(struct wl_listener *listener, void *data)
wlr_renderer_destroy(old_drw);
}
+void
+gamepadbutton(unsigned int button, int state)
+{
+ const GamepadButton *b;
+ if (!state || locked)
+ return;
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+ for (b = gamepadbuttons; b < END(gamepadbuttons); b++) {
+ if (button == b->button && b->func) {
+ b->func(&b->arg);
+ break;
+ }
+ }
+}
+
void
handlesig(int signo)
{
@@ -2643,6 +2668,7 @@ setup(void)
kb_group = createkeyboardgroup();
wl_list_init(&kb_group->destroy.link);
+ gamepad = gamepad_create(event_loop, session, gamepadbutton);
output_mgr = wlr_output_manager_v1_create(dpy);
wl_signal_add(&output_mgr->events.apply, &output_mgr_apply);
diff --git a/gamepad.c b/gamepad.c
new file mode 100644
index 0000000..6bad2f6
--- /dev/null
+++ b/gamepad.c
@@ -0,0 +1,255 @@
+#include <fcntl.h>
+#include <libevdev/libevdev.h>
+#include <libudev.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <wayland-server-core.h>
+#include <wlr/backend/session.h>
+
+#include "gamepad.h"
+
+struct pad {
+ struct wl_list link;
+ char *path;
+ int fd;
+ struct libevdev *dev;
+ struct wl_event_source *src;
+ unsigned char key[KEY_CNT];
+ unsigned char abs[ABS_CNT];
+ int enabled;
+ GamepadHandler fn;
+};
+
+struct gamepad {
+ struct udev *udev;
+ struct udev_monitor *mon;
+ struct wl_event_source *msrc;
+ struct wl_event_loop *loop;
+ struct wl_list pads;
+ GamepadHandler fn;
+};
+
+static int
+ispad(struct udev_device *d)
+{
+ const char *p;
+
+ p = udev_device_get_property_value(d, "ID_INPUT_JOYSTICK");
+ return !strcmp(udev_device_get_subsystem(d), "input")
+ && !strncmp(udev_device_get_sysname(d), "event", 5)
+ && p && !strcmp(p, "1");
+}
+
+static void
+padstop(struct pad *p)
+{
+ if (p->src)
+ wl_event_source_remove(p->src);
+ if (p->dev)
+ libevdev_free(p->dev);
+ if (p->fd >= 0)
+ close(p->fd);
+ p->src = NULL;
+ p->dev = NULL;
+ p->fd = -1;
+}
+
+static void
+padclose(struct pad *p)
+{
+ padstop(p);
+ wl_list_remove(&p->link);
+ free(p->path);
+ free(p);
+}
+
+static int
+padin(int fd, uint32_t mask, void *data)
+{
+ struct pad *p = data;
+ struct input_event e;
+ int r, v;
+
+ if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) {
+ padclose(p);
+ return 0;
+ }
+ while ((r = libevdev_next_event(p->dev, LIBEVDEV_READ_FLAG_NORMAL, &e)) == 0
+ || r == LIBEVDEV_READ_STATUS_SYNC) {
+ if (e.type == EV_KEY) {
+ v = !!e.value;
+ if (p->key[e.code] != v) {
+ p->key[e.code] = v;
+ if (p->enabled)
+ p->fn(e.code, v);
+ if ((e.code == BTN_TL || e.code == BTN_TR)
+ && p->key[BTN_TL] && p->key[BTN_TR] && v)
+ p->enabled ^= 1;
+ }
+ } else if (e.type == EV_ABS && (e.code == ABS_Z || e.code == ABS_RZ
+ || e.code == ABS_GAS || e.code == ABS_BRAKE)) {
+ const struct input_absinfo *a = libevdev_get_abs_info(p->dev, e.code);
+
+ v = e.value > (a->minimum + a->maximum) / 2;
+ if (p->abs[e.code] != v) {
+ p->abs[e.code] = v;
+ if (p->enabled)
+ p->fn(e.code, v);
+ }
+ } else if (e.type == EV_ABS && e.code == ABS_HAT0X) {
+ v = e.value + 1;
+ if (p->abs[e.code] != v) {
+ if (p->enabled) {
+ p->fn(BTN_DPAD_LEFT, 0);
+ p->fn(BTN_DPAD_RIGHT, 0);
+ }
+ p->abs[e.code] = v;
+ if (p->enabled) {
+ p->fn(BTN_DPAD_LEFT, e.value < 0);
+ p->fn(BTN_DPAD_RIGHT, e.value > 0);
+ }
+ }
+ } else if (e.type == EV_ABS && e.code == ABS_HAT0Y) {
+ v = e.value + 1;
+ if (p->abs[e.code] != v) {
+ if (p->enabled) {
+ p->fn(BTN_DPAD_UP, 0);
+ p->fn(BTN_DPAD_DOWN, 0);
+ }
+ p->abs[e.code] = v;
+ if (p->enabled) {
+ p->fn(BTN_DPAD_UP, e.value < 0);
+ p->fn(BTN_DPAD_DOWN, e.value > 0);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static void
+padstart(struct pad *p, struct wl_event_loop *loop)
+{
+ if (p->fd >= 0 || (p->fd = open(p->path, O_RDONLY | O_NONBLOCK | O_CLOEXEC)) < 0)
+ return;
+ if (libevdev_new_from_fd(p->fd, &p->dev)) {
+ close(p->fd);
+ p->fd = -1;
+ return;
+ }
+ if (!(p->src = wl_event_loop_add_fd(loop, p->fd, WL_EVENT_READABLE, padin, p)))
+ padstop(p);
+}
+
+static void
+padadd(struct gamepad *g, struct udev_device *d)
+{
+ struct pad *p;
+ struct pad *q;
+ const char *path;
+
+ if (!ispad(d) || !(path = udev_device_get_devnode(d)))
+ return;
+ wl_list_for_each(q, &g->pads, link) {
+ if (!strcmp(q->path, path))
+ return;
+ }
+ if (!(p = calloc(1, sizeof(*p))))
+ return;
+ if (!(p->path = strdup(path))) {
+ free(p);
+ return;
+ }
+ p->fd = -1;
+ p->enabled = 1;
+ p->fn = g->fn;
+ wl_list_insert(&g->pads, &p->link);
+ padstart(p, g->loop);
+}
+
+static void
+padremove(struct gamepad *g, const char *path)
+{
+ struct pad *p, *t;
+
+ wl_list_for_each_safe(p, t, &g->pads, link) {
+ if (!strcmp(p->path, path)) {
+ padclose(p);
+ break;
+ }
+ }
+}
+
+static int
+monin(int fd, uint32_t mask, void *data)
+{
+ struct gamepad *g = data;
+ struct udev_device *d;
+ const char *a;
+ const char *path;
+
+ if (!(d = udev_monitor_receive_device(g->mon)))
+ return 0;
+ a = udev_device_get_action(d);
+ path = udev_device_get_devnode(d);
+ if (a && !strcmp(a, "add"))
+ padadd(g, d);
+ else if (a && !strcmp(a, "remove") && path)
+ padremove(g, path);
+ udev_device_unref(d);
+ return 0;
+}
+
+struct gamepad *
+gamepad_create(struct wl_event_loop *loop, struct wlr_session *s, GamepadHandler fn)
+{
+ struct gamepad *g;
+ struct udev_enumerate *e;
+ struct udev_list_entry *l;
+ struct udev_device *d;
+
+ if (!s || !(g = calloc(1, sizeof(*g))) || !(g->udev = udev_new()))
+ return NULL;
+ g->loop = loop;
+ g->fn = fn;
+ wl_list_init(&g->pads);
+ if ((e = udev_enumerate_new(g->udev))) {
+ udev_enumerate_add_match_subsystem(e, "input");
+ udev_enumerate_scan_devices(e);
+ udev_list_entry_foreach(l, udev_enumerate_get_list_entry(e)) {
+ d = udev_device_new_from_syspath(g->udev, udev_list_entry_get_name(l));
+ if (d) {
+ padadd(g, d);
+ udev_device_unref(d);
+ }
+ }
+ udev_enumerate_unref(e);
+ }
+ if (!(g->mon = udev_monitor_new_from_netlink(g->udev, "udev"))
+ || udev_monitor_filter_add_match_subsystem_devtype(g->mon, "input", NULL)
+ || udev_monitor_enable_receiving(g->mon)
+ || !(g->msrc = wl_event_loop_add_fd(loop, udev_monitor_get_fd(g->mon), WL_EVENT_READABLE, monin, g))) {
+ gamepad_destroy(g);
+ return NULL;
+ }
+ return g;
+}
+
+void
+gamepad_destroy(struct gamepad *g)
+{
+ struct pad *p, *t;
+
+ if (!g)
+ return;
+ wl_list_for_each_safe(p, t, &g->pads, link)
+ padclose(p);
+ if (g->msrc)
+ wl_event_source_remove(g->msrc);
+ if (g->mon)
+ udev_monitor_unref(g->mon);
+ if (g->udev)
+ udev_unref(g->udev);
+ free(g);
+}
diff --git a/gamepad.h b/gamepad.h
new file mode 100644
index 0000000..5d45d28
--- /dev/null
+++ b/gamepad.h
@@ -0,0 +1,15 @@
+#ifndef GAMEPAD_H
+#define GAMEPAD_H
+
+#include <linux/input.h>
+
+struct gamepad;
+struct wl_event_loop;
+struct wlr_session;
+
+typedef void (*GamepadHandler)(unsigned int, int);
+
+struct gamepad *gamepad_create(struct wl_event_loop *, struct wlr_session *, GamepadHandler);
+void gamepad_destroy(struct gamepad *);
+
+#endif
+2 -1
View File
@@ -10,9 +10,10 @@ Examples provided:
- exclude certain keyboards (eg ydotool) from keyboard group - exclude certain keyboards (eg ydotool) from keyboard group
### Download ### Download
- [git branch](https://codeberg.org/bencc/dwl/src/branch/inputdevicerules) - [v0.8](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/inputdevicerules/inputdevicerules-v0.8.patch)
- [v0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/inputdevicerules/inputdevicerules-v0.7.patch) - [v0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/inputdevicerules/inputdevicerules-v0.7.patch)
- [v0.6](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/inputdevicerules/inputdevicerules-v0.6.patch) - [v0.6](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/inputdevicerules/inputdevicerules-v0.6.patch)
### Authors ### Authors
- [Viktor Woloszczuk](https://codeberg.org/vwoloszczuk)
- [Ben Collerson](https://codeberg.org/bencc) - [Ben Collerson](https://codeberg.org/bencc)
@@ -0,0 +1,173 @@
From 31c8493d7f2a863949a91cd14769e28894f259e7 Mon Sep 17 00:00:00 2001
From: Viktor Woloszczuk <viktor@woloszcz.uk>
Date: Wed, 11 Mar 2026 19:41:02 +0000
Subject: [PATCH] input device rules (v0.8)
* customise input device handling
* ignore unwanted input devices
* configure a toggle for an input device
---
config.def.h | 13 ++++++++++
dwl.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8a6eda0..4dbcfd1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -56,6 +56,18 @@ static const struct xkb_rule_names xkb_rules = {
.options = NULL,
};
+/* input devices */
+static const InputRule inputrules[] = {
+ /* name kbcreate ptrcreate */
+ /* ignore bad device - like a touchpad ;) */
+ { "BAD DEVICE", NULL, NULL },
+ /* ungroup ydotool device - fixes a bug */
+ { "ydotoold virtual device", createungroupedkeyboard, createpointer },
+ /* put your touchpad name here to enable toggle touchpad */
+ { "Elan Touchpad", createkeyboard, createtogglepointer },
+ { NULL, createkeyboard, createpointer },
+};
+
static const int repeat_rate = 25;
static const int repeat_delay = 600;
@@ -138,6 +150,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY, XKB_KEY_u, togglepointer, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
diff --git a/dwl.c b/dwl.c
index 44f3ad9..42557fe 100644
--- a/dwl.c
+++ b/dwl.c
@@ -141,6 +141,12 @@ typedef struct {
uint32_t resize; /* configure serial of a pending resize */
} Client;
+typedef struct {
+ const char *name;
+ void (*kbcreate)(struct wlr_keyboard *);
+ void (*ptrcreate)(struct wlr_pointer *);
+} InputRule;
+
typedef struct {
uint32_t mod;
xkb_keysym_t keysym;
@@ -268,6 +274,8 @@ static void createnotify(struct wl_listener *listener, void *data);
static void createpointer(struct wlr_pointer *pointer);
static void createpointerconstraint(struct wl_listener *listener, void *data);
static void createpopup(struct wl_listener *listener, void *data);
+static void createtogglepointer(struct wlr_pointer *pointer);
+static void createungroupedkeyboard(struct wlr_keyboard *keyboard);
static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint);
static void cursorframe(struct wl_listener *listener, void *data);
static void cursorwarptohint(void);
@@ -336,6 +344,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
+static void togglepointer(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -406,6 +415,8 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static struct libinput_device *togglepointerdevice = NULL;
+
/* global event handlers */
static struct wl_listener cursor_axis = {.notify = axisnotify};
static struct wl_listener cursor_button = {.notify = buttonpress};
@@ -1199,6 +1210,33 @@ createpopup(struct wl_listener *listener, void *data)
LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup);
}
+void
+createtogglepointer(struct wlr_pointer *pointer)
+{
+ struct libinput_device *device;
+
+ createpointer(pointer);
+
+ if (wlr_input_device_is_libinput(&pointer->base)
+ && (device = wlr_libinput_get_device_handle(&pointer->base))) {
+ togglepointerdevice = device;
+ }
+}
+
+void
+createungroupedkeyboard(struct wlr_keyboard *keyboard)
+{
+ /* for keyboards that need their own keyboard group */
+ KeyboardGroup *group = createkeyboardgroup();
+
+ /* Set the keymap to match the group keymap */
+ wlr_keyboard_set_keymap(keyboard, group->wlr_group->keyboard.keymap);
+ LISTEN(&keyboard->base.events.destroy, &group->destroy, destroykeyboardgroup);
+
+ /* Add the new keyboard to the group */
+ wlr_keyboard_group_add_keyboard(group->wlr_group, keyboard);
+}
+
void
cursorconstrain(struct wlr_pointer_constraint_v1 *constraint)
{
@@ -1582,13 +1620,27 @@ inputdevice(struct wl_listener *listener, void *data)
* available. */
struct wlr_input_device *device = data;
uint32_t caps;
+ const InputRule *r;
switch (device->type) {
case WLR_INPUT_DEVICE_KEYBOARD:
- createkeyboard(wlr_keyboard_from_input_device(device));
+ for (r = inputrules; r < END(inputrules); r++) {
+ if (!r->name || strstr(device->name, r->name)) {
+ if (r->kbcreate)
+ r->kbcreate(wlr_keyboard_from_input_device(device));
+ break;
+ }
+ }
+
break;
case WLR_INPUT_DEVICE_POINTER:
- createpointer(wlr_pointer_from_input_device(device));
+ for (r = inputrules; r < END(inputrules); r++) {
+ if (!r->name || strstr(device->name, r->name)) {
+ if (r->ptrcreate)
+ r->ptrcreate(wlr_pointer_from_input_device(device));
+ break;
+ }
+ }
break;
default:
/* TODO handle other input device types */
@@ -2760,6 +2812,18 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+togglepointer(const Arg *arg)
+{
+ if (!togglepointerdevice)
+ return;
+
+ libinput_device_config_send_events_set_mode(
+ togglepointerdevice,
+ libinput_device_config_send_events_get_mode(togglepointerdevice) ^ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
+ );
+}
+
void
toggletag(const Arg *arg)
{
--
2.53.0
+2 -1
View File
@@ -10,10 +10,11 @@ This patch adds the following functions:
If you don't assign keybindings to any of the above functions and so get a compiler warning about them not being used, just remove them from your dwl branch to stop the warning. If you don't assign keybindings to any of the above functions and so get a compiler warning about them not being used, just remove them from your dwl branch to stop the warning.
### Download ### Download
- [git branch (v0.6)](https://codeberg.org/bencc/dwl/src/branch/namedscratchpads)
- [2024-07-13 (v0.6)](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/namedscratchpads/namedscratchpads.patch) - [2024-07-13 (v0.6)](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/namedscratchpads/namedscratchpads.patch)
- [namedscratchpads-0.8.patch](/dwl/dwl-patches/raw/branch/main/patches/namedscratchpads/namedscratchpads-0.8.patch)
### Authors ### Authors
- [nshan651](https://codeberg.org/nshan651)
- [Ben Collerson](https://codeberg.org/bencc) - [Ben Collerson](https://codeberg.org/bencc)
- [wochap](https://codeberg.org/wochap) - [wochap](https://codeberg.org/wochap)
- [Louis-Michel Raynauld](https://github.com/loumray) - [Louis-Michel Raynauld](https://github.com/loumray)
@@ -0,0 +1,277 @@
From 40ef197886f402c44a5a5c6856478cad5277e0bb Mon Sep 17 00:00:00 2001
From: nshan651 <nshan651@proton.me>
Date: Fri, 19 Jun 2026 13:04:21 -0500
Subject: [PATCH 1/2] namedscratchpads: v0.8 compatibility
---
config.def.h | 11 ++++++++---
dwl.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 8a6eda0..79b4efb 100644
--- a/config.def.h
+++ b/config.def.h
@@ -21,9 +21,10 @@ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;
static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
- { "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
- { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
+ /* app_id title tags mask isfloating monitor scratchkey */
+ { "Gimp_EXAMPLE", NULL, 0, 1, -1, 0 }, /* Start on currently visible tags floating, not tiled */
+ { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1, 0 }, /* Start on ONLY tag "9" */
+ { NULL, "scratchpad", 0, 1, -1, 's' },
/* default/example rule: can be changed but cannot be eliminated; at least one rule must exist */
};
@@ -118,11 +119,15 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
static const char *termcmd[] = { "foot", NULL };
static const char *menucmd[] = { "wmenu-run", NULL };
+/* named scratchpads - First arg only serves to match against key in rules*/
+static const char *scratchpadcmd[] = { "s", "foot", "-T", "scratchpad", NULL };
+
static const Key keys[] = {
/* Note that Shift changes certain key codes: 2 -> at, etc. */
/* modifier key function argument */
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
+ { MODKEY, XKB_KEY_grave, togglescratch, {.v = scratchpadcmd } },
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
diff --git a/dwl.c b/dwl.c
index 44f3ad9..3e3db4c 100644
--- a/dwl.c
+++ b/dwl.c
@@ -138,6 +138,7 @@ typedef struct {
unsigned int bw;
uint32_t tags;
int isfloating, isurgent, isfullscreen;
+ char scratchkey;
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -228,6 +229,7 @@ typedef struct {
uint32_t tags;
int isfloating;
int monitor;
+ const char scratchkey;
} Rule;
typedef struct {
@@ -330,12 +332,14 @@ static void setpsel(struct wl_listener *listener, void *data);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
static void spawn(const Arg *arg);
+static void spawnscratch(const Arg *arg);
static void startdrag(struct wl_listener *listener, void *data);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
+static void togglescratch(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -483,6 +487,7 @@ applyrules(Client *c)
const Rule *r;
Monitor *mon = selmon, *m;
+ c->scratchkey = 0;
appid = client_get_appid(c);
title = client_get_title(c);
@@ -490,6 +495,7 @@ applyrules(Client *c)
if ((!r->title || strstr(title, r->title))
&& (!r->id || strstr(appid, r->id))) {
c->isfloating = r->isfloating;
+ c->scratchkey = r->scratchkey;
newtags |= r->tags;
i = 0;
wl_list_for_each(m, &mons, link) {
@@ -2677,6 +2683,16 @@ spawn(const Arg *arg)
}
}
+void spawnscratch(const Arg *arg)
+{
+ if (fork() == 0) {
+ dup2(STDERR_FILENO, STDOUT_FILENO);
+ setsid();
+ execvp(((char **)arg->v)[1], ((char **)arg->v)+1);
+ die("dwl: execvp %s failed:", ((char **)arg->v)[1]);
+ }
+}
+
void
startdrag(struct wl_listener *listener, void *data)
{
@@ -2760,6 +2776,29 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+togglescratch(const Arg *arg)
+{
+ Client *c;
+ unsigned int found = 0;
+
+ /* search for first window that matches the scratchkey */
+ wl_list_for_each(c, &clients, link)
+ if (c->scratchkey == ((char**)arg->v)[0][0]) {
+ found = 1;
+ break;
+ }
+
+ if (found) {
+ c->tags = VISIBLEON(c, selmon) ? 0 : selmon->tagset[selmon->seltags];
+
+ focusclient(c->tags == 0 ? focustop(selmon) : c, 1);
+ arrange(selmon);
+ } else{
+ spawnscratch(arg);
+ }
+}
+
void
toggletag(const Arg *arg)
{
--
2.52.0
From e21146a0924c5940c7fb912d0c99790e2553b613 Mon Sep 17 00:00:00 2001
From: nshan651 <nshan651@proton.me>
Date: Fri, 19 Jun 2026 13:05:33 -0500
Subject: [PATCH 2/2] namedscratchpads: focusortoggle functions v0.8
---
config.def.h | 2 ++
dwl.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+)
diff --git a/config.def.h b/config.def.h
index 79b4efb..e253862 100644
--- a/config.def.h
+++ b/config.def.h
@@ -128,6 +128,8 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
{ MODKEY, XKB_KEY_grave, togglescratch, {.v = scratchpadcmd } },
+ // { MODKEY, XKB_KEY_grave, focusortogglescratch, {.v = scratchpadcmd } },
+ // { MODKEY, XKB_KEY_grave, focusortogglematchingscratch, {.v = scratchpadcmd } },
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
diff --git a/dwl.c b/dwl.c
index 3e3db4c..0f406d9 100644
--- a/dwl.c
+++ b/dwl.c
@@ -286,6 +286,8 @@ static void destroykeyboardgroup(struct wl_listener *listener, void *data);
static Monitor *dirtomon(enum wlr_direction dir);
static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
+static void focusortogglematchingscratch(const Arg *arg);
+static void focusortogglescratch(const Arg *arg);
static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
@@ -1491,6 +1493,91 @@ focusmon(const Arg *arg)
focusclient(focustop(selmon), 1);
}
+void
+focusortogglematchingscratch(const Arg *arg)
+{
+ Client *c;
+ unsigned int found = 0;
+ unsigned int hide = 0;
+
+ wl_list_for_each(c, &clients, link) {
+ if (c->scratchkey == 0) {
+ continue;
+ }
+ if (c->scratchkey == ((char**)arg->v)[0][0]) {
+ if (VISIBLEON(c, selmon)) {
+ if (found == 1) {
+ if (hide == 1) {
+ c->tags = 0;
+ focusclient(focustop(selmon), 1);
+ }
+ continue;
+ }
+ if (focustop(selmon) == c) {
+ // hide
+ c->tags = 0;
+ focusclient(focustop(selmon), 1);
+ hide = 1;
+ } else {
+ // focus
+ focusclient(c, 1);
+ }
+ } else {
+ // show
+ c->tags = selmon->tagset[selmon->seltags];
+ // focus
+ focusclient(c, 1);
+ }
+ found = 1;
+ continue;
+ }
+ if (VISIBLEON(c, selmon)) {
+ // hide
+ c->tags = 0;
+ }
+ }
+
+ if (found) {
+ arrange(selmon);
+ } else {
+ spawnscratch(arg);
+ }
+}
+
+void
+focusortogglescratch(const Arg *arg)
+{
+ Client *c;
+ unsigned int found = 0;
+
+ /* search for first window that matches the scratchkey */
+ wl_list_for_each(c, &clients, link)
+ if (c->scratchkey == ((char**)arg->v)[0][0]) {
+ found = 1;
+ break;
+ }
+
+ if (found) {
+ if (VISIBLEON(c, selmon)) {
+ if (focustop(selmon) == c) {
+ // hide
+ c->tags = 0;
+ focusclient(focustop(selmon), 1);
+ } else {
+ // focus
+ focusclient(c, 1);
+ }
+ } else {
+ // show
+ c->tags = selmon->tagset[selmon->seltags];
+ focusclient(c, 1);
+ }
+ arrange(selmon);
+ } else{
+ spawnscratch(arg);
+ }
+}
+
void
focusstack(const Arg *arg)
{
--
2.52.0
@@ -27,7 +27,7 @@ index 8101ffa..7f4d059 100644
struct wlr_xwayland_surface *xwayland; struct wlr_xwayland_surface *xwayland;
} surface; } surface;
struct wlr_xdg_toplevel_decoration_v1 *decoration; struct wlr_xdg_toplevel_decoration_v1 *decoration;
+ struct wlr_ext_foreign_toplevel_handle_v1 *foreign_toplevel; + struct wlr_ext_foreign_toplevel_handle_v1 *ext_foreign_toplevel;
struct wl_listener commit; struct wl_listener commit;
struct wl_listener map; struct wl_listener map;
struct wl_listener maximize; struct wl_listener maximize;
@@ -63,9 +63,9 @@ index 8101ffa..7f4d059 100644
static struct wlr_scene_rect *locked_bg; static struct wlr_scene_rect *locked_bg;
static struct wlr_session_lock_v1 *cur_lock; static struct wlr_session_lock_v1 *cur_lock;
+static struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list; +static struct wlr_ext_foreign_toplevel_list_v1 *ext_foreign_toplevel_list;
+static struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1 *toplevel_capture_mgr; +static struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1 *toplevel_capture_mgr;
+static struct wl_listener foreign_toplevel_capture_request = {.notify = handlecapturerequest}; +static struct wl_listener ext_foreign_toplevel_capture_request = {.notify = handlecapturerequest};
+ +
static struct wlr_seat *seat; static struct wlr_seat *seat;
static KeyboardGroup *kb_group; static KeyboardGroup *kb_group;
@@ -90,7 +90,7 @@ index 8101ffa..7f4d059 100644
wl_list_remove(&request_start_drag.link); wl_list_remove(&request_start_drag.link);
wl_list_remove(&start_drag.link); wl_list_remove(&start_drag.link);
wl_list_remove(&new_session_lock.link); wl_list_remove(&new_session_lock.link);
+ wl_list_remove(&foreign_toplevel_capture_request.link); + wl_list_remove(&ext_foreign_toplevel_capture_request.link);
#ifdef XWAYLAND #ifdef XWAYLAND
wl_list_remove(&new_xwayland_surface.link); wl_list_remove(&new_xwayland_surface.link);
wl_list_remove(&xwayland_ready.link); wl_list_remove(&xwayland_ready.link);
@@ -107,7 +107,7 @@ index 8101ffa..7f4d059 100644
+ struct wlr_ext_image_capture_source_v1 *source; + struct wlr_ext_image_capture_source_v1 *source;
+ +
+ wl_list_for_each(c, &clients, link) { + wl_list_for_each(c, &clients, link) {
+ if (c->foreign_toplevel != req->toplevel_handle) + if (c->ext_foreign_toplevel != req->toplevel_handle)
+ continue; + continue;
+ +
+ cs = ecalloc(1, sizeof(*cs)); + cs = ecalloc(1, sizeof(*cs));
@@ -145,7 +145,7 @@ index 8101ffa..7f4d059 100644
+ .title = client_get_title(c), + .title = client_get_title(c),
+ .app_id = client_get_appid(c), + .app_id = client_get_appid(c),
+ }; + };
+ c->foreign_toplevel = wlr_ext_foreign_toplevel_handle_v1_create(foreign_toplevel_list, &ft_state); + c->ext_foreign_toplevel = wlr_ext_foreign_toplevel_handle_v1_create(ext_foreign_toplevel_list, &ft_state);
+ } + }
+ +
/* Set initial monitor, tags, floating status, and focus: /* Set initial monitor, tags, floating status, and focus:
@@ -155,9 +155,9 @@ index 8101ffa..7f4d059 100644
wlr_presentation_create(dpy, backend, 2); wlr_presentation_create(dpy, backend, 2);
wlr_alpha_modifier_v1_create(dpy); wlr_alpha_modifier_v1_create(dpy);
+ foreign_toplevel_list = wlr_ext_foreign_toplevel_list_v1_create(dpy, 1); + ext_foreign_toplevel_list = wlr_ext_foreign_toplevel_list_v1_create(dpy, 1);
+ toplevel_capture_mgr = wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create(dpy, 1); + toplevel_capture_mgr = wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create(dpy, 1);
+ wl_signal_add(&toplevel_capture_mgr->events.new_request, &foreign_toplevel_capture_request); + wl_signal_add(&toplevel_capture_mgr->events.new_request, &ext_foreign_toplevel_capture_request);
+ +
/* Initializes the interface used to implement urgency hints */ /* Initializes the interface used to implement urgency hints */
activation = wlr_xdg_activation_v1_create(dpy); activation = wlr_xdg_activation_v1_create(dpy);
@@ -166,9 +166,9 @@ index 8101ffa..7f4d059 100644
wl_list_remove(&c->flink); wl_list_remove(&c->flink);
} }
+ if (c->foreign_toplevel) { + if (c->ext_foreign_toplevel) {
+ wlr_ext_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); + wlr_ext_foreign_toplevel_handle_v1_destroy(c->ext_foreign_toplevel);
+ c->foreign_toplevel = NULL; + c->ext_foreign_toplevel = NULL;
+ } + }
+ +
wlr_scene_node_destroy(&c->scene->node); wlr_scene_node_destroy(&c->scene->node);
@@ -179,12 +179,12 @@ index 8101ffa..7f4d059 100644
if (c == focustop(c->mon)) if (c == focustop(c->mon))
printstatus(); printstatus();
+ +
+ if (c->foreign_toplevel) { + if (c->ext_foreign_toplevel) {
+ struct wlr_ext_foreign_toplevel_handle_v1_state ft_state = { + struct wlr_ext_foreign_toplevel_handle_v1_state ft_state = {
+ .title = client_get_title(c), + .title = client_get_title(c),
+ .app_id = client_get_appid(c), + .app_id = client_get_appid(c),
+ }; + };
+ wlr_ext_foreign_toplevel_handle_v1_update_state(c->foreign_toplevel, &ft_state); + wlr_ext_foreign_toplevel_handle_v1_update_state(c->ext_foreign_toplevel, &ft_state);
+ } + }
} }
+4 -5
View File
@@ -2,12 +2,11 @@
Like smartborders. Don't put borders when there is only one window on the screen. Like smartborders. Don't put borders when there is only one window on the screen.
The patch for tag v0.7 below appears to apply cleanly to the current HEAD of
upstream/main as at 2024-10-11.
### Download ### Download
- [git branch](https://codeberg.org/bencc/dwl/src/branch/simpleborders) - [git branch](https://codeberg.org/bencc/dwl/src/branch/simpleborders)
- [v0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders-v0.7.patch) - [simpleborders-wlroots-next-f4249db](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders-wlroots-next-f4249db.patch)
- [v0.6](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders-v0.6.patch) - [simpleborders-0.8.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/simpleborders/simpleborders-v0.8.patch)
### Authors ### Authors
- [A Frederick Christensen](https://codeberg.org/fauxmight)
- [Ben Collerson](https://codeberg.org/bencc) - [Ben Collerson](https://codeberg.org/bencc)
@@ -1,34 +1,34 @@
From 681e520deaeee460647de36f5312af3cb0c31f4a Mon Sep 17 00:00:00 2001 From 41eb0c0d196d302790ae87a5ca1a4da660864f10 Mon Sep 17 00:00:00 2001
From: Ben Collerson <benc@benc.cc> From: A Frederick Christensen <dwl@ivories.org>
Date: Sat, 30 Dec 2023 13:39:31 +1000 Date: Wed, 25 Feb 2026 20:11:56 -0600
Subject: [PATCH] simpleborders Subject: [PATCH] Apply simpleborders patch
--- ---
dwl.c | 22 ++++++++++++++++++++++ dwl.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+) 1 file changed, 22 insertions(+)
diff --git a/dwl.c b/dwl.c diff --git a/dwl.c b/dwl.c
index 4d19357..900e651 100644 index 44f3ad9..defe2a8 100644
--- a/dwl.c --- a/dwl.c
+++ b/dwl.c +++ b/dwl.c
@@ -245,6 +245,7 @@ static void cleanupmon(struct wl_listener *listener, void *data); @@ -257,6 +257,7 @@ static void closemon(Monitor *m);
static void closemon(Monitor *m);
static void commitlayersurfacenotify(struct wl_listener *listener, void *data); static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
static void commitnotify(struct wl_listener *listener, void *data); static void commitnotify(struct wl_listener *listener, void *data);
static void commitpopup(struct wl_listener *listener, void *data);
+static int countclients(Monitor *m); +static int countclients(Monitor *m);
static void createdecoration(struct wl_listener *listener, void *data); static void createdecoration(struct wl_listener *listener, void *data);
static void createidleinhibitor(struct wl_listener *listener, void *data); static void createidleinhibitor(struct wl_listener *listener, void *data);
static void createkeyboard(struct wlr_keyboard *keyboard); static void createkeyboard(struct wlr_keyboard *keyboard);
@@ -286,6 +287,7 @@ static void motionabsolute(struct wl_listener *listener, void *data); @@ -305,6 +306,7 @@ static void motionnotify(uint32_t time, struct wlr_input_device *device, double
static void motionnotify(uint32_t time); double sy, double sx_unaccel, double sy_unaccel);
static void motionrelative(struct wl_listener *listener, void *data); static void motionrelative(struct wl_listener *listener, void *data);
static void moveresize(const Arg *arg); static void moveresize(const Arg *arg);
+static int needsborder(Client *c); +static int needsborder(Client *c);
static void outputmgrapply(struct wl_listener *listener, void *data); static void outputmgrapply(struct wl_listener *listener, void *data);
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test); static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
static void outputmgrtest(struct wl_listener *listener, void *data); static void outputmgrtest(struct wl_listener *listener, void *data);
@@ -739,6 +741,17 @@ commitnotify(struct wl_listener *listener, void *data) @@ -915,6 +917,17 @@ commitpopup(struct wl_listener *listener, void *data)
c->resize = 0; free(listener);
} }
+int +int
@@ -45,7 +45,7 @@ index 4d19357..900e651 100644
void void
createdecoration(struct wl_listener *listener, void *data) createdecoration(struct wl_listener *listener, void *data)
{ {
@@ -1697,6 +1710,14 @@ moveresize(const Arg *arg) @@ -1980,6 +1993,14 @@ moveresize(const Arg *arg)
} }
} }
@@ -60,8 +60,8 @@ index 4d19357..900e651 100644
void void
outputmgrapply(struct wl_listener *listener, void *data) outputmgrapply(struct wl_listener *listener, void *data)
{ {
@@ -1930,6 +1951,7 @@ resize(Client *c, struct wlr_box geo, int interact) @@ -2215,6 +2236,7 @@ resize(Client *c, struct wlr_box geo, int interact)
struct wlr_box clip;
client_set_bounds(c, geo.width, geo.height); client_set_bounds(c, geo.width, geo.height);
c->geom = geo; c->geom = geo;
+ c->bw = needsborder(c) ? borderpx : 0; + c->bw = needsborder(c) ? borderpx : 0;
@@ -69,5 +69,5 @@ index 4d19357..900e651 100644
/* Update scene-graph, including borders */ /* Update scene-graph, including borders */
-- --
2.43.0 2.52.0
@@ -1,14 +1,14 @@
From 09759c3ef75158c366e9fc63814485fbb31a3ccf Mon Sep 17 00:00:00 2001 From 33364ee84f8063813fbdb8b319965a87f63e2694 Mon Sep 17 00:00:00 2001
From: Ben Collerson <benc@benc.cc> From: A Frederick Christensen <dwl@ivories.org>
Date: Sat, 30 Dec 2023 13:39:31 +1000 Date: Wed, 25 Feb 2026 20:14:28 -0600
Subject: [PATCH] simpleborders Subject: [PATCH] Apply simpleborders patch
--- ---
dwl.c | 22 ++++++++++++++++++++++ dwl.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+) 1 file changed, 22 insertions(+)
diff --git a/dwl.c b/dwl.c diff --git a/dwl.c b/dwl.c
index a2711f67..415fe1a0 100644 index 8a9715d..a3caac8 100644
--- a/dwl.c --- a/dwl.c
+++ b/dwl.c +++ b/dwl.c
@@ -259,6 +259,7 @@ static void closemon(Monitor *m); @@ -259,6 +259,7 @@ static void closemon(Monitor *m);
@@ -19,7 +19,7 @@ index a2711f67..415fe1a0 100644
static void createdecoration(struct wl_listener *listener, void *data); static void createdecoration(struct wl_listener *listener, void *data);
static void createidleinhibitor(struct wl_listener *listener, void *data); static void createidleinhibitor(struct wl_listener *listener, void *data);
static void createkeyboard(struct wlr_keyboard *keyboard); static void createkeyboard(struct wlr_keyboard *keyboard);
@@ -308,6 +309,7 @@ static void motionnotify(uint32_t time, struct wlr_input_device *device, double @@ -307,6 +308,7 @@ static void motionnotify(uint32_t time, struct wlr_input_device *device, double
double sy, double sx_unaccel, double sy_unaccel); double sy, double sx_unaccel, double sy_unaccel);
static void motionrelative(struct wl_listener *listener, void *data); static void motionrelative(struct wl_listener *listener, void *data);
static void moveresize(const Arg *arg); static void moveresize(const Arg *arg);
@@ -27,8 +27,8 @@ index a2711f67..415fe1a0 100644
static void outputmgrapply(struct wl_listener *listener, void *data); static void outputmgrapply(struct wl_listener *listener, void *data);
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test); static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
static void outputmgrtest(struct wl_listener *listener, void *data); static void outputmgrtest(struct wl_listener *listener, void *data);
@@ -849,6 +851,17 @@ commitpopup(struct wl_listener *listener, void *data) @@ -917,6 +919,17 @@ commitpopup(struct wl_listener *listener, void *data)
wl_list_remove(&listener->link); free(listener);
} }
+int +int
@@ -45,7 +45,7 @@ index a2711f67..415fe1a0 100644
void void
createdecoration(struct wl_listener *listener, void *data) createdecoration(struct wl_listener *listener, void *data)
{ {
@@ -1927,6 +1940,14 @@ moveresize(const Arg *arg) @@ -1982,6 +1995,14 @@ moveresize(const Arg *arg)
} }
} }
@@ -60,7 +60,7 @@ index a2711f67..415fe1a0 100644
void void
outputmgrapply(struct wl_listener *listener, void *data) outputmgrapply(struct wl_listener *listener, void *data)
{ {
@@ -2190,6 +2211,7 @@ resize(Client *c, struct wlr_box geo, int interact) @@ -2217,6 +2238,7 @@ resize(Client *c, struct wlr_box geo, int interact)
client_set_bounds(c, geo.width, geo.height); client_set_bounds(c, geo.width, geo.height);
c->geom = geo; c->geom = geo;
@@ -69,5 +69,5 @@ index a2711f67..415fe1a0 100644
/* Update scene-graph, including borders */ /* Update scene-graph, including borders */
-- --
2.45.2 2.52.0