From 0f1aa53f886991dd8d43be64abf61494c7e74706 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 20 Aug 2023 17:43:55 +0200 Subject: [PATCH] Add dwl and patches --- dwl_patches/autostart.patch | 145 +++++++++++ dwl_patches/cursor_wrap.patch | 65 +++++ dwl_patches/deck.patch | 83 +++++++ dwl_patches/focusMonPointer.patch | 28 +++ dwl_patches/keyboard-shortcut-inhibit.patch | 107 ++++++++ dwl_patches/output-power-managment.patch | 257 ++++++++++++++++++++ dwl_patches/point.patch | 228 +++++++++++++++++ flake.lock | 45 ++-- flake.nix | 10 +- modules/dwl/config.h | 180 ++++++++++++++ modules/dwl/default.nix | 33 +++ modules/dwl/home.nix | 21 ++ modules/home/git/default.nix | 1 + modules/nixos/fonts/default.nix | 2 +- overlays/default.nix | 50 ++-- 15 files changed, 1222 insertions(+), 33 deletions(-) create mode 100644 dwl_patches/autostart.patch create mode 100644 dwl_patches/cursor_wrap.patch create mode 100644 dwl_patches/deck.patch create mode 100644 dwl_patches/focusMonPointer.patch create mode 100644 dwl_patches/keyboard-shortcut-inhibit.patch create mode 100644 dwl_patches/output-power-managment.patch create mode 100644 dwl_patches/point.patch create mode 100644 modules/dwl/config.h create mode 100644 modules/dwl/default.nix create mode 100644 modules/dwl/home.nix diff --git a/dwl_patches/autostart.patch b/dwl_patches/autostart.patch new file mode 100644 index 0000000..9bd2de3 --- /dev/null +++ b/dwl_patches/autostart.patch @@ -0,0 +1,145 @@ +From c602d9af1971fa219ff4d6821f7c30445f548f2f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= + +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,6 +7,12 @@ 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 */ + static const int tagcount = 9; + +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) diff --git a/dwl_patches/cursor_wrap.patch b/dwl_patches/cursor_wrap.patch new file mode 100644 index 0000000..7fdbb0d --- /dev/null +++ b/dwl_patches/cursor_wrap.patch @@ -0,0 +1,65 @@ +diff --git a/config.def.h b/config.def.h +index 447ba00..2eaf29f 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -9,6 +9,9 @@ static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; + + /* tagging - tagcount must be no greater than 31 */ + static const int tagcount = 9; ++/* cursor warping */ ++static const bool cursor_warp = true; ++ + + static const Rule rules[] = { + /* app_id title tags mask isfloating monitor */ +diff --git a/dwl.c b/dwl.c +index 93f66ef..5562c0d 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -314,6 +314,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 struct wlr_scene_node *xytonode(double x, double y, struct wlr_surface **psurface, + Client **pc, LayerSurface **pl, double *nx, double *ny); +@@ -486,6 +487,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); + } +@@ -1210,6 +1214,9 @@ focusclient(Client *c, int lift) + + if (locked) + return; ++ /* Warp cursor to center of client if it is outside */ ++ if (cursor_warp && c) ++ warpcursor(c); + + /* Raise client in stacking order if requested */ + if (c && lift) +@@ -2616,6 +2623,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) + { diff --git a/dwl_patches/deck.patch b/dwl_patches/deck.patch new file mode 100644 index 0000000..bbce210 --- /dev/null +++ b/dwl_patches/deck.patch @@ -0,0 +1,83 @@ +From c696b91d0def051b6bab2b50a1c3a748eaa3aa91 Mon Sep 17 00:00:00 2001 +From: Palanix +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) + { diff --git a/dwl_patches/focusMonPointer.patch b/dwl_patches/focusMonPointer.patch new file mode 100644 index 0000000..be3b93e --- /dev/null +++ b/dwl_patches/focusMonPointer.patch @@ -0,0 +1,28 @@ +From bc8d50cb39b925b0bf551a65e2cdf3420c2f77cf Mon Sep 17 00:00:00 2001 +From: Stivvo +Date: Tue, 15 Sep 2020 13:20:05 +0200 +Subject: [PATCH] focusmon() moves the cursor accordingly + +Moves the cursor to the recently focused monito + +Keeps same x and y position relative to the monitor +--- + dwl.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dwl.c b/dwl.c +index 730e46a1f..f6cdcbb26 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -734,9 +734,11 @@ void + focusmon(const Arg *arg) + { + Client *sel = selclient(); ++ Monitor *prevm = selmon; + + selmon = dirtomon(arg->i); + focusclient(sel, focustop(selmon), 1); ++ wlr_cursor_move(cursor, NULL, selmon->m.x - prevm->m.x , 0); + } + + void diff --git a/dwl_patches/keyboard-shortcut-inhibit.patch b/dwl_patches/keyboard-shortcut-inhibit.patch new file mode 100644 index 0000000..9a09476 --- /dev/null +++ b/dwl_patches/keyboard-shortcut-inhibit.patch @@ -0,0 +1,107 @@ +From cd7954be78ba9abe38423f2537c39c29ca7695db Mon Sep 17 00:00:00 2001 +From: MadcowOG +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 + #include + #include ++#include + #include + #include + #include +@@ -245,6 +246,7 @@ 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 createshortcutsinhibitor(struct wl_listener *listener, void *data); + static void createpointerconstraint(struct wl_listener *listener, void *data); + static void deck(Monitor *m); + static void cursorframe(struct wl_listener *listener, void *data); + 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), diff --git a/dwl_patches/output-power-managment.patch b/dwl_patches/output-power-managment.patch new file mode 100644 index 0000000..156104c --- /dev/null +++ b/dwl_patches/output-power-managment.patch @@ -0,0 +1,257 @@ +From 598d88c868f35444008c458ae95e0e68a10946d1 Mon Sep 17 00:00:00 2001 +From: Guido Cella +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 pointer-constraints-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 pointer-constraints-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 + #include + #include ++#include + #include + #include + #include +@@ -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 @@ ++ ++ ++ ++ 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. ++ ++ ++ ++ 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. ++ ++ ++ ++ ++ This interface is a manager that allows creating per-output power ++ management mode controls. ++ ++ ++ ++ ++ Create a output power management mode control that can be used to ++ adjust the power management mode for a given output. ++ ++ ++ ++ ++ ++ ++ ++ All objects created by the manager will still remain valid, until their ++ appropriate destroy request has been called. ++ ++ ++ ++ ++ ++ ++ This object offers requests to set the power management mode of ++ an output. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 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. ++ ++ ++ ++ ++ ++ ++ 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. ++ ++ ++ ++ ++ ++ ++ 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. ++ ++ ++ ++ ++ ++ Destroys the output power management mode control object. ++ ++ ++ ++ + +From 66a957c61b84c2753663c5ffed78abcee8a0bca1 Mon Sep 17 00:00:00 2001 +From: Dima Krasner +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 + #include + #include ++#include + #include + #include + #include +@@ -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); + } + diff --git a/dwl_patches/point.patch b/dwl_patches/point.patch new file mode 100644 index 0000000..9339ace --- /dev/null +++ b/dwl_patches/point.patch @@ -0,0 +1,228 @@ +From 701cc94e7db68d7d943561be47f8a9d8663f30be Mon Sep 17 00:00:00 2001 +From: Palanix +Date: Sun, 3 Jul 2022 18:46:18 +0200 +Subject: [PATCH] Fix pointerconstraints + +--- + Makefile | 5 +++- + config.def.h | 3 ++ + dwl.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 90 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index ccca07948..ee1316146 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 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 +@@ -28,6 +28,9 @@ WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols` + xdg-shell-protocol.h: + $(WAYLAND_SCANNER) server-header \ + $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ ++pointer-constraints-unstable-v1-protocol.h: ++ $(WAYLAND_SCANNER) server-header \ ++ $(WAYLAND_PROTOCOLS)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@ + wlr-layer-shell-unstable-v1-protocol.h: + $(WAYLAND_SCANNER) server-header \ + protocols/wlr-layer-shell-unstable-v1.xml $@ +diff --git a/config.def.h b/config.def.h +index 447ba0051..9f3a40131 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,6 +10,9 @@ static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; + /* tagging - tagcount must be no greater than 31 */ + static const int tagcount = 9; + ++/* pointer constraints */ ++static const int allow_constrain = 1; ++ + static const Rule rules[] = { + /* app_id title tags mask isfloating monitor */ + /* examples: +diff --git a/dwl.c b/dwl.c +index 93f66efe6..d3b5cdac1 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -1,6 +1,7 @@ + /* + * See LICENSE file for copyright and license details. + */ ++#include + #include + #include + #include +@@ -34,8 +35,10 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -203,6 +206,14 @@ typedef struct { + int x, y; + } MonitorRule; + ++struct pointer_constraint { ++ struct wlr_pointer_constraint_v1 *constraint; ++ ++ struct wl_listener set_region; ++ struct wl_listener destroy; ++}; ++ ++ + typedef struct { + const char *id; + const char *title; +@@ -245,6 +256,7 @@ 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 cursorframe(struct wl_listener *listener, void *data); + static void destroydragicon(struct wl_listener *listener, void *data); + static void destroyidleinhibitor(struct wl_listener *listener, void *data); +@@ -254,12 +266,14 @@ 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 destroypointerconstraint(struct wl_listener *listener, void *data); + static Monitor *dirtomon(enum wlr_direction dir); + static void focusclient(Client *c, int lift); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); + static Client *focustop(Monitor *m); + 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 inputdevice(struct wl_listener *listener, void *data); +@@ -367,6 +381,11 @@ static struct wlr_box sgeom; + static struct wl_list mons; + static Monitor *selmon; + ++struct wlr_pointer_constraints_v1 *pointer_constraints; ++struct wlr_pointer_constraint_v1 *active_constraint; ++static struct wl_listener constraint_commit; ++struct wlr_relative_pointer_manager_v1 *relative_pointer_manager; ++ + /* global event handlers */ + static struct wl_listener cursor_axis = {.notify = axisnotify}; + static struct wl_listener cursor_button = {.notify = buttonpress}; +@@ -382,6 +401,7 @@ static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard}; + static struct wl_listener new_output = {.notify = createmon}; + static struct wl_listener new_xdg_surface = {.notify = createnotify}; + static struct wl_listener new_xdg_decoration = {.notify = createdecoration}; ++static struct wl_listener pointer_constraint_create = {.notify = createpointerconstraint}; + static struct wl_listener new_layer_shell_surface = {.notify = createlayersurface}; + static struct wl_listener output_mgr_apply = {.notify = outputmgrapply}; + static struct wl_listener output_mgr_test = {.notify = outputmgrtest}; +@@ -976,6 +996,30 @@ createmon(struct wl_listener *listener, void *data) + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); + } + ++void ++createpointerconstraint(struct wl_listener *listener, void *data) ++{ ++ if (focustop(selmon)) { ++ struct wlr_pointer_constraint_v1 *constraint = data; ++ struct pointer_constraint *pointer_constraint = calloc(1, sizeof(struct pointer_constraint)); ++ pointer_constraint->constraint = constraint; ++ ++ pointer_constraint->destroy.notify = destroypointerconstraint; ++ wl_signal_add(&constraint->events.destroy, &pointer_constraint->destroy); ++ ++ if (client_surface(focustop(selmon)) == constraint->surface) { ++ if (allow_constrain == 0 || active_constraint == constraint) ++ return; ++ ++ active_constraint = constraint; ++ wlr_pointer_constraint_v1_send_activated(constraint); ++ ++ constraint_commit.notify = handleconstraintcommit; ++ wl_signal_add(&constraint->surface->events.commit, &constraint_commit); ++ } ++ } ++} ++ + void + createnotify(struct wl_listener *listener, void *data) + { +@@ -1064,6 +1108,25 @@ createpointer(struct wlr_pointer *pointer) + wlr_cursor_attach_input_device(cursor, &pointer->base); + } + ++void ++destroypointerconstraint(struct wl_listener *listener, void *data) ++{ ++ struct wlr_pointer_constraint_v1 *constraint = data; ++ struct pointer_constraint *pointer_constraint = wl_container_of(listener, pointer_constraint, destroy); ++ ++ wl_list_remove(&pointer_constraint->destroy.link); ++ ++ if (active_constraint == constraint) { ++ if (constraint_commit.link.next != NULL) { ++ wl_list_remove(&constraint_commit.link); ++ } ++ wl_list_init(&constraint_commit.link); ++ active_constraint = NULL; ++ } ++ ++ free(pointer_constraint); ++} ++ + void + cursorframe(struct wl_listener *listener, void *data) + { +@@ -1355,6 +1418,12 @@ handlesig(int signo) + } + } + ++void ++handleconstraintcommit(struct wl_listener *listener, void *data) ++{ ++ assert(active_constraint->surface == data); ++} ++ + void + incnmaster(const Arg *arg) + { +@@ -1717,7 +1786,15 @@ 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); ++ wlr_relative_pointer_manager_v1_send_relative_motion( ++ relative_pointer_manager, ++ seat, (uint64_t)event->time_msec * 1000, ++ event->delta_x, event->delta_y, event->unaccel_dx, event->unaccel_dy); ++ ++ if (!active_constraint) { ++ wlr_cursor_move(cursor, &event->pointer->base, ++ event->delta_x, event->delta_y); ++ } + motionnotify(event->time_msec); + } + +@@ -2243,6 +2320,11 @@ setup(void) + xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy); + wl_signal_add(&xdg_decoration_mgr->events.new_toplevel_decoration, &new_xdg_decoration); + ++ pointer_constraints = wlr_pointer_constraints_v1_create(dpy); ++ wl_signal_add(&pointer_constraints->events.new_constraint, &pointer_constraint_create); ++ ++ relative_pointer_manager = wlr_relative_pointer_manager_v1_create(dpy); ++ + /* + * Creates a cursor, which is a wlroots utility for tracking the cursor + * image shown on screen. diff --git a/flake.lock b/flake.lock index b115c6e..8c79a62 100644 --- a/flake.lock +++ b/flake.lock @@ -16,6 +16,22 @@ "type": "github" } }, + "dwl-source": { + "flake": false, + "locked": { + "lastModified": 1692416242, + "narHash": "sha256-WE3HaiOZhUAy13BMAZ5eCyOu0n4Z/k599yKm7QJdi4o=", + "owner": "djpohly", + "repo": "dwl", + "rev": "4567979b16b0509bb80b6102ecb9b601b3cf6fa1", + "type": "github" + }, + "original": { + "owner": "djpohly", + "repo": "dwl", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -39,11 +55,11 @@ ] }, "locked": { - "lastModified": 1690652600, - "narHash": "sha256-Dy09g7mezToVwtFPyY25fAx1hzqNXv73/QmY5/qyR44=", + "lastModified": 1692503956, + "narHash": "sha256-MOA6FKc1YgfGP3ESnjSYfsyJ1BXlwV5pGlY/u5XdJfY=", "owner": "nix-community", "repo": "home-manager", - "rev": "f58889c07efa8e1328fdf93dc1796ec2a5c47f38", + "rev": "958c06303f43cf0625694326b7f7e5475b1a2d5c", "type": "github" }, "original": { @@ -54,11 +70,11 @@ }, "impermanence": { "locked": { - "lastModified": 1684264534, - "narHash": "sha256-K0zr+ry3FwIo3rN2U/VWAkCJSgBslBisvfRIPwMbuCQ=", + "lastModified": 1690797372, + "narHash": "sha256-GImz19e33SeVcIvBB7NnhbJSbTpFFmNtWLh7Z85Y188=", "owner": "nix-community", "repo": "impermanence", - "rev": "89253fb1518063556edd5e54509c30ac3089d5e6", + "rev": "e3a7acd113903269a1b5c8b527e84ce7ee859851", "type": "github" }, "original": { @@ -104,11 +120,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1690548937, - "narHash": "sha256-x3ZOPGLvtC0/+iFAg9Kvqm/8hTAIkGjc634SqtgaXTA=", + "lastModified": 1692447944, + "narHash": "sha256-fkJGNjEmTPvqBs215EQU4r9ivecV5Qge5cF/QDLVn3U=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2a9d660ff0f7ffde9d73be328ee6e6f10ef66b28", + "rev": "d680ded26da5cf104dd2735a51e88d2d8f487b4d", "type": "github" }, "original": { @@ -135,11 +151,11 @@ }, "nur": { "locked": { - "lastModified": 1690721668, - "narHash": "sha256-550poDnDiMXLPQBJnUwhEzv0ZC4zjiFiwTaOIi3jfs4=", + "lastModified": 1692518211, + "narHash": "sha256-7gyJ9lOH87Tn5zfMYfiMNgJON5pqME0JtJXJwq9nKV4=", "owner": "nix-community", "repo": "NUR", - "rev": "1c4ba84e2cbfd43976a0fd3f848b536611735a79", + "rev": "6a11e17484e90c1255dc89693322710be86b71ad", "type": "github" }, "original": { @@ -150,6 +166,7 @@ }, "root": { "inputs": { + "dwl-source": "dwl-source", "home-manager": "home-manager", "impermanence": "impermanence", "jq": "jq", @@ -167,8 +184,8 @@ ] }, "locked": { - "lastModified": 1690360663, - "narHash": "sha256-3/t/MAP0kD+bYIjQ5j74c/pgEZ8CvlATBALvIFqwzRw=", + "lastModified": 1692354899, + "narHash": "sha256-18fKnFTJoa1jrjWdNROqLBF+TnvuIa4zCvnqdbsJhA4=", "path": "/home/zoriya/projects/tuxedo-nixos", "type": "path" }, diff --git a/flake.nix b/flake.nix index 52c0e3a..fe952ad 100644 --- a/flake.nix +++ b/flake.nix @@ -19,6 +19,11 @@ url = "path:/home/zoriya/projects/tuxedo-nixos"; #"github:blitz/tuxedo-nixos"; inputs.nixpkgs.follows = "nixpkgs"; }; + dwl-source = { + # Use dwl's master. + url = "github:djpohly/dwl"; + flake = false; + }; }; outputs = { @@ -28,6 +33,7 @@ nur, nixpkgs, tuxedo-nixos, + dwl-source, ... } @ rawInput: let user = "zoriya"; @@ -43,11 +49,12 @@ modules = [ ./modules/nixos ./modules/gnome + # ./modules/dwl nixModules nur.nixosModules.nur { nixpkgs.overlays = [ - (import ./overlays) + (import ./overlays { inherit dwl-source; }) nur.overlay # neovim-nightly.overlay ]; @@ -80,6 +87,7 @@ imports = [ ./modules/home ./modules/gnome/home.nix + ./modules/dwl/home.nix ]; config.modules = homeModules; }; diff --git a/modules/dwl/config.h b/modules/dwl/config.h new file mode 100644 index 0000000..3def413 --- /dev/null +++ b/modules/dwl/config.h @@ -0,0 +1,180 @@ +/* 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 unsigned int borderpx = 1; /* border pixel of windows */ +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}; + +/* tagging - tagcount must be no greater than 31 */ +static const int tagcount = 9; +static const bool cursor_warp = true; + +/* Autostart */ +static const char *const autostart[] = { + // "wbg", "/path/to/your/image", NULL, + NULL /* terminate */ +}; + +/* pointer constraints */ +static const int allow_constrain = 1; + +static const Rule rules[] = { + /* app_id title tags mask isfloating monitor */ + /* examples: + { "Gimp", NULL, 0, 1, -1 }, + */ + { "discord", NULL, 1 << 3, 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 */ + /* example of a HiDPI laptop monitor: + { "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, + */ + /* defaults */ + { NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, +}; + +/* keyboard */ +static const struct xkb_rule_names xkb_rules = { + /* can specify fields: rules, model, layout, variant, options */ + /* example: + .options = "ctrl:nocaps", + */ + .options = NULL, +}; + +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 = 1; +static const int natural_scrolling = 0; +static const int disable_while_typing = 1; +static const int left_handed = 0; +static const int middle_button_emulation = 0; +/* 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) { .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", NULL }; + +// static const char *upvol[] = { "amixer", "-q", "-c", "0", "set", "Master", "2+", NULL }; +// static const char *downvol[] = { "amixer", "-q", "-c", "0", "set", "Master", "2-", NULL }; +// for muting/unmuting // +// static const char *mute[] = { "amixer", "-q", "set", "Master", "toggle", 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, 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_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, 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_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} }, + { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, + 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} }, + + /* 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), + + // { 0,XF86XK_AudioRaiseVolume, spawn,{.v = upvol } }, + // { 0,XF86XK_AudioLowerVolume, spawn,{.v = downvol } }, + // { 0,XF86XK_AudioMute,spawn,{.v = mute } }, +}; + +static const Button buttons[] = { + { MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} }, + { MODKEY, BTN_MIDDLE, togglefloating, {0} }, + { MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} }, +}; diff --git a/modules/dwl/default.nix b/modules/dwl/default.nix new file mode 100644 index 0000000..87ca1f1 --- /dev/null +++ b/modules/dwl/default.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + pkgs, + inputs, + ... +}: +{ + services.xserver = { + enable = true; + displayManager = { + gdm.enable = true; + autoLogin = { + enable = true; + user = "zoriya"; + }; + }; + }; + + # Those two lines prevent a crash with gdm autologin. + systemd.services."getty@tty1".enable = false; + systemd.services."autovt@tty1".enable = false; + + xdg.portal = { + enable = true; + wlr.enable = true; + # gtk portal needed to make gtk apps happy + extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; + }; + + i18n.inputMethod.enabled = "ibus"; + i18n.inputMethod.ibus.engines = with pkgs.ibus-engines; [mozc]; +} diff --git a/modules/dwl/home.nix b/modules/dwl/home.nix new file mode 100644 index 0000000..afd88ff --- /dev/null +++ b/modules/dwl/home.nix @@ -0,0 +1,21 @@ +{ + pkgs, + lib, + config, + user, + ... +}: { + home.packages = with pkgs; [ + dwl + alsa-utils + ]; + home.pointerCursor = { + name = "Adwaita"; + package = pkgs.gnome.adwaita-icon-theme; + size = 24; + x11 = { + enable = true; + defaultCursor = "Adwaita"; + }; + }; +} diff --git a/modules/home/git/default.nix b/modules/home/git/default.nix index 5b27500..e8c4e99 100644 --- a/modules/home/git/default.nix +++ b/modules/home/git/default.nix @@ -27,6 +27,7 @@ in { push.autoSetupRemote = true; init.defaultBranch = "master"; pull.ff = "only"; + advice.diverging = false; }; userEmail = "zoe.roux@zoriya.dev"; diff --git a/modules/nixos/fonts/default.nix b/modules/nixos/fonts/default.nix index 26bf0fd..8246b60 100644 --- a/modules/nixos/fonts/default.nix +++ b/modules/nixos/fonts/default.nix @@ -15,7 +15,7 @@ in { earlySetup = true; }; fonts = { - fonts = with pkgs; [ + packages = with pkgs; [ roboto dejavu_fonts # Some japanese fonts diff --git a/overlays/default.nix b/overlays/default.nix index 1c1589a..3d89275 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,20 +1,36 @@ -self: super: - let - enableWayland = drv: bins: - super.symlinkJoin { - name = drv.name; - paths = [ drv ]; - buildInputs = [ super.makeWrapper ]; - postBuild = super.lib.concatStrings (map (bin: '' +{dwl-source}: self: super: let + enableWayland = drv: bins: + super.symlinkJoin { + name = drv.name; + paths = [drv]; + buildInputs = [super.makeWrapper]; + postBuild = super.lib.concatStrings (map (bin: '' wrapProgram $out/bin/${bin} \ --add-flags "--enable-features=UseOzonePlatform" \ --add-flags "--ozone-platform=wayland" - '') bins); - }; - in { - tuxedo-keyboard = super.callPackage ./tuxedo-keyboard {}; - slack = enableWayland super.slack ["slack"]; - discord = enableWayland super.discord ["discord" "Discord"]; - youtube-music = enableWayland super.youtube-music ["youtube-music"]; - vscode = enableWayland super.vscode ["code"]; - } + '') + bins); + }; +in { + dwl = + (super.dwl.override + {conf = ../modules/dwl/config.h;}) + .overrideAttrs (oldAttrs: { + src = dwl-source; + patches = [ + ../dwl_patches/autostart.patch + ../dwl_patches/deck.patch + # ../dwl_patches/focusMonPointer.patch + ../dwl_patches/point.patch + ../dwl_patches/output-power-managment.patch + ../dwl_patches/keyboard-shortcut-inhibit.patch + ../dwl_patches/cursor_wrap.patch + ]; + }); + + tuxedo-keyboard = super.callPackage ./tuxedo-keyboard {}; + slack = enableWayland super.slack ["slack"]; + discord = enableWayland super.discord ["discord" "Discord"]; + youtube-music = enableWayland super.youtube-music ["youtube-music"]; + vscode = enableWayland super.vscode ["code"]; +}