mirror of
https://github.com/zoriya/flake.git
synced 2025-12-06 06:36:19 +00:00
Remove dwl
This commit is contained in:
@@ -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)
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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),
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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 */
|
||||
@@ -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)
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
12
flake.nix
12
flake.nix
@@ -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
|
||||
];
|
||||
};
|
||||
|
||||
@@ -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} },
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
'';
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user