Remove dwl

This commit is contained in:
2024-07-08 15:07:42 +07:00
parent d564e89c3b
commit 184ff78c09
26 changed files with 4 additions and 3097 deletions

View File

@@ -1,146 +0,0 @@
From c602d9af1971fa219ff4d6821f7c30445f548f2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@proton.me>
Date: Sat, 8 Jul 2023 17:11:36 -0600
Subject: [PATCH] port autostart patch from dwm
https://dwm.suckless.org/patches/cool_autostart/
---
config.def.h | 6 ++++++
dwl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/config.def.h b/config.def.h
index 447ba0051..3cf694c7b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -7,7 +7,13 @@ static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
+/* Autostart */
+static const char *const autostart[] = {
+ "wbg", "/path/to/your/image", NULL,
+ NULL /* terminate */
+};
+
/* tagging - tagcount must be no greater than 31 */
#define TAGCOUNT (9)
static const int tagcount = TAGCOUNT;
diff --git a/dwl.c b/dwl.c
index 93f66efe6..de1f6e5ed 100644
--- a/dwl.c
+++ b/dwl.c
@@ -227,6 +227,7 @@ static void arrange(Monitor *m);
static void arrangelayer(Monitor *m, struct wl_list *list,
struct wlr_box *usable_area, int exclusive);
static void arrangelayers(Monitor *m);
+static void autostartexec(void);
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
static void chvt(const Arg *arg);
@@ -413,6 +414,9 @@ static Atom netatom[NetLast];
/* attempt to encapsulate suck into one file */
#include "client.h"
+static pid_t *autostart_pids;
+static size_t autostart_len;
+
/* function implementations */
void
applybounds(Client *c, struct wlr_box *bbox)
@@ -553,6 +557,27 @@ arrangelayers(Monitor *m)
}
}
+void
+autostartexec(void) {
+ const char *const *p;
+ size_t i = 0;
+
+ /* count entries */
+ for (p = autostart; *p; autostart_len++, p++)
+ while (*++p);
+
+ autostart_pids = calloc(autostart_len, sizeof(pid_t));
+ for (p = autostart; *p; i++, p++) {
+ if ((autostart_pids[i] = fork()) == 0) {
+ setsid();
+ execvp(*p, (char *const *)p);
+ die("dwl: execvp %s:", *p);
+ }
+ /* skip arguments */
+ while (*++p);
+ }
+}
+
void
axisnotify(struct wl_listener *listener, void *data)
{
@@ -652,10 +677,20 @@ checkidleinhibitor(struct wlr_surface *exclude)
void
cleanup(void)
{
+ size_t i;
#ifdef XWAYLAND
wlr_xwayland_destroy(xwayland);
#endif
wl_display_destroy_clients(dpy);
+
+ /* kill child processes */
+ for (i = 0; i < autostart_len; i++) {
+ if (0 < autostart_pids[i]) {
+ kill(autostart_pids[i], SIGTERM);
+ waitpid(autostart_pids[i], NULL, 0);
+ }
+ }
+
if (child_pid > 0) {
kill(child_pid, SIGTERM);
waitpid(child_pid, NULL, 0);
@@ -1338,18 +1373,31 @@ void
handlesig(int signo)
{
if (signo == SIGCHLD) {
-#ifdef XWAYLAND
siginfo_t in;
/* wlroots expects to reap the XWayland process itself, so we
* use WNOWAIT to keep the child waitable until we know it's not
* XWayland.
*/
while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
- && (!xwayland || in.si_pid != xwayland->server->pid))
- waitpid(in.si_pid, NULL, 0);
-#else
- while (waitpid(-1, NULL, WNOHANG) > 0);
+#ifdef XWAYLAND
+ && (!xwayland || in.si_pid != xwayland->server->pid)
#endif
+ ) {
+ pid_t *p, *lim;
+ waitpid(in.si_pid, NULL, 0);
+ if (in.si_pid == child_pid)
+ child_pid = -1;
+ if (!(p = autostart_pids))
+ continue;
+ lim = &p[autostart_len];
+
+ for (; p < lim; p++) {
+ if (*p == in.si_pid) {
+ *p = -1;
+ break;
+ }
+ }
+ }
} else if (signo == SIGINT || signo == SIGTERM) {
quit(NULL);
}
@@ -1968,6 +2016,7 @@ run(char *startup_cmd)
die("startup: backend_start");
/* Now that the socket exists and the backend is started, run the startup command */
+ autostartexec();
if (startup_cmd) {
int piperw[2];
if (pipe(piperw) < 0)

View File

@@ -1,65 +0,0 @@
diff --git a/dwl.c b/dwl.c
index 0841bef..b53cc14 100644
--- a/dwl.c
+++ b/dwl.c
@@ -322,6 +322,7 @@ static void updatetitle(struct wl_listener *listener, void *data);
static void urgent(struct wl_listener *listener, void *data);
static void view(const Arg *arg);
static void virtualkeyboard(struct wl_listener *listener, void *data);
+static void warpcursor(const Client *c);
static Monitor *xytomon(double x, double y);
static void xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny);
@@ -503,6 +504,9 @@ arrange(Monitor *m)
if (m->lt[m->sellt]->arrange)
m->lt[m->sellt]->arrange(m);
+ c = focustop(selmon);
+ if (cursor_warp && c)
+ warpcursor(c);
motionnotify(0);
checkidleinhibitor(NULL);
}
@@ -1304,6 +1308,10 @@ focusclient(Client *c, int lift)
if (c && client_surface(c) == old)
return;
+ /* Warp cursor to center of client if it is outside */
+ if (cursor_warp && c)
+ warpcursor(c);
+
if ((old_client_type = toplevel_from_wlr_surface(old, &old_c, &old_l)) == XDGShell) {
struct wlr_xdg_popup *popup, *tmp;
wl_list_for_each_safe(popup, tmp, &old_c->surface.xdg->popups, link)
@@ -1372,6 +1380,12 @@ focusmon(const Arg *arg)
selmon = dirtomon(arg->i);
while (!selmon->wlr_output->enabled && i++ < nmons);
focusclient(focustop(selmon), 1);
+ if (cursor_warp) {
+ wlr_cursor_warp_closest(cursor,
+ NULL,
+ selmon->m.x + selmon->m.width / 2.0,
+ selmon->m.y + selmon->m.height / 2.0);
+ }
}
void
@@ -2736,6 +2750,18 @@ virtualkeyboard(struct wl_listener *listener, void *data)
createkeyboard(&keyboard->keyboard);
}
+void
+warpcursor(const Client *c) {
+ if (cursor->x < c->geom.x ||
+ cursor->x > c->geom.x + c->geom.width ||
+ cursor->y < c->geom.y ||
+ cursor->y > c->geom.y + c->geom.height)
+ wlr_cursor_warp_closest(cursor,
+ NULL,
+ c->geom.x + c->geom.width / 2.0,
+ c->geom.y + c->geom.height / 2.0);
+}
+
Monitor *
xytomon(double x, double y)
{

View File

@@ -1,83 +0,0 @@
From c696b91d0def051b6bab2b50a1c3a748eaa3aa91 Mon Sep 17 00:00:00 2001
From: Palanix <palanixyt@gmail.com>
Date: Sun, 9 Jul 2023 19:35:19 +0200
Subject: [PATCH] Deck layout
---
config.def.h | 2 ++
dwl.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/config.def.h b/config.def.h
index 447ba0051..0febbdd7e 100644
--- a/config.def.h
+++ b/config.def.h
@@ -24,6 +24,7 @@ static const Layout layouts[] = {
{ "[]=", tile },
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "[D]", deck },
};
/* monitors */
@@ -123,6 +124,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_D, setlayout, {.v = &layouts[3]} },
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
diff --git a/dwl.c b/dwl.c
index 93f66efe6..584db4d24 100644
--- a/dwl.c
+++ b/dwl.c
@@ -246,6 +246,7 @@ static void createmon(struct wl_listener *listener, void *data);
static void createnotify(struct wl_listener *listener, void *data);
static void createpointer(struct wlr_pointer *pointer);
static void cursorframe(struct wl_listener *listener, void *data);
+static void deck(Monitor *m);
static void destroydragicon(struct wl_listener *listener, void *data);
static void destroyidleinhibitor(struct wl_listener *listener, void *data);
static void destroylayersurfacenotify(struct wl_listener *listener, void *data);
@@ -1075,6 +1076,40 @@ cursorframe(struct wl_listener *listener, void *data)
wlr_seat_pointer_notify_frame(seat);
}
+void
+deck(Monitor *m)
+{
+ unsigned int i, n = 0, mw, my;
+ Client *c;
+
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen)
+ n++;
+ if (n == 0)
+ return;
+
+ if (n > m->nmaster)
+ mw = m->nmaster ? m->w.width * m->mfact : 0;
+ else
+ mw = m->w.width;
+ i = my = 0;
+ wl_list_for_each(c, &clients, link) {
+ if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+ continue;
+ if (i < m->nmaster) {
+ resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
+ .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
+ my += c->geom.height;
+ } else {
+ resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y,
+ .width = m->w.width - mw, .height = m->w.height}, 0);
+ if (i == m->nmaster)
+ wlr_scene_node_raise_to_top(&c->scene->node);
+ }
+ i++;
+ }
+}
+
void
destroydragicon(struct wl_listener *listener, void *data)
{

View File

@@ -1,39 +0,0 @@
diff --git a/Makefile b/Makefile
index ccca079..31f5c70 100644
--- a/Makefile
+++ b/Makefile
@@ -52,8 +52,11 @@ install: dwl
mkdir -p $(DESTDIR)$(MANDIR)/man1
cp -f dwl.1 $(DESTDIR)$(MANDIR)/man1
chmod 644 $(DESTDIR)$(MANDIR)/man1/dwl.1
+ install -Dm 644 dwl.desktop $(DESTDIR)$(DESKTOP)/dwl.desktop
+ sed -i 's@$$(OUT)@$(DESTDIR)$(PREFIX)@' $(DESTDIR)$(DESKTOP)/dwl.desktop
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1
+ rm -f $(DESTDIR)$(DESKTOP)/dwl.desktop
.SUFFIXES: .c .o
.c.o:
diff --git a/config.mk b/config.mk
index f50156f..12bef12 100644
--- a/config.mk
+++ b/config.mk
@@ -6,6 +6,7 @@ PKG_CONFIG = pkg-config
# paths
PREFIX = /usr/local
MANDIR = $(PREFIX)/share/man
+DESKTOP= $(PREFIX)/share/wayland-sessions
XWAYLAND =
XLIBS =
diff --git a/dwl.desktop b/dwl.desktop
new file mode 100644
index 0000000..f8c743d
--- /dev/null
+++ b/dwl.desktop
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=DWL
+Comment=dwm for Wayland
+Exec=$(OUT)/bin/dwl -s ags
+Type=Application

View File

@@ -1,47 +0,0 @@
diff --git a/dwl.c b/dwl.c
index a7c2e28..b23067a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2090,29 +2090,31 @@ printstatus(void)
+ if (!m->wlr_output->enabled)
+ continue;
occ = urg = 0;
wl_list_for_each(c, &clients, link) {
occ |= c->tags;
if (c->isurgent)
urg |= c->tags;
}
if ((c = focustop(m))) {
title = client_get_title(c);
appid = client_get_appid(c);
- printf("%s title %s\n", m->wlr_output->name, title ? title : broken);
- printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken);
- printf("%s fullscreen %u\n", m->wlr_output->name, c->isfullscreen);
- printf("%s floating %u\n", m->wlr_output->name, c->isfloating);
+ printf("%s:%d,%d title %s\n", m->wlr_output->name, m->m.x, m->m.y, title ? title : broken);
+ printf("%s:%d,%d appid %s\n", m->wlr_output->name, m->m.x, m->m.y, appid ? appid : broken);
+ printf("%s:%d,%d fullscreen %u\n", m->wlr_output->name, m->m.x, m->m.y, c->isfullscreen);
+ printf("%s:%d,%d floating %u\n", m->wlr_output->name, m->m.x, m->m.y, c->isfloating);
sel = c->tags;
} else {
- printf("%s title \n", m->wlr_output->name);
- printf("%s appid \n", m->wlr_output->name);
- printf("%s fullscreen \n", m->wlr_output->name);
- printf("%s floating \n", m->wlr_output->name);
+ printf("%s:%d,%d title \n", m->wlr_output->name, m->m.x, m->m.y);
+ printf("%s:%d,%d appid \n", m->wlr_output->name, m->m.x, m->m.y);
+ printf("%s:%d,%d fullscreen \n", m->wlr_output->name, m->m.x, m->m.y);
+ printf("%s:%d,%d floating \n", m->wlr_output->name, m->m.x, m->m.y);
sel = 0;
}
- printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
- printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags],
+ printf("%s:%d,%d selmon %u\n", m->wlr_output->name, m->m.x, m->m.y, m == selmon);
+ printf("%s:%d,%d tags %u %u %u %u\n", m->wlr_output->name, m->m.x, m->m.y, occ, m->tagset[m->seltags],
sel, urg);
- printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
+ printf("%s:%d,%d layout %s\n", m->wlr_output->name, m->m.x, m->m.y, m->ltsymbol);
}
fflush(stdout);
}

View File

@@ -1,106 +0,0 @@
From cd7954be78ba9abe38423f2537c39c29ca7695db Mon Sep 17 00:00:00 2001
From: MadcowOG <N/A>
Date: Mon, 1 May 2023 02:35:42 -0700
Subject: [PATCH] Implemented wlr_keyboard_shortcuts_inhibit
---
dwl.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/dwl.c b/dwl.c
index b7436bb4f..842e0b147 100644
--- a/dwl.c
+++ b/dwl.c
@@ -28,6 +28,7 @@
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_input_inhibitor.h>
#include <wlr/types/wlr_keyboard.h>
+#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h>
@@ -247,7 +248,8 @@ static void createlocksurface(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 createpointer(struct wlr_pointer *pointer);
static void cursorframe(struct wl_listener *listener, void *data);
+static void createshortcutsinhibitor(struct wl_listener *listener, void *data);
static void deck(Monitor *m);
static void destroydragicon(struct wl_listener *listener, void *data);
static void destroyidleinhibitor(struct wl_listener *listener, void *data);
@@ -254,6 +256,7 @@ static void destroylocksurface(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 destroysessionmgr(struct wl_listener *listener, void *data);
+static void destroyshortcutsinhibitmgr(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);
@@ -342,6 +345,7 @@ static struct wlr_idle *idle;
static struct wlr_idle_notifier_v1 *idle_notifier;
static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr;
static struct wlr_input_inhibit_manager *input_inhibit_mgr;
+static struct wlr_keyboard_shortcuts_inhibit_manager_v1 *shortcuts_inhibit_mgr;
static struct wlr_layer_shell_v1 *layer_shell;
static struct wlr_output_manager_v1 *output_mgr;
static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
@@ -377,6 +381,7 @@ static struct wl_listener layout_change = {.notify = updatemons};
static struct wl_listener new_input = {.notify = inputdevice};
static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard};
static struct wl_listener new_output = {.notify = createmon};
+static struct wl_listener new_shortcuts_inhibitor = {.notify = createshortcutsinhibitor};
static struct wl_listener new_xdg_surface = {.notify = createnotify};
static struct wl_listener new_xdg_decoration = {.notify = createdecoration};
static struct wl_listener new_layer_shell_surface = {.notify = createlayersurface};
@@ -390,6 +395,7 @@ static struct wl_listener request_start_drag = {.notify = requeststartdrag};
static struct wl_listener start_drag = {.notify = startdrag};
static struct wl_listener session_lock_create_lock = {.notify = locksession};
static struct wl_listener session_lock_mgr_destroy = {.notify = destroysessionmgr};
+static struct wl_listener shortcuts_inhibit_mgr_destroy = {.notify = destroyshortcutsinhibitmgr};
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
@@ -1061,6 +1067,10 @@ createpointer(struct wlr_pointer *pointer)
wlr_cursor_attach_input_device(cursor, &pointer->base);
}
+void createshortcutsinhibitor(struct wl_listener *listener, void *data) {
+ wlr_keyboard_shortcuts_inhibitor_v1_activate(data);
+}
+
void
cursorframe(struct wl_listener *listener, void *data)
{
@@ -1181,6 +1191,11 @@ destroysessionmgr(struct wl_listener *listener, void *data)
wl_list_remove(&session_lock_mgr_destroy.link);
}
+void destroyshortcutsinhibitmgr(struct wl_listener *listener, void *data) {
+ wl_list_remove(&new_shortcuts_inhibitor.link);
+ wl_list_remove(&shortcuts_inhibit_mgr_destroy.link);
+}
+
Monitor *
dirtomon(enum wlr_direction dir)
{
@@ -1407,7 +1422,8 @@ keypress(struct wl_listener *listener, void *data)
/* On _press_ if there is no active screen locker,
* attempt to process a compositor keybinding. */
if (!locked && !input_inhibit_mgr->active_inhibitor
- && event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
+ && event->state == WL_KEYBOARD_KEY_STATE_PRESSED
+ && wl_list_empty(&shortcuts_inhibit_mgr->inhibitors))
for (i = 0; i < nsyms; i++)
handled = keybinding(mods, syms[i]) || handled;
@@ -2233,6 +2249,10 @@ setup(void)
(float [4]){0.1, 0.1, 0.1, 1.0});
wlr_scene_node_set_enabled(&locked_bg->node, 0);
+ shortcuts_inhibit_mgr = wlr_keyboard_shortcuts_inhibit_v1_create(dpy);
+ wl_signal_add(&shortcuts_inhibit_mgr->events.new_inhibitor, &new_shortcuts_inhibitor);
+ wl_signal_add(&shortcuts_inhibit_mgr->events.destroy, &shortcuts_inhibit_mgr_destroy);
+
/* Use decoration protocols to negotiate server-side decorations */
wlr_server_decoration_manager_set_default_mode(
wlr_server_decoration_manager_create(dpy),

View File

@@ -1,28 +0,0 @@
diff --git a/dwl.c b/dwl.c
index e32e58f..a7c2e28 100644
--- a/dwl.c
+++ b/dwl.c
@@ -211,6 +211,7 @@ typedef struct {
const Layout *lt;
enum wl_output_transform rr;
int x, y;
+ unsigned tagset;
} MonitorRule;
struct pointer_constraint {
@@ -997,7 +998,6 @@ createmon(struct wl_listener *listener, void *data)
m->gappiv = gappiv;
m->gappoh = gappoh;
m->gappov = gappov;
- m->tagset[0] = m->tagset[1] = (1<<getunusedtag()) & TAGMASK;
for (r = monrules; r < END(monrules); r++) {
if (!r->name || strstr(wlr_output->name, r->name)) {
m->mfact = r->mfact;
@@ -1008,6 +1008,7 @@ createmon(struct wl_listener *listener, void *data)
wlr_output_set_transform(wlr_output, r->rr);
m->m.x = r->x;
m->m.y = r->y;
+ m->tagset[0] = m->tagset[1] = (r->tagset ? r->tagset : (1<<getunusedtag())) & TAGMASK;
break;
}
}

View File

@@ -1,77 +0,0 @@
From f8507a681f838d13874cb541f60249e069f5d52f Mon Sep 17 00:00:00 2001
From: Abanoub <abanoubsameh@protonmail.com>
Date: Wed, 21 Jun 2023 18:07:43 +0300
Subject: [PATCH] Fix the bug with the movestack patch, which crashes dwl if
the current tag has no clients
---
config.def.h | 2 ++
dwl.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/config.def.h b/config.def.h
index 447ba0051..ffd0af28c 100644
--- a/config.def.h
+++ b/config.def.h
@@ -113,6 +113,8 @@ static const Key keys[] = {
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
diff --git a/dwl.c b/dwl.c
index da3a51613..efbe0c016 100644
--- a/dwl.c
+++ b/dwl.c
@@ -272,6 +272,7 @@ static void maplayersurfacenotify(struct wl_listener *listener, void *data);
static void mapnotify(struct wl_listener *listener, void *data);
static void maximizenotify(struct wl_listener *listener, void *data);
static void monocle(Monitor *m);
+static void movestack(const Arg *arg);
static void motionabsolute(struct wl_listener *listener, void *data);
static void motionnotify(uint32_t time);
static void motionrelative(struct wl_listener *listener, void *data);
@@ -1615,6 +1616,40 @@ monocle(Monitor *m)
wlr_scene_node_raise_to_top(&c->scene->node);
}
+void
+movestack(const Arg *arg)
+{
+ Client *c, *sel = focustop(selmon);
+
+ if (!sel) {
+ return;
+ }
+
+ if (wl_list_length(&clients) <= 1) {
+ return;
+ }
+
+ if (arg->i > 0) {
+ wl_list_for_each(c, &sel->link, link) {
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
+ break; /* found it */
+ }
+ }
+ } else {
+ wl_list_for_each_reverse(c, &sel->link, link) {
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
+ break; /* found it */
+ }
+ }
+ /* backup one client */
+ c = wl_container_of(c->link.prev, c, link);
+ }
+
+ wl_list_remove(&sel->link);
+ wl_list_insert(&c->link, &sel->link);
+ arrange(selmon);
+}
+
void
motionabsolute(struct wl_listener *listener, void *data)
{

View File

@@ -1,27 +0,0 @@
From b4eb343faff1ff15dd5d70a1f317dca201c5e37c Mon Sep 17 00:00:00 2001
From: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
Date: Sun, 21 May 2023 17:40:15 +0200
Subject: [PATCH] Set natural scrolling only for trackpads
---
dwl.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dwl.c b/dwl.c
index b7436bb4f..8db928292 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1029,10 +1029,10 @@ createpointer(struct wlr_pointer *pointer)
libinput_device_config_tap_set_drag_enabled(libinput_device, tap_and_drag);
libinput_device_config_tap_set_drag_lock_enabled(libinput_device, drag_lock);
libinput_device_config_tap_set_button_map(libinput_device, button_map);
- }
- if (libinput_device_config_scroll_has_natural_scroll(libinput_device))
- libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, natural_scrolling);
+ if (libinput_device_config_scroll_has_natural_scroll(libinput_device))
+ libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, natural_scrolling);
+ }
if (libinput_device_config_dwt_is_available(libinput_device))
libinput_device_config_dwt_set_enabled(libinput_device, disable_while_typing);

View File

@@ -1,257 +0,0 @@
From 598d88c868f35444008c458ae95e0e68a10946d1 Mon Sep 17 00:00:00 2001
From: Guido Cella <guido@guidocella.xyz>
Date: Sun, 20 Mar 2022 21:19:29 +0100
Subject: [PATCH 1/2] Implement the output power management protocol.
I thought wlr-randr used this, but it doesn't so I don't even know what
this is for.
---
Makefile | 5 +-
dwl.c | 16 +++
...lr-output-power-management-unstable-v1.xml | 128 ++++++++++++++++++
3 files changed, 148 insertions(+), 1 deletion(-)
create mode 100644 protocols/wlr-output-power-management-unstable-v1.xml
diff --git a/Makefile b/Makefile
index ccca07948..9d0a4b049 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS)
all: dwl
dwl: dwl.o util.o
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
-dwl.o: dwl.c config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h
+dwl.o: dwl.c config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h wlr-output-power-management-unstable-v1-protocol.h
util.o: util.c util.h
# wayland-scanner is a tool which generates C headers and rigging for Wayland
@@ -31,6 +31,9 @@ xdg-shell-protocol.h:
wlr-layer-shell-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) server-header \
protocols/wlr-layer-shell-unstable-v1.xml $@
+wlr-output-power-management-unstable-v1-protocol.h:
+ $(WAYLAND_SCANNER) server-header \
+ protocols/wlr-output-power-management-unstable-v1.xml $@
config.h:
cp config.def.h $@
diff --git a/dwl.c b/dwl.c
index b7436bb4f..8c7348ad3 100644
--- a/dwl.c
+++ b/dwl.c
@@ -32,6 +32,7 @@
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output_management_v1.h>
+#include <wlr/types/wlr_output_power_management_v1.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection.h>
@@ -282,6 +283,7 @@ static void outputmgrtest(struct wl_listener *listener, void *data);
static void pointerfocus(Client *c, struct wlr_surface *surface,
double sx, double sy, uint32_t time);
static void printstatus(void);
+static void powermgrsetmodenotify(struct wl_listener *listener, void *data);
static void quit(const Arg *arg);
static void quitsignal(int signo);
static void rendermon(struct wl_listener *listener, void *data);
@@ -353,6 +355,9 @@ static struct wlr_session_lock_manager_v1 *session_lock_mgr;
static struct wlr_scene_rect *locked_bg;
static struct wlr_session_lock_v1 *cur_lock;
+static struct wlr_output_power_manager_v1 *power_mgr;
+static struct wl_listener power_mgr_set_mode = {.notify = powermgrsetmodenotify};
+
static struct wlr_seat *seat;
static struct wl_list keyboards;
static unsigned int cursor_mode;
@@ -1861,6 +1866,14 @@ printstatus(void)
fflush(stdout);
}
+void
+powermgrsetmodenotify(struct wl_listener *listener, void *data)
+{
+ struct wlr_output_power_v1_set_mode_event *event = data;
+ wlr_output_enable(event->output, event->mode);
+ wlr_output_commit(event->output);
+}
+
void
quit(const Arg *arg)
{
@@ -2193,6 +2206,9 @@ setup(void)
activation = wlr_xdg_activation_v1_create(dpy);
wl_signal_add(&activation->events.request_activate, &request_activate);
+ power_mgr = wlr_output_power_manager_v1_create(dpy);
+ wl_signal_add(&power_mgr->events.set_mode, &power_mgr_set_mode);
+
/* Creates an output layout, which a wlroots utility for working with an
* arrangement of screens in a physical layout. */
output_layout = wlr_output_layout_create();
diff --git a/protocols/wlr-output-power-management-unstable-v1.xml b/protocols/wlr-output-power-management-unstable-v1.xml
new file mode 100644
index 000000000..a97783991
--- /dev/null
+++ b/protocols/wlr-output-power-management-unstable-v1.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="wlr_output_power_management_unstable_v1">
+ <copyright>
+ Copyright © 2019 Purism SPC
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+
+ <description summary="Control power management modes of outputs">
+ This protocol allows clients to control power management modes
+ of outputs that are currently part of the compositor space. The
+ intent is to allow special clients like desktop shells to power
+ down outputs when the system is idle.
+
+ To modify outputs not currently part of the compositor space see
+ wlr-output-management.
+
+ Warning! The protocol described in this file is experimental and
+ backward incompatible changes may be made. Backward compatible changes
+ may be added together with the corresponding interface version bump.
+ Backward incompatible changes are done by bumping the version number in
+ the protocol and interface names and resetting the interface version.
+ Once the protocol is to be declared stable, the 'z' prefix and the
+ version number in the protocol and interface names are removed and the
+ interface version number is reset.
+ </description>
+
+ <interface name="zwlr_output_power_manager_v1" version="1">
+ <description summary="manager to create per-output power management">
+ This interface is a manager that allows creating per-output power
+ management mode controls.
+ </description>
+
+ <request name="get_output_power">
+ <description summary="get a power management for an output">
+ Create a output power management mode control that can be used to
+ adjust the power management mode for a given output.
+ </description>
+ <arg name="id" type="new_id" interface="zwlr_output_power_v1"/>
+ <arg name="output" type="object" interface="wl_output"/>
+ </request>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy the manager">
+ All objects created by the manager will still remain valid, until their
+ appropriate destroy request has been called.
+ </description>
+ </request>
+ </interface>
+
+ <interface name="zwlr_output_power_v1" version="1">
+ <description summary="adjust power management mode for an output">
+ This object offers requests to set the power management mode of
+ an output.
+ </description>
+
+ <enum name="mode">
+ <entry name="off" value="0"
+ summary="Output is turned off."/>
+ <entry name="on" value="1"
+ summary="Output is turned on, no power saving"/>
+ </enum>
+
+ <enum name="error">
+ <entry name="invalid_mode" value="1" summary="inexistent power save mode"/>
+ </enum>
+
+ <request name="set_mode">
+ <description summary="Set an outputs power save mode">
+ Set an output's power save mode to the given mode. The mode change
+ is effective immediately. If the output does not support the given
+ mode a failed event is sent.
+ </description>
+ <arg name="mode" type="uint" enum="mode" summary="the power save mode to set"/>
+ </request>
+
+ <event name="mode">
+ <description summary="Report a power management mode change">
+ Report the power management mode change of an output.
+
+ The mode event is sent after an output changed its power
+ management mode. The reason can be a client using set_mode or the
+ compositor deciding to change an output's mode.
+ This event is also sent immediately when the object is created
+ so the client is informed about the current power management mode.
+ </description>
+ <arg name="mode" type="uint" enum="mode"
+ summary="the output's new power management mode"/>
+ </event>
+
+ <event name="failed">
+ <description summary="object no longer valid">
+ This event indicates that the output power management mode control
+ is no longer valid. This can happen for a number of reasons,
+ including:
+ - The output doesn't support power management
+ - Another client already has exclusive power management mode control
+ for this output
+ - The output disappeared
+
+ Upon receiving this event, the client should destroy this object.
+ </description>
+ </event>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy this power management">
+ Destroys the output power management mode control object.
+ </description>
+ </request>
+ </interface>
+</protocol>
From 66a957c61b84c2753663c5ffed78abcee8a0bca1 Mon Sep 17 00:00:00 2001
From: Dima Krasner <dima@dimakrasner.com>
Date: Mon, 4 Apr 2022 01:20:06 +0800
Subject: [PATCH 2/2] damage the output after wlopm --on
---
dwl.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dwl.c b/dwl.c
index 8c7348ad3..c694573d2 100644
--- a/dwl.c
+++ b/dwl.c
@@ -30,6 +30,7 @@
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_output.h>
+#include <wlr/interfaces/wlr_output.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_output_power_management_v1.h>
@@ -1871,6 +1872,8 @@ powermgrsetmodenotify(struct wl_listener *listener, void *data)
{
struct wlr_output_power_v1_set_mode_event *event = data;
wlr_output_enable(event->output, event->mode);
+ if (event->mode)
+ wlr_output_damage_whole(event->output);
wlr_output_commit(event->output);
}

View File

@@ -1,173 +0,0 @@
From b279a1b92089b89e562f35eedaebf5f8ee06c53f Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Fri, 8 Sep 2023 23:46:51 -0500
Subject: [PATCH] Implement pointer-gestures-unstable-v1
Forward the following events to client:
swipe_begin, swipe_update, swipe_end, pinch_begin, pinch_update and pinch_end
---
dwl.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/dwl.c b/dwl.c
index 4ff5c37f..de818096 100644
--- a/dwl.c
+++ b/dwl.c
@@ -33,6 +33,7 @@
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_pointer.h>
+#include <wlr/types/wlr_pointer_gestures_v1.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_primary_selection_v1.h>
@@ -229,6 +230,12 @@ static void arrangelayer(Monitor *m, struct wl_list *list,
static void arrangelayers(Monitor *m);
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
+static void swipe_begin(struct wl_listener *listener, void *data);
+static void swipe_update(struct wl_listener *listener, void *data);
+static void swipe_end(struct wl_listener *listener, void *data);
+static void pinch_begin(struct wl_listener *listener, void *data);
+static void pinch_update(struct wl_listener *listener, void *data);
+static void pinch_end(struct wl_listener *listener, void *data);
static void chvt(const Arg *arg);
static void checkidleinhibitor(struct wlr_surface *exclude);
static void cleanup(void);
@@ -348,6 +355,7 @@ static struct wlr_input_inhibit_manager *input_inhibit_mgr;
static struct wlr_layer_shell_v1 *layer_shell;
static struct wlr_output_manager_v1 *output_mgr;
static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
+static struct wlr_pointer_gestures_v1 *pointer_gestures;
static struct wlr_cursor *cursor;
static struct wlr_xcursor_manager *cursor_mgr;
@@ -370,6 +378,12 @@ static Monitor *selmon;
/* global event handlers */
static struct wl_listener cursor_axis = {.notify = axisnotify};
static struct wl_listener cursor_button = {.notify = buttonpress};
+static struct wl_listener cursor_swipe_begin = {.notify = swipe_begin};
+static struct wl_listener cursor_swipe_update = {.notify = swipe_update};
+static struct wl_listener cursor_swipe_end = {.notify = swipe_end};
+static struct wl_listener cursor_pinch_begin = {.notify = pinch_begin};
+static struct wl_listener cursor_pinch_update = {.notify = pinch_update};
+static struct wl_listener cursor_pinch_end = {.notify = pinch_end};
static struct wl_listener cursor_frame = {.notify = cursorframe};
static struct wl_listener cursor_motion = {.notify = motionrelative};
static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute};
@@ -624,6 +638,94 @@ buttonpress(struct wl_listener *listener, void *data)
event->time_msec, event->button, event->state);
}
+void
+swipe_begin(struct wl_listener *listener, void *data)
+{
+ struct wlr_pointer_swipe_begin_event *event = data;
+
+ // Forward swipe begin event to client
+ wlr_pointer_gestures_v1_send_swipe_begin(
+ pointer_gestures,
+ seat,
+ event->time_msec,
+ event->fingers
+ );
+}
+
+void
+swipe_update(struct wl_listener *listener, void *data)
+{
+ struct wlr_pointer_swipe_update_event *event = data;
+
+ // Forward swipe update event to client
+ wlr_pointer_gestures_v1_send_swipe_update(
+ pointer_gestures,
+ seat,
+ event->time_msec,
+ event->dx,
+ event->dy
+ );
+}
+
+void
+swipe_end(struct wl_listener *listener, void *data)
+{
+ struct wlr_pointer_swipe_end_event *event = data;
+
+ // Forward swipe end event to client
+ wlr_pointer_gestures_v1_send_swipe_end(
+ pointer_gestures,
+ seat,
+ event->time_msec,
+ event->cancelled
+ );
+}
+
+void
+pinch_begin(struct wl_listener *listener, void *data)
+{
+ struct wlr_pointer_pinch_begin_event *event = data;
+
+ // Forward pinch begin event to client
+ wlr_pointer_gestures_v1_send_pinch_begin(
+ pointer_gestures,
+ seat,
+ event->time_msec,
+ event->fingers
+ );
+}
+
+void
+pinch_update(struct wl_listener *listener, void *data)
+{
+ struct wlr_pointer_pinch_update_event *event = data;
+
+ // Forward pinch update event to client
+ wlr_pointer_gestures_v1_send_pinch_update(
+ pointer_gestures,
+ seat,
+ event->time_msec,
+ event->dx,
+ event->dy,
+ event->scale,
+ event->rotation
+ );
+}
+
+void
+pinch_end(struct wl_listener *listener, void *data)
+{
+ struct wlr_pointer_pinch_end_event *event = data;
+
+ // Forward pinch end event to client
+ wlr_pointer_gestures_v1_send_pinch_end(
+ pointer_gestures,
+ seat,
+ event->time_msec,
+ event->cancelled
+ );
+}
+
void
chvt(const Arg *arg)
{
@@ -2265,6 +2367,12 @@ setup(void)
wl_signal_add(&cursor->events.motion, &cursor_motion);
wl_signal_add(&cursor->events.motion_absolute, &cursor_motion_absolute);
wl_signal_add(&cursor->events.button, &cursor_button);
+ wl_signal_add(&cursor->events.swipe_begin, &cursor_swipe_begin);
+ wl_signal_add(&cursor->events.swipe_update, &cursor_swipe_update);
+ wl_signal_add(&cursor->events.swipe_end, &cursor_swipe_end);
+ wl_signal_add(&cursor->events.pinch_begin, &cursor_pinch_begin);
+ wl_signal_add(&cursor->events.pinch_update, &cursor_pinch_update);
+ wl_signal_add(&cursor->events.pinch_end, &cursor_pinch_end);
wl_signal_add(&cursor->events.axis, &cursor_axis);
wl_signal_add(&cursor->events.frame, &cursor_frame);
@@ -2279,6 +2387,7 @@ setup(void)
virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy);
wl_signal_add(&virtual_keyboard_mgr->events.new_virtual_keyboard,
&new_virtual_keyboard);
+ pointer_gestures = wlr_pointer_gestures_v1_create(dpy);
seat = wlr_seat_create(dpy, "seat0");
wl_signal_add(&seat->events.request_set_cursor, &request_cursor);
wl_signal_add(&seat->events.request_set_selection, &request_set_sel);

View File

@@ -1,19 +0,0 @@
diff --git a/dwl.c b/dwl.c
index 03833e3..4616f26 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2606,8 +2606,13 @@ setlayout(const Arg *arg)
if (!selmon)
return;
selmon->sellt ^= 1;
- if (arg && arg->v && arg->v != selmon->lt[selmon->sellt ^ 1])
+ if (arg && arg->v && arg->v != selmon->lt[selmon->sellt ^ 1]) {
+ Client *c;
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, selmon))
+ c->isfloating = 0;
selmon->lt[selmon->sellt] = (Layout *)arg->v;
+ }
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol));
if (!selmon->lt[selmon->sellt]->arrange) {
/* floating layout, draw borders around all clients */

View File

@@ -1,79 +0,0 @@
From 9dbdc4269c8db1b9580a153d99165aaa9cf14ad7 Mon Sep 17 00:00:00 2001
From: korei999 <ju7t1xe@gmail.com>
Date: Mon, 17 Jul 2023 01:02:22 +0300
Subject: [PATCH] This patch provides the ability to rotate the tagset left /
right. It implements a new function rotatetags which modifies the current
tagset. Same as original dwm patch. Also adds ability to "shift" focused
client to left / right tag.
---
config.def.h | 6 +++++-
dwl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/dwl.c b/dwl.c
index 93f66efe6..3928c2b9b 100644
--- a/dwl.c
+++ b/dwl.c
@@ -318,6 +318,8 @@ static Monitor *xytomon(double x, double y);
static struct wlr_scene_node *xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny);
static void zoom(const Arg *arg);
+static void rotatetags(const Arg *arg);
+static void clientshift(const Arg *arg);
/* variables */
static const char broken[] = "broken";
@@ -2687,6 +2689,52 @@ zoom(const Arg *arg)
arrange(selmon);
}
+static void
+rotatetags(const Arg *arg)
+{
+ Arg a;
+ size_t ntags = tagcount;
+ int i = arg->i;
+ int nextseltags, curseltags = selmon->tagset[selmon->seltags];
+
+ if (i > 0) // left circular shift
+ nextseltags = (curseltags << 1) | (curseltags >> (ntags - 1));
+ else // right circular shift
+ nextseltags = curseltags >> 1 | (curseltags << (ntags - 1));
+
+ i += arg->i;
+
+ a.i = nextseltags;
+ view(&a);
+}
+
+static void
+clientshift(const Arg *arg)
+{
+ Client *sel = focustop(selmon);
+
+ Arg a;
+ size_t ntags = tagcount;
+ int i = arg->i;
+ int nextseltags, curseltags = selmon->tagset[selmon->seltags];
+
+ if (i > 0) // left circular shift
+ nextseltags = (curseltags << 1) | (curseltags >> (ntags - 1));
+ else // right circular shift
+ nextseltags = curseltags >> 1 | (curseltags << (ntags - 1));
+
+ i += arg->i;
+
+ a.i = nextseltags;
+
+ if (sel && a.i) {
+ sel->tags = a.i;
+ focusclient(focustop(selmon), 1);
+ arrange(selmon);
+ }
+ printstatus();
+}
+
#ifdef XWAYLAND
void
activatex11(struct wl_listener *listener, void *data)

View File

@@ -1,200 +0,0 @@
diff --git a/dwl.c b/dwl.c
index ae39203..2e60842 100644
--- a/dwl.c
+++ b/dwl.c
@@ -234,6 +234,7 @@ static void arrange(Monitor *m);
static void arrangelayer(Monitor *m, struct wl_list *list,
struct wlr_box *usable_area, int exclusive);
static void arrangelayers(Monitor *m);
+static void attachclients(Monitor *m);
static void autostartexec(void);
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
@@ -271,6 +272,7 @@ static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
+static size_t getunusedtag(void);
static void handlesig(int signo);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
@@ -538,6 +540,15 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
}
}
+void
+attachclients(Monitor *m)
+{
+ Client *c;
+ wl_list_for_each(c, &clients, link)
+ if (c->tags & m->tagset[m->seltags])
+ setmon(c, m, c->tags);
+}
+
void
arrangelayers(Monitor *m)
{
@@ -970,7 +981,7 @@ createmon(struct wl_listener *listener, void *data)
m->gappiv = gappiv;
m->gappoh = gappoh;
m->gappov = gappov;
- m->tagset[0] = m->tagset[1] = 1;
+ m->tagset[0] = m->tagset[1] = (1<<getunusedtag()) & TAGMASK;
for (r = monrules; r < END(monrules); r++) {
if (!r->name || strstr(wlr_output->name, r->name)) {
m->mfact = r->mfact;
@@ -1455,6 +1466,26 @@ fullscreennotify(struct wl_listener *listener, void *data)
setfullscreen(c, client_wants_fullscreen(c));
}
+size_t
+getunusedtag(void)
+{
+ size_t i = 0;
+ bool empty = true;
+ Monitor *m;
+ if (wl_list_empty(&mons))
+ return i;
+ for (i=0; i < TAGCOUNT; i++) {
+ wl_list_for_each(m, &mons, link) {
+ if (m->tagset[m->seltags] & (1<<i))
+ empty = false;
+ }
+ if (empty)
+ return i;
+ empty = true;
+ }
+ return i;
+}
+
void
handlesig(int signo)
{
@@ -1999,8 +2030,6 @@ printstatus(void)
wl_list_for_each(m, &mons, link) {
occ = urg = 0;
wl_list_for_each(c, &clients, link) {
- if (c->mon != m)
- continue;
occ |= c->tags;
if (c->isurgent)
urg |= c->tags;
@@ -2504,22 +2533,32 @@ startdrag(struct wl_listener *listener, void *data)
void
tag(const Arg *arg)
{
+ Monitor *m;
Client *sel = focustop(selmon);
if (!sel || (arg->ui & TAGMASK) == 0)
return;
sel->tags = arg->ui & TAGMASK;
focusclient(focustop(selmon), 1);
- arrange(selmon);
+ wl_list_for_each(m, &mons, link) {
+ attachclients(m);
+ arrange(m);
+ }
printstatus();
}
void
tagmon(const Arg *arg)
{
+ Monitor *m;
Client *sel = focustop(selmon);
- if (sel)
+ if (sel) {
setmon(sel, dirtomon(arg->i), 0);
+ wl_list_for_each(m, &mons, link) {
+ arrange(m);
+ }
+ focusclient(focustop(sel->mon), 1);
+ }
}
void
@@ -2587,6 +2626,7 @@ togglefullscreen(const Arg *arg)
void
toggletag(const Arg *arg)
{
+ Monitor *m;
uint32_t newtags;
Client *sel = focustop(selmon);
if (!sel)
@@ -2595,7 +2635,11 @@ toggletag(const Arg *arg)
if (!newtags)
return;
+ wl_list_for_each(m, &mons, link)
+ if (m !=selmon && newtags & m->tagset[m->seltags])
+ return;
sel->tags = newtags;
+ attachclients(selmon);
focusclient(focustop(selmon), 1);
arrange(selmon);
printstatus();
@@ -2604,12 +2648,17 @@ toggletag(const Arg *arg)
void
toggleview(const Arg *arg)
{
+ Monitor *m;
uint32_t newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0;
if (!newtagset)
return;
+ wl_list_for_each(m, &mons, link)
+ if (m !=selmon && newtagset & m->tagset[m->seltags])
+ return;
selmon->tagset[selmon->seltags] = newtagset;
+ attachclients(selmon);
focusclient(focustop(selmon), 1);
arrange(selmon);
printstatus();
@@ -2778,15 +2827,41 @@ urgent(struct wl_listener *listener, void *data)
void
view(const Arg *arg)
{
+ Monitor *m, *origm = selmon;
+ Client *c;
+ unsigned int newtags = selmon->tagset[selmon->seltags ^ 1];
+
if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) {
view(&((Arg) { .ui = 0 }));
return;
}
- selmon->seltags ^= 1; /* toggle sel tagset */
+
+ /* swap tags when trying to display a tag from another monitor */
if (arg->ui & TAGMASK)
- selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
- focusclient(focustop(selmon), 1);
- arrange(selmon);
+ newtags = arg->ui & TAGMASK;
+ wl_list_for_each(m, &mons, link) {
+ if (m != selmon && newtags & m->tagset[m->seltags] && m->wlr_output->enabled) {
+ /* prevent displaying all tags (MODKEY-0) when multiple monitors
+ * are connected */
+ if (newtags & selmon->tagset[selmon->seltags])
+ return;
+ m->seltags ^= 1;
+ m->tagset[m->seltags] = selmon->tagset[selmon->seltags];
+ attachclients(m);
+ // disabled since i preffer keeping focus on the current monitor
+ // focusclient(focustop(m), 1);
+ arrange(m);
+ break;
+ }
+ }
+
+ origm->seltags ^= 1; /* toggle sel tagset */
+ if (arg->ui & TAGMASK)
+ origm->tagset[origm->seltags] = arg->ui & TAGMASK;
+ attachclients(origm);
+ c = focustop(origm);
+ focusclient(c, 1);
+ arrange(origm);
printstatus();
}

View File

@@ -1,350 +0,0 @@
diff --git a/config.def.h b/config.def.h
index 34a7795..b38db08 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,6 +1,7 @@
/* appearance */
static const int sloppyfocus = 1; /* focus follows mouse */
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
+static const int smartborders = 1;
static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */
static const int monoclegaps = 0; /* 1 means outer gaps in monocle layout */
static const unsigned int borderpx = 1; /* border pixel of windows */
diff --git a/dwl.c b/dwl.c
index dc16e16..7b1ca6f 100644
--- a/dwl.c
+++ b/dwl.c
@@ -287,13 +286,6 @@ 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 incnmaster(const Arg *arg);
-static void incgaps(const Arg *arg);
-static void incigaps(const Arg *arg);
-static void incihgaps(const Arg *arg);
-static void incivgaps(const Arg *arg);
-static void incogaps(const Arg *arg);
-static void incohgaps(const Arg *arg);
-static void incovgaps(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
static int keybinding(uint32_t mods, xkb_keysym_t sym);
static void keypress(struct wl_listener *listener, void *data);
@@ -319,12 +311,11 @@ static void powermgrsetmodenotify(struct wl_listener *listener, void *data);
static void quit(const Arg *arg);
static void rendermon(struct wl_listener *listener, void *data);
static void requeststartdrag(struct wl_listener *listener, void *data);
-static void resize(Client *c, struct wlr_box geo, int interact);
+static void resize(Client *c, struct wlr_box geo, int interact, int draw_borders);
static void run(char *startup_cmd);
static void setcursor(struct wl_listener *listener, void *data);
static void setfloating(Client *c, int floating);
static void setfullscreen(Client *c, int fullscreen);
-static void setgaps(int oh, int ov, int ih, int iv);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setmon(Client *c, Monitor *m, uint32_t newtags);
@@ -338,7 +329,6 @@ 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 togglegaps(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -809,7 +799,7 @@ closemon(Monitor *m)
wl_list_for_each(c, &clients, link) {
if (c->isfloating && c->geom.x > m->m.width)
resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y,
- .width = c->geom.width, .height = c->geom.height}, 0);
+ .width = c->geom.width, .height = c->geom.height}, 0, 1);
if (c->mon == m)
setmon(c, selmon, c->tags);
}
@@ -1204,7 +1194,7 @@ cursorframe(struct wl_listener *listener, void *data)
void
deck(Monitor *m)
{
- unsigned int i, n = 0, h, r, oe = enablegaps, ie = enablegaps, mw, my;
+ unsigned int i, n = 0, h, r, oe = enablegaps, ie = enablegaps, mw, my, draw_borders = 1;
Client *c;
wl_list_for_each(c, &clients, link)
@@ -1212,6 +1202,8 @@ deck(Monitor *m)
n++;
if (n == 0)
return;
+ if (smartborders == n)
+ draw_borders = 0;
if (smartgaps == n) {
oe = 0; // outer gaps disabled
@@ -1230,12 +1222,12 @@ deck(Monitor *m)
r = MIN(n, m->nmaster) - i;
h = (m->w.height - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
resize(c, (struct wlr_box){.x = m->w.x + m->gappov*oe, .y = m->w.y + my,
- .width = mw - m->gappiv*ie, .height = h}, 0);
+ .width = mw - m->gappiv*ie, .height = h}, 0, draw_borders);
my += c->geom.height + m->gappih*ie;
} else {
h = m->w.height - m->gappoh*oe*2;
resize(c, (struct wlr_box){.x = m->w.x + mw + m->gappov*oe, .y = m->w.y + m->gappoh*oe,
- .width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0);
+ .width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0, draw_borders);
if (i == m->nmaster)
wlr_scene_node_raise_to_top(&c->scene->node);
}
@@ -1243,12 +1235,6 @@ deck(Monitor *m)
}
}
-void
-defaultgaps(const Arg *arg)
-{
- setgaps(gappoh, gappov, gappih, gappiv);
-}
-
void
destroydragicon(struct wl_listener *listener, void *data)
{
@@ -1561,83 +1547,6 @@ incnmaster(const Arg *arg)
arrange(selmon);
}
-void
-incgaps(const Arg *arg)
-{
- setgaps(
- selmon->gappoh + arg->i,
- selmon->gappov + arg->i,
- selmon->gappih + arg->i,
- selmon->gappiv + arg->i
- );
-}
-
-void
-incigaps(const Arg *arg)
-{
- setgaps(
- selmon->gappoh,
- selmon->gappov,
- selmon->gappih + arg->i,
- selmon->gappiv + arg->i
- );
-}
-
-void
-incihgaps(const Arg *arg)
-{
- setgaps(
- selmon->gappoh,
- selmon->gappov,
- selmon->gappih + arg->i,
- selmon->gappiv
- );
-}
-
-void
-incivgaps(const Arg *arg)
-{
- setgaps(
- selmon->gappoh,
- selmon->gappov,
- selmon->gappih,
- selmon->gappiv + arg->i
- );
-}
-
-void
-incogaps(const Arg *arg)
-{
- setgaps(
- selmon->gappoh + arg->i,
- selmon->gappov + arg->i,
- selmon->gappih,
- selmon->gappiv
- );
-}
-
-void
-incohgaps(const Arg *arg)
-{
- setgaps(
- selmon->gappoh + arg->i,
- selmon->gappov,
- selmon->gappih,
- selmon->gappiv
- );
-}
-
-void
-incovgaps(const Arg *arg)
-{
- setgaps(
- selmon->gappoh,
- selmon->gappov + arg->i,
- selmon->gappih,
- selmon->gappiv
- );
-}
-
void
inputdevice(struct wl_listener *listener, void *data)
{
@@ -1905,10 +1814,10 @@ monocle(Monitor *m)
continue;
n++;
if (!monoclegaps)
- resize(c, m->w, 0);
+ resize(c, m->w, 0, !smartborders);
else
resize(c, (struct wlr_box){.x = m->w.x + gappoh, .y = m->w.y + gappov,
- .width = m->w.width - 2 * gappoh, .height = m->w.height - 2 * gappov}, 0);
+ .width = m->w.width - 2 * gappoh, .height = m->w.height - 2 * gappov}, 0, !smartborders);
}
if (n)
snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n);
@@ -1955,11 +1864,11 @@ motionnotify(uint32_t time)
if (cursor_mode == CurMove) {
/* Move the grabbed client to the new position. */
resize(grabc, (struct wlr_box){.x = cursor->x - grabcx, .y = cursor->y - grabcy,
- .width = grabc->geom.width, .height = grabc->geom.height}, 1);
+ .width = grabc->geom.width, .height = grabc->geom.height}, 1, 1);
return;
} else if (cursor_mode == CurResize) {
resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y,
- .width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1);
+ .width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1, 1);
return;
}
@@ -2227,11 +2136,12 @@ requeststartdrag(struct wl_listener *listener, void *data)
}
void
-resize(Client *c, struct wlr_box geo, int interact)
+resize(Client *c, struct wlr_box geo, int interact, int draw_borders)
{
struct wlr_box *bbox = interact ? &sgeom : &c->mon->w;
client_set_bounds(c, geo.width, geo.height);
c->geom = geo;
+ c->bw = draw_borders ? borderpx : 0;
applybounds(c, bbox);
/* Update scene-graph, including borders */
@@ -2329,6 +2239,8 @@ setfloating(Client *c, int floating)
{
c->isfloating = floating;
wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]);
+ if (c->isfloating && !c->bw)
+ resize(c, c->mon->m, 0, 1);
arrange(c->mon);
printstatus();
}
@@ -2346,26 +2258,16 @@ setfullscreen(Client *c, int fullscreen)
if (fullscreen) {
c->prev = c->geom;
- resize(c, c->mon->m, 0);
+ resize(c, c->mon->m, 0, 0);
} else {
/* restore previous size instead of arrange for floating windows since
* client positions are set by the user and cannot be recalculated */
- resize(c, c->prev, 0);
+ resize(c, c->prev, 0, 1);
}
arrange(c->mon);
printstatus();
}
-void
-setgaps(int oh, int ov, int ih, int iv)
-{
- selmon->gappoh = MAX(oh, 0);
- selmon->gappov = MAX(ov, 0);
- selmon->gappih = MAX(ih, 0);
- selmon->gappiv = MAX(iv, 0);
- arrange(selmon);
-}
-
void
setlayout(const Arg *arg)
{
@@ -2376,6 +2278,12 @@ setlayout(const Arg *arg)
if (arg && arg->v)
selmon->lt[selmon->sellt] = (Layout *)arg->v;
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol));
+ if (!selmon->lt[selmon->sellt]->arrange) {
+ /* floating layout, draw borders around all clients */
+ Client *c;
+ wl_list_for_each(c, &clients, link)
+ resize(c, c->mon->m, 0, 1);
+ }
arrange(selmon);
printstatus();
}
@@ -2410,7 +2318,7 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
arrange(oldmon);
if (m) {
/* Make sure window actually overlaps with the monitor */
- resize(c, c->geom, 0);
+ resize(c, c->geom, 0, 1);
c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
}
@@ -2675,7 +2583,7 @@ tagmon(const Arg *arg)
void
tile(Monitor *m)
{
- unsigned int i, n = 0, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty;
+ unsigned int i, n = 0, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty, draw_borders = 1;
Client *c;
wl_list_for_each(c, &clients, link)
@@ -2688,6 +2596,9 @@ tile(Monitor *m)
oe = 0; // outer gaps disabled
}
+ if (n == smartborders)
+ draw_borders = 0;
+
if (n > m->nmaster)
mw = m->nmaster ? (m->w.width + m->gappiv*ie) * m->mfact : 0;
else
@@ -2701,13 +2612,13 @@ tile(Monitor *m)
r = MIN(n, m->nmaster) - i;
h = (m->w.height - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
resize(c, (struct wlr_box){.x = m->w.x + m->gappov*oe, .y = m->w.y + my,
- .width = mw - m->gappiv*ie, .height = h}, 0);
+ .width = mw - m->gappiv*ie, .height = h}, 0, draw_borders);
my += c->geom.height + m->gappih*ie;
} else {
r = n - i;
h = (m->w.height - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
resize(c, (struct wlr_box){.x = m->w.x + mw + m->gappov*oe, .y = m->w.y + ty,
- .width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0);
+ .width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0, draw_borders);
ty += c->geom.height + m->gappih*ie;
}
i++;
@@ -2731,13 +2642,6 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
-void
-togglegaps(const Arg *arg)
-{
- enablegaps = !enablegaps;
- arrange(selmon);
-}
-
void
toggletag(const Arg *arg)
{
@@ -3051,7 +2955,7 @@ configurex11(struct wl_listener *listener, void *data)
return;
if (c->isfloating || c->type == X11Unmanaged)
resize(c, (struct wlr_box){.x = event->x, .y = event->y,
- .width = event->width, .height = event->height}, 0);
+ .width = event->width, .height = event->height}, 0, 1);
else
arrange(c->mon);
}

View File

@@ -1,562 +0,0 @@
diff --git a/Makefile b/Makefile
index 12ab1a2..0c7305d 100644
--- a/Makefile
+++ b/Makefile
@@ -9,14 +9,14 @@ DWLDEVCFLAGS = -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused
-Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types
# CFLAGS / LDFLAGS
-PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS)
+PKGS = wlroots wayland-server xkbcommon libinput pixman-1 $(XLIBS)
DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS)
-LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS)
+LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS)
all: dwl
dwl: dwl.o util.o
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
-dwl.o: dwl.c config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h wlr-output-power-management-unstable-v1-protocol.h
+dwl.o: dwl.c config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h wlr-output-power-management-unstable-v1-protocol.h pointer-constraints-unstable-v1-protocol.h
util.o: util.c util.h
# wayland-scanner is a tool which generates C headers and rigging for Wayland
@@ -34,6 +34,9 @@ wlr-layer-shell-unstable-v1-protocol.h:
wlr-output-power-management-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) server-header \
protocols/wlr-output-power-management-unstable-v1.xml $@
+pointer-constraints-unstable-v1-protocol.h:
+ $(WAYLAND_SCANNER) server-header \
+ $(WAYLAND_PROTOCOLS)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@
config.h:
cp config.def.h $@
diff --git a/dwl.c b/dwl.c
index ff4bb84..54553ce 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1,10 +1,16 @@
/*
* See LICENSE file for copyright and license details.
*/
+
+#ifndef POINTERCONSTRAINTS
+#define POINTERCONSTRAINTS
+#endif
+
#include <getopt.h>
#include <libinput.h>
#include <limits.h>
#include <linux/input-event-codes.h>
+#include <pixman-1/pixman.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -36,10 +42,12 @@
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_output_power_management_v1.h>
#include <wlr/types/wlr_pointer.h>
+#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_pointer_gestures_v1.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection.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_screencopy_v1.h>
#include <wlr/types/wlr_seat.h>
@@ -55,6 +63,7 @@
#include <wlr/types/wlr_xdg_output_v1.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/log.h>
+#include <wlr/util/region.h>
#include <xkbcommon/xkbcommon.h>
#ifdef XWAYLAND
#include <wlr/xwayland.h>
@@ -212,6 +221,14 @@ typedef struct {
unsigned tagset;
} MonitorRule;
+typedef struct {
+ struct wlr_pointer_constraint_v1 *constraint;
+ Client *focused;
+
+ struct wl_listener set_region;
+ struct wl_listener destroy;
+} PointerConstraint;
+
typedef struct {
const char *id;
const char *title;
@@ -255,6 +272,7 @@ static void closemon(Monitor *m);
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
static void commitnotify(struct wl_listener *listener, void *data);
static void createdecoration(struct wl_listener *listener, void *data);
+static void commitpointerconstraint(struct wl_listener *listener, void *data);
static void createidleinhibitor(struct wl_listener *listener, void *data);
static void createkeyboard(struct wlr_keyboard *keyboard);
static void createlayersurface(struct wl_listener *listener, void *data);
@@ -262,15 +280,19 @@ static void createlocksurface(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 createpointer(struct wlr_pointer *pointer);
+static void createpointerconstraint(struct wl_listener *listener, void *data);
+static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint);
static void cursorframe(struct wl_listener *listener, void *data);
static void createshortcutsinhibitor(struct wl_listener *listener, void *data);
static void deck(Monitor *m);
+static void cursorwarptoconstrainthint(void);
static void destroydragicon(struct wl_listener *listener, void *data);
static void destroyidleinhibitor(struct wl_listener *listener, void *data);
static void destroylayersurfacenotify(struct wl_listener *listener, void *data);
static void destroylock(SessionLock *lock, int unlocked);
static void destroylocksurface(struct wl_listener *listener, void *data);
static void destroynotify(struct wl_listener *listener, void *data);
+static void destroypointerconstraint(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 destroyshortcutsinhibitmgr(struct wl_listener *listener, void *data);
@@ -296,12 +318,14 @@ static void maximizenotify(struct wl_listener *listener, void *data);
static void monocle(Monitor *m);
static void movestack(const Arg *arg);
static void motionabsolute(struct wl_listener *listener, void *data);
-static void motionnotify(uint32_t time);
+static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx,
+ double sy, double sx_unaccel, double sy_unaccel);
static void motionrelative(struct wl_listener *listener, void *data);
static void moveresize(const Arg *arg);
static void outputmgrapply(struct wl_listener *listener, void *data);
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
static void outputmgrtest(struct wl_listener *listener, void *data);
+static void pointerconstraintsetregion(struct wl_listener *listener, void *data);
static void pointerfocus(Client *c, struct wlr_surface *surface,
double sx, double sy, uint32_t time);
static void printstatus(void);
@@ -377,6 +401,13 @@ static struct wlr_output_manager_v1 *output_mgr;
static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
static struct wlr_pointer_gestures_v1 *pointer_gestures;
+static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr;
+static struct wlr_pointer_constraints_v1 *pointer_constraints;
+static struct wl_listener pointer_constraint_commit;
+static PointerConstraint *active_constraint;
+static pixman_region32_t active_confine;
+static int active_confine_requires_warp;
+
static struct wlr_cursor *cursor;
static struct wlr_xcursor_manager *cursor_mgr;
@@ -419,6 +450,7 @@ static struct wl_listener layout_change = {.notify = updatemons};
static struct wl_listener new_input = {.notify = inputdevice};
static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard};
static struct wl_listener new_output = {.notify = createmon};
+static struct wl_listener new_pointer_constraint = {.notify = createpointerconstraint};
static struct wl_listener new_shortcuts_inhibitor = {.notify = createshortcutsinhibitor};
static struct wl_listener new_xdg_surface = {.notify = createnotify};
static struct wl_listener new_xdg_decoration = {.notify = createdecoration};
@@ -533,7 +565,7 @@ arrange(Monitor *m)
c = focustop(selmon);
if (cursor_warp && c)
warpcursor(c);
- motionnotify(0);
+ motionnotify(0, NULL, 0, 0, 0, 0);
checkidleinhibitor(NULL);
}
@@ -685,7 +717,7 @@ buttonpress(struct wl_listener *listener, void *data)
* we will send an enter event after which the client will provide us
* a cursor surface */
wlr_seat_pointer_clear_focus(seat);
- motionnotify(0);
+ motionnotify(0, NULL, 0, 0, 0, 0);
/* Drop the window off on its new monitor */
selmon = xytomon(cursor->x, cursor->y);
setmon(grabc, selmon, 0);
@@ -789,6 +821,42 @@ pinch_end(struct wl_listener *listener, void *data)
);
}
+void
+checkconstraintregion(void)
+{
+ struct wlr_pointer_constraint_v1 *constraint = active_constraint->constraint;
+ pixman_region32_t *region = &constraint->region;
+ Client *c = NULL;
+ double sx, sy;
+ toplevel_from_wlr_surface(constraint->surface, &c, NULL);
+ if (active_confine_requires_warp && c) {
+ active_confine_requires_warp = 0;
+
+ sx = cursor->x + c->geom.x;
+ sy = cursor->y + c->geom.y;
+
+ if (!pixman_region32_contains_point(region,
+ floor(sx), floor(sy), NULL)) {
+ int nboxes;
+ pixman_box32_t *boxes = pixman_region32_rectangles(region, &nboxes);
+ if (nboxes > 0) {
+ sx = (boxes[0].x1 + boxes[0].x2) / 2.;
+ sy = (boxes[0].y1 + boxes[0].y2) / 2.;
+
+ wlr_cursor_warp_closest(cursor, NULL,
+ sx - c->geom.x, sy - c->geom.y);
+ }
+ }
+ }
+
+ /* A locked pointer will result in an empty region, thus disallowing all movement. */
+ if (constraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED) {
+ pixman_region32_copy(&active_confine, region);
+ } else {
+ pixman_region32_clear(&active_confine);
+ }
+}
+
void
chvt(const Arg *arg)
{
@@ -943,6 +1011,12 @@ void
commitnotify(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, commit);
+ struct wlr_box box = {0};
+ client_get_geometry(c, &box);
+
+ if (c->mon && !wlr_box_empty(&box) && (box.width != c->geom.width - 2 * c->bw
+ || box.height != c->geom.height - 2 * c->bw))
+ c->isfloating ? resize(c, c->geom, 1, 1) : arrange(c->mon);
/* mark a pending resize as completed */
if (c->resize && c->resize <= c->surface.xdg->current.configure_serial)
@@ -956,6 +1030,12 @@ createdecoration(struct wl_listener *listener, void *data)
wlr_xdg_toplevel_decoration_v1_set_mode(dec, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
}
+void
+commitpointerconstraint(struct wl_listener *listener, void *data)
+{
+ checkconstraintregion();
+}
+
void
createidleinhibitor(struct wl_listener *listener, void *data)
{
@@ -1242,6 +1322,74 @@ void createshortcutsinhibitor(struct wl_listener *listener, void *data) {
wlr_keyboard_shortcuts_inhibitor_v1_activate(data);
}
+void
+createpointerconstraint(struct wl_listener *listener, void *data)
+{
+ struct wlr_pointer_constraint_v1 *wlr_constraint = data;
+ PointerConstraint *constraint = ecalloc(1, sizeof(*constraint));
+ Client *c = NULL, *sel = focustop(selmon);
+ toplevel_from_wlr_surface(wlr_constraint->surface, &c, NULL);
+ constraint->constraint = wlr_constraint;
+ wlr_constraint->data = constraint;
+
+ LISTEN(&wlr_constraint->events.set_region, &constraint->set_region,
+ pointerconstraintsetregion);
+ LISTEN(&wlr_constraint->events.destroy, &constraint->destroy,
+ destroypointerconstraint);
+
+ if (c == sel)
+ cursorconstrain(wlr_constraint);
+}
+
+void
+cursorconstrain(struct wlr_pointer_constraint_v1 *wlr_constraint)
+{
+ PointerConstraint *constraint = wlr_constraint->data;
+
+ if (active_constraint == constraint)
+ return;
+
+ wl_list_remove(&pointer_constraint_commit.link);
+ if (active_constraint) {
+ if (!wlr_constraint)
+ cursorwarptoconstrainthint();
+
+ wlr_pointer_constraint_v1_send_deactivated(active_constraint->constraint);
+ }
+
+ active_constraint = constraint;
+
+ if (!wlr_constraint) {
+ wl_list_init(&pointer_constraint_commit.link);
+ return;
+ }
+
+ active_confine_requires_warp = 1;
+
+ /* Stolen from sway/input/cursor.c:1435
+ *
+ * FIXME: Big hack, stolen from wlr_pointer_constraints_v1.c:121.
+ * This is necessary because the focus may be set before the surface
+ * has finished committing, which means that warping won't work properly,
+ * since this code will be run *after* the focus has been set.
+ * That is why we duplicate the code here.
+ */
+ if (pixman_region32_not_empty(&wlr_constraint->current.region)) {
+ pixman_region32_intersect(&wlr_constraint->region,
+ &wlr_constraint->surface->input_region, &wlr_constraint->current.region);
+ } else {
+ pixman_region32_copy(&wlr_constraint->region,
+ &wlr_constraint->surface->input_region);
+ }
+
+ checkconstraintregion();
+
+ wlr_pointer_constraint_v1_send_activated(wlr_constraint);
+
+ LISTEN(&wlr_constraint->surface->events.commit, &pointer_constraint_commit,
+ commitpointerconstraint);
+}
+
void
cursorframe(struct wl_listener *listener, void *data)
{
@@ -1297,6 +1445,32 @@ deck(Monitor *m)
}
}
+void
+cursorwarptoconstrainthint(void)
+{
+ struct wlr_pointer_constraint_v1 *constraint = active_constraint->constraint;
+
+ if (constraint->current.committed &
+ WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) {
+ double lx, ly;
+ double sx = lx = constraint->current.cursor_hint.x;
+ double sy = ly = constraint->current.cursor_hint.y;
+
+ Client *c = NULL;
+ toplevel_from_wlr_surface(constraint->surface, &c, NULL);
+ if (c) {
+ lx -= c->geom.x;
+ ly -= c->geom.y;
+ }
+
+ wlr_cursor_warp(cursor, NULL, lx, ly);
+
+ /* Warp the pointer as well, so that on the next pointer rebase we don't
+ * send an unexpected synthetic motion event to clients. */
+ wlr_seat_pointer_warp(seat, sx, sy);
+ }
+}
+
void
destroydragicon(struct wl_listener *listener, void *data)
{
@@ -1304,7 +1478,7 @@ destroydragicon(struct wl_listener *listener, void *data)
wlr_scene_node_destroy(icon->data);
/* Focus enter isn't sent during drag, so refocus the focused node. */
focusclient(focustop(selmon), 1);
- motionnotify(0);
+ motionnotify(0, NULL, 0, 0, 0, 0);
}
void
@@ -1339,7 +1513,7 @@ destroylock(SessionLock *lock, int unlock)
wlr_scene_node_set_enabled(&locked_bg->node, 0);
focusclient(focustop(selmon), 0);
- motionnotify(0);
+ motionnotify(0, NULL, 0, 0, 0, 0);
destroy:
wl_list_remove(&lock->new_surface.link);
@@ -1393,6 +1567,26 @@ destroynotify(struct wl_listener *listener, void *data)
free(c);
}
+void
+destroypointerconstraint(struct wl_listener *listener, void *data)
+{
+ PointerConstraint *constraint = wl_container_of(listener, constraint, destroy);
+ wl_list_remove(&constraint->set_region.link);
+ wl_list_remove(&constraint->destroy.link);
+
+ if (active_constraint == constraint) {
+ cursorwarptoconstrainthint();
+
+ if (pointer_constraint_commit.link.next)
+ wl_list_remove(&pointer_constraint_commit.link);
+
+ wl_list_init(&pointer_constraint_commit.link);
+ active_constraint = NULL;
+ }
+
+ free(constraint);
+}
+
void
destroysessionlock(struct wl_listener *listener, void *data)
{
@@ -1499,7 +1693,7 @@ focusclient(Client *c, int lift)
}
/* Change cursor surface */
- motionnotify(0);
+ motionnotify(0, NULL, 0, 0, 0, 0);
/* Have a client, so focus its top-level wlr_surface */
client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat));
@@ -1794,7 +1988,7 @@ void
maplayersurfacenotify(struct wl_listener *listener, void *data)
{
LayerSurface *l = wl_container_of(listener, l, map);
- motionnotify(0);
+ motionnotify(0, NULL, 0, 0, 0, 0);
}
void
@@ -1947,21 +2141,61 @@ motionabsolute(struct wl_listener *listener, void *data)
* so we have to warp the mouse there. There is also some hardware which
* emits these events. */
struct wlr_pointer_motion_absolute_event *event = data;
- wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y);
- motionnotify(event->time_msec);
+ double lx, ly, dx, dy;
+ wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, event->x, event->y, &lx, &ly);
+ dx = lx - cursor->x;
+ dy = ly - cursor->y;
+
+ motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
}
void
-motionnotify(uint32_t time)
+motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double dy,
+ double dx_unaccel, double dy_unaccel)
{
double sx = 0, sy = 0;
+ double sx_confined, sy_confined;
Client *c = NULL, *w = NULL;
LayerSurface *l = NULL;
int type;
struct wlr_surface *surface = NULL;
+ struct wlr_pointer_constraint_v1 *constraint = NULL;
+
+ /* Find the client under the pointer and send the event along. */
+ xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);
+
+ if (cursor_mode == CurPressed && !seat->drag) {
+ if ((type = toplevel_from_wlr_surface(
+ seat->pointer_state.focused_surface, &w, &l)) >= 0) {
+ c = w;
+ surface = seat->pointer_state.focused_surface;
+ sx = cursor->x - (type == LayerShell ? l->geom.x : w->geom.x);
+ sy = cursor->y - (type == LayerShell ? l->geom.y : w->geom.y);
+ }
+ }
/* time is 0 in internal calls meant to restore pointer focus. */
if (time) {
+ wlr_relative_pointer_manager_v1_send_relative_motion(
+ relative_pointer_mgr, seat, (uint64_t)time * 1000,
+ dx, dy, dx_unaccel, dy_unaccel);
+
+ wl_list_for_each(constraint, &pointer_constraints->constraints, link)
+ cursorconstrain(constraint);
+
+ if (active_constraint) {
+ constraint = active_constraint->constraint;
+ if (constraint->surface == surface
+ && wlr_region_confine(&active_confine, sx, sy, sx + dx,
+ sy + dy, &sx_confined, &sy_confined)) {
+ dx = sx_confined - sx;
+ dy = sy_confined - sy;
+ } else {
+ return;
+ }
+ }
+ wlr_cursor_move(cursor, device, dx, dy);
+
IDLE_NOTIFY_ACTIVITY;
/* Update selmon (even while dragging a window) */
@@ -1984,19 +2218,6 @@ motionnotify(uint32_t time)
return;
}
- /* Find the client under the pointer and send the event along. */
- xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);
-
- if (cursor_mode == CurPressed && !seat->drag) {
- if ((type = toplevel_from_wlr_surface(
- seat->pointer_state.focused_surface, &w, &l)) >= 0) {
- c = w;
- surface = seat->pointer_state.focused_surface;
- sx = cursor->x - (type == LayerShell ? l->geom.x : w->geom.x);
- sy = cursor->y - (type == LayerShell ? l->geom.y : w->geom.y);
- }
- }
-
/* If there's no client surface under the cursor, set the cursor image to a
* default. This is what makes the cursor image appear when you move it
* off of a client or over its border. */
@@ -2017,8 +2238,8 @@ motionrelative(struct wl_listener *listener, void *data)
* special configuration applied for the specific input device which
* generated the event. You can pass NULL for the device if you want to move
* the cursor around without any input. */
- wlr_cursor_move(cursor, &event->pointer->base, event->delta_x, event->delta_y);
- motionnotify(event->time_msec);
+ motionnotify(event->time_msec, &event->pointer->base, event->delta_x, event->delta_y,
+ event->unaccel_dx, event->unaccel_dy);
}
void
@@ -2120,6 +2341,14 @@ outputmgrtest(struct wl_listener *listener, void *data)
outputmgrapplyortest(config, 1);
}
+void
+pointerconstraintsetregion(struct wl_listener *listener, void *data)
+{
+ PointerConstraint *constraint = wl_container_of(listener, constraint, set_region);
+ active_confine_requires_warp = 1;
+ constraint->constraint->surface->data = NULL;
+}
+
void
pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
uint32_t time)
@@ -2625,6 +2854,11 @@ setup(void)
wl_signal_add(&output_mgr->events.apply, &output_mgr_apply);
wl_signal_add(&output_mgr->events.test, &output_mgr_test);
+ relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(dpy);
+ pointer_constraints = wlr_pointer_constraints_v1_create(dpy);
+ wl_signal_add(&pointer_constraints->events.new_constraint, &new_pointer_constraint);
+ wl_list_init(&pointer_constraint_commit.link);
+
wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend));
#ifdef XWAYLAND
@@ -2663,6 +2897,7 @@ startdrag(struct wl_listener *listener, void *data)
return;
drag->icon->data = &wlr_scene_subsurface_tree_create(drag_icon, drag->icon->surface)->node;
+ motionnotify(0, NULL, 0, 0, 0, 0);
wl_signal_add(&drag->icon->events.destroy, &drag_icon_destroy);
}
@@ -2822,7 +3057,7 @@ unmaplayersurfacenotify(struct wl_listener *listener, void *data)
if (layersurface->layer_surface->surface ==
seat->keyboard_state.focused_surface)
focusclient(focustop(selmon), 1);
- motionnotify(0);
+ motionnotify(0, NULL, 0, 0, 0, 0);
}
void
@@ -2849,7 +3084,7 @@ unmapnotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->commit.link);
wlr_scene_node_destroy(&c->scene->node);
printstatus();
- motionnotify(0);
+ motionnotify(0, NULL, 0, 0, 0, 0);
}
void

View File

@@ -1,16 +0,0 @@
diff --git a/dwl.c b/dwl.c
index 7b1ca6f..242bd2a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2273,9 +2273,8 @@ setlayout(const Arg *arg)
{
if (!selmon)
return;
- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
- selmon->sellt ^= 1;
- if (arg && arg->v)
+ selmon->sellt ^= 1;
+ if (arg && arg->v && arg->v != selmon->lt[selmon->sellt ^ 1])
selmon->lt[selmon->sellt] = (Layout *)arg->v;
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol));
if (!selmon->lt[selmon->sellt]->arrange) {

View File

@@ -1,16 +0,0 @@
diff --git a/dwl.c b/dwl.c
index 7b1ca6f..e6bb8c6 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2836,8 +2836,10 @@ urgent(struct wl_listener *listener, void *data)
void
view(const Arg *arg)
{
- if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+ if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) {
+ view(&((Arg) { .ui = 0 }));
return;
+ }
selmon->seltags ^= 1; /* toggle sel tagset */
if (arg->ui & TAGMASK)
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;

View File

@@ -1,51 +0,0 @@
diff --git a/dwl.c b/dwl.c
index 140c1b1..dc16e16 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1204,7 +1204,7 @@ cursorframe(struct wl_listener *listener, void *data)
void
deck(Monitor *m)
{
- unsigned int i, n = 0, mw, my;
+ unsigned int i, n = 0, h, r, oe = enablegaps, ie = enablegaps, mw, my;
Client *c;
wl_list_for_each(c, &clients, link)
@@ -1213,21 +1213,29 @@ deck(Monitor *m)
if (n == 0)
return;
+ if (smartgaps == n) {
+ oe = 0; // outer gaps disabled
+ }
+
if (n > m->nmaster)
- mw = m->nmaster ? m->w.width * m->mfact : 0;
+ mw = m->nmaster ? (m->w.width + m->gappiv*ie) * m->mfact : 0;
else
- mw = m->w.width;
- i = my = 0;
+ mw = m->w.width - 2*m->gappov*oe + m->gappiv*ie;
+ i = 0;
+ my = m->gappoh*oe;
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if (i < m->nmaster) {
- resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
- .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
- my += c->geom.height;
+ r = MIN(n, m->nmaster) - i;
+ h = (m->w.height - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
+ resize(c, (struct wlr_box){.x = m->w.x + m->gappov*oe, .y = m->w.y + my,
+ .width = mw - m->gappiv*ie, .height = h}, 0);
+ my += c->geom.height + m->gappih*ie;
} else {
- resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y,
- .width = m->w.width - mw, .height = m->w.height}, 0);
+ h = m->w.height - m->gappoh*oe*2;
+ resize(c, (struct wlr_box){.x = m->w.x + mw + m->gappov*oe, .y = m->w.y + m->gappoh*oe,
+ .width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0);
if (i == m->nmaster)
wlr_scene_node_raise_to_top(&c->scene->node);
}

View File

@@ -1,337 +0,0 @@
From b93e775500c303fca893a18581198f1d46c27956 Mon Sep 17 00:00:00 2001
From: Bonicgamer <44382222+Bonicgamer@users.noreply.github.com>
Date: Mon, 17 Aug 2020 14:48:24 -0400
Subject: [PATCH 1/2] Implement vanitygaps
---
config.def.h | 21 ++++++++
dwl.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 161 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 447ba0051..7958f3436 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,7 +1,12 @@
/* appearance */
static const int sloppyfocus = 1; /* focus follows mouse */
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
+static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */
static const unsigned int borderpx = 1; /* border pixel of windows */
+static const unsigned int gappih = 10; /* horiz inner gap between windows */
+static const unsigned int gappiv = 10; /* vert inner gap between windows */
+static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */
+static const unsigned int gappov = 10; /* vert outer gap between windows and screen edge */
static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
@@ -117,6 +122,22 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_h, incgaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_l, incgaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_H, incogaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_L, incogaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_CTRL, XKB_KEY_h, incigaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_CTRL, XKB_KEY_l, incigaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_0, togglegaps, {0} },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_parenright,defaultgaps, {0} },
+ { MODKEY, XKB_KEY_y, incihgaps, {.i = +1 } },
+ { MODKEY, XKB_KEY_o, incihgaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_y, incivgaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_o, incivgaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_y, incohgaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_o, incohgaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Y, incovgaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_O, incovgaps, {.i = -1 } },
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
diff --git a/dwl.c b/dwl.c
index b5e146d10..0af910980 100644
--- a/dwl.c
+++ b/dwl.c
@@ -185,6 +185,10 @@ struct Monitor {
struct wlr_box w; /* window area, layout-relative */
struct wl_list layers[4]; /* LayerSurface::link */
const Layout *lt[2];
+ int gappih; /* horizontal gap between windows */
+ int gappiv; /* vertical gap between windows */
+ int gappoh; /* horizontal outer gaps */
+ int gappov; /* vertical outer gaps */
unsigned int seltags;
unsigned int sellt;
uint32_t tagset[2];
@@ -262,6 +267,13 @@ static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
static int handlesig(int signo, void *data);
static void incnmaster(const Arg *arg);
+static void incgaps(const Arg *arg);
+static void incigaps(const Arg *arg);
+static void incihgaps(const Arg *arg);
+static void incivgaps(const Arg *arg);
+static void incogaps(const Arg *arg);
+static void incohgaps(const Arg *arg);
+static void incovgaps(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
static int keybinding(uint32_t mods, xkb_keysym_t sym);
static void keypress(struct wl_listener *listener, void *data);
@@ -291,6 +303,7 @@ static void run(char *startup_cmd);
static void setcursor(struct wl_listener *listener, void *data);
static void setfloating(Client *c, int floating);
static void setfullscreen(Client *c, int fullscreen);
+static void setgaps(int oh, int ov, int ih, int iv);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setmon(Client *c, Monitor *m, uint32_t newtags);
@@ -304,6 +317,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 togglegaps(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -368,6 +382,8 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static int enablegaps = 1; /* enables gaps, used by togglegaps */
+
/* global event handlers */
static struct wl_listener cursor_axis = {.notify = axisnotify};
static struct wl_listener cursor_button = {.notify = buttonpress};
@@ -915,6 +931,11 @@ createmon(struct wl_listener *listener, void *data)
/* Initialize monitor state using configured rules */
for (i = 0; i < LENGTH(m->layers); i++)
wl_list_init(&m->layers[i]);
+
+ m->gappih = gappih;
+ m->gappiv = gappiv;
+ m->gappoh = gappoh;
+ m->gappov = gappov;
m->tagset[0] = m->tagset[1] = 1;
for (r = monrules; r < END(monrules); r++) {
if (!r->name || strstr(wlr_output->name, r->name)) {
@@ -1077,6 +1098,12 @@ cursorframe(struct wl_listener *listener, void *data)
wlr_seat_pointer_notify_frame(seat);
}
+void
+defaultgaps(const Arg *arg)
+{
+ setgaps(gappoh, gappov, gappih, gappiv);
+}
+
void
destroydragicon(struct wl_listener *listener, void *data)
{
@@ -1367,6 +1394,83 @@ incnmaster(const Arg *arg)
arrange(selmon);
}
+void
+incgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh + arg->i,
+ selmon->gappov + arg->i,
+ selmon->gappih + arg->i,
+ selmon->gappiv + arg->i
+ );
+}
+
+void
+incigaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh,
+ selmon->gappov,
+ selmon->gappih + arg->i,
+ selmon->gappiv + arg->i
+ );
+}
+
+void
+incihgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh,
+ selmon->gappov,
+ selmon->gappih + arg->i,
+ selmon->gappiv
+ );
+}
+
+void
+incivgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh,
+ selmon->gappov,
+ selmon->gappih,
+ selmon->gappiv + arg->i
+ );
+}
+
+void
+incogaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh + arg->i,
+ selmon->gappov + arg->i,
+ selmon->gappih,
+ selmon->gappiv
+ );
+}
+
+void
+incohgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh + arg->i,
+ selmon->gappov,
+ selmon->gappih,
+ selmon->gappiv
+ );
+}
+
+void
+incovgaps(const Arg *arg)
+{
+ setgaps(
+ selmon->gappoh,
+ selmon->gappov + arg->i,
+ selmon->gappih,
+ selmon->gappiv
+ );
+}
+
void
inputdevice(struct wl_listener *listener, void *data)
{
@@ -2063,6 +2167,16 @@ setfullscreen(Client *c, int fullscreen)
printstatus();
}
+void
+setgaps(int oh, int ov, int ih, int iv)
+{
+ selmon->gappoh = MAX(oh, 0);
+ selmon->gappov = MAX(ov, 0);
+ selmon->gappih = MAX(ih, 0);
+ selmon->gappiv = MAX(iv, 0);
+ arrange(selmon);
+}
+
void
setlayout(const Arg *arg)
{
@@ -2366,7 +2480,7 @@ tagmon(const Arg *arg)
void
tile(Monitor *m)
{
- unsigned int i, n = 0, mw, my, ty;
+ unsigned int i, n = 0, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty;
Client *c;
wl_list_for_each(c, &clients, link)
@@ -2374,23 +2488,32 @@ tile(Monitor *m)
n++;
if (n == 0)
return;
+
+ if (smartgaps == n) {
+ oe = 0; // outer gaps disabled
+ }
if (n > m->nmaster)
- mw = m->nmaster ? m->w.width * m->mfact : 0;
+ mw = m->nmaster ? (m->w.width + m->gappiv*ie) * m->mfact : 0;
else
- mw = m->w.width;
- i = my = ty = 0;
+ mw = m->w.width - 2*m->gappov*oe + m->gappiv*ie;
+ i = 0;
+ my = ty = m->gappoh*oe;
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if (i < m->nmaster) {
- resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
- .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
- my += c->geom.height;
+ r = MIN(n, m->nmaster) - i;
+ h = (m->w.height - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
+ resize(c, (struct wlr_box){.x = m->w.x + m->gappov*oe, .y = m->w.y + my,
+ .width = mw - m->gappiv*ie, .height = h}, 0);
+ my += c->geom.height + m->gappih*ie;
} else {
- resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty,
- .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0);
- ty += c->geom.height;
+ r = n - i;
+ h = (m->w.height - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
+ resize(c, (struct wlr_box){.x = m->w.x + mw + m->gappov*oe, .y = m->w.y + ty,
+ .width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0);
+ ty += c->geom.height + m->gappih*ie;
}
i++;
}
@@ -2413,6 +2536,13 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+togglegaps(const Arg *arg)
+{
+ enablegaps = !enablegaps;
+ arrange(selmon);
+}
+
void
toggletag(const Arg *arg)
{
From bb4e29db2a38d14c36253f02ec22ea2eb9bc5c0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@protonmail.com>
Date: Wed, 20 Jul 2022 00:15:32 -0500
Subject: [PATCH 2/2] allow gaps in monocle layout if requested
---
config.def.h | 1 +
dwl.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 7958f3436..ed2cdae36 100644
--- a/config.def.h
+++ b/config.def.h
@@ -2,6 +2,7 @@
static const int sloppyfocus = 1; /* focus follows mouse */
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */
+static const int monoclegaps = 0; /* 1 means outer gaps in monocle layout */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int gappih = 10; /* horiz inner gap between windows */
static const unsigned int gappiv = 10; /* vert inner gap between windows */
diff --git a/dwl.c b/dwl.c
index 0af910980..1a654f358 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1735,8 +1735,12 @@ monocle(Monitor *m)
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
- resize(c, m->w, 0);
n++;
+ if (!monoclegaps)
+ resize(c, m->w, 0);
+ else
+ resize(c, (struct wlr_box){.x = m->w.x + gappoh, .y = m->w.y + gappov,
+ .width = m->w.width - 2 * gappoh, .height = m->w.height - 2 * gappov}, 0);
}
if (n)
snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n);

View File

@@ -24,11 +24,6 @@
ghostty = {
url = "git+ssh://git@github.com/mitchellh/ghostty";
};
dwl-source = {
# Use dwl's master.
url = "github:djpohly/dwl?ref=755fcae2afbed51f38c167bdc56a5437cda8137a";
flake = false;
};
flood = {
url = "github:zoriya/flood";
flake = false;
@@ -41,7 +36,6 @@
neovim-nightly,
nixpkgs,
ghostty,
dwl-source,
flood,
impermanence,
nixos-hardware,
@@ -57,10 +51,10 @@
[
impermanence.nixosModules.impermanence
./modules/cli
(./modules + "/${de}")
(./environments + "/${de}")
{
nixpkgs.overlays = [
(import ./overlays {inherit dwl-source flood;})
(import ./overlays {inherit flood;})
neovim-nightly.overlays.default
];
}
@@ -85,7 +79,7 @@
users.${user} = {
imports = [
./modules/cli/home.nix
(./modules + "/${de}/home.nix")
(./environments + "/${de}/home.nix")
nix-index-database.hmModules.nix-index
];
};

View File

@@ -1,206 +0,0 @@
/* appearance */
static const int sloppyfocus = 1; /* focus follows mouse */
static const int smartgaps = 1; /* 1 means no outer gap when there is only one window */
static const int monoclegaps = 0; /* 1 means outer gaps in monocle layout */
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
static const int smartborders = 1;
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int gappih = 10; /* horiz inner gap between windows */
static const unsigned int gappiv = 10; /* vert inner gap between windows */
static const unsigned int gappoh = 20; /* horiz outer gap between windows and screen edge */
static const unsigned int gappov = 20; /* vert outer gap between windows and screen edge */
static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
static bool cursor_warp = true;
/* tagging - tagcount must be no greater than 31 */
#define TAGCOUNT 9
static const int tagcount = 9;
/* Autostart */
static const char *const autostart[] = {
"dwlstartup", NULL,
"polkit-gnome-authentication-agent-1", NULL,
"wallpaper", NULL,
"ydotoold", NULL,
"shikane", NULL,
"wl-paste", "--watch", "cliphist", "store", NULL,
"discord", NULL,
"youtube-music", NULL,
NULL /* terminate */
};
static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */
/* examples:
{ "Gimp", NULL, 0, 1, -1 },
*/
{ "discord", NULL, 1 << 2, 0, -1 },
{ "YouTube Music", NULL, 1 << 1, 0, -1 },
};
/* layout(s) */
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile },
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
{ "[D]", deck },
};
/* monitors */
static const MonitorRule monrules[] = {
/* name mfact nmaster scale layout rotate/reflect x y tagset*/
{ "eDP-1", 0.55, 1, 1.75, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0, 0, 1 << 3 },
/* defaults */
{ NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1, 0},
};
/* keyboard */
static const struct xkb_rule_names xkb_rules = {
/* can specify fields: rules, model, layout, variant, options */
.options = "caps:escape_shifted_capslock",
};
static const int repeat_rate = 25;
static const int repeat_delay = 600;
/* Trackpad */
static const int tap_to_click = 1;
static const int tap_and_drag = 1;
static const int drag_lock = 0;
static const int natural_scrolling = 1;
static const int disable_while_typing = 1;
static const int left_handed = 0;
static const int middle_button_emulation = 1;
/* You can choose between:
LIBINPUT_CONFIG_SCROLL_NO_SCROLL
LIBINPUT_CONFIG_SCROLL_2FG
LIBINPUT_CONFIG_SCROLL_EDGE
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
*/
static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
/* You can choose between:
LIBINPUT_CONFIG_CLICK_METHOD_NONE
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
*/
static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
/* You can choose between:
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE
*/
static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
/* You can choose between:
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
*/
static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
static const double accel_speed = 0.0;
/* You can choose between:
LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
*/
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
#define MODKEY WLR_MODIFIER_LOGO
#define TAGKEYS(KEY,SKEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) spawn, { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* commands */
static const char *termcmd[] = { "kitty", NULL };
static const char *browcmd[] = { "firefox", NULL };
static const char *menucmd[] = { "rofi", "-show", "drun", "-show-icons", NULL };
static const Key keys[] = {
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
/* modifier key function argument */
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
{ MODKEY, XKB_KEY_e, spawn, {.v = termcmd} },
{ MODKEY, XKB_KEY_r, spawn, {.v = browcmd} },
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_u, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} },
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY, XKB_KEY_c, killclient, {0} },
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_BackSpace, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XKB_KEY_d, setlayout, {.v = &layouts[3]} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_F, togglefloating, {0} },
{ MODKEY, XKB_KEY_f, togglefullscreen, {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|WLR_DIRECTION_DOWN} },
{ MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT|WLR_DIRECTION_UP} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT|WLR_DIRECTION_DOWN} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT|WLR_DIRECTION_UP} },
{ MODKEY, XKB_KEY_Left, rotatetags, {.i = -1} },
{ MODKEY, XKB_KEY_Right, rotatetags, {.i = +1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, clientshift, {.i = -1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, clientshift, {.i = +1} },
TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0),
TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1),
TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2),
TAGKEYS( XKB_KEY_4, XKB_KEY_dollar, 3),
TAGKEYS( XKB_KEY_5, XKB_KEY_percent, 4),
TAGKEYS( XKB_KEY_6, XKB_KEY_asciicircum, 5),
TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6),
TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7),
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
{ MODKEY, XKB_KEY_b, SHCMD("hyprpicker | wl-copy") },
{ MODKEY, XKB_KEY_x, SHCMD("grim -g \"$(slurp -b 00000000 -s 61616140)\" - | wl-copy") },
{ MODKEY, XKB_KEY_v, SHCMD("cliphist list | rofi -dmenu | cliphist decode | wl-copy") },
{ 0, XKB_KEY_XF86PowerOff, spawn, {.v = (const char*[]){"ags", "-t", "powermenu", NULL}}},
// TODO: Allow those bindings on lockscreen
// TODO: Allow those bindings on repeat
{ 0, XKB_KEY_XF86MonBrightnessUp, spawn, {.v = (const char*[]){"ags", "run-js", "brightness.screen += 0.05; indicator.display()", NULL}}},
{ 0, XKB_KEY_XF86MonBrightnessDown, spawn, {.v = (const char*[]){"ags", "run-js", "brightness.screen -= 0.05; indicator.display()", NULL}}},
{ 0, XKB_KEY_XF86KbdBrightnessUp, spawn, {.v = (const char*[]){"ags", "run-js", "brightness.kbd++; indicator.kbd()", NULL}}},
{ 0, XKB_KEY_XF86KbdBrightnessDown, spawn, {.v = (const char*[]){"ags", "run-js", "brightness.kbd--; indicator.kbd()", NULL}}},
{ 0, XKB_KEY_XF86AudioRaiseVolume, spawn, {.v = (const char*[]){"ags", "run-js", "audio.speaker.volume += 0.05; indicator.speaker()", NULL}}},
{ 0, XKB_KEY_XF86AudioLowerVolume, spawn, {.v = (const char*[]){"ags", "run-js", "audio.speaker.volume -= 0.05; indicator.speaker()", NULL}}},
{ 0, XKB_KEY_XF86AudioMute, spawn, {.v = (const char*[]){"ags", "run-js", "audio.speaker.isMuted = !audio.speaker.isMuted; indicator.speaker()", NULL}}},
{ 0, XKB_KEY_XF86AudioMicMute, spawn, {.v = (const char*[]){"pactl", "set-source-mute", "@DEFAULT_SOURCE@", "toggle", NULL}}},
{ 0, XKB_KEY_XF86AudioPlay, spawn, {.v = (const char*[]){"ags", "run-js", "mpris.getPlayer()?.playPause()", NULL}}},
{ 0, XKB_KEY_XF86AudioStop, spawn, {.v = (const char*[]){"ags", "run-js", "mpris.getPlayer()?.stop()", NULL}}},
{ 0, XKB_KEY_XF86AudioPause, spawn, {.v = (const char*[]){"ags", "run-js", "mpris.getPlayer()?.pause()", NULL}}},
{ 0, XKB_KEY_XF86AudioPrev, spawn, {.v = (const char*[]){"ags", "run-js", "mpris.getPlayer()?.previous()", NULL}}},
{ 0, XKB_KEY_XF86AudioNext, spawn, {.v = (const char*[]){"ags", "run-js", "mpris.getPlayer()?.next()", NULL}}},
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
};
static const Button buttons[] = {
{ MODKEY|WLR_MODIFIER_SHIFT, BTN_LEFT, moveresize, {.ui = CurMove} },
{ MODKEY|WLR_MODIFIER_SHIFT, BTN_MIDDLE, togglefloating, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, BTN_RIGHT, moveresize, {.ui = CurResize} },
};

View File

@@ -1,76 +0,0 @@
{pkgs, ...}: {
services.xserver = {
enable = true;
displayManager.gdm = {
enable = true;
settings = {
"org/gnome/desktop/peripherals/touchpad" = {
tap-to-click = true;
};
};
};
};
services.displayManager = {
autoLogin = {
enable = true;
user = "zoriya";
};
sessionPackages = [pkgs.dwl];
};
networking.networkmanager.enable = true;
environment.systemPackages = with pkgs; [
dwl
polkit_gnome
wineWowPackages.stable
wineWowPackages.waylandFull
winetricks
];
hardware.steam-hardware.enable = true;
services.flatpak.enable = true;
# Those two lines prevent a crash with gdm autologin.
systemd.services."getty@tty1".enable = false;
systemd.services."autovt@tty1".enable = false;
services.printing.enable = true;
security.rtkit.enable = true;
hardware.pulseaudio.enable = false;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
jack.enable = true;
pulse.enable = true;
};
hardware.bluetooth.enable = true;
security.polkit.enable = true;
# needed for GNOME services outside of GNOME Desktop
services = {
dbus.packages = [pkgs.gcr];
udev.packages = with pkgs; [gnome.gnome-settings-daemon];
};
programs.dconf.enable = true;
services.dbus.enable = true;
xdg.portal = {
enable = true;
wlr.enable = true;
# gtk portal needed to make gtk apps happy
extraPortals = [pkgs.xdg-desktop-portal-gtk];
config.common.default = "*";
};
services.upower.enable = true;
services.gvfs.enable = true;
# i18n.inputMethod.enabled = "ibus";
# i18n.inputMethod.ibus.engines = with pkgs.ibus-engines; [mozc];
virtualisation.libvirtd.enable = true;
programs.virt-manager.enable = true;
}

View File

@@ -1,8 +0,0 @@
#! /bin/sh
dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP=wlroots
# Stop any services that are running, so that they receive the new env var when they restart.
systemctl --user stop pipewire wireplumber xdg-desktop-portal xdg-desktop-portal-wlr xdg-desktop-portal-gtk
systemctl --user start wireplumber
fusuma -c ~/.config/fusuma/config.yaml

View File

@@ -1,80 +0,0 @@
{pkgs, ...}: let
dwlstartup = pkgs.writeShellScriptBin "dwlstartup" (builtins.readFile ./dwlstartup.sh);
in {
imports = [
../common/apps.nix
];
home.packages = with pkgs; [
alsa-utils
sassc
brightnessctl
pavucontrol
blueberry
networkmanagerapplet
glib
# Only used for pactl.
pulseaudio
dwlstartup
hyprpicker
wdisplays
wlr-randr
grim
slurp
cliphist
ydotool
fusuma
gnome-control-center
gnome.gnome-weather
shikane
];
# Keycodes here: https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h#L202
# :1 is for keydown, :0 for keyup
xdg.configFile."fusuma/config.yaml".text = ''
swipe:
3:
right:
command: 'ydotool key 125:1 105:1 105:0 125:0'
left:
command: 'ydotool key 125:1 106:1 106:0 125:0'
up:
command: 'ydotool key 125:1 4:1 4:0 125:0'
down:
command: 'ydotool key 125:1 4:1 4:0 125:0'
hold:
4:
command: 'ydotool key 125:1 52:1 52:0 125:0'
'';
xdg.configFile."shikane/config.toml".text = ''
[[profile]]
name = "laptop"
[[profile.output]]
match = "eDP-1"
enable = true
[[profile]]
name = "docked"
exec = ["bash -c 'ags -q; cat /proc/$(pidof dwl)/fd/1 | ags & disown'"]
[[profile.output]]
match = "eDP-1"
enable = false
[[profile.output]]
match = "/DP-2|.*|EB243Y A/"
enable = true
mode = { width = 1920, height = 1080, refresh = 60 }
position = { x = 0, y = 0 }
scale = 1
[[profile.output]]
match = "/DP-1|.*|EB243Y A/"
enable = true
mode = { width = 1920, height = 1080, refresh = 60 }
position = { x = 0, y = 1180 }
scale = 1
'';
}

View File

@@ -1,7 +1,4 @@
{
dwl-source,
flood,
}: self: super: let
{flood}: self: super: let
wrapProgram = drv: bins: wrapProgramFlags:
super.symlinkJoin {
name = drv.name;
@@ -18,42 +15,6 @@
--add-flags "--enable-features=UseOzonePlatform" \
--add-flags "--ozone-platform=wayland"'';
in {
# Patch dwl.
dwl =
(super.dwl.override
{
wlroots = super.pkgs.wlroots_0_16;
conf = ../modules/dwl/config.h;
})
.overrideAttrs (oldAttrs: {
version = "0.4";
src = dwl-source;
enableXWayland = true;
passthru.providedSessions = ["dwl"];
patches = [
../dwl_patches/autostart.patch
../dwl_patches/deck.patch
../dwl_patches/output-power-managment.patch
../dwl_patches/keyboard-shortcut-inhibit.patch
../dwl_patches/cursor_warp.patch
../dwl_patches/vanitygaps.patch
../dwl_patches/vanity_deck.patch
../dwl_patches/smartborders.patch
../dwl_patches/desktop.patch
../dwl_patches/togglelayout.patch
../dwl_patches/toggletag.patch
../dwl_patches/singletagset.patch
../dwl_patches/montagset.patch
../dwl_patches/movestack.patch
../dwl_patches/gdk_monitors_status.patch
../dwl_patches/rotatetags.patch
../dwl_patches/naturalscrolltrackpad.patch
../dwl_patches/pointer-gesture.patch
../dwl_patches/sway-pointer-contraints.patch
../dwl_patches/retore-tiling.patch
];
});
# Use my fork of flood to enable smart scripts.
flood = self.pkgs.buildNpmPackage {
pname = "flood";