commit 7e17314e4b25b84b83b0712bc6dae30c59bc6977
parent 6e32aa82cde233b652ef382c7c5cc93e7b34df6f
Author: stojshic <stojshic@arch.pc>
Date: Tue, 6 Feb 2024 20:29:51 +0100
Added a patch changing shortcut for use with only two monitor setup
Diffstat:
2 files changed, 268 insertions(+), 0 deletions(-)
diff --git a/dwm.suckless.org/patches/two_monitor_setup/dwm-twomonitorsetup-6.4.diff b/dwm.suckless.org/patches/two_monitor_setup/dwm-twomonitorsetup-6.4.diff
@@ -0,0 +1,242 @@
+From 4928b5e9f4e5666ed35e3aa3f61df25c503e921e Mon Sep 17 00:00:00 2001
+From: stojshic <stojshic@arch.pc>
+Date: Tue, 6 Feb 2024 19:54:47 +0100
+Subject: [PATCH] Modified to work with two monitors, 'ModKey + <' [or 'ModKey
+ + Shift + <'] moves focus [or windows] to left monitor but doesn't bring it
+ back to right monitor on another click
+
+---
+ dwm.c | 119 ++++++++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 82 insertions(+), 37 deletions(-)
+
+diff --git a/dwm.c b/dwm.c
+index e5efb6a..2234780 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -160,7 +160,7 @@ static Monitor *createmon(void);
+ static void destroynotify(XEvent *e);
+ static void detach(Client *c);
+ static void detachstack(Client *c);
+-static Monitor *dirtomon(int dir);
++// static Monitor *dirtomon(int dir);
+ static void drawbar(Monitor *m);
+ static void drawbars(void);
+ static void enternotify(XEvent *e);
+@@ -194,6 +194,7 @@ static void resizeclient(Client *c, int x, int y, int w, int h);
+ static void resizemouse(const Arg *arg);
+ static void restack(Monitor *m);
+ static void run(void);
++static void runAutostart(void);
+ static void scan(void);
+ static int sendevent(Client *c, Atom proto);
+ static void sendmon(Client *c, Monitor *m);
+@@ -205,7 +206,6 @@ static void setmfact(const Arg *arg);
+ static void setup(void);
+ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+-static void sigchld(int unused);
+ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+@@ -681,6 +681,7 @@ detachstack(Client *c)
+ }
+ }
+
++/*
+ Monitor *
+ dirtomon(int dir)
+ {
+@@ -695,7 +696,7 @@ dirtomon(int dir)
+ for (m = mons; m->next != selmon; m = m->next);
+ return m;
+ }
+-
++*/
+ void
+ drawbar(Monitor *m)
+ {
+@@ -737,7 +738,8 @@ drawbar(Monitor *m)
+
+ if ((w = m->ww - tw - x) > bh) {
+ if (m->sel) {
+- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
++ drw_setscheme(drw, scheme[SchemeNorm]);
++ // drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+ if (m->sel->isfloating)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
+@@ -823,17 +825,22 @@ focusin(XEvent *e)
+ }
+
+ void
+-focusmon(const Arg *arg)
+-{
+- Monitor *m;
++focusmon(const Arg *arg) {
++ Monitor *m = NULL;
+
+- if (!mons->next)
+- return;
+- if ((m = dirtomon(arg->i)) == selmon)
+- return;
+- unfocus(selmon->sel, 0);
+- selmon = m;
+- focus(NULL);
++ if (!mons->next)
++ return;
++
++ if (arg->i > 0) {
++ m = mons->next;
++ } else if (arg->i < 0 && mons->next) {
++ m = mons;
++ }
++
++ if (m) {
++ selmon = m;
++ focus(NULL);
++ }
+ }
+
+ void
+@@ -955,16 +962,26 @@ grabkeys(void)
+ {
+ updatenumlockmask();
+ {
+- unsigned int i, j;
++ unsigned int i, j, k;
+ unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+- KeyCode code;
++ int start, end, skip;
++ KeySym *syms;
+
+ XUngrabKey(dpy, AnyKey, AnyModifier, root);
+- for (i = 0; i < LENGTH(keys); i++)
+- if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
+- for (j = 0; j < LENGTH(modifiers); j++)
+- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
+- True, GrabModeAsync, GrabModeAsync);
++ XDisplayKeycodes(dpy, &start, &end);
++ syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip);
++ if (!syms)
++ return;
++ for (k = start; k <= end; k++)
++ for (i = 0; i < LENGTH(keys); i++)
++ /* skip modifier codes, we do that ourselves */
++ if (keys[i].keysym == syms[(k - start) * skip])
++ for (j = 0; j < LENGTH(modifiers); j++)
++ XGrabKey(dpy, k,
++ keys[i].mod | modifiers[j],
++ root, True,
++ GrabModeAsync, GrabModeAsync);
++ XFree(syms);
+ }
+ }
+
+@@ -1381,6 +1398,12 @@ run(void)
+ handler[ev.type](&ev); /* call handler */
+ }
+
++void
++runAutostart(void) {
++ system("cd ~/.dwm; ./autostart_blocking.sh");
++ system("cd ~/.dwm; ./autostart.sh &");
++}
++
+ void
+ scan(void)
+ {
+@@ -1533,9 +1556,16 @@ setup(void)
+ int i;
+ XSetWindowAttributes wa;
+ Atom utf8string;
++ struct sigaction sa;
++
++ /* do not transform children into zombies when they terminate */
++ sigemptyset(&sa.sa_mask);
++ sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART;
++ sa.sa_handler = SIG_IGN;
++ sigaction(SIGCHLD, &sa, NULL);
+
+- /* clean up any zombies immediately */
+- sigchld(0);
++ /* clean up any zombies (inherited from .xinitrc etc) immediately */
++ while (waitpid(-1, NULL, WNOHANG) > 0);
+
+ /* init screen */
+ screen = DefaultScreen(dpy);
+@@ -1628,21 +1658,23 @@ showhide(Client *c)
+ }
+ }
+
+-void
+-sigchld(int unused)
+-{
+- if (signal(SIGCHLD, sigchld) == SIG_ERR)
+- die("can't install SIGCHLD handler:");
+- while (0 < waitpid(-1, NULL, WNOHANG));
+-}
+-
+ void
+ spawn(const Arg *arg)
+ {
++ struct sigaction sa;
++
++ if (arg->v == dmenucmd)
++ dmenumon[0] = '0' + selmon->num;
+ if (fork() == 0) {
+ if (dpy)
+ close(ConnectionNumber(dpy));
+ setsid();
++
++ sigemptyset(&sa.sa_mask);
++ sa.sa_flags = 0;
++ sa.sa_handler = SIG_DFL;
++ sigaction(SIGCHLD, &sa, NULL);
++
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
+ }
+@@ -1658,14 +1690,26 @@ tag(const Arg *arg)
+ }
+ }
+
+-void
+-tagmon(const Arg *arg)
+-{
+- if (!selmon->sel || !mons->next)
+- return;
+- sendmon(selmon->sel, dirtomon(arg->i));
++void tagmon(const Arg *arg) {
++ if (!selmon->sel || !mons->next)
++ return;
++
++ Monitor *m;
++
++ if (arg->i > 0) {
++ m = mons->next; // Move to mon1
++ } else if (arg->i < 0 && mons->next) {
++ m = mons; // Move to mon2
++ } else {
++ return; // Do nothing for arg->i == 0
++ }
++
++ sendmon(selmon->sel, m);
++ focus(NULL);
++ arrange(selmon);
+ }
+
++
+ void
+ tile(Monitor *m)
+ {
+@@ -2140,6 +2184,7 @@ main(int argc, char *argv[])
+ die("pledge");
+ #endif /* __OpenBSD__ */
+ scan();
++ runAutostart();
+ run();
+ cleanup();
+ XCloseDisplay(dpy);
+--
+2.43.0
+
diff --git a/dwm.suckless.org/patches/two_monitor_setup/index.md b/dwm.suckless.org/patches/two_monitor_setup/index.md
@@ -0,0 +1,26 @@
+Two Monitor Setup
+=====
+
+Description
+-----------
+I have a two monitor setup, and I always find default config confusing.
+Using `ModKey + <` and `ModKey + ShiftKey + <` to move window or focus
+to left monitor, and when it's on the leftmost monitor, it moves it to
+the rightmost. It's probably good for multiple-monitor setup, but in my
+setup it just switches back and forth, and if I accidentally press
+`ModKey + <` two times, it switches focus to the same monitor on which
+I was before, which was confusing to me.
+
+With this patch `ModKey + <` and `ModKey + ShiftKey + <` only sends the
+focus or window to left monitor, and if it's already on the left monitor,
+it does nothing. Same with `ModKey + >` and `ModKey + ShiftKey + >`, if
+the focus is on left monitor, it will swith the focus to right monitor,
+otherwise, it will do nothing.
+
+Download
+--------
+* [dwm-twomonitorsetup-6.4.diff](dwm-twomonitorsetup-6.4.diff)
+
+Authors
+-------
+* Slavko Stojshic - <stojshic@gmail.com>