diff --git a/.gitignore b/.gitignore index cfadb18..344ddc9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,5 @@ *.o dwm/dwm st/st -st/config.h -dwm/config.h -dmenu/config.h dmenu/dmenu dmenu/stest diff --git a/README.md b/README.md index 11e5d8f..c6694f1 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ I will refactor this soon. Sorry for how weird everything is. **If you want polybar**: you need the `waffle` and `castella` fonts installed from here: https://addy-dclxvi.github.io/post/bitmap-fonts/ as well as polybar-dwm-module (https://github.com/mihirlad55/polybar-dwm-module) +**Warning: the polybar configuration is deprecated** + **If you get unexpected colors/fonts**: make sure you applied the Xresources file from this repo. **GTK Theme I use**: https://github.com/TheGreatMcPain/gruvbox-material-gtk diff --git a/dmenu/config.def.h b/dmenu/config.def.h index c96adcc..58d8297 100644 --- a/dmenu/config.def.h +++ b/dmenu/config.def.h @@ -12,7 +12,7 @@ static const char fg2[] = "#dcdfe4"; static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { - "castella:size=12" + "JetBrainsMono Nerd Font:size=10:antialias=true:autohint=true" }; static const char *prompt = NULL; /* -p option; prompt to the left of input field */ static const char *colors[SchemeLast][2] = { diff --git a/dmenu/config.h b/dmenu/config.h index c96adcc..58d8297 100644 --- a/dmenu/config.h +++ b/dmenu/config.h @@ -12,7 +12,7 @@ static const char fg2[] = "#dcdfe4"; static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { - "castella:size=12" + "JetBrainsMono Nerd Font:size=10:antialias=true:autohint=true" }; static const char *prompt = NULL; /* -p option; prompt to the left of input field */ static const char *colors[SchemeLast][2] = { diff --git a/dmenu/dmenu b/dmenu/dmenu index ec50dfa..fff9b89 100755 Binary files a/dmenu/dmenu and b/dmenu/dmenu differ diff --git a/dmenu/applied_patches/dmenu-lineheight-5.0.diff b/dmenu/patches/dmenu-lineheight-5.0.diff similarity index 100% rename from dmenu/applied_patches/dmenu-lineheight-5.0.diff rename to dmenu/patches/dmenu-lineheight-5.0.diff diff --git a/dmenu/applied_patches/dmenu-xresources-4.9.diff b/dmenu/patches/dmenu-xresources-4.9.diff similarity index 100% rename from dmenu/applied_patches/dmenu-xresources-4.9.diff rename to dmenu/patches/dmenu-xresources-4.9.diff diff --git a/dmenu/stest b/dmenu/stest index c1f1031..27cb972 100755 Binary files a/dmenu/stest and b/dmenu/stest differ diff --git a/dots/.scripts/cmus_status_delegate b/dots/.scripts/cmus_status_delegate new file mode 100755 index 0000000..4752c1a --- /dev/null +++ b/dots/.scripts/cmus_status_delegate @@ -0,0 +1,19 @@ +#!/bin/sh + +# This script is meant to be set in cmus' `status_display_program`. +# This script will be called by cmus and will send the +# status to other programs (e.g. statusupdatectl) + +# put values from cmus into their own variables +# TODO: hack +while test $# -ge 2 +do + eval _$1='$2' + shift + shift +done +if [ -z "${_title}" -o "${_status}" = "paused" ]; then + statusupdatectl "set_media_name::" +else + statusupdatectl "set_media_name::${_artist} - ${_title}" +fi diff --git a/dots/.scripts/dmenucalc b/dots/.scripts/dmenucalc index 415d52e..1e1c762 100755 --- a/dots/.scripts/dmenucalc +++ b/dots/.scripts/dmenucalc @@ -1,7 +1,7 @@ #!/bin/sh docalc() { - res=$(true | dmenu -p "calc" | bc) + res=$(true | dmenu -p "calc" | bc -l) [ "$res" = "" ] && exit next=$(printf "exit\nnext" | dmenu -p "calc;res=${res}") [ "next" = "${next}" ] && docalc || exit diff --git a/dots/.scripts/dwmstatus b/dots/.scripts/dwmstatus index 550ee93..c6ce230 100755 --- a/dots/.scripts/dwmstatus +++ b/dots/.scripts/dwmstatus @@ -1,7 +1,93 @@ #!/bin/sh +# create fifo +fifo="${XDG_RUNTIME_DIR}/statusupdated" + +mkfifo "${fifo}" +trap "echo 'exit' > '${fifo}' ; rm -f '${fifo}'" EXIT + +extra="" +message="" +media_name="" +date_value="" + +dark_medium="#282828" +dark_hard="#1d2021" +dark_soft="#32302f" +red="#ea6962" +green="#a9b665" +yellow="#d8a657" +blue="#7daea3" +magenta="#d3869b" +cyan="#89b482" +white="#d4be98" + + +clean() { + rm -f "${fifo}" +} + +getstatus() { + data="" + if [ ! -z "${extra}" ]; then + data="${data}${extra} •" + fi + if [ ! -z "${message}" ]; then + data="${data}^c${magenta}^  ^d^${message} •" + fi + if [ ! -z "${media_name}" ]; then + data="${data}^c${magenta}^  ^d^${media_name} •" + fi + if [ ! -z "${date_value}" ]; then + data="${data}^c${magenta}^  ^d^${date_value}" + fi + echo "${data}" +} + +updatestatus() { + xsetroot -name "$(getstatus)" +} + + while : do - xsetroot -name "$(date '+%a %d %b %H:%M')" - sleep 40 + if read fifoline < $fifo; then + case "${fifoline}" in + set_message*) + # cuts after :: + # example: `set_message::nice day outside` + message="${fifoline##*::}" + ;; + set_media_name*) + # cuts after :: + # example: `set_media_name::Song Name Goes Here` + media_name="${fifoline##*::}" + ;; + set_date_value*) + # cuts after :: + # example: `set_date_value::Date Goes Here` + date_value="${fifoline##*::}" + ;; + set_extra*) + # cuts after :: + # example `set_extra::something happened` + extra="${fifoline##*::}" + ;; + update) + ;; + exit) + echo "statusupdated: warn: got exit command, exiting..." + exit 1 + ;; + *) ;; + esac + updatestatus + fi +done & + +# send the time string every 30 seconds through the FIFO +while : +do + echo "set_date_value::$(date '+%a %d %b %-I:%M')" > "${fifo}" + sleep 30 done diff --git a/dots/.scripts/funccf b/dots/.scripts/funccf new file mode 100755 index 0000000..d16f805 --- /dev/null +++ b/dots/.scripts/funccf @@ -0,0 +1,5 @@ +#!/bin/sh + +cf() { + cd $(find ~/code -maxdepth 4 -type d -name "$1" -print | sed 1q) +} diff --git a/dots/.scripts/polybar b/dots/.scripts/polybar new file mode 100755 index 0000000..e75ffc5 --- /dev/null +++ b/dots/.scripts/polybar @@ -0,0 +1,3 @@ +#!/bin/sh + +polybar top & diff --git a/dots/.scripts/statusupdatectl b/dots/.scripts/statusupdatectl new file mode 100755 index 0000000..80ffac5 --- /dev/null +++ b/dots/.scripts/statusupdatectl @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "${1}" > "${XDG_RUNTIME_DIR}/statusupdated" diff --git a/dots/.scripts/xorgsettings b/dots/.scripts/xorgsettings index 140f9b2..f7da10a 100755 --- a/dots/.scripts/xorgsettings +++ b/dots/.scripts/xorgsettings @@ -5,3 +5,7 @@ xinput --set-prop 13 'libinput Accel Speed' '-1' # Set refresh rate xrandr --output HDMI-A-0 --mode 1920x1080 --rate 75 +xrandr --output "DisplayPort-0" --mode 1024x768 --rate 60 + +# Rotate my secondary monitor +xrandr --output "DisplayPort-0" --rotate "right" diff --git a/dwm/applied_patches/dwm-anybar-20200810-bb2e722.diff b/dwm/applied_patches/dwm-anybar-20200810-bb2e722.diff deleted file mode 100644 index 00fe940..0000000 --- a/dwm/applied_patches/dwm-anybar-20200810-bb2e722.diff +++ /dev/null @@ -1,335 +0,0 @@ -From 782f63d8f858b1c14df38aaf623438d7ea2f75e1 Mon Sep 17 00:00:00 2001 -From: mihirlad55 -Date: Mon, 10 Aug 2020 01:39:35 +0000 -Subject: [PATCH] Add support for managing external status bars - -This patch allows dwm to manage other status bars such as -polybar/lemonbar without them needing to set override-redirect. For -all intents and purposes, DWM treats this bar as if it were its own -and as a result helps the status bar and DWM live in harmony. - -This has a few advantages -* The bar does not block fullscreen windows -* DWM makes room for the status bar, so windows do not overlap the bar -* The bar can be hidden/killed and DWM will not keep an unsightly gap - where the bar was -* DWM receives EnterNotify events when your cursor enters the bar - -To use another status bar, set usealtbar to 1 in your config.h and set -altbarclass to the class name (can be found using xprop) to the class -name of your status bar. Also make sure that if your status bar will -be displayed on top, topbar is set to 1 in your config, and if it will -be displayed on bottom, topbar is set to 0. This patch does not -support bars that are not docked at the top or at the bottom of your -monitor. - -The patch is developed at https://github.com/mihirlad55/dwm-anybar ---- - config.def.h | 3 ++ - dwm.c | 114 ++++++++++++++++++++++++++++++++++++++++++++------- - 2 files changed, 103 insertions(+), 14 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..d0d60aa 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -5,6 +5,9 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ -+static const int usealtbar = 1; /* 1 means use non-dwm status bar */ -+static const char *altbarclass = "Polybar"; /* Alternate bar class name */ -+static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */ - static const char *fonts[] = { "monospace:size=10" }; - static const char dmenufont[] = "monospace:size=10"; - static const char col_gray1[] = "#222222"; -diff --git a/dwm.c b/dwm.c -index 9fd0286..f149ab4 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -47,8 +47,8 @@ - /* macros */ - #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) - #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) --#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ -- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) -+#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - MAX((x),(m)->mx)) \ -+ * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - MAX((y),(m)->my))) - #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) - #define LENGTH(X) (sizeof X / sizeof X[0]) - #define MOUSEMASK (BUTTONMASK|PointerMotionMask) -@@ -116,7 +116,7 @@ struct Monitor { - float mfact; - int nmaster; - int num; -- int by; /* bar geometry */ -+ int by, bh; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; -@@ -179,6 +179,7 @@ static void incnmaster(const Arg *arg); - static void keypress(XEvent *e); - static void killclient(const Arg *arg); - static void manage(Window w, XWindowAttributes *wa); -+static void managealtbar(Window win, XWindowAttributes *wa); - static void mappingnotify(XEvent *e); - static void maprequest(XEvent *e); - static void monocle(Monitor *m); -@@ -207,6 +208,7 @@ 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 spawnbar(); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -216,6 +218,7 @@ static void toggletag(const Arg *arg); - static void toggleview(const Arg *arg); - static void unfocus(Client *c, int setfocus); - static void unmanage(Client *c, int destroyed); -+static void unmanagealtbar(Window w); - static void unmapnotify(XEvent *e); - static void updatebarpos(Monitor *m); - static void updatebars(void); -@@ -230,6 +233,7 @@ static void updatewmhints(Client *c); - static void view(const Arg *arg); - static Client *wintoclient(Window w); - static Monitor *wintomon(Window w); -+static int wmclasscontains(Window win, const char *class, const char *name); - static int xerror(Display *dpy, XErrorEvent *ee); - static int xerrordummy(Display *dpy, XErrorEvent *ee); - static int xerrorstart(Display *dpy, XErrorEvent *ee); -@@ -505,8 +509,10 @@ cleanupmon(Monitor *mon) - for (m = mons; m && m->next != mon; m = m->next); - m->next = mon->next; - } -- XUnmapWindow(dpy, mon->barwin); -- XDestroyWindow(dpy, mon->barwin); -+ if (!usealtbar) { -+ XUnmapWindow(dpy, mon->barwin); -+ XDestroyWindow(dpy, mon->barwin); -+ } - free(mon); - } - -@@ -568,7 +574,7 @@ configurenotify(XEvent *e) - for (c = m->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); -- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, m->bh); - } - focus(NULL); - arrange(NULL); -@@ -639,6 +645,7 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->bh = bh; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -649,10 +656,13 @@ void - destroynotify(XEvent *e) - { - Client *c; -+ Monitor *m; - XDestroyWindowEvent *ev = &e->xdestroywindow; - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); -+ else if ((m = wintomon(ev->window)) && m->barwin == ev->window) -+ unmanagealtbar(ev->window); - } - - void -@@ -696,6 +706,9 @@ dirtomon(int dir) - void - drawbar(Monitor *m) - { -+ if (usealtbar) -+ return; -+ - int x, w, tw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; -@@ -1077,6 +1090,25 @@ manage(Window w, XWindowAttributes *wa) - focus(NULL); - } - -+void -+managealtbar(Window win, XWindowAttributes *wa) -+{ -+ Monitor *m; -+ if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height))) -+ return; -+ -+ m->barwin = win; -+ m->by = wa->y; -+ bh = m->bh = wa->height; -+ updatebarpos(m); -+ arrange(m); -+ XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); -+ XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height); -+ XMapWindow(dpy, win); -+ XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, -+ (unsigned char *) &win, 1); -+} -+ - void - mappingnotify(XEvent *e) - { -@@ -1097,7 +1129,9 @@ maprequest(XEvent *e) - return; - if (wa.override_redirect) - return; -- if (!wintoclient(ev->window)) -+ if (wmclasscontains(ev->window, altbarclass, "")) -+ managealtbar(ev->window, &wa); -+ else if (!wintoclient(ev->window)) - manage(ev->window, &wa); - } - -@@ -1393,7 +1427,9 @@ scan(void) - if (!XGetWindowAttributes(dpy, wins[i], &wa) - || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) - continue; -- if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) -+ if (wmclasscontains(wins[i], altbarclass, "")) -+ managealtbar(wins[i], &wa); -+ else if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) - manage(wins[i], &wa); - } - for (i = 0; i < num; i++) { /* now the transients */ -@@ -1546,7 +1582,7 @@ setup(void) - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; -- bh = drw->fonts->h + 2; -+ bh = usealtbar ? 0 : drw->fonts->h + 2; - updategeom(); - /* init atoms */ - utf8string = XInternAtom(dpy, "UTF8_STRING", False); -@@ -1595,6 +1631,7 @@ setup(void) - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); - focus(NULL); -+ spawnbar(); - } - - -@@ -1653,6 +1690,13 @@ spawn(const Arg *arg) - } - } - -+void -+spawnbar() -+{ -+ if (*altbarcmd) -+ system(altbarcmd); -+} -+ - void - tag(const Arg *arg) - { -@@ -1704,7 +1748,7 @@ togglebar(const Arg *arg) - { - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); -- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); -+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, selmon->bh); - arrange(selmon); - } - -@@ -1787,10 +1831,26 @@ unmanage(Client *c, int destroyed) - arrange(m); - } - -+void -+unmanagealtbar(Window w) -+{ -+ Monitor *m = wintomon(w); -+ -+ if (!m) -+ return; -+ -+ m->barwin = 0; -+ m->by = 0; -+ m->bh = 0; -+ updatebarpos(m); -+ arrange(m); -+} -+ - void - unmapnotify(XEvent *e) - { - Client *c; -+ Monitor *m; - XUnmapEvent *ev = &e->xunmap; - - if ((c = wintoclient(ev->window))) { -@@ -1798,12 +1858,16 @@ unmapnotify(XEvent *e) - setclientstate(c, WithdrawnState); - else - unmanage(c, 0); -- } -+ } else if ((m = wintomon(ev->window)) && m->barwin == ev->window) -+ unmanagealtbar(ev->window); - } - - void - updatebars(void) - { -+ if (usealtbar) -+ return; -+ - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, -@@ -1829,11 +1893,11 @@ updatebarpos(Monitor *m) - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { -- m->wh -= bh; -+ m->wh -= m->bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; -- m->wy = m->topbar ? m->wy + bh : m->wy; -+ m->wy = m->topbar ? m->wy + m->bh : m->wy; - } else -- m->by = -bh; -+ m->by = -m->bh; - } - - void -@@ -2077,6 +2141,28 @@ wintomon(Window w) - return selmon; - } - -+int -+wmclasscontains(Window win, const char *class, const char *name) -+{ -+ XClassHint ch = { NULL, NULL }; -+ int res = 1; -+ -+ if (XGetClassHint(dpy, win, &ch)) { -+ if (ch.res_name && strstr(ch.res_name, name) == NULL) -+ res = 0; -+ if (ch.res_class && strstr(ch.res_class, class) == NULL) -+ res = 0; -+ } else -+ res = 0; -+ -+ if (ch.res_class) -+ XFree(ch.res_class); -+ if (ch.res_name) -+ XFree(ch.res_name); -+ -+ return res; -+} -+ - /* There's no way to check accesses to destroyed windows, thus those cases are - * ignored (especially on UnmapNotify's). Other types of errors call Xlibs - * default error handler, which may call exit. */ --- -2.28.0 - diff --git a/dwm/applied_patches/dwm-ewmhtags-6.2.diff b/dwm/applied_patches/dwm-ewmhtags-6.2.diff deleted file mode 100644 index 32abb8c..0000000 --- a/dwm/applied_patches/dwm-ewmhtags-6.2.diff +++ /dev/null @@ -1,161 +0,0 @@ -From e5f0eefa921e6bad1e6f75faced0c3ae519995b3 Mon Sep 17 00:00:00 2001 -From: Ryan Kes -Date: Thu, 28 Mar 2019 14:49:28 +0100 -Subject: [PATCH] dwm-ewhmtags-6.2 - ---- - dwm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 48 insertions(+), 1 deletion(-) - -diff --git a/dwm.c b/dwm.c -index 4465af1..92022a1 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -55,6 +55,7 @@ - #define WIDTH(X) ((X)->w + 2 * (X)->bw) - #define HEIGHT(X) ((X)->h + 2 * (X)->bw) - #define TAGMASK ((1 << LENGTH(tags)) - 1) -+#define TAGSLENGTH (LENGTH(tags)) - #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - - /* enums */ -@@ -62,7 +63,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ - enum { SchemeNorm, SchemeSel }; /* color schemes */ - enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, -- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -+ NetWMWindowTypeDialog, NetClientList, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ - enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ -@@ -197,11 +198,15 @@ static void scan(void); - static int sendevent(Client *c, Atom proto); - static void sendmon(Client *c, Monitor *m); - static void setclientstate(Client *c, long state); -+static void setcurrentdesktop(void); -+static void setdesktopnames(void); - static void setfocus(Client *c); - static void setfullscreen(Client *c, int fullscreen); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); -+static void setnumdesktops(void); - static void setup(void); -+static void setviewport(void); - static void seturgent(Client *c, int urg); - static void showhide(Client *c); - static void sigchld(int unused); -@@ -216,6 +221,7 @@ static void toggleview(const Arg *arg); - static void unfocus(Client *c, int setfocus); - static void unmanage(Client *c, int destroyed); - static void unmapnotify(XEvent *e); -+static void updatecurrentdesktop(void); - static void updatebarpos(Monitor *m); - static void updatebars(void); - static void updateclientlist(void); -@@ -1431,6 +1437,16 @@ setclientstate(Client *c, long state) - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, - PropModeReplace, (unsigned char *)data, 2); - } -+void -+setcurrentdesktop(void){ -+ long data[] = { 0 }; -+ XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); -+} -+void setdesktopnames(void){ -+ XTextProperty text; -+ Xutf8TextListToTextProperty(dpy, tags, TAGSLENGTH, XUTF8StringStyle, &text); -+ XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]); -+} - - int - sendevent(Client *c, Atom proto) -@@ -1457,6 +1473,12 @@ sendevent(Client *c, Atom proto) - return exists; - } - -+void -+setnumdesktops(void){ -+ long data[] = { TAGSLENGTH }; -+ XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); -+} -+ - void - setfocus(Client *c) - { -@@ -1562,6 +1584,10 @@ setup(void) - netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); - netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); - netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); -+ netatom[NetDesktopViewport] = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False); -+ netatom[NetNumberOfDesktops] = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False); -+ netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False); -+ netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False); - /* init cursors */ - cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); - cursor[CurResize] = drw_cur_create(drw, XC_sizing); -@@ -1584,6 +1610,10 @@ setup(void) - /* EWMH support per view */ - XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, - PropModeReplace, (unsigned char *) netatom, NetLast); -+ setnumdesktops(); -+ setcurrentdesktop(); -+ setdesktopnames(); -+ setviewport(); - XDeleteProperty(dpy, root, netatom[NetClientList]); - /* select events */ - wa.cursor = cursor[CurNormal]->cursor; -@@ -1595,6 +1625,11 @@ setup(void) - grabkeys(); - focus(NULL); - } -+void -+setviewport(void){ -+ long data[] = { 0, 0 }; -+ XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2); -+} - - - void -@@ -1732,6 +1767,7 @@ toggletag(const Arg *arg) - focus(NULL); - arrange(selmon); - } -+ updatecurrentdesktop(); - } - - void -@@ -1744,6 +1780,7 @@ toggleview(const Arg *arg) - focus(NULL); - arrange(selmon); - } -+ updatecurrentdesktop(); - } - - void -@@ -1846,6 +1883,15 @@ updateclientlist() - XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); - } -+void updatecurrentdesktop(void){ -+ long rawdata[] = { selmon->tagset[selmon->seltags] }; -+ int i=0; -+ while(*rawdata >> i+1){ -+ i++; -+ } -+ long data[] = { i }; -+ XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); -+} - - int - updategeom(void) -@@ -2042,6 +2088,7 @@ view(const Arg *arg) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); -+ updatecurrentdesktop(); - } - - Client * --- -2.21.0 - diff --git a/dwm/config.def.h b/dwm/config.def.h index f619216..6bea0cd 100644 --- a/dwm/config.def.h +++ b/dwm/config.def.h @@ -1,30 +1,35 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -static const int startwithgaps = 0; /* 1 means gaps are used by default */ -static const unsigned int gappx = 10; -static unsigned int borderpx = 2; /* border pixel of windows */ -static unsigned int snap = 32; /* snap pixel */ -static int showbar = 1; /* 0 means no bar */ -static int topbar = 1; /* 0 means bottom bar */ -static const int usealtbar = 1; /* 1 means use non-dwm status bar */ -static const char *altbarclass = "Polybar"; /* Alternate bar class name */ -static const char *altbarcmd = "$HOME/.scripts/polybar"; /* Alternate bar launch command */ -static char font[] = "castella:size=12"; -static const char *fonts[] = {font}; -static char dmenufont[] = "castella:size=12"; -static char normbgcolor[] = "#222222"; -static char normbordercolor[] = "#444444"; -static char normfgcolor[] = "#bbbbbb"; -static char selfgcolor[] = "#eeeeee"; -static char selbordercolor[] = "#005577"; -static char selbgcolor[] = "#005577"; +static unsigned int borderpx = 1; /* border pixel of windows */ +static unsigned int snap = 32; /* snap pixel */ +static int showbar = 1; /* 0 means no bar */ +static int topbar = 1; /* 0 means bottom bar */ +static const int startwithgaps = 0; /* 1 means gaps are used by default */ +static const unsigned int gappx = 10; /* default gap between windows in pixels */ +static const int user_bh = 0; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */ +static const char *fonts[] = { "monospace:size=10" }; +static const char dmenufont[] = "monospace:size=10"; +static char normbgcolor[] = "#222222"; +static char normbordercolor[] = "#444444"; +static char normfgcolor[] = "#bbbbbb"; +static char selfgcolor[] = "#eeeeee"; +static char selbordercolor[] = "#005577"; +static char selbgcolor[] = "#005577"; static char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = {normfgcolor, normbgcolor, normbordercolor}, - [SchemeSel] = {selfgcolor, selbgcolor, selbordercolor}, + /* fg bg border */ + [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, + [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor }, + [SchemeHid] = { col_cyan, col_gray1, col_cyan }, }; -static char *tags[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}; + +/* tagging */ +static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +static const unsigned int ulinepad = 5; /* horizontal padding between the underline and tag */ +static const unsigned int ulinestroke = 2; /* thickness / height of the underline */ +static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */ +static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ static const Rule rules[] = { /* xprop(1): @@ -32,117 +37,116 @@ static const Rule rules[] = { * WM_NAME(STRING) = title */ /* class instance title tags mask isfloating monitor */ - {"Gimp", NULL, NULL, 0, 1, -1}, - {"Firefox", NULL, NULL, 1 << 8, 0, -1}, + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, }; /* layout(s) */ -static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static int nmaster = 1; /* number of clients in master area */ -static int resizehints = 0; /* 1 means respect size hints in tiled resizals */ - -#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ +static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static int nmaster = 1; /* number of clients in master area */ +static int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const Layout layouts[] = { /* symbol arrange function */ - {"[]=", tile}, /* first entry is default */ - {"[M]", monocle}, - {"><>", NULL}, /* no layout function means floating behavior */ - {NULL, NULL}, + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, }; /* key definitions */ #define MODKEY Mod1Mask -#define TAGKEYS(KEY, TAG) \ - {MODKEY, KEY, view, {.ui = 1 << TAG}}, \ - {MODKEY | ControlMask, KEY, toggleview, {.ui = 1 << TAG}}, \ - {MODKEY | ShiftMask, KEY, tag, {.ui = 1 << TAG}}, \ - {MODKEY | ControlMask | ShiftMask, KEY, toggletag, {.ui = 1 << TAG}}, +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, 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 char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = {"dmenu_run", "-p", "run", "-m", dmenumon, NULL}; -static const char *termcmd[] = {"st", NULL}; +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL }; +static const char *termcmd[] = { "st", NULL }; /* * Xresources preferences to load at startup */ ResourcePref resources[] = { - {"font", STRING, &font}, - {"dmenufont", STRING, &dmenufont}, - {"normbgcolor", STRING, &normbgcolor}, - {"normbordercolor", STRING, &normbordercolor}, - {"normfgcolor", STRING, &normfgcolor}, - {"selbgcolor", STRING, &selbgcolor}, - {"selbordercolor", STRING, &selbordercolor}, - {"selfgcolor", STRING, &selfgcolor}, - {"borderpx", INTEGER, &borderpx}, - {"snap", INTEGER, &snap}, - {"showbar", INTEGER, &showbar}, - {"topbar", INTEGER, &topbar}, - {"nmaster", INTEGER, &nmaster}, - {"resizehints", INTEGER, &resizehints}, - {"mfact", FLOAT, &mfact}, + { "normbgcolor", STRING, &normbgcolor }, + { "normbordercolor", STRING, &normbordercolor }, + { "normfgcolor", STRING, &normfgcolor }, + { "selbgcolor", STRING, &selbgcolor }, + { "selbordercolor", STRING, &selbordercolor }, + { "selfgcolor", STRING, &selfgcolor }, + { "borderpx", INTEGER, &borderpx }, + { "snap", INTEGER, &snap }, + { "showbar", INTEGER, &showbar }, + { "topbar", INTEGER, &topbar }, + { "nmaster", INTEGER, &nmaster }, + { "resizehints", INTEGER, &resizehints }, + { "mfact", FLOAT, &mfact }, }; -static const char *screenshotscript[] = {"/bin/sh", "-c", "~/.scripts/dwmscreenshot", NULL}; -static const char *calcscript[] = {"/bin/sh", "-c", "~/.scripts/dmenucalc", NULL}; - static Key keys[] = { /* modifier key function argument */ - {MODKEY | ShiftMask, XK_o, spawn, {.v = calcscript}}, - {MODKEY | ShiftMask, XK_p, spawn, {.v = screenshotscript}}, - {MODKEY, XK_p, spawn, {.v = dmenucmd}}, - {MODKEY | ShiftMask, XK_Return, spawn, {.v = termcmd}}, - {MODKEY, XK_b, togglebar, {0}}, - {MODKEY, XK_j, focusstack, {.i = +1}}, - {MODKEY, XK_k, focusstack, {.i = -1}}, - {MODKEY, XK_i, incnmaster, {.i = +1}}, - {MODKEY, XK_d, incnmaster, {.i = -1}}, - {MODKEY, XK_h, setmfact, {.f = -0.05}}, - {MODKEY, XK_l, setmfact, {.f = +0.05}}, - {MODKEY, XK_Return, zoom, {0}}, - {MODKEY, XK_Tab, view, {0}}, - {MODKEY, XK_c, killclient, {0}}, - {MODKEY, XK_t, setlayout, {.v = &layouts[0]}}, - {MODKEY, XK_f, setlayout, {.v = &layouts[1]}}, - {MODKEY, XK_m, setlayout, {.v = &layouts[2]}}, - {MODKEY, XK_space, setlayout, {0}}, - {MODKEY | ShiftMask, XK_space, togglefloating, {0}}, - {MODKEY, XK_0, view, {.ui = ~0}}, - {MODKEY | ShiftMask, XK_0, tag, {.ui = ~0}}, - {MODKEY, XK_comma, focusmon, {.i = -1}}, - {MODKEY, XK_period, focusmon, {.i = +1}}, - {MODKEY | ShiftMask, XK_comma, tagmon, {.i = -1}}, - {MODKEY | ShiftMask, XK_period, tagmon, {.i = +1}}, - {MODKEY, XK_minus, setgaps, {.i = -5}}, - {MODKEY, XK_equal, setgaps, {.i = +5}}, - {MODKEY | ShiftMask, XK_minus, setgaps, {.i = GAP_RESET}}, - {MODKEY | ShiftMask, XK_equal, setgaps, {.i = GAP_TOGGLE}}, - TAGKEYS(XK_1, 0) - TAGKEYS(XK_2, 1) - TAGKEYS(XK_3, 2) - TAGKEYS(XK_4, 3) - TAGKEYS(XK_5, 4) - TAGKEYS(XK_6, 5) - TAGKEYS(XK_7, 6) - TAGKEYS(XK_8, 7) - TAGKEYS(XK_9, 8){MODKEY | ShiftMask, XK_q, quit, {0}}, + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstackvis, {.i = +1 } }, + { MODKEY, XK_k, focusstackvis, {.i = -1 } }, + { MODKEY|ShiftMask, XK_j, focusstackhid, {.i = +1 } }, + { MODKEY|ShiftMask, XK_k, focusstackhid, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_minus, setgaps, {.i = -5 } }, + { MODKEY, XK_equal, setgaps, {.i = +5 } }, + { MODKEY|ShiftMask, XK_minus, setgaps, {.i = GAP_RESET } }, + { MODKEY|ShiftMask, XK_equal, setgaps, {.i = GAP_TOGGLE} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + { MODKEY, XK_s, show, {0} }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, }; /* button definitions */ /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static Button buttons[] = { /* click event mask button function argument */ - {ClkLtSymbol, 0, Button1, setlayout, {0}}, - {ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]}}, - {ClkWinTitle, 0, Button2, zoom, {0}}, - {ClkStatusText, 0, Button2, spawn, {.v = termcmd}}, - {ClkClientWin, MODKEY, Button1, movemouse, {0}}, - {ClkClientWin, MODKEY, Button2, togglefloating, {0}}, - {ClkClientWin, MODKEY, Button3, resizemouse, {0}}, - {ClkTagBar, 0, Button1, view, {0}}, - {ClkTagBar, 0, Button3, toggleview, {0}}, - {ClkTagBar, MODKEY, Button1, tag, {0}}, - {ClkTagBar, MODKEY, Button3, toggletag, {0}}, + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button1, togglewin, {0} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, }; + diff --git a/dwm/config.h b/dwm/config.h new file mode 100644 index 0000000..3f2ae59 --- /dev/null +++ b/dwm/config.h @@ -0,0 +1,156 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +static unsigned int borderpx = 1; /* border pixel of windows */ +static unsigned int snap = 32; /* snap pixel */ +static int showbar = 1; /* 0 means no bar */ +static int topbar = 1; /* 0 means bottom bar */ +static const int startwithgaps = 0; /* 1 means gaps are used by default */ +static const unsigned int gappx = 10; /* default gap between windows in pixels */ +static const int user_bh = 28; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */ +static const char *fonts[] = { "JetBrainsMono Nerd Font:size=10:antialias=true:autohint=true" }; +static const char dmenufont[] = "JetBrainsMono Nerd Font:size=10:antialias=true:autohint=true"; +static char normbgcolor[] = "#222222"; +static char normbordercolor[] = "#444444"; +static char normfgcolor[] = "#bbbbbb"; +static char selfgcolor[] = "#eeeeee"; +static char selbordercolor[] = "#005577"; +static char selbgcolor[] = "#005577"; +static char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, + [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor }, + [SchemeHid] = { normfgcolor, normbgcolor, normbordercolor }, +}; + +/* tagging */ +static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +static const unsigned int ulinepad = 5; /* horizontal padding between the underline and tag */ +static const unsigned int ulinestroke = 2; /* thickness / height of the underline */ +static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */ +static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ + +static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, +}; + +/* layout(s) */ +static float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static int nmaster = 1; /* number of clients in master area */ +static int resizehints = 0; /* 1 means respect size hints in tiled resizals */ + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, +}; + +/* key definitions */ +#define MODKEY Mod1Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, 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 char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *dmenucmd[] = { "dmenu_run", NULL }; +static const char *termcmd[] = { "st", NULL }; +static const char *screenshotscript[] = {"/bin/sh", "-c", "~/.scripts/dwmscreenshot", NULL}; +static const char *calcscript[] = {"/bin/sh", "-c", "~/.scripts/dmenucalc", NULL}; + +/* + * Xresources preferences to load at startup + */ +ResourcePref resources[] = { + { "normbgcolor", STRING, &normbgcolor }, + { "normbordercolor", STRING, &normbordercolor }, + { "normfgcolor", STRING, &normfgcolor }, + { "selbgcolor", STRING, &selbgcolor }, + { "selbordercolor", STRING, &selbordercolor }, + { "selfgcolor", STRING, &selfgcolor }, + { "borderpx", INTEGER, &borderpx }, + { "snap", INTEGER, &snap }, + { "showbar", INTEGER, &showbar }, + { "topbar", INTEGER, &topbar }, + { "nmaster", INTEGER, &nmaster }, + { "resizehints", INTEGER, &resizehints }, + { "mfact", FLOAT, &mfact }, +}; + +static Key keys[] = { + /* modifier key function argument */ + { MODKEY|ShiftMask, XK_o, spawn, {.v = calcscript} }, + { MODKEY|ShiftMask, XK_p, spawn, {.v = screenshotscript} }, + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstackvis, {.i = +1 } }, + { MODKEY, XK_k, focusstackvis, {.i = -1 } }, + { MODKEY|ShiftMask, XK_j, focusstackhid, {.i = +1 } }, + { MODKEY|ShiftMask, XK_k, focusstackhid, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY, XK_c, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_minus, setgaps, {.i = -5 } }, + { MODKEY, XK_equal, setgaps, {.i = +5 } }, + { MODKEY|ShiftMask, XK_minus, setgaps, {.i = GAP_RESET } }, + { MODKEY|ShiftMask, XK_equal, setgaps, {.i = GAP_TOGGLE} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + { MODKEY, XK_s, show, {0} }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, +}; + +/* button definitions */ +/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static Button buttons[] = { + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button1, togglewin, {0} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, +}; + diff --git a/dwm/config.mk b/dwm/config.mk index 7084c33..6d36cb7 100644 --- a/dwm/config.mk +++ b/dwm/config.mk @@ -25,7 +25,7 @@ INCS = -I${X11INC} -I${FREETYPEINC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} LDFLAGS = ${LIBS} diff --git a/dwm/drw.c b/dwm/drw.c index 8f1059e..e4968a0 100644 --- a/dwm/drw.c +++ b/dwm/drw.c @@ -95,7 +95,6 @@ drw_free(Drw *drw) { XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); - drw_fontset_free(drw->fonts); free(drw); } diff --git a/dwm/dwm.1 b/dwm/dwm.1 index ddc8321..13b3729 100644 --- a/dwm/dwm.1 +++ b/dwm/dwm.1 @@ -33,7 +33,7 @@ dwm draws a small border around windows to indicate the focus state. .SH OPTIONS .TP .B \-v -prints version information to stderr, then exits. +prints version information to standard output, then exits. .SH USAGE .SS Status bar .TP diff --git a/dwm/dwm.c b/dwm/dwm.c index b2ad61c..a61e80c 100644 --- a/dwm/dwm.c +++ b/dwm/dwm.c @@ -48,15 +48,15 @@ /* macros */ #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) -#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - MAX((x),(m)->mx)) \ - * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - MAX((y),(m)->my))) +#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) +#define HIDDEN(C) ((getstate(C->win) == IconicState)) #define LENGTH(X) (sizeof X / sizeof X[0]) #define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define WIDTH(X) ((X)->w + 2 * (X)->bw) #define HEIGHT(X) ((X)->h + 2 * (X)->bw) #define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TAGSLENGTH (LENGTH(tags)) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) #define GAP_TOGGLE 100 @@ -64,10 +64,10 @@ /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel }; /* color schemes */ +enum { SchemeNorm, SchemeSel, SchemeHid }; /* color schemes */ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop, NetLast }; /* EWMH atoms */ + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ @@ -121,7 +121,9 @@ struct Monitor { float mfact; int nmaster; int num; - int by, bh; /* bar geometry */ + int by; /* bar geometry */ + int btw; /* width of tasks portion of bar */ + int bt; /* number of tasks */ int mx, my, mw, mh; /* screen size */ int wx, wy, ww, wh; /* window area */ int gappx; /* gaps between windows */ @@ -131,6 +133,7 @@ struct Monitor { unsigned int tagset[2]; int showbar; int topbar; + int hidsel; Client *clients; Client *sel; Client *stack; @@ -183,23 +186,26 @@ static void detachstack(Client *c); static Monitor *dirtomon(int dir); static void drawbar(Monitor *m); static void drawbars(void); +static int drawstatusbar(Monitor *m, int bh, char* text); static void enternotify(XEvent *e); static void expose(XEvent *e); static void focus(Client *c); static void focusin(XEvent *e); static void focusmon(const Arg *arg); -static void focusstack(const Arg *arg); -static Atom getatomprop(Client *c, Atom prop); +static void focusstackvis(const Arg *arg); +static void focusstackhid(const Arg *arg); +static void focusstack(int inc, int vis); static int getrootptr(int *x, int *y); static long getstate(Window w); static int gettextprop(Window w, Atom atom, char *text, unsigned int size); static void grabbuttons(Client *c, int focused); static void grabkeys(void); +static void hide(const Arg *arg); +static void hidewin(Client *c); static void incnmaster(const Arg *arg); static void keypress(XEvent *e); static void killclient(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); -static void managealtbar(Window win, XWindowAttributes *wa); static void mappingnotify(XEvent *e); static void maprequest(XEvent *e); static void monocle(Monitor *m); @@ -219,21 +225,18 @@ static void scan(void); static int sendevent(Client *c, Atom proto); static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); -static void setcurrentdesktop(void); -static void setdesktopnames(void); static void setfocus(Client *c); static void setfullscreen(Client *c, int fullscreen); static void setgaps(const Arg *arg); static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); -static void setnumdesktops(void); static void setup(void); -static void setviewport(void); static void seturgent(Client *c, int urg); +static void show(const Arg *arg); +static void showwin(Client *c); static void showhide(Client *c); static void sigchld(int unused); static void spawn(const Arg *arg); -static void spawnbar(); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *); @@ -241,11 +244,10 @@ static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); +static void togglewin(const Arg *arg); static void unfocus(Client *c, int setfocus); static void unmanage(Client *c, int destroyed); -static void unmanagealtbar(Window w); static void unmapnotify(XEvent *e); -static void updatecurrentdesktop(void); static void updatebarpos(Monitor *m); static void updatebars(void); static void updateclientlist(void); @@ -259,7 +261,6 @@ static void updatewmhints(Client *c); static void view(const Arg *arg); static Client *wintoclient(Window w); static Monitor *wintomon(Window w); -static int wmclasscontains(Window win, const char *class, const char *name); static int xerror(Display *dpy, XErrorEvent *ee); static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); @@ -269,7 +270,7 @@ static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, /* variables */ static const char broken[] = "broken"; -static char stext[256]; +static char stext[1024]; static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh, blw = 0; /* bar geometry */ @@ -472,10 +473,25 @@ buttonpress(XEvent *e) arg.ui = 1 << i; } else if (ev->x < x + blw) click = ClkLtSymbol; - else if (ev->x > selmon->ww - (int)TEXTW(stext)) + /* 2px right padding */ + else if (ev->x > selmon->ww - TEXTW(stext) + lrpad - 2) click = ClkStatusText; - else - click = ClkWinTitle; + else { + x += blw; + c = m->clients; + + if (c) { + do { + if (!ISVISIBLE(c)) + continue; + else + x += (1.0 / (double)m->bt) * m->btw; + } while (ev->x > x && (c = c->next)); + + click = ClkWinTitle; + arg.v = c; + } + } } else if ((c = wintoclient(ev->window))) { focus(c); restack(selmon); @@ -485,7 +501,7 @@ buttonpress(XEvent *e) for (i = 0; i < LENGTH(buttons); i++) if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); + buttons[i].func((click == ClkTagBar || click == ClkWinTitle) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); } void @@ -517,7 +533,7 @@ cleanup(void) cleanupmon(mons); for (i = 0; i < CurLast; i++) drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) + for (i = 0; i < LENGTH(colors) + 1; i++) free(scheme[i]); XDestroyWindow(dpy, wmcheckwin); drw_free(drw); @@ -537,10 +553,8 @@ cleanupmon(Monitor *mon) for (m = mons; m && m->next != mon; m = m->next); m->next = mon->next; } - if (!usealtbar) { - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - } + XUnmapWindow(dpy, mon->barwin); + XDestroyWindow(dpy, mon->barwin); free(mon); } @@ -602,7 +616,7 @@ configurenotify(XEvent *e) for (c = m->clients; c; c = c->next) if (c->isfullscreen) resizeclient(c, m->mx, m->my, m->mw, m->mh); - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, m->bh); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); } focus(NULL); arrange(NULL); @@ -673,7 +687,6 @@ createmon(void) m->nmaster = nmaster; m->showbar = showbar; m->topbar = topbar; - m->bh = bh; m->gappx = gappx; m->drawwithgaps = startwithgaps; m->lt[0] = &layouts[0]; @@ -686,13 +699,10 @@ void destroynotify(XEvent *e) { Client *c; - Monitor *m; XDestroyWindowEvent *ev = &e->xdestroywindow; if ((c = wintoclient(ev->window))) unmanage(c, 1); - else if ((m = wintomon(ev->window)) && m->barwin == ev->window) - unmanagealtbar(ev->window); } void @@ -733,13 +743,118 @@ dirtomon(int dir) return m; } +int +drawstatusbar(Monitor *m, int bh, char* stext) { + int ret, i, w, x, len; + short isCode = 0; + char *text; + char *p; + + len = strlen(stext) + 1 ; + if (!(text = (char*) malloc(sizeof(char)*len))) + die("malloc"); + p = text; + memcpy(text, stext, len); + + /* compute width of the status text */ + w = 0; + i = -1; + while (text[++i]) { + if (text[i] == '^') { + if (!isCode) { + isCode = 1; + text[i] = '\0'; + w += TEXTW(text) - lrpad; + text[i] = '^'; + if (text[++i] == 'f') + w += atoi(text + ++i); + } else { + isCode = 0; + text = text + i + 1; + i = -1; + } + } + } + if (!isCode) + w += TEXTW(text) - lrpad; + else + isCode = 0; + text = p; + + w += 2; /* 1px padding on both sides */ + ret = x = m->ww - w; + + drw_setscheme(drw, scheme[LENGTH(colors)]); + drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; + drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; + drw_rect(drw, x, 0, w, bh, 1, 1); + x++; + + /* process status text */ + i = -1; + while (text[++i]) { + if (text[i] == '^' && !isCode) { + isCode = 1; + + text[i] = '\0'; + w = TEXTW(text) - lrpad; + drw_text(drw, x, 0, w, bh, 0, text, 0); + + x += w; + + /* process code */ + while (text[++i] != '^') { + if (text[i] == 'c') { + char buf[8]; + memcpy(buf, (char*)text+i+1, 7); + buf[7] = '\0'; + drw_clr_create(drw, &drw->scheme[ColFg], buf); + i += 7; + } else if (text[i] == 'b') { + char buf[8]; + memcpy(buf, (char*)text+i+1, 7); + buf[7] = '\0'; + drw_clr_create(drw, &drw->scheme[ColBg], buf); + i += 7; + } else if (text[i] == 'd') { + drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; + drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; + } else if (text[i] == 'r') { + int rx = atoi(text + ++i); + while (text[++i] != ','); + int ry = atoi(text + ++i); + while (text[++i] != ','); + int rw = atoi(text + ++i); + while (text[++i] != ','); + int rh = atoi(text + ++i); + + drw_rect(drw, rx + x, ry, rw, rh, 1, 0); + } else if (text[i] == 'f') { + x += atoi(text + ++i); + } + } + + text = text + i + 1; + i=-1; + isCode = 0; + } + } + + if (!isCode) { + w = TEXTW(text) - lrpad; + drw_text(drw, x, 0, w, bh, 0, text, 0); + } + + drw_setscheme(drw, scheme[SchemeNorm]); + free(p); + + return ret; +} + void drawbar(Monitor *m) { - if (usealtbar) - return; - - int x, w, tw = 0; + int x, w, sw = 0, n = 0, scm; int boxs = drw->fonts->h / 9; int boxw = drw->fonts->h / 6 + 2; unsigned int i, occ = 0, urg = 0; @@ -747,12 +862,12 @@ drawbar(Monitor *m) /* draw status first so it can be overdrawn by tags later */ if (m == selmon) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); + sw = m->ww - drawstatusbar(m, bh, stext); } for (c = m->clients; c; c = c->next) { + if (ISVISIBLE(c)) + n++; occ |= c->tags; if (c->isurgent) urg |= c->tags; @@ -762,6 +877,8 @@ drawbar(Monitor *m) w = TEXTW(tags[i]); drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); + if (ulineall || m->tagset[m->seltags] & 1 << i) /* if there are conflicts, just move these lines directly underneath both 'drw_setscheme' and 'drw_text' :) */ + drw_rect(drw, x + ulinepad, bh - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0); if (occ & 1 << i) drw_rect(drw, x + boxs, boxs, boxw, boxw, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, @@ -772,17 +889,38 @@ drawbar(Monitor *m) drw_setscheme(drw, scheme[SchemeNorm]); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { - 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); + if ((w = m->ww - sw - x) > bh) { + if (n > 0) { + int remainder = w % n; + int tabw = (1.0 / (double)n) * w + 1; + for (c = m->clients; c; c = c->next) { + if (!ISVISIBLE(c)) + continue; + if (m->sel == c) + scm = SchemeSel; + else if (HIDDEN(c)) + scm = SchemeHid; + else + scm = SchemeNorm; + drw_setscheme(drw, scheme[scm]); + + if (remainder >= 0) { + if (remainder == 0) { + tabw--; + } + remainder--; + } + drw_text(drw, x, 0, tabw, bh, lrpad / 2, c->name, 0); + x += tabw; + } } else { drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, x, 0, w, bh, 1, 1); } } + + m->bt = n; + m->btw = w; drw_map(drw, m->barwin, 0, 0, m->ww, bh); } @@ -828,9 +966,17 @@ void focus(Client *c) { if (!c || !ISVISIBLE(c)) - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); - if (selmon->sel && selmon->sel != c) + for (c = selmon->stack; c && (!ISVISIBLE(c) || HIDDEN(c)); c = c->snext); + if (selmon->sel && selmon->sel != c) { unfocus(selmon->sel, 0); + + if (selmon->hidsel) { + hidewin(selmon->sel); + if (c) + arrange(c->mon); + selmon->hidsel = 0; + } + } if (c) { if (c->mon != selmon) selmon = c->mon; @@ -880,28 +1026,57 @@ focusmon(const Arg *arg) } void -focusstack(const Arg *arg) +focusstackvis(const Arg *arg) +{ + focusstack(arg->i, 0); +} + +void +focusstackhid(const Arg *arg) +{ + focusstack(arg->i, 1); +} + +void +focusstack(int inc, int hid) { Client *c = NULL, *i; - if (!selmon->sel || selmon->sel->isfullscreen) + if (!selmon->sel && !hid) return; - if (arg->i > 0) { - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); + if (!selmon->clients) + return; + + if (inc > 0) { + if (selmon->sel) + for (c = selmon->sel->next; + c && (!ISVISIBLE(c) || (!hid && HIDDEN(c))); + c = c->next); if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); + for (c = selmon->clients; + c && (!ISVISIBLE(c) || (!hid && HIDDEN(c))); + c = c->next); } else { - for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) - c = i; + if (selmon->sel) { + for (i = selmon->clients; i != selmon->sel; i = i->next) + if (ISVISIBLE(i) && !(!hid && HIDDEN(i))) + c = i; + } else + c = selmon->clients; if (!c) for (; i; i = i->next) - if (ISVISIBLE(i)) + if (ISVISIBLE(i) && !(!hid && HIDDEN(i))) c = i; } + if (c) { focus(c); restack(selmon); + + if (HIDDEN(c)) { + showwin(c); + c->mon->hidsel = 1; + } } } @@ -1013,6 +1188,36 @@ grabkeys(void) } } +void +hide(const Arg *arg) +{ + hidewin(selmon->sel); + focus(NULL); + arrange(selmon); +} + +void +hidewin(Client *c) { + if (!c || HIDDEN(c)) + return; + + Window w = c->win; + static XWindowAttributes ra, ca; + + // more or less taken directly from blackbox's hide() function + XGrabServer(dpy); + XGetWindowAttributes(dpy, root, &ra); + XGetWindowAttributes(dpy, w, &ca); + // prevent UnmapNotify events + XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask); + XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask); + XUnmapWindow(dpy, w); + setclientstate(c, IconicState); + XSelectInput(dpy, root, ra.your_event_mask); + XSelectInput(dpy, w, ca.your_event_mask); + XUngrabServer(dpy); +} + void incnmaster(const Arg *arg) { @@ -1119,34 +1324,17 @@ manage(Window w, XWindowAttributes *wa) XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, (unsigned char *) &(c->win), 1); XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - setclientstate(c, NormalState); + if (!HIDDEN(c)) + setclientstate(c, NormalState); if (c->mon == selmon) unfocus(selmon->sel, 0); c->mon->sel = c; arrange(c->mon); - XMapWindow(dpy, c->win); + if (!HIDDEN(c)) + XMapWindow(dpy, c->win); focus(NULL); } -void -managealtbar(Window win, XWindowAttributes *wa) -{ - Monitor *m; - if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height))) - return; - - m->barwin = win; - m->by = wa->y; - bh = m->bh = wa->height; - updatebarpos(m); - arrange(m); - XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height); - XMapWindow(dpy, win); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &win, 1); -} - void mappingnotify(XEvent *e) { @@ -1167,9 +1355,7 @@ maprequest(XEvent *e) return; if (wa.override_redirect) return; - if (wmclasscontains(ev->window, altbarclass, "")) - managealtbar(ev->window, &wa); - else if (!wintoclient(ev->window)) + if (!wintoclient(ev->window)) manage(ev->window, &wa); } @@ -1271,7 +1457,7 @@ movemouse(const Arg *arg) Client * nexttiled(Client *c) { - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); + for (; c && (c->isfloating || !ISVISIBLE(c) || HIDDEN(c)); c = c->next); return c; } @@ -1324,6 +1510,16 @@ propertynotify(XEvent *e) void quit(const Arg *arg) { + // fix: reloading dwm keeps all the hidden clients hidden + Monitor *m; + Client *c; + for (m = mons; m; m = m->next) { + if (m) { + for (c = m->stack; c; c = c->next) + if (c && HIDDEN(c)) showwin(c); + } + } + running = 0; } @@ -1477,9 +1673,7 @@ scan(void) if (!XGetWindowAttributes(dpy, wins[i], &wa) || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) continue; - if (wmclasscontains(wins[i], altbarclass, "")) - managealtbar(wins[i], &wa); - else if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) manage(wins[i], &wa); } for (i = 0; i < num; i++) { /* now the transients */ @@ -1518,16 +1712,6 @@ setclientstate(Client *c, long state) XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, PropModeReplace, (unsigned char *)data, 2); } -void -setcurrentdesktop(void){ - long data[] = { 0 }; - XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); -} -void setdesktopnames(void){ - XTextProperty text; - Xutf8TextListToTextProperty(dpy, tags, TAGSLENGTH, XUTF8StringStyle, &text); - XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]); -} int sendevent(Client *c, Atom proto) @@ -1554,12 +1738,6 @@ sendevent(Client *c, Atom proto) return exists; } -void -setnumdesktops(void){ - long data[] = { TAGSLENGTH }; - XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); -} - void setfocus(Client *c) { @@ -1643,7 +1821,7 @@ setmfact(const Arg *arg) if (!arg || !selmon->lt[selmon->sellt]->arrange) return; f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if (f < 0.05 || f > 0.95) + if (f < 0.1 || f > 0.9) return; selmon->mfact = f; arrange(selmon); @@ -1668,7 +1846,7 @@ setup(void) if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); lrpad = drw->fonts->h; - bh = usealtbar ? 0 : drw->fonts->h + 2; + bh = user_bh ? user_bh : drw->fonts->h + 2; updategeom(); /* init atoms */ utf8string = XInternAtom(dpy, "UTF8_STRING", False); @@ -1685,16 +1863,13 @@ setup(void) netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); - netatom[NetDesktopViewport] = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False); - netatom[NetNumberOfDesktops] = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False); - netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False); - netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False); /* init cursors */ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurResize] = drw_cur_create(drw, XC_sizing); cursor[CurMove] = drw_cur_create(drw, XC_fleur); /* init appearance */ - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); + scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); + scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); for (i = 0; i < LENGTH(colors); i++) scheme[i] = drw_scm_create(drw, colors[i], 3); /* init bars */ @@ -1711,10 +1886,6 @@ setup(void) /* EWMH support per view */ XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, PropModeReplace, (unsigned char *) netatom, NetLast); - setnumdesktops(); - setcurrentdesktop(); - setdesktopnames(); - setviewport(); XDeleteProperty(dpy, root, netatom[NetClientList]); /* select events */ wa.cursor = cursor[CurNormal]->cursor; @@ -1725,12 +1896,6 @@ setup(void) XSelectInput(dpy, root, wa.event_mask); grabkeys(); focus(NULL); - spawnbar(); -} -void -setviewport(void){ - long data[] = { 0, 0 }; - XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2); } @@ -1747,6 +1912,25 @@ seturgent(Client *c, int urg) XFree(wmh); } +void +show(const Arg *arg) +{ + if (selmon->hidsel) + selmon->hidsel = 0; + showwin(selmon->sel); +} + +void +showwin(Client *c) +{ + if (!c || !HIDDEN(c)) + return; + + XMapWindow(dpy, c->win); + setclientstate(c, NormalState); + arrange(c->mon); +} + void showhide(Client *c) { @@ -1789,13 +1973,6 @@ spawn(const Arg *arg) } } -void -spawnbar() -{ - if (*altbarcmd) - system(altbarcmd); -} - void tag(const Arg *arg) { @@ -1823,42 +2000,43 @@ tile(Monitor *m) for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); if (n == 0) return; - if (m->drawwithgaps) { /* draw with fullgaps logic */ - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww - m->gappx; - for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; - resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); - if (my + HEIGHT(c) + m->gappx < m->wh) - my += HEIGHT(c) + m->gappx; - } else { - h = (m->wh - ty) / (n - i) - m->gappx; - resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); - if (ty + HEIGHT(c) + m->gappx < m->wh) - ty += HEIGHT(c) + m->gappx; - } - } else { /* draw with singularborders logic */ - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - if (n == 1) - resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False); - else - resize(c, m->wx - c->bw, m->wy + my, mw - c->bw, h - c->bw, False); - my += HEIGHT(c) - c->bw; - } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw - c->bw, m->wy + ty, m->ww - mw, h - c->bw, False); - ty += HEIGHT(c) - c->bw; - } - } + + if (m->drawwithgaps) { /* draw with fullgaps logic */ + if (n > m->nmaster) + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww - m->gappx; + for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; + resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); + if (my + HEIGHT(c) + m->gappx < m->wh) + my += HEIGHT(c) + m->gappx; + } else { + h = (m->wh - ty) / (n - i) - m->gappx; + resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); + if (ty + HEIGHT(c) + m->gappx < m->wh) + ty += HEIGHT(c) + m->gappx; + } + } else { /* draw with singularborders logic */ + if (n > m->nmaster) + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww; + for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i); + if (n == 1) + resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False); + else + resize(c, m->wx - c->bw, m->wy + my, mw - c->bw, h - c->bw, False); + my += HEIGHT(c) - c->bw; + } else { + h = (m->wh - ty) / (n - i); + resize(c, m->wx + mw - c->bw, m->wy + ty, m->ww - mw, h - c->bw, False); + ty += HEIGHT(c) - c->bw; + } + } } void @@ -1866,7 +2044,7 @@ togglebar(const Arg *arg) { selmon->showbar = !selmon->showbar; updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, selmon->bh); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); arrange(selmon); } @@ -1897,7 +2075,6 @@ toggletag(const Arg *arg) focus(NULL); arrange(selmon); } - updatecurrentdesktop(); } void @@ -1910,7 +2087,23 @@ toggleview(const Arg *arg) focus(NULL); arrange(selmon); } - updatecurrentdesktop(); +} + +void +togglewin(const Arg *arg) +{ + Client *c = (Client*)arg->v; + + if (c == selmon->sel) { + hidewin(c); + focus(NULL); + arrange(c->mon); + } else { + if (HIDDEN(c)) + showwin(c); + focus(c); + restack(selmon); + } } void @@ -1951,26 +2144,10 @@ unmanage(Client *c, int destroyed) arrange(m); } -void -unmanagealtbar(Window w) -{ - Monitor *m = wintomon(w); - - if (!m) - return; - - m->barwin = 0; - m->by = 0; - m->bh = 0; - updatebarpos(m); - arrange(m); -} - void unmapnotify(XEvent *e) { Client *c; - Monitor *m; XUnmapEvent *ev = &e->xunmap; if ((c = wintoclient(ev->window))) { @@ -1978,16 +2155,12 @@ unmapnotify(XEvent *e) setclientstate(c, WithdrawnState); else unmanage(c, 0); - } else if ((m = wintomon(ev->window)) && m->barwin == ev->window) - unmanagealtbar(ev->window); + } } void updatebars(void) { - if (usealtbar) - return; - Monitor *m; XSetWindowAttributes wa = { .override_redirect = True, @@ -2013,11 +2186,11 @@ updatebarpos(Monitor *m) m->wy = m->my; m->wh = m->mh; if (m->showbar) { - m->wh -= m->bh; + m->wh -= bh; m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + m->bh : m->wy; + m->wy = m->topbar ? m->wy + bh : m->wy; } else - m->by = -m->bh; + m->by = -bh; } void @@ -2033,15 +2206,6 @@ updateclientlist() XA_WINDOW, 32, PropModeAppend, (unsigned char *) &(c->win), 1); } -void updatecurrentdesktop(void){ - long rawdata[] = { selmon->tagset[selmon->seltags] }; - int i=0; - while(*rawdata >> (i+1)){ - i++; - } - long data[] = { i }; - XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); -} int updategeom(void) @@ -2238,7 +2402,6 @@ view(const Arg *arg) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; focus(NULL); arrange(selmon); - updatecurrentdesktop(); } Client * @@ -2271,28 +2434,6 @@ wintomon(Window w) return selmon; } -int -wmclasscontains(Window win, const char *class, const char *name) -{ - XClassHint ch = { NULL, NULL }; - int res = 1; - - if (XGetClassHint(dpy, win, &ch)) { - if (ch.res_name && strstr(ch.res_name, name) == NULL) - res = 0; - if (ch.res_class && strstr(ch.res_class, class) == NULL) - res = 0; - } else - res = 0; - - if (ch.res_class) - XFree(ch.res_class); - if (ch.res_name) - XFree(ch.res_name); - - return res; -} - /* There's no way to check accesses to destroyed windows, thus those cases are * ignored (especially on UnmapNotify's). Other types of errors call Xlibs * default error handler, which may call exit. */ diff --git a/dwm/applied_patches/dwm-alwayscenter-20200625-f04cac6.diff b/dwm/patches/dwm-alwayscenter-20200625-f04cac6.diff similarity index 100% rename from dwm/applied_patches/dwm-alwayscenter-20200625-f04cac6.diff rename to dwm/patches/dwm-alwayscenter-20200625-f04cac6.diff diff --git a/dwm/patches/dwm-awesomebar-20200907-6.2.diff b/dwm/patches/dwm-awesomebar-20200907-6.2.diff new file mode 100644 index 0000000..1cb92a9 --- /dev/null +++ b/dwm/patches/dwm-awesomebar-20200907-6.2.diff @@ -0,0 +1,431 @@ +diff --git a/config.def.h b/config.def.h +index 1c0b587..bb8f3f7 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -16,6 +16,7 @@ static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, ++ [SchemeHid] = { col_cyan, col_gray1, col_cyan }, + }; + + /* tagging */ +@@ -64,8 +65,10 @@ static Key keys[] = { + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, +- { MODKEY, XK_j, focusstack, {.i = +1 } }, +- { MODKEY, XK_k, focusstack, {.i = -1 } }, ++ { MODKEY, XK_j, focusstackvis, {.i = +1 } }, ++ { MODKEY, XK_k, focusstackvis, {.i = -1 } }, ++ { MODKEY|ShiftMask, XK_j, focusstackhid, {.i = +1 } }, ++ { MODKEY|ShiftMask, XK_k, focusstackhid, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, +@@ -84,6 +87,8 @@ static Key keys[] = { + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, ++ { MODKEY, XK_s, show, {0} }, ++ { MODKEY, XK_h, hide, {0} }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) +@@ -102,6 +107,7 @@ static Button buttons[] = { + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, ++ { ClkWinTitle, 0, Button1, togglewin, {0} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, +diff --git a/dwm.c b/dwm.c +index 4465af1..e780189 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -50,6 +50,7 @@ + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) + #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) ++#define HIDDEN(C) ((getstate(C->win) == IconicState)) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) + #define WIDTH(X) ((X)->w + 2 * (X)->bw) +@@ -59,7 +60,7 @@ + + /* enums */ + enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +-enum { SchemeNorm, SchemeSel }; /* color schemes */ ++enum { SchemeNorm, SchemeSel, SchemeHid }; /* color schemes */ + enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ +@@ -117,6 +118,8 @@ struct Monitor { + int nmaster; + int num; + int by; /* bar geometry */ ++ int btw; /* width of tasks portion of bar */ ++ int bt; /* number of tasks */ + int mx, my, mw, mh; /* screen size */ + int wx, wy, ww, wh; /* window area */ + unsigned int seltags; +@@ -124,6 +127,7 @@ struct Monitor { + unsigned int tagset[2]; + int showbar; + int topbar; ++ int hidsel; + Client *clients; + Client *sel; + Client *stack; +@@ -168,12 +172,16 @@ static void expose(XEvent *e); + static void focus(Client *c); + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); +-static void focusstack(const Arg *arg); ++static void focusstackvis(const Arg *arg); ++static void focusstackhid(const Arg *arg); ++static void focusstack(int inc, int vis); + static int getrootptr(int *x, int *y); + static long getstate(Window w); + static int gettextprop(Window w, Atom atom, char *text, unsigned int size); + static void grabbuttons(Client *c, int focused); + static void grabkeys(void); ++static void hide(const Arg *arg); ++static void hidewin(Client *c); + static void incnmaster(const Arg *arg); + static void keypress(XEvent *e); + static void killclient(const Arg *arg); +@@ -203,6 +211,8 @@ static void setlayout(const Arg *arg); + static void setmfact(const Arg *arg); + static void setup(void); + static void seturgent(Client *c, int urg); ++static void show(const Arg *arg); ++static void showwin(Client *c); + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); +@@ -213,6 +223,7 @@ static void togglebar(const Arg *arg); + static void togglefloating(const Arg *arg); + static void toggletag(const Arg *arg); + static void toggleview(const Arg *arg); ++static void togglewin(const Arg *arg); + static void unfocus(Client *c, int setfocus); + static void unmanage(Client *c, int destroyed); + static void unmapnotify(XEvent *e); +@@ -439,10 +450,25 @@ buttonpress(XEvent *e) + arg.ui = 1 << i; + } else if (ev->x < x + blw) + click = ClkLtSymbol; +- else if (ev->x > selmon->ww - TEXTW(stext)) ++ /* 2px right padding */ ++ else if (ev->x > selmon->ww - TEXTW(stext) + lrpad - 2) + click = ClkStatusText; +- else +- click = ClkWinTitle; ++ else { ++ x += blw; ++ c = m->clients; ++ ++ if (c) { ++ do { ++ if (!ISVISIBLE(c)) ++ continue; ++ else ++ x += (1.0 / (double)m->bt) * m->btw; ++ } while (ev->x > x && (c = c->next)); ++ ++ click = ClkWinTitle; ++ arg.v = c; ++ } ++ } + } else if ((c = wintoclient(ev->window))) { + focus(c); + restack(selmon); +@@ -452,7 +478,7 @@ buttonpress(XEvent *e) + for (i = 0; i < LENGTH(buttons); i++) + if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) +- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); ++ buttons[i].func((click == ClkTagBar || click == ClkWinTitle) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); + } + + void +@@ -695,7 +721,7 @@ dirtomon(int dir) + void + drawbar(Monitor *m) + { +- int x, w, sw = 0; ++ int x, w, sw = 0, n = 0, scm; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; +@@ -709,6 +735,8 @@ drawbar(Monitor *m) + } + + for (c = m->clients; c; c = c->next) { ++ if (ISVISIBLE(c)) ++ n++; + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; +@@ -729,16 +757,37 @@ drawbar(Monitor *m) + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + + if ((w = m->ww - sw - x) > bh) { +- if (m->sel) { +- 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); ++ if (n > 0) { ++ int remainder = w % n; ++ int tabw = (1.0 / (double)n) * w + 1; ++ for (c = m->clients; c; c = c->next) { ++ if (!ISVISIBLE(c)) ++ continue; ++ if (m->sel == c) ++ scm = SchemeSel; ++ else if (HIDDEN(c)) ++ scm = SchemeHid; ++ else ++ scm = SchemeNorm; ++ drw_setscheme(drw, scheme[scm]); ++ ++ if (remainder >= 0) { ++ if (remainder == 0) { ++ tabw--; ++ } ++ remainder--; ++ } ++ drw_text(drw, x, 0, tabw, bh, lrpad / 2, c->name, 0); ++ x += tabw; ++ } + } else { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, x, 0, w, bh, 1, 1); + } + } ++ ++ m->bt = n; ++ m->btw = w; + drw_map(drw, m->barwin, 0, 0, m->ww, bh); + } + +@@ -784,9 +833,17 @@ void + focus(Client *c) + { + if (!c || !ISVISIBLE(c)) +- for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); +- if (selmon->sel && selmon->sel != c) ++ for (c = selmon->stack; c && (!ISVISIBLE(c) || HIDDEN(c)); c = c->snext); ++ if (selmon->sel && selmon->sel != c) { + unfocus(selmon->sel, 0); ++ ++ if (selmon->hidsel) { ++ hidewin(selmon->sel); ++ if (c) ++ arrange(c->mon); ++ selmon->hidsel = 0; ++ } ++ } + if (c) { + if (c->mon != selmon) + selmon = c->mon; +@@ -830,28 +887,57 @@ focusmon(const Arg *arg) + } + + void +-focusstack(const Arg *arg) ++focusstackvis(const Arg *arg) ++{ ++ focusstack(arg->i, 0); ++} ++ ++void ++focusstackhid(const Arg *arg) ++{ ++ focusstack(arg->i, 1); ++} ++ ++void ++focusstack(int inc, int hid) + { + Client *c = NULL, *i; + +- if (!selmon->sel) ++ if (!selmon->sel && !hid) + return; +- if (arg->i > 0) { +- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); ++ if (!selmon->clients) ++ return; ++ ++ if (inc > 0) { ++ if (selmon->sel) ++ for (c = selmon->sel->next; ++ c && (!ISVISIBLE(c) || (!hid && HIDDEN(c))); ++ c = c->next); + if (!c) +- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); ++ for (c = selmon->clients; ++ c && (!ISVISIBLE(c) || (!hid && HIDDEN(c))); ++ c = c->next); + } else { +- for (i = selmon->clients; i != selmon->sel; i = i->next) +- if (ISVISIBLE(i)) +- c = i; ++ if (selmon->sel) { ++ for (i = selmon->clients; i != selmon->sel; i = i->next) ++ if (ISVISIBLE(i) && !(!hid && HIDDEN(i))) ++ c = i; ++ } else ++ c = selmon->clients; + if (!c) + for (; i; i = i->next) +- if (ISVISIBLE(i)) ++ if (ISVISIBLE(i) && !(!hid && HIDDEN(i))) + c = i; + } ++ + if (c) { + focus(c); + restack(selmon); ++ ++ if (HIDDEN(c)) { ++ showwin(c); ++ c->mon->hidsel = 1; ++ } + } + } + +@@ -963,6 +1049,36 @@ grabkeys(void) + } + } + ++void ++hide(const Arg *arg) ++{ ++ hidewin(selmon->sel); ++ focus(NULL); ++ arrange(selmon); ++} ++ ++void ++hidewin(Client *c) { ++ if (!c || HIDDEN(c)) ++ return; ++ ++ Window w = c->win; ++ static XWindowAttributes ra, ca; ++ ++ // more or less taken directly from blackbox's hide() function ++ XGrabServer(dpy); ++ XGetWindowAttributes(dpy, root, &ra); ++ XGetWindowAttributes(dpy, w, &ca); ++ // prevent UnmapNotify events ++ XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask); ++ XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask); ++ XUnmapWindow(dpy, w); ++ setclientstate(c, IconicState); ++ XSelectInput(dpy, root, ra.your_event_mask); ++ XSelectInput(dpy, w, ca.your_event_mask); ++ XUngrabServer(dpy); ++} ++ + void + incnmaster(const Arg *arg) + { +@@ -1067,12 +1183,14 @@ manage(Window w, XWindowAttributes *wa) + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); + XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ +- setclientstate(c, NormalState); ++ if (!HIDDEN(c)) ++ setclientstate(c, NormalState); + if (c->mon == selmon) + unfocus(selmon->sel, 0); + c->mon->sel = c; + arrange(c->mon); +- XMapWindow(dpy, c->win); ++ if (!HIDDEN(c)) ++ XMapWindow(dpy, c->win); + focus(NULL); + } + +@@ -1195,7 +1313,7 @@ movemouse(const Arg *arg) + Client * + nexttiled(Client *c) + { +- for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); ++ for (; c && (c->isfloating || !ISVISIBLE(c) || HIDDEN(c)); c = c->next); + return c; + } + +@@ -1248,6 +1366,16 @@ propertynotify(XEvent *e) + void + quit(const Arg *arg) + { ++ // fix: reloading dwm keeps all the hidden clients hidden ++ Monitor *m; ++ Client *c; ++ for (m = mons; m; m = m->next) { ++ if (m) { ++ for (c = m->stack; c; c = c->next) ++ if (c && HIDDEN(c)) showwin(c); ++ } ++ } ++ + running = 0; + } + +@@ -1610,6 +1738,25 @@ seturgent(Client *c, int urg) + XFree(wmh); + } + ++void ++show(const Arg *arg) ++{ ++ if (selmon->hidsel) ++ selmon->hidsel = 0; ++ showwin(selmon->sel); ++} ++ ++void ++showwin(Client *c) ++{ ++ if (!c || !HIDDEN(c)) ++ return; ++ ++ XMapWindow(dpy, c->win); ++ setclientstate(c, NormalState); ++ arrange(c->mon); ++} ++ + void + showhide(Client *c) + { +@@ -1746,6 +1893,23 @@ toggleview(const Arg *arg) + } + } + ++void ++togglewin(const Arg *arg) ++{ ++ Client *c = (Client*)arg->v; ++ ++ if (c == selmon->sel) { ++ hidewin(c); ++ focus(NULL); ++ arrange(c->mon); ++ } else { ++ if (HIDDEN(c)) ++ showwin(c); ++ focus(c); ++ restack(selmon); ++ } ++} ++ + void + unfocus(Client *c, int setfocus) + { diff --git a/dwm/patches/dwm-bar-height-6.2.diff b/dwm/patches/dwm-bar-height-6.2.diff new file mode 100644 index 0000000..a576111 --- /dev/null +++ b/dwm/patches/dwm-bar-height-6.2.diff @@ -0,0 +1,25 @@ +diff --git a/config.def.h b/config.def.h +index 1c0b587..9814500 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -5,6 +5,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ + static const int showbar = 1; /* 0 means no bar */ + static const int topbar = 1; /* 0 means bottom bar */ ++static const int user_bh = 0; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */ + static const char *fonts[] = { "monospace:size=10" }; + static const char dmenufont[] = "monospace:size=10"; + static const char col_gray1[] = "#222222"; +diff --git a/dwm.c b/dwm.c +index 4465af1..2c27cb3 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -1545,7 +1545,7 @@ setup(void) + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; +- bh = drw->fonts->h + 2; ++ bh = user_bh ? user_bh : drw->fonts->h + 2; + updategeom(); + /* init atoms */ + utf8string = XInternAtom(dpy, "UTF8_STRING", False); diff --git a/dwm/applied_patches/dwm-functionalgaps-6.2.diff b/dwm/patches/dwm-functionalgaps-6.2.diff similarity index 100% rename from dwm/applied_patches/dwm-functionalgaps-6.2.diff rename to dwm/patches/dwm-functionalgaps-6.2.diff diff --git a/dwm/patches/dwm-status2d-6.2.diff b/dwm/patches/dwm-status2d-6.2.diff new file mode 100644 index 0000000..ce7f53f --- /dev/null +++ b/dwm/patches/dwm-status2d-6.2.diff @@ -0,0 +1,166 @@ +diff --git a/dwm.c b/dwm.c +index d27cb67..464c9d6 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -163,6 +163,7 @@ static void detach(Client *c); + static Monitor *dirtomon(int dir); + static void drawbar(Monitor *m); + static void drawbars(void); ++static int drawstatusbar(Monitor *m, int bh, char* text); + static void enternotify(XEvent *e); + static void expose(XEvent *e); + static void focus(Client *c); +@@ -237,7 +238,7 @@ static void zoom(const Arg *arg); + + /* variables */ + static const char broken[] = "broken"; +-static char stext[256]; ++static char stext[1024]; + static int screen; + static int sw, sh; /* X display screen geometry width, height */ + static int bh, blw = 0; /* bar geometry */ +@@ -483,7 +484,7 @@ cleanup(void) + cleanupmon(mons); + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); +- for (i = 0; i < LENGTH(colors); i++) ++ for (i = 0; i < LENGTH(colors) + 1; i++) + free(scheme[i]); + XDestroyWindow(dpy, wmcheckwin); + drw_free(drw); +@@ -690,6 +691,114 @@ dirtomon(int dir) + return m; + } + ++int ++drawstatusbar(Monitor *m, int bh, char* stext) { ++ int ret, i, w, x, len; ++ short isCode = 0; ++ char *text; ++ char *p; ++ ++ len = strlen(stext) + 1 ; ++ if (!(text = (char*) malloc(sizeof(char)*len))) ++ die("malloc"); ++ p = text; ++ memcpy(text, stext, len); ++ ++ /* compute width of the status text */ ++ w = 0; ++ i = -1; ++ while (text[++i]) { ++ if (text[i] == '^') { ++ if (!isCode) { ++ isCode = 1; ++ text[i] = '\0'; ++ w += TEXTW(text) - lrpad; ++ text[i] = '^'; ++ if (text[++i] == 'f') ++ w += atoi(text + ++i); ++ } else { ++ isCode = 0; ++ text = text + i + 1; ++ i = -1; ++ } ++ } ++ } ++ if (!isCode) ++ w += TEXTW(text) - lrpad; ++ else ++ isCode = 0; ++ text = p; ++ ++ w += 2; /* 1px padding on both sides */ ++ ret = x = m->ww - w; ++ ++ drw_setscheme(drw, scheme[LENGTH(colors)]); ++ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; ++ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; ++ drw_rect(drw, x, 0, w, bh, 1, 1); ++ x++; ++ ++ /* process status text */ ++ i = -1; ++ while (text[++i]) { ++ if (text[i] == '^' && !isCode) { ++ isCode = 1; ++ ++ text[i] = '\0'; ++ w = TEXTW(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0); ++ ++ x += w; ++ ++ /* process code */ ++ while (text[++i] != '^') { ++ if (text[i] == 'c') { ++ char buf[8]; ++ memcpy(buf, (char*)text+i+1, 7); ++ buf[7] = '\0'; ++ drw_clr_create(drw, &drw->scheme[ColFg], buf); ++ i += 7; ++ } else if (text[i] == 'b') { ++ char buf[8]; ++ memcpy(buf, (char*)text+i+1, 7); ++ buf[7] = '\0'; ++ drw_clr_create(drw, &drw->scheme[ColBg], buf); ++ i += 7; ++ } else if (text[i] == 'd') { ++ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; ++ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; ++ } else if (text[i] == 'r') { ++ int rx = atoi(text + ++i); ++ while (text[++i] != ','); ++ int ry = atoi(text + ++i); ++ while (text[++i] != ','); ++ int rw = atoi(text + ++i); ++ while (text[++i] != ','); ++ int rh = atoi(text + ++i); ++ ++ drw_rect(drw, rx + x, ry, rw, rh, 1, 0); ++ } else if (text[i] == 'f') { ++ x += atoi(text + ++i); ++ } ++ } ++ ++ text = text + i + 1; ++ i=-1; ++ isCode = 0; ++ } ++ } ++ ++ if (!isCode) { ++ w = TEXTW(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0); ++ } ++ ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ free(p); ++ ++ return ret; ++} ++ + void + drawbar(Monitor *m) + { +@@ -701,9 +802,7 @@ drawbar(Monitor *m) + + /* draw status first so it can be overdrawn by tags later */ + if (m == selmon) { /* status is only drawn on selected monitor */ +- drw_setscheme(drw, scheme[SchemeNorm]); +- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ +- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); ++ sw = m->ww - drawstatusbar(m, bh, stext); + } + + for (c = m->clients; c; c = c->next) { +@@ -1572,7 +1671,8 @@ setup(void) + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ +- scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); ++ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); ++ scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); + /* init bars */ diff --git a/dwm/patches/dwm-underlinetags-6.2.diff b/dwm/patches/dwm-underlinetags-6.2.diff new file mode 100644 index 0000000..ea3a1c9 --- /dev/null +++ b/dwm/patches/dwm-underlinetags-6.2.diff @@ -0,0 +1,27 @@ +diff -pu dwm.git/config.def.h dwm.underlinetags/config.def.h +--- dwm.git/config.def.h 2021-02-27 20:04:32.030570909 -0600 ++++ dwm.underlinetags/config.def.h 2021-03-16 16:42:26.278703624 -0500 +@@ -21,6 +21,11 @@ static const char *colors[][3] = { + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + ++static const unsigned int ulinepad = 5; /* horizontal padding between the underline and tag */ ++static const unsigned int ulinestroke = 2; /* thickness / height of the underline */ ++static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */ ++static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ ++ + static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class +diff -pu dwm.git/dwm.c dwm.underlinetags/dwm.c +--- dwm.git/dwm.c 2021-02-27 20:04:32.030570909 -0600 ++++ dwm.underlinetags/dwm.c 2021-03-16 16:41:21.468077151 -0500 +@@ -719,6 +719,8 @@ drawbar(Monitor *m) + w = TEXTW(tags[i]); + drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); ++ if (ulineall || m->tagset[m->seltags] & 1 << i) /* if there are conflicts, just move these lines directly underneath both 'drw_setscheme' and 'drw_text' :) */ ++ drw_rect(drw, x + ulinepad, bh - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0); + if (occ & 1 << i) + drw_rect(drw, x + boxs, boxs, boxw, boxw, + m == selmon && selmon->sel && selmon->sel->tags & 1 << i, diff --git a/dwm/applied_patches/dwm-xresources-20210314.diff b/dwm/patches/dwm-xresources-6.2.diff similarity index 88% rename from dwm/applied_patches/dwm-xresources-20210314.diff rename to dwm/patches/dwm-xresources-6.2.diff index 07e08f4..c1875c0 100644 --- a/dwm/applied_patches/dwm-xresources-20210314.diff +++ b/dwm/patches/dwm-xresources-6.2.diff @@ -1,22 +1,20 @@ -From d28a26439326d7566a43459e1ef00b5b7c7f5b11 Mon Sep 17 00:00:00 2001 -From: David JULIEN -Date: Sun, 14 Mar 2021 18:19:17 +0100 -Subject: [PATCH] [PATCH] feat: manage font through xrdb +From 2832bd78a690606a48a7e1d370cd60fd92ee4988 Mon Sep 17 00:00:00 2001 +From: MLquest8 +Date: Fri, 12 Jun 2020 15:43:31 +0400 +Subject: [PATCH] handle various setting of various types from Xresources -add font management to the dwm-resources patch, enabling to manage fonts -by sourcing $XRESOURCES --- - config.def.h | 61 ++++++++++++++++++++++++++++++-------------- + config.def.h | 54 ++++++++++++++++++++++++++------------- drw.c | 2 +- drw.h | 2 +- dwm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 116 insertions(+), 21 deletions(-) + 4 files changed, 111 insertions(+), 19 deletions(-) diff --git a/config.def.h b/config.def.h -index 1c0b587..db7b7bb 100644 +index 1c0b587..e69f288 100644 --- a/config.def.h +++ b/config.def.h -@@ -1,21 +1,23 @@ +@@ -1,21 +1,22 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ @@ -24,8 +22,12 @@ index 1c0b587..db7b7bb 100644 -static const unsigned int snap = 32; /* snap pixel */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ --static const char *fonts[] = { "monospace:size=10" }; --static const char dmenufont[] = "monospace:size=10"; ++static unsigned int borderpx = 1; /* border pixel of windows */ ++static unsigned int snap = 32; /* snap pixel */ ++static int showbar = 1; /* 0 means no bar */ ++static int topbar = 1; /* 0 means bottom bar */ + static const char *fonts[] = { "monospace:size=10" }; + static const char dmenufont[] = "monospace:size=10"; -static const char col_gray1[] = "#222222"; -static const char col_gray2[] = "#444444"; -static const char col_gray3[] = "#bbbbbb"; @@ -35,13 +37,6 @@ index 1c0b587..db7b7bb 100644 - /* fg bg border */ - [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, -+static unsigned int borderpx = 1; /* border pixel of windows */ -+static unsigned int snap = 32; /* snap pixel */ -+static int showbar = 1; /* 0 means no bar */ -+static int topbar = 1; /* 0 means bottom bar */ -+static char font[] = "monospace:size=10"; -+static char dmenufont[] = "monospace:size=10"; -+static const char *fonts[] = { font }; +static char normbgcolor[] = "#222222"; +static char normbordercolor[] = "#444444"; +static char normfgcolor[] = "#bbbbbb"; @@ -55,7 +50,7 @@ index 1c0b587..db7b7bb 100644 }; /* tagging */ -@@ -32,9 +34,9 @@ static const Rule rules[] = { +@@ -32,9 +33,9 @@ static const Rule rules[] = { }; /* layout(s) */ @@ -68,7 +63,7 @@ index 1c0b587..db7b7bb 100644 static const Layout layouts[] = { /* symbol arrange function */ -@@ -56,9 +58,30 @@ static const Layout layouts[] = { +@@ -56,9 +57,28 @@ static const Layout layouts[] = { /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ @@ -80,8 +75,6 @@ index 1c0b587..db7b7bb 100644 + * Xresources preferences to load at startup + */ +ResourcePref resources[] = { -+ { "font", STRING, &font }, -+ { "dmenufont", STRING, &dmenufont }, + { "normbgcolor", STRING, &normbgcolor }, + { "normbordercolor", STRING, &normbordercolor }, + { "normfgcolor", STRING, &normfgcolor }, @@ -127,7 +120,7 @@ index 4bcd5ad..42b04ce 100644 /* Cursor abstraction */ Cur *drw_cur_create(Drw *drw, int shape); diff --git a/dwm.c b/dwm.c -index 664c527..17bb21e 100644 +index 9fd0286..dc0d219 100644 --- a/dwm.c +++ b/dwm.c @@ -36,6 +36,7 @@ @@ -238,5 +231,5 @@ index 664c527..17bb21e 100644 #ifdef __OpenBSD__ if (pledge("stdio rpath proc exec", NULL) == -1) -- -2.30.2 +2.26.2 diff --git a/st/config.def.h b/st/config.def.h index 69c05f2..2cd4da0 100644 --- a/st/config.def.h +++ b/st/config.def.h @@ -5,7 +5,7 @@ * * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html */ -static char *font = "castella:size=14"; +static char *font = "JetBrainsMono Nerd Font:size=12:antialias=true:autohint=true"; static int borderpx = 4; /* diff --git a/st/config.h b/st/config.h new file mode 100644 index 0000000..2cd4da0 --- /dev/null +++ b/st/config.h @@ -0,0 +1,510 @@ +/* See LICENSE file for copyright and license details. */ + +/* + * appearance + * + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ +static char *font = "JetBrainsMono Nerd Font:size=12:antialias=true:autohint=true"; +static int borderpx = 4; + +/* + * What program is execed by st depends of these precedence rules: + * 1: program passed with -e + * 2: scroll and/or utmp + * 3: SHELL environment variable + * 4: value of shell in /etc/passwd + * 5: value of shell in config.h + */ +static char *shell = "/bin/zsh"; +char *utmp = NULL; +/* scroll program: to enable use a string like "scroll" */ +char *scroll = NULL; +char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; + +/* identification sequence returned in DA and DECID */ +char *vtiden = "\033[?6c"; + +/* Kerning / character bounding-box multipliers */ +static float cwscale = 1.0; +static float chscale = 1.0; + +/* + * word delimiter string + * + * More advanced example: L" `'\"()[]{}" + */ +wchar_t *worddelimiters = L" "; + +/* selection timeouts (in milliseconds) */ +static unsigned int doubleclicktimeout = 300; +static unsigned int tripleclicktimeout = 600; + +/* alt screens */ +int allowaltscreen = 1; + +/* allow certain non-interactive (insecure) window operations such as: + setting the clipboard text */ +int allowwindowops = 0; + +/* + * draw latency range in ms - from new content/keypress/etc until drawing. + * within this range, st draws when content stops arriving (idle). mostly it's + * near minlatency, but it waits longer for slow updates to avoid partial draw. + * low minlatency will tear/flicker more, as it can "detect" idle too early. + */ +static double minlatency = 8; +static double maxlatency = 33; + +/* + * blinking timeout (set to 0 to disable blinking) for the terminal blinking + * attribute. + */ +static unsigned int blinktimeout = 800; + +/* + * thickness of underline and bar cursors + */ +static unsigned int cursorthickness = 2; + +/* + * bell volume. It must be a value between -100 and 100. Use 0 for disabling + * it + */ +static int bellvolume = 0; + +/* default TERM value */ +char *termname = "st-256color"; + +/* + * spaces per tab + * + * When you are changing this value, don't forget to adapt the »it« value in + * the st.info and appropriately install the st.info in the environment where + * you use this st version. + * + * it#$tabspaces, + * + * Secondly make sure your kernel is not expanding tabs. When running `stty + * -a` »tab0« should appear. You can tell the terminal to not expand tabs by + * running following command: + * + * stty tabs + */ +unsigned int tabspaces = 8; + +/* Terminal colors (16 first used in escape sequence) */ +static const char *colorname[] = { + "#1C1E26", + "#232530", + "#2E303E", + "#6F6F70", + "#9DA0A2", + "#CBCED0", + "#DCDFE4", + "#E3E6EE", + "#E95678", + "#FAB795", + "#FAC29A", + "#29D398", + "#59E1E3", + "#26BBD9", + "#EE64AC", + "#F09383" +}; + +unsigned int defaultfg = 7; +unsigned int defaultbg = 0; +static unsigned int defaultcs = 13; +static unsigned int defaultrcs = 0; + +static const int resizehints = 0; + +/* + * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81 + * Default style of cursor + * 0: Blinking block + * 1: Blinking block (default) + * 2: Steady block ("█") + * 3: Blinking underline + * 4: Steady underline ("_") + * 5: Blinking bar + * 6: Steady bar ("|") + * 7: Blinking st cursor + * 8: Steady st cursor + */ +static unsigned int cursorstyle = 1; +static Rune stcursor = 0x2603; /* snowman (U+2603) */ + +/* + * Default columns and rows numbers + */ + +static unsigned int cols = 80; +static unsigned int rows = 24; + +/* + * Default colour and shape of the mouse cursor + */ +static unsigned int mouseshape = XC_xterm; +static unsigned int mousefg = 7; +static unsigned int mousebg = 0; + +/* + * Color used to display font attributes when fontconfig selected a font which + * doesn't match the ones requested. + */ +static unsigned int defaultattr = 11; + +/* + * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). + * Note that if you want to use ShiftMask with selmasks, set this to an other + * modifier, set to 0 to not use it. + */ +static uint forcemousemod = ShiftMask; + +/* + * Xresources preferences to load at startup + */ +ResourcePref resources[] = { + { "font", STRING, &font }, + { "color0", STRING, &colorname[0] }, + { "color1", STRING, &colorname[1] }, + { "color2", STRING, &colorname[2] }, + { "color3", STRING, &colorname[3] }, + { "color4", STRING, &colorname[4] }, + { "color5", STRING, &colorname[5] }, + { "color6", STRING, &colorname[6] }, + { "color7", STRING, &colorname[7] }, + { "color8", STRING, &colorname[8] }, + { "color9", STRING, &colorname[9] }, + { "color10", STRING, &colorname[10] }, + { "color11", STRING, &colorname[11] }, + { "color12", STRING, &colorname[12] }, + { "color13", STRING, &colorname[13] }, + { "color14", STRING, &colorname[14] }, + { "color15", STRING, &colorname[15] }, + { "background", STRING, &colorname[256] }, + { "foreground", STRING, &colorname[257] }, + { "cursorColor", STRING, &colorname[258] }, + { "termname", STRING, &termname }, + { "shell", STRING, &shell }, + { "minlatency", INTEGER, &minlatency }, + { "maxlatency", INTEGER, &maxlatency }, + { "blinktimeout", INTEGER, &blinktimeout }, + { "bellvolume", INTEGER, &bellvolume }, + { "tabspaces", INTEGER, &tabspaces }, + { "borderpx", INTEGER, &borderpx }, + { "cwscale", FLOAT, &cwscale }, + { "chscale", FLOAT, &chscale }, +}; + +/* + * Internal mouse shortcuts. + * Beware that overloading Button1 will disable the selection. + */ +static MouseShortcut mshortcuts[] = { + /* mask button function argument release */ + + // Scrollback mouse added manually + { ShiftMask, Button4, kscrollup, {.i = 1} }, + { ShiftMask, Button5, kscrolldown, {.i = 1} }, + + { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, + { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, + { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, + { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, + { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, +}; + +/* Internal keyboard shortcuts. */ +#define MODKEY Mod1Mask +#define TERMMOD (ControlMask|ShiftMask) + +static Shortcut shortcuts[] = { + /* mask keysym function argument */ + { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, + { ControlMask, XK_Print, toggleprinter, {.i = 0} }, + { ShiftMask, XK_Print, printscreen, {.i = 0} }, + { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, + { TERMMOD, XK_Prior, zoom, {.f = +1} }, + { TERMMOD, XK_Next, zoom, {.f = -1} }, + { TERMMOD, XK_Home, zoomreset, {.f = 0} }, + { TERMMOD, XK_C, clipcopy, {.i = 0} }, + { TERMMOD, XK_V, clippaste, {.i = 0} }, + { TERMMOD, XK_Y, selpaste, {.i = 0} }, + { ShiftMask, XK_Insert, selpaste, {.i = 0} }, + { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, + { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, + { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, +}; + +/* + * Special keys (change & recompile st.info accordingly) + * + * Mask value: + * * Use XK_ANY_MOD to match the key no matter modifiers state + * * Use XK_NO_MOD to match the key alone (no modifiers) + * appkey value: + * * 0: no value + * * > 0: keypad application mode enabled + * * = 2: term.numlock = 1 + * * < 0: keypad application mode disabled + * appcursor value: + * * 0: no value + * * > 0: cursor application mode enabled + * * < 0: cursor application mode disabled + * + * Be careful with the order of the definitions because st searches in + * this table sequentially, so any XK_ANY_MOD must be in the last + * position for a key. + */ + +/* + * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) + * to be mapped below, add them to this array. + */ +static KeySym mappedkeys[] = { -1 }; + +/* + * State bits to ignore when matching key or button events. By default, + * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. + */ +static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; + +/* + * This is the huge key array which defines all compatibility to the Linux + * world. Please decide about changes wisely. + */ +static Key key[] = { + /* keysym mask string appkey appcursor */ + { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, + { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, + { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, + { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, + { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, + { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, + { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, + { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, + { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, + { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, + { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, + { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, + { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, + { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, + { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, + { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, + { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, + { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, + { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, + { XK_KP_End, ControlMask, "\033[J", -1, 0}, + { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, + { XK_KP_End, ShiftMask, "\033[K", -1, 0}, + { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, + { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, + { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, + { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, + { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, + { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, + { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, + { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, + { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, + { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, + { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, + { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, + { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, + { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, + { XK_KP_Delete, XK_ANY_MOD, "\033[3~", -1, 0}, + { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, + { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, + { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, + { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, + { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, + { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, + { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, + { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, + { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, + { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, + { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, + { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, + { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, + { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, + { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, + { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, + { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, + { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, + { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, + { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, + { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, + { XK_Up, ControlMask, "\033[1;5A", 0, 0}, + { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, + { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, + { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, + { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, + { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, + { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, + { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, + { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, + { XK_Down, ControlMask, "\033[1;5B", 0, 0}, + { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, + { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, + { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, + { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, + { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, + { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, + { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, + { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, + { XK_Left, ControlMask, "\033[1;5D", 0, 0}, + { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, + { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, + { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, + { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, + { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, + { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, + { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, + { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, + { XK_Right, ControlMask, "\033[1;5C", 0, 0}, + { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, + { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, + { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, + { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, + { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, + { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, + { XK_Return, Mod1Mask, "\033\r", 0, 0}, + { XK_Return, XK_ANY_MOD, "\r", 0, 0}, + { XK_Insert, ShiftMask, "\033[4l", -1, 0}, + { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, + { XK_Insert, ControlMask, "\033[L", -1, 0}, + { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, + { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, + { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, + { XK_Delete, ControlMask, "\033[M", -1, 0}, + { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, + { XK_Delete, ShiftMask, "\033[2K", -1, 0}, + { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, + { XK_Delete, XK_ANY_MOD, "\033[3~", -1, 0}, + { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, + { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, + { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, + { XK_Home, ShiftMask, "\033[2J", 0, -1}, + { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, + { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, + { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, + { XK_End, ControlMask, "\033[J", -1, 0}, + { XK_End, ControlMask, "\033[1;5F", +1, 0}, + { XK_End, ShiftMask, "\033[K", -1, 0}, + { XK_End, ShiftMask, "\033[1;2F", +1, 0}, + { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, + { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, + { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, + { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, + { XK_Next, ControlMask, "\033[6;5~", 0, 0}, + { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, + { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, + { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, + { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, + { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, + { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, + { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, + { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, + { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, + { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, + { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, + { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, + { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, + { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, + { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, + { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, + { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, + { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, + { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, + { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, + { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, + { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, + { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, + { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, + { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, + { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, + { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, + { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, + { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, + { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, + { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, + { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, + { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, + { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, + { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, + { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, + { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, + { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, + { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, + { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, + { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, + { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, + { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, + { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, + { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, + { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, + { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, + { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, + { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, + { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, + { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, + { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, + { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, + { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, + { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, + { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, + { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, + { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, + { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, + { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, + { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, + { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, + { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, + { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, + { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, + { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, + { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, + { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, + { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, + { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, + { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, + { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, + { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, + { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, + { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, + { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, + { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, + { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, + { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, + { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, + { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, + { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, + { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, + { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, + { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, + { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, + { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, + { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, +}; + +/* + * Selection types' masks. + * Use the same masks as usual. + * Button1Mask is always unset, to make masks match between ButtonPress. + * ButtonRelease and MotionNotify. + * If no match is found, regular selection is used. + */ +static uint selmasks[] = { + [SEL_RECTANGULAR] = Mod1Mask, +}; + +/* + * Printable characters in ASCII, used to estimate the advance width + * of single wide characters. + */ +static char ascii_printable[] = + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/st/applied_patches/st-anysize-20201003-407a3d0.diff b/st/patches/st-anysize-20201003-407a3d0.diff similarity index 100% rename from st/applied_patches/st-anysize-20201003-407a3d0.diff rename to st/patches/st-anysize-20201003-407a3d0.diff diff --git a/st/applied_patches/st-blinking_cursor-20200531-a2a7044.diff b/st/patches/st-blinking_cursor-20200531-a2a7044.diff similarity index 100% rename from st/applied_patches/st-blinking_cursor-20200531-a2a7044.diff rename to st/patches/st-blinking_cursor-20200531-a2a7044.diff diff --git a/st/applied_patches/st-clipboard-20180309-c5ba9c0.diff b/st/patches/st-clipboard-20180309-c5ba9c0.diff similarity index 100% rename from st/applied_patches/st-clipboard-20180309-c5ba9c0.diff rename to st/patches/st-clipboard-20180309-c5ba9c0.diff diff --git a/st/applied_patches/st-delkey-20201112-4ef0cbd.diff b/st/patches/st-delkey-20201112-4ef0cbd.diff similarity index 100% rename from st/applied_patches/st-delkey-20201112-4ef0cbd.diff rename to st/patches/st-delkey-20201112-4ef0cbd.diff diff --git a/st/applied_patches/st-gruvbox-dark-0.8.2.diff b/st/patches/st-gruvbox-dark-0.8.2.diff similarity index 100% rename from st/applied_patches/st-gruvbox-dark-0.8.2.diff rename to st/patches/st-gruvbox-dark-0.8.2.diff diff --git a/st/applied_patches/st-nordtheme-0.8.2.diff b/st/patches/st-nordtheme-0.8.2.diff similarity index 100% rename from st/applied_patches/st-nordtheme-0.8.2.diff rename to st/patches/st-nordtheme-0.8.2.diff diff --git a/st/applied_patches/st-scrollback-20201205-4ef0cbd.diff b/st/patches/st-scrollback-20201205-4ef0cbd.diff similarity index 100% rename from st/applied_patches/st-scrollback-20201205-4ef0cbd.diff rename to st/patches/st-scrollback-20201205-4ef0cbd.diff diff --git a/st/applied_patches/st-scrollback-mouse-20191024-a2c479c.diff b/st/patches/st-scrollback-mouse-20191024-a2c479c.diff similarity index 100% rename from st/applied_patches/st-scrollback-mouse-20191024-a2c479c.diff rename to st/patches/st-scrollback-mouse-20191024-a2c479c.diff diff --git a/st/applied_patches/st-xresources-20200604-9ba7ecf.diff b/st/patches/st-xresources-20200604-9ba7ecf.diff similarity index 100% rename from st/applied_patches/st-xresources-20200604-9ba7ecf.diff rename to st/patches/st-xresources-20200604-9ba7ecf.diff