From 57cecd9032be600887bb393ca264350026057bad Mon Sep 17 00:00:00 2001 From: Clay Gomera Date: Wed, 20 Jul 2022 10:51:13 -0400 Subject: [PATCH] Refactored dwm --- user/.config/suckless/dwm/config.def.h | 172 ++++++------ user/.config/suckless/dwm/drw.c | 104 ++++--- user/.config/suckless/dwm/drw.h | 8 +- user/.config/suckless/dwm/dwm.1 | 28 +- user/.config/suckless/dwm/dwm.c | 262 +++++++++--------- .../suckless/dwm/{layouts.c => grid.c} | 7 +- user/.config/suckless/dwm/transient.c | 7 +- user/.config/suckless/dwm/util.c | 8 +- user/.config/suckless/dwm/util.h | 7 +- 9 files changed, 326 insertions(+), 277 deletions(-) rename user/.config/suckless/dwm/{layouts.c => grid.c} (67%) diff --git a/user/.config/suckless/dwm/config.def.h b/user/.config/suckless/dwm/config.def.h index ce4bd1271..145175a18 100644 --- a/user/.config/suckless/dwm/config.def.h +++ b/user/.config/suckless/dwm/config.def.h @@ -63,7 +63,8 @@ static const Rule rules[] = { static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ static const int nmaster = 1; /* number of clients in master area */ static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ -#include "layouts.c" +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ +#include "grid.c" static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, /* first entry is default */ @@ -77,13 +78,12 @@ static const Layout layouts[] = { /* |||--- VARIABLES ---||| */ /* key definitions */ #define MODKEY Mod4Mask -#define TAGKEYS(CHAIN,KEY,TAG) \ - { MODKEY, CHAIN, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, CHAIN, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, CHAIN, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask|ShiftMask, CHAIN, KEY, toggletag, {.ui = 1 << TAG} }, +#define TAGKEYS(KEY,TAG) \ + {1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }, \ + {1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }, \ + {1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }, \ + {1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} }, /* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define CMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } /* dmenu */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ @@ -93,160 +93,160 @@ static const char *termcmd[] = { "alacritty", NULL }; /* |||--- KEY BIDINGS ---||| */ -static Key keys[] = { +static Keychord keychords[] = { /* modifier chain key key function argument */ /* Terminal */ - { MODKEY, -1, XK_Return, spawn, {.v = termcmd } }, + {1, {{MODKEY, XK_Return}}, spawn, {.v = termcmd } }, /* Top bar toggle */ - { MODKEY, -1, XK_b, togglebar, {0} }, + {1, {{MODKEY|ShiftMask, XK_b}}, togglebar, {0} }, /* WINDOW TAG AND LAYOUT MANIPULATION */ /* Tag Bindings */ - TAGKEYS( -1, XK_1, 0) - TAGKEYS( -1, XK_2, 1) - TAGKEYS( -1, XK_3, 2) - TAGKEYS( -1, XK_4, 3) - TAGKEYS( -1, XK_5, 4) - TAGKEYS( -1, XK_6, 5) - TAGKEYS( -1, XK_7, 6) - TAGKEYS( -1, XK_8, 7) - TAGKEYS( -1, XK_9, 8) + 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) /* Close Window */ - { MODKEY, -1, XK_q, killclient, {0} }, + {1, {{MODKEY|ShiftMask, XK_c}}, killclient, {0} }, /* Cycle between tags */ - { MODKEY|ControlMask, -1, XK_Tab, view, {0} }, + {1, {{MODKEY|ControlMask, XK_Tab}}, view, {0} }, /* Window moving */ - { MODKEY|ShiftMask, -1, XK_j, rotatestack, {.i = +1 } }, - { MODKEY|ShiftMask, -1, XK_k, rotatestack, {.i = -1 } }, + {1, {{MODKEY|ShiftMask, XK_j}}, rotatestack, {.i = +1 } }, + {1, {{MODKEY|ShiftMask, XK_k}}, rotatestack, {.i = -1 } }, /* Window focusing */ - { MODKEY, -1, XK_j, focusstack, {.i = +1 } }, - { MODKEY, -1, XK_k, focusstack, {.i = -1 } }, + {1, {{MODKEY, XK_j}}, focusstack, {.i = +1 } }, + {1, {{MODKEY, XK_k}}, focusstack, {.i = -1 } }, /* Increase and decrease master windows count */ - { MODKEY, -1, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, -1, XK_d, incnmaster, {.i = -1 } }, + {1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } }, + {1, {{MODKEY, XK_d}}, incnmaster, {.i = -1 } }, /* Increase and decrease master window size */ - { MODKEY, -1, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, -1, XK_l, setmfact, {.f = +0.05} }, + {1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} }, + {1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} }, /* Move window to master */ - { MODKEY|ControlMask, -1, XK_Return, zoom, {0} }, + {1, {{MODKEY|ControlMask, XK_Return}}, zoom, {0} }, /* Cycle between layouts fowards and backwards */ - { MODKEY, -1, XK_Tab, cyclelayout, {.i = -1 } }, - { MODKEY|ShiftMask, -1, XK_Tab, cyclelayout, {.i = +1 } }, - /* Cycle between recently used layouts */ - { MODKEY, -1, XK_space, setlayout, {0} }, + {1, {{ MODKEY, XK_Tab}}, cyclelayout, {.i = -1 } }, + {1, {{ MODKEY|ShiftMask, XK_Tab}}, cyclelayout, {.i = +1 } }, /* Switch to tiling layout */ - { MODKEY, -1, XK_t, setlayout, {.v = &layouts[0]} }, + {1, {{MODKEY, XK_t}}, setlayout, {.v = &layouts[0]} }, /* Switch to floating layout */ - { MODKEY, -1, XK_f, setlayout, {.v = &layouts[1]} }, + {1, {{MODKEY, XK_f}}, setlayout, {.v = &layouts[1]} }, /* Switch to monocle layout */ - { MODKEY, -1, XK_m, setlayout, {.v = &layouts[2]} }, + {1, {{MODKEY, XK_m}}, setlayout, {.v = &layouts[2]} }, /* Switch to grid layout */ - { MODKEY, -1, XK_g, setlayout, {.v = &layouts[3]} }, + {1, {{MODKEY, XK_g}}, setlayout, {.v = &layouts[3]} }, /* Toggle floating mode */ - { MODKEY|ShiftMask, -1, XK_space, togglefloating, {0} }, + {1, {{MODKEY|ShiftMask, XK_f}}, togglefloating, {0} }, + /* Toggle fullscreen mode */ + {1, {{MODKEY, XK_space}}, togglefullscr, {0} }, /* View all windows of all tags in the current tag */ - { MODKEY, -1, XK_0, view, {.ui = ~0 } }, + {1, {{MODKEY, XK_0}}, view, {.ui = ~0 } }, /* Show focused window on all tags */ - { MODKEY|ShiftMask, -1, XK_0, tag, {.ui = ~0 } }, + {1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } }, /* Focusing between monitors */ - { MODKEY, -1, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, -1, XK_period, focusmon, {.i = +1 } }, + {1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } }, + {1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } }, /* Move focused window between monitors */ - { MODKEY|ShiftMask, -1, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, -1, XK_period, tagmon, {.i = +1 } }, + {1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } }, + {1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } }, /* VOLUME CONTROL */ /* Toggle mute */ - { MODKEY, -1, XK_F1, spawn, CMD("pamixer -t") }, + {1, {{MODKEY, XK_F1}}, spawn, SHCMD("pamixer -t") }, /* Decrease volume by 5% */ - { MODKEY, -1, XK_F2, spawn, CMD("pamixer -d 5") }, + {1, {{MODKEY, XK_F2}}, spawn, SHCMD("pamixer -d 5") }, /* Increase volume by 5% */ - { MODKEY, -1, XK_F3, spawn, CMD("pamixer -i 5") }, + {1, {{MODKEY, XK_F3}}, spawn, SHCMD("pamixer -i 5") }, /* Toggle microphone mute */ - { MODKEY, -1, XK_F4, spawn, CMD("pamixer --default-source -t") }, + {1, {{MODKEY, XK_F4}}, spawn, SHCMD("pamixer --default-source -t") }, /* BRIGHTNESS CONTROL */ /* Decrease brightness by 5% */ - { MODKEY, -1, XK_F5, spawn, CMD("xbacklight -dec 10") }, + {1, {{MODKEY, XK_F5}}, spawn, SHCMD("xbacklight -dec 10") }, /* Increase brightness by 5% */ - { MODKEY, -1, XK_F6, spawn, CMD("xbacklight -inc 10") }, + {1, {{MODKEY, XK_F6}}, spawn, SHCMD("xbacklight -inc 10") }, /* Set screen backlight to off */ - { MODKEY, -1, XK_F7, spawn, CMD("xbacklight -set 0") }, + {1, {{MODKEY, XK_F7}}, spawn, SHCMD("xbacklight -set 0") }, /* KEYBOARD LAYOUTS changed with emacs-style keychords SUPER + k (keyboard) followed by "key" */ /* Switch to the spanish keyboard layout */ - { MODKEY, XK_k, XK_e, spawn, CMD("setxkbmap -layout es") }, + {2, {{MODKEY, XK_k}, {0, XK_e}}, spawn, SHCMD("setxkbmap -layout es") }, /* Switch to the english keyboard layout */ - { MODKEY, XK_k, XK_u, spawn, CMD("setxkbmap -layout us") }, + {2, {{MODKEY, XK_k}, {0, XK_u}}, spawn, SHCMD("setxkbmap -layout us") }, /* EMACS PROGRAMS launched with emacs-style heychords SUPER + e (app) followed by "key" */ - { MODKEY, XK_e, XK_e, spawn, CMD("emacsclient -c -a 'emacs'") }, - { MODKEY, XK_e, XK_b, spawn, CMD("emacsclient -c -a 'emacs' --eval '(ibuffer)'") }, - { MODKEY, XK_e, XK_d, spawn, CMD("emacsclient -c -a 'emacs' --eval '(dired nil)'") }, - { MODKEY, XK_e, XK_t, spawn, CMD("emacsclient -c -a 'emacs' --eval '(+vterm/here nil)'") }, - { MODKEY, XK_e, XK_w, spawn, CMD("emacsclient -c -a 'emacs' --eval '(doom/window-maximize-buffer(eww \"gnu.org\"))'") }, - { MODKEY, XK_e, XK_s, spawn, CMD("emacsclient -c -a 'emacs' --eval '(eshell)'") }, + {2, {{MODKEY, XK_e}, {0, XK_e}}, spawn, SHCMD("emacsclient -c -a 'emacs'") }, + {2, {{MODKEY, XK_e}, {0, XK_b}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(ibuffer)'") }, + {2, {{MODKEY, XK_e}, {0, XK_d}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(dired nil)'") }, + {2, {{MODKEY, XK_e}, {0, XK_v}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(+vterm/here nil)'") }, + {2, {{MODKEY, XK_e}, {0, XK_s}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(eshell)'") }, + {2, {{MODKEY, XK_e}, {0, XK_w}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(doom/window-maximize-buffer(eww \"gnu.org\"))'") }, /* PROGRAMS launched with emacs-style keychords SUPER + a (app) followed by "key" */ /* File manager */ - { MODKEY, XK_a, XK_f, spawn, CMD("alacritty -t exp --class exp,exp -e $HOME/.config/vifm/scripts/vifmrun") }, + {2, {{MODKEY, XK_a}, {0, XK_f}}, spawn, SHCMD("alacritty -t exp --class exp,exp -e $HOME/.config/vifm/scripts/vifmrun") }, /* Web browser */ - { MODKEY, XK_a, XK_w, spawn, CMD("qutebrowser") }, + {2, {{MODKEY, XK_a}, {0, XK_w}}, spawn, SHCMD("qutebrowser") }, /* Chat app */ - { MODKEY, XK_a, XK_c, spawn, CMD("alacritty -t cht --class cht,cht -e gomuks") }, + {2, {{MODKEY, XK_a}, {0, XK_c}}, spawn, SHCMD("alacritty -t cht --class cht,cht -e gomuks") }, /* Music player */ - { MODKEY, XK_a, XK_m, spawn, CMD("alacritty -t msc --class msc,msc -e cmus") }, + {2, {{MODKEY, XK_a}, {0, XK_m}}, spawn, SHCMD("alacritty -t msc --class msc,msc -e cmus") }, /* Game app */ - { MODKEY, XK_a, XK_g, spawn, CMD("retroarch") }, + {2, {{MODKEY, XK_a}, {0, XK_g}}, spawn, SHCMD("retroarch") }, /* Virtual machine manager */ - { MODKEY, XK_a, XK_v, spawn, CMD("virt-manager") }, + {2, {{MODKEY, XK_a}, {0, XK_v}}, spawn, SHCMD("virt-manager") }, /* MISC PROGRAMS launched with emacs-style keychords SUPER + m (app) followed by "key" */ /* System monitor btop */ - { MODKEY, XK_s, XK_b, spawn, CMD("alacritty -t misc --class misc,misc -e btop") }, + {2, {{MODKEY, XK_s}, {0, XK_b}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e btop") }, /* System monitor htop */ - { MODKEY, XK_s, XK_h, spawn, CMD("alacritty -t misc --class misc,misc -e htop") }, + {2, {{MODKEY, XK_s}, {0, XK_h}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e htop") }, /* Pulse mixer */ - { MODKEY, XK_s, XK_p, spawn, CMD("alacritty -t misc --class misc,misc -e pulsemixer") }, + {2, {{MODKEY, XK_s}, {0, XK_p}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e pulsemixer") }, /* Alsa mixer */ - { MODKEY, XK_s, XK_m, spawn, CMD("alacritty -t misc --class misc,misc -e alsamixer") }, + {2, {{MODKEY, XK_s}, {0, XK_m}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e alsamixer") }, /* Rss reader */ - { MODKEY, XK_s, XK_n, spawn, CMD("alacritty -t misc --class misc,misc -e newsboat") }, + {2, {{MODKEY, XK_s}, {0, XK_n}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e newsboat") }, /* Ytfzf */ - { MODKEY, XK_s, XK_y, spawn, CMD("alacritty -t misc --class misc,misc -e ytfzf -flst") }, + {2, {{MODKEY, XK_s}, {0, XK_y}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e ytfzf -flst") }, /* Ani-cli */ - { MODKEY, XK_s, XK_a, spawn, CMD("alacritty -t misc --class misc,misc -e ani-cli") }, + {2, {{MODKEY, XK_s}, {0, XK_a}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e ani-cli") }, /* Flix-cli */ - { MODKEY, XK_s, XK_f, spawn, CMD("alacritty -t misc --class misc,misc -e flix-cli") }, + {2, {{MODKEY, XK_s}, {0, XK_f}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e flix-cli") }, /* Castero */ - { MODKEY, XK_s, XK_c, spawn, CMD("alacritty -t misc --class misc,misc -e castero") }, + {2, {{MODKEY, XK_s}, {0, XK_c}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e castero") }, /* DMENU PROMPTS launched with emacs-style keychords SUPER + p (prompt) followed by "key" */ /* dmenu */ - { MODKEY, XK_p, XK_r, spawn, {.v = dmenucmd } }, + {2, {{MODKEY, XK_p}, {0, XK_r}}, spawn, {.v = dmenucmd } }, /* dmenu_power */ - { MODKEY, XK_p, XK_q, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_power") }, + {2, {{MODKEY, XK_p}, {0, XK_q}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_power") }, /* dmenu_wifi */ - { MODKEY, XK_p, XK_i, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_wifi") }, + {2, {{MODKEY, XK_p}, {0, XK_i}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_wifi") }, /* dmenu_wall */ - { MODKEY, XK_p, XK_w, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_wall") }, + {2, {{MODKEY, XK_p}, {0, XK_w}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_wall") }, /* dmenu_edit */ - { MODKEY, XK_p, XK_e, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_edit") }, + {2, {{MODKEY, XK_p}, {0, XK_e}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_edit") }, /* dmenu_scrot */ - { MODKEY, XK_p, XK_s, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_scrot") }, + {2, {{MODKEY, XK_p}, {0, XK_s}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_scrot") }, /* dmenu_drun */ - { MODKEY, XK_p, XK_d, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_drun") }, + {2, {{MODKEY, XK_p}, {0, XK_d}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_drun") }, /* dmenu_blue */ - { MODKEY, XK_p, XK_b, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_blue") }, + {2, {{MODKEY, XK_p}, {0, XK_b}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_blue") }, /* dmenu_emoji */ - { MODKEY, XK_p, XK_z, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_emoji") }, + {2, {{MODKEY, XK_p}, {0, XK_z}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_emoji") }, /* DWM BOOTSTRAP */ - { MODKEY|ShiftMask|ControlMask, -1, XK_q, quit, {0} }, - { MODKEY|ControlMask, -1, XK_r, quit, {1} }, + {1, {{MODKEY|ControlMask, XK_r}}, quit, {1} }, + {1, {{MODKEY|ShiftMask, XK_q}}, quit, {0} }, }; /* button definitions */ diff --git a/user/.config/suckless/dwm/drw.c b/user/.config/suckless/dwm/drw.c index 9f5a2141f..801b35541 100644 --- a/user/.config/suckless/dwm/drw.c +++ b/user/.config/suckless/dwm/drw.c @@ -1,3 +1,4 @@ +/* See LICENSE file for copyright and license details. */ #include #include #include @@ -97,6 +98,7 @@ drw_free(Drw *drw) { XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); free(drw); } @@ -134,6 +136,19 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) die("no font specified."); } + /* Do not allow using color fonts. This is a workaround for a BadLength + * error from Xft with color glyphs. Modelled on the Xterm workaround. See + * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 + * https://lists.suckless.org/dev/1701/30932.html + * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 + * and lots more all over the internet. + */ + FcBool iscol; + if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) { + XftFontClose(drw->dpy, xfont); + return NULL; + } + font = ecalloc(1, sizeof(Fnt)); font->xfont = xfont; font->pattern = pattern; @@ -240,12 +255,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) { - char buf[1024]; - int ty; - unsigned int ew; + int i, ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; XftDraw *d = NULL; Fnt *usedfont, *curfont, *nextfont; - size_t i, len; int utf8strlen, utf8charlen, render = x || y || w || h; long utf8codepoint = 0; const char *utf8str; @@ -253,13 +266,17 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp FcPattern *fcpattern; FcPattern *match; XftResult result; - int charexists = 0; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + enum { nomatches_len = 64 }; + static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; + static unsigned int ellipsis_width = 0; - if (!drw || (render && !drw->scheme) || !text || !drw->fonts) + if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) return 0; if (!render) { - w = ~w; + w = invert ? invert : ~invert; } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); @@ -269,8 +286,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); while (1) { - utf8strlen = 0; + ew = ellipsis_len = utf8strlen = 0; utf8str = text; nextfont = NULL; while (*text) { @@ -278,9 +297,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp for (curfont = drw->fonts; curfont; curfont = curfont->next) { charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); if (charexists) { - if (curfont == usedfont) { + drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); + if (ew + ellipsis_width <= w) { + /* keep track where the ellipsis still fits */ + ellipsis_x = x + ew; + ellipsis_w = w - ew; + ellipsis_len = utf8strlen; + } + + if (ew + tmpw > w) { + overflow = 1; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; + } else if (curfont == usedfont) { utf8strlen += utf8charlen; text += utf8charlen; + ew += tmpw; } else { nextfont = curfont; } @@ -288,36 +325,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } } - if (!charexists || nextfont) + if (overflow || !charexists || nextfont) break; else charexists = 0; } if (utf8strlen) { - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); - /* shorten text if necessary */ - for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - - if (len) { - memcpy(buf, utf8str, len); - buf[len] = '\0'; - if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.') - ; /* NOP */ - - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)buf, len); - } - x += ew; - w -= ew; + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); } + x += ew; + w -= ew; } + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); - if (!*text) { + if (!*text || overflow) { break; } else if (nextfont) { charexists = 0; @@ -327,6 +353,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp * character must be drawn. */ charexists = 1; + for (i = 0; i < nomatches_len; ++i) { + /* avoid calling XftFontMatch if we know we won't find a match */ + if (utf8codepoint == nomatches.codepoint[i]) + goto no_match; + } + fccharset = FcCharSetCreate(); FcCharSetAddChar(fccharset, utf8codepoint); @@ -355,6 +387,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp curfont->next = usedfont; } else { xfont_free(usedfont); + nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; +no_match: usedfont = drw->fonts; } } @@ -384,6 +418,15 @@ drw_fontset_getwidth(Drw *drw, const char *text) return drw_text(drw, 0, 0, 0, 0, 0, text, 0); } +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} + void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) { @@ -421,4 +464,3 @@ drw_cur_free(Drw *drw, Cur *cursor) XFreeCursor(drw->dpy, cursor->cursor); free(cursor); } - diff --git a/user/.config/suckless/dwm/drw.h b/user/.config/suckless/dwm/drw.h index bc7d7c290..94b8bbd19 100644 --- a/user/.config/suckless/dwm/drw.h +++ b/user/.config/suckless/dwm/drw.h @@ -1,8 +1,4 @@ -/* ____ __ */ -/* / __ \_________ _/ /_____ */ -/* / / / / ___/ __ `/ //_/ _ \ */ -/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */ -/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */ +/* See LICENSE file for copyright and license details. */ typedef struct { Cursor cursor; @@ -42,6 +38,7 @@ void drw_free(Drw *drw); Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); void drw_fontset_free(Fnt* set); unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); /* Colorscheme abstraction */ @@ -62,4 +59,3 @@ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned in /* Map functions */ void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); - diff --git a/user/.config/suckless/dwm/dwm.1 b/user/.config/suckless/dwm/dwm.1 index 85d1cdc6f..ab3967c32 100644 --- a/user/.config/suckless/dwm/dwm.1 +++ b/user/.config/suckless/dwm/dwm.1 @@ -30,10 +30,18 @@ top left corner. The tags which are applied to one or more windows are indicated with an empty square in the top left corner. .P dwm draws a small border around windows to indicate the focus state. +.P +On start, dwm can start additional programs that may be specified in two special +shell scripts (see the FILES section below), autostart_blocking.sh and +autostart.sh. The former is executed first and dwm will wait for its +termination before starting. The latter is executed in the background before +dwm enters its handler loop. +.P +Either of these files may be omitted. .SH OPTIONS .TP .B \-v -prints version information to standard output, then exits. +prints version information to stderr, then exits. .SH USAGE .SS Status bar .TP @@ -122,6 +130,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only). .B Mod1\-Shift\-c Close focused window. .TP +.B Mod1\-Shift\-f +Toggle fullscreen for focused window. +.TP .B Mod1\-Shift\-space Toggle focused window between tiled and floating state. .TP @@ -161,6 +172,21 @@ Toggles focused window between floating and tiled state. .TP .B Mod1\-Button3 Resize focused window while dragging. Tiled windows will be toggled to the floating state. +.SH FILES +The files containing programs to be started along with dwm are searched for in +the following directories: +.IP "1. $XDG_DATA_HOME/dwm" +.IP "2. $HOME/.local/share/dwm" +.IP "3. $HOME/.dwm" +.P +The first existing directory is scanned for any of the autostart files below. +.TP 15 +autostart.sh +This file is started as a shell background process before dwm enters its handler +loop. +.TP 15 +autostart_blocking.sh +This file is started before any autostart.sh; dwm waits for its termination. .SH CUSTOMIZATION dwm is customized by creating a custom config.h and (re)compiling the source code. This keeps it fast, secure and simple. diff --git a/user/.config/suckless/dwm/dwm.c b/user/.config/suckless/dwm/dwm.c index 07fd92b25..0480d4a20 100644 --- a/user/.config/suckless/dwm/dwm.c +++ b/user/.config/suckless/dwm/dwm.c @@ -1,9 +1,5 @@ -/* ____ __ */ -/* / __ \_________ _/ /_____ */ -/* / / / / ___/ __ `/ //_/ _ \ */ -/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */ -/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */ -/* +/* See LICENSE file for copyright and license details. + * * dynamic window manager is designed like any other X client as well. It is * driven through handling X events. In contrast to other X clients, a window * manager selects for SubstructureRedirectMask on the root window, to receive @@ -24,7 +20,6 @@ * * To understand everything else, start reading main(). */ - #include #include #include @@ -34,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -54,8 +50,7 @@ #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 ISVISIBLEONTAG(C, T) ((C->tags & T)) -#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags]) +#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) #define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx) @@ -97,7 +92,7 @@ struct Client { float mina, maxa; int x, y, w, h; int oldx, oldy, oldw, oldh; - int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; int bw, oldbw; unsigned int tags; int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; @@ -109,11 +104,15 @@ struct Client { typedef struct { unsigned int mod; - KeySym chain; KeySym keysym; +} Key; + +typedef struct { + unsigned int n; + const Key keys[5]; void (*func)(const Arg *); const Arg arg; -} Key; +} Keychord; typedef struct { const char *symbol; @@ -156,7 +155,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac static void arrange(Monitor *m); static void arrangemon(Monitor *m); static void attach(Client *c); -static void attachaside(Client *c); +static void attachbottom(Client *c); static void attachstack(Client *c); static void buttonpress(XEvent *e); static void checkotherwm(void); @@ -182,6 +181,7 @@ 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 int getrootptr(int *x, int *y); static long getstate(Window w); static int gettextprop(Window w, Atom atom, char *text, unsigned int size); @@ -196,7 +196,6 @@ static void maprequest(XEvent *e); static void monocle(Monitor *m); static void motionnotify(XEvent *e); static void movemouse(const Arg *arg); -static Client *nexttagged(Client *c); static Client *nexttiled(Client *c); static void pop(Client *); static void propertynotify(XEvent *e); @@ -229,6 +228,7 @@ static void tagmon(const Arg *arg); static void tile(Monitor *); static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); +static void togglefullscr(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); static void unfocus(Client *c, int setfocus); @@ -287,7 +287,7 @@ static Display *dpy; static Drw *drw; static Monitor *mons, *selmon; static Window root, wmcheckwin; -static KeySym keychain = -1; +unsigned int currentkey = 0; static int useargb = 0; static Visual *visual; @@ -370,6 +370,8 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) if (*w < bh) *w = bh; if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { + if (!c->hintsvalid) + updatesizehints(c); /* see last two sentences in ICCCM 4.1.2.3 */ baseismin = c->basew == c->minw && c->baseh == c->minh; if (!baseismin) { /* temporarily remove base dimensions */ @@ -433,17 +435,14 @@ attach(Client *c) } void -attachaside(Client *c) { - Client *at = nexttagged(c); - if(!at) { - attach(c); - return; - } - c->next = at->next; - at->next = c; +attachbottom(Client *c) +{ + Client **tc; + c->next = NULL; + for (tc = &c->mon->clients; *tc; tc = &(*tc)->next); + *tc = c; } - void attachstack(Client *c) { @@ -477,7 +476,7 @@ buttonpress(XEvent *e) arg.ui = 1 << i; } else if (ev->x < x + blw) click = ClkLtSymbol; - else if (ev->x > selmon->ww - TEXTW(stext)) + else if (ev->x > selmon->ww - (int)TEXTW(stext)) click = ClkStatusText; else click = ClkWinTitle; @@ -524,6 +523,7 @@ cleanup(void) drw_cur_free(drw, cursor[i]); for (i = 0; i < LENGTH(colors); i++) free(scheme[i]); + free(scheme); XDestroyWindow(dpy, wmcheckwin); drw_free(drw); XSync(dpy, False); @@ -750,17 +750,20 @@ dirtomon(int dir) void drawbar(Monitor *m) { - int x, w, sw = 0; + int x, w, tw = 0; int boxs = drw->fonts->h / 9; int boxw = drw->fonts->h / 6 + 2; unsigned int i, occ = 0, urg = 0; Client *c; + if (!m->showbar) + return; + /* draw status first so it can be overdrawn by tags later */ - if (m == selmon || 1) { /* status is only drawn on selected monitor */ + if (m == selmon) { /* status is only drawn on selected monitor */ drw_setscheme(drw, scheme[SchemeNorm]); - sw = TEXTW(stext); - drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2, stext, 0); + tw = TEXTW(stext); + drw_text(drw, m->ww - tw, 0, tw, bh, lrpad / 2, stext, 0); } for (c = m->clients; c; c = c->next) { @@ -783,7 +786,7 @@ 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 - sw - x) > bh) { + 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); @@ -911,7 +914,7 @@ focusstack(const Arg *arg) { Client *c = NULL, *i; - if (!selmon->sel) + if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) return; if (arg->i > 0) { for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); @@ -1027,21 +1030,16 @@ grabkeys(void) { updatenumlockmask(); { - unsigned int i, j; + unsigned int i, k; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; KeyCode code; - KeyCode chain; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < LENGTH(keys); i++) - if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) { - if (keys[i].chain != -1 && - ((chain = XKeysymToKeycode(dpy, keys[i].chain)))) - code = chain; - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, - True, GrabModeAsync, GrabModeAsync); - } + for (i = 0; i < LENGTH(keychords); i++) + if ((code = XKeysymToKeycode(dpy, keychords[i].keys[currentkey].keysym))) + for (k = 0; k < LENGTH(modifiers); k++) + XGrabKey(dpy, code, keychords[i].keys[currentkey].mod | modifiers[k], root, + True, GrabModeAsync, GrabModeAsync); } } @@ -1067,37 +1065,48 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) void keypress(XEvent *e) { - unsigned int i, j; + XEvent event = *e; + Keychord *keychord; + unsigned int ran = 0; KeySym keysym; XKeyEvent *ev; - int current = 0; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; + Keychord *newoptions; + Keychord *oldoptions = (Keychord *)malloc(sizeof(keychords)); - ev = &e->xkey; - keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for (i = 0; i < LENGTH(keys); i++) { - if (keysym == keys[i].keysym && keys[i].chain == -1 - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); - else if (keysym == keys[i].chain && keychain == -1 - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) { - current = 1; - keychain = keysym; - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, AnyKey, 0 | modifiers[j], root, - True, GrabModeAsync, GrabModeAsync); - } else if (!current && keysym == keys[i].keysym - && keychain != -1 - && keys[i].chain == keychain - && keys[i].func) - keys[i].func(&(keys[i].arg)); - } - if (!current) { - keychain = -1; + memcpy(oldoptions, keychords, sizeof(keychords)); + size_t numoption = 0; + while(!ran){ + ev = &event.xkey; + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + newoptions = (Keychord *)malloc(0); + numoption = 0; + for (keychord = oldoptions; keychord->n != 0 && currentkey < 5; keychord = (Keychord *)((char *)keychord + sizeof(Keychord))){ + if(keysym == keychord->keys[currentkey].keysym + && CLEANMASK(keychord->keys[currentkey].mod) == CLEANMASK(ev->state) + && keychord->func){ + if(keychord->n == currentkey +1){ + keychord->func(&(keychord->arg)); + ran = 1; + }else{ + numoption++; + newoptions = (Keychord *)realloc(newoptions, numoption * sizeof(Keychord)); + memcpy((char *)newoptions + (numoption -1) * sizeof(Keychord),keychord, sizeof(Keychord)); + } + } + } + currentkey++; + if(numoption == 0) + break; grabkeys(); + while (running && !XNextEvent(dpy, &event) && !ran) + if(event.type == KeyPress) + break; + free(oldoptions); + oldoptions = newoptions; } + free(newoptions); + currentkey = 0; + grabkeys(); } void @@ -1164,7 +1173,7 @@ manage(Window w, XWindowAttributes *wa) c->isfloating = c->oldstate = trans != None || c->isfixed; if (c->isfloating) XRaiseWindow(dpy, c->win); - attachaside(c); + attachbottom(c); attachstack(c); XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, (unsigned char *) &(c->win), 1); @@ -1294,16 +1303,6 @@ movemouse(const Arg *arg) } } - Client * -nexttagged(Client *c) { - Client *walked = c->mon->clients; - for(; - walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags)); - walked = walked->next - ); - return walked; -} - Client * nexttiled(Client *c) { @@ -1340,7 +1339,7 @@ propertynotify(XEvent *e) arrange(c->mon); break; case XA_WM_NORMAL_HINTS: - updatesizehints(c); + c->hintsvalid = 0; break; case XA_WM_HINTS: updatewmhints(c); @@ -1396,15 +1395,15 @@ resizeclient(Client *c, int x, int y, int w, int h) wc.border_width = c->bw; - /* Get number of clients for the selected monitor */ - for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++); + /* Get number of clients for the client's monitor */ + for (n = 0, nbc = nexttiled(c->mon->clients); nbc; nbc = nexttiled(nbc->next), n++); /* Do nothing if layout is floating */ - if (c->isfloating || selmon->lt[selmon->sellt]->arrange == NULL) { + if (c->isfloating || c->mon->lt[c->mon->sellt]->arrange == NULL) { gapincr = gapoffset = 0; } else { /* Remove border and gap if layout is monocle or only one client */ - if (selmon->lt[selmon->sellt]->arrange == monocle || n == 1) { + if (c->mon->lt[c->mon->sellt]->arrange == monocle || n == 1) { gapoffset = 0; gapincr = -2 * borderpx; wc.border_width = 0; @@ -1591,7 +1590,7 @@ sendmon(Client *c, Monitor *m) detachstack(c); c->mon = m; c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ - attachaside(c); + attachbottom(c); attachstack(c); focus(NULL); arrange(NULL); @@ -1694,7 +1693,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.1 || f > 0.9) + if (f < 0.05 || f > 0.95) return; selmon->mfact = f; arrange(selmon); @@ -1879,12 +1878,14 @@ tile(Monitor *m) 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); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); - my += HEIGHT(c); + resize(c, m->wx, m->wy + my, mw - (2*c->bw) + (n > 1 ? gappx : 0), h - (2*c->bw), 0); + if (my + HEIGHT(c) < m->wh) + my += HEIGHT(c); } else { h = (m->wh - ty) / (n - i); resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); - ty += HEIGHT(c); + if (ty + HEIGHT(c) < m->wh) + ty += HEIGHT(c); } } @@ -1911,6 +1912,13 @@ togglefloating(const Arg *arg) arrange(selmon); } +void +togglefullscr(const Arg *arg) +{ + if(selmon->sel) + setfullscreen(selmon->sel, !selmon->sel->isfullscreen); +} + void toggletag(const Arg *arg) { @@ -2062,43 +2070,43 @@ updategeom(void) memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); XFree(info); nn = j; - if (n <= nn) { /* new monitors available */ - for (i = 0; i < (nn - n); i++) { - for (m = mons; m && m->next; m = m->next); - if (m) - m->next = createmon(); - else - mons = createmon(); + + /* new monitors if nn > n */ + for (i = n; i < nn; i++) { + for (m = mons; m && m->next; m = m->next); + if (m) + m->next = createmon(); + else + mons = createmon(); + } + for (i = 0, m = mons; i < nn && m; m = m->next, i++) + if (i >= n + || unique[i].x_org != m->mx || unique[i].y_org != m->my + || unique[i].width != m->mw || unique[i].height != m->mh) + { + dirty = 1; + m->num = i; + m->mx = m->wx = unique[i].x_org; + m->my = m->wy = unique[i].y_org; + m->mw = m->ww = unique[i].width; + m->mh = m->wh = unique[i].height; + updatebarpos(m); } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n - || unique[i].x_org != m->mx || unique[i].y_org != m->my - || unique[i].width != m->mw || unique[i].height != m->mh) - { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - } else { /* less monitors available nn < n */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - attachaside(c); - attachstack(c); - } - if (m == selmon) - selmon = mons; - cleanupmon(m); + /* removed monitors if n > nn */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); + while ((c = m->clients)) { + dirty = 1; + m->clients = c->next; + detachstack(c); + c->mon = mons; + attach(c); + attachbottom(c); + attachstack(c); } + if (m == selmon) + selmon = mons; + cleanupmon(m); } free(unique); } else @@ -2177,16 +2185,15 @@ updatesizehints(Client *c) } else c->maxa = c->mina = 0.0; c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); + c->hintsvalid = 1; } void updatestatus(void) { - Monitor* m; if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) strcpy(stext, "dwm-"VERSION); - for(m = mons; m; m = m->next) - drawbar(m); + drawbar(selmon); } void @@ -2383,4 +2390,3 @@ main(int argc, char *argv[]) XCloseDisplay(dpy); return EXIT_SUCCESS; } - diff --git a/user/.config/suckless/dwm/layouts.c b/user/.config/suckless/dwm/grid.c similarity index 67% rename from user/.config/suckless/dwm/layouts.c rename to user/.config/suckless/dwm/grid.c index b076ff365..de24c449f 100644 --- a/user/.config/suckless/dwm/layouts.c +++ b/user/.config/suckless/dwm/grid.c @@ -1,9 +1,3 @@ -/* ____ __ */ -/* / __ \_________ _/ /_____ */ -/* / / / / ___/ __ `/ //_/ _ \ */ -/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */ -/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */ - void grid(Monitor *m) { unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows; @@ -31,3 +25,4 @@ grid(Monitor *m) { i++; } } + diff --git a/user/.config/suckless/dwm/transient.c b/user/.config/suckless/dwm/transient.c index 18fe81887..040adb5b3 100644 --- a/user/.config/suckless/dwm/transient.c +++ b/user/.config/suckless/dwm/transient.c @@ -1,10 +1,5 @@ -/* ____ __ */ -/* / __ \_________ _/ /_____ */ -/* / / / / ___/ __ `/ //_/ _ \ */ -/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */ -/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */ - /* cc transient.c -o transient -lX11 */ + #include #include #include diff --git a/user/.config/suckless/dwm/util.c b/user/.config/suckless/dwm/util.c index 2173edf54..fe044fc7b 100644 --- a/user/.config/suckless/dwm/util.c +++ b/user/.config/suckless/dwm/util.c @@ -1,9 +1,4 @@ -/* ____ __ */ -/* / __ \_________ _/ /_____ */ -/* / / / / ___/ __ `/ //_/ _ \ */ -/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */ -/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */ - +/* See LICENSE file for copyright and license details. */ #include #include #include @@ -38,4 +33,3 @@ die(const char *fmt, ...) { exit(1); } - diff --git a/user/.config/suckless/dwm/util.h b/user/.config/suckless/dwm/util.h index 35cdd1457..f633b5173 100644 --- a/user/.config/suckless/dwm/util.h +++ b/user/.config/suckless/dwm/util.h @@ -1,8 +1,4 @@ -/* ____ __ */ -/* / __ \_________ _/ /_____ */ -/* / / / / ___/ __ `/ //_/ _ \ */ -/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */ -/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */ +/* See LICENSE file for copyright and license details. */ #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B)) @@ -10,4 +6,3 @@ void die(const char *fmt, ...); void *ecalloc(size_t nmemb, size_t size); -