re-adding X11 for freebsd computers. - dotfiles - These are my dotfiles. There are many like it, but these are mine.
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit 4cd431555432812ba6c2b17095fc64c439957e87
 (DIR) parent 2ed9f6a741a303736c9daee0e1dbaadae9f5707b
 (HTM) Author: Jay Scott <me@jay.scot>
       Date:   Tue, 20 Sep 2022 09:25:09 +0100
       
       re-adding X11 for freebsd computers.
       
       Diffstat:
         A X11/Xresources                      |      53 ++++++++++++++++++++++++++++++
         A X11/xinitrc                         |      10 ++++++++++
         R bin/old/dwmstatus.sh -> bin/dwmsta… |       0 
         M bootstrap.sh                        |      11 +++--------
         M pkg/archlinux                       |       3 ++-
         M profile                             |       8 ++++++++
         A suckless/dmenu/Makefile             |      39 +++++++++++++++++++++++++++++++
         A suckless/dmenu/config.h             |      13 +++++++++++++
         A suckless/dmenu/patches/01-dmenu-bo… |      25 +++++++++++++++++++++++++
         A suckless/dmenu/patches/02-dmenu-ce… |     120 +++++++++++++++++++++++++++++++
         A suckless/dwm/Makefile               |      35 +++++++++++++++++++++++++++++++
         A suckless/dwm/config.h               |     195 +++++++++++++++++++++++++++++++
         A suckless/herbe/Makefile             |      40 +++++++++++++++++++++++++++++++
         A suckless/herbe/config.h             |      19 +++++++++++++++++++
         A suckless/st/Makefile                |      39 +++++++++++++++++++++++++++++++
         A suckless/st/config.h                |     476 +++++++++++++++++++++++++++++++
         A suckless/st/patches/01-st-scrollba… |     351 +++++++++++++++++++++++++++++++
         A suckless/st/patches/02-st-w3m-hack… |      12 ++++++++++++
       
       18 files changed, 1440 insertions(+), 9 deletions(-)
       ---
 (DIR) diff --git a/X11/Xresources b/X11/Xresources
       @@ -0,0 +1,53 @@
       +! vim:ft=xdefaults
       +
       +/* COLOURS */
       +#define RED0            #cc0403
       +#define RED1            #f2201f
       +#define GREEN0          #19cb00
       +#define GREEN1          #23fd00
       +#define YELLOW0         #cecb00
       +#define YELLOW1         #fffd00
       +#define BLUE0           #0d73cc
       +#define BLUE1           #1a8fff
       +#define MAGENTA0        #cb1ed1
       +#define MAGENTA1        #fd28ff
       +#define CYAN0           #0dcdcd
       +#define CYAN1           #14ffff
       +#define BLACK           #000000
       +#define GREY1           #767676
       +#define GREY2           #dddddd
       +#define WHITE           #ffffff
       +
       +#define FONT                       Hack:size=14
       +
       +/* XFT */
       +Xft.dpi:       96
       +Xft.hinting:   true
       +Xft.rgba:      rgb
       +Xft.antialias: true
       +Xft.autohint:  false
       +Xft.hintstyle: hintslight
       +Xft.lcdfilter: lcddefault
       +
       +*.foreground:        WHITE
       +*.background:         BLACK
       +
       +/* NORMAL */
       +*.color0:         BLACK
       +*.color1:         RED0
       +*.color2:          GREEN0
       +*.color3:          YELLOW0
       +*.color4:          BLUE0
       +*.color5:          MAGENTA0
       +*.color6:          CYAN0
       +*.color7:          GREY2
       +
       +/* BRIGHT */
       +*.color8:         GREY1
       +*.color9:         RED1
       +*.color10:         GREEN1
       +*.color11:         YELLOW1
       +*.color12:         BLUE1
       +*.color13:         MAGENTA1
       +*.color14:         CYAN1
       +*.color15:         WHITE
 (DIR) diff --git a/X11/xinitrc b/X11/xinitrc
       @@ -0,0 +1,10 @@
       +# x stuff
       +setxkbmap gb
       +xset s off -dpms
       +xrdb -load ~/.config/X11/Xresources
       +~/bin/dwmstatus.sh &
       +
       +# apps
       +mpd &
       +
       +exec dwm
 (DIR) diff --git a/bin/old/dwmstatus.sh b/bin/dwmstatus.sh
 (DIR) diff --git a/bootstrap.sh b/bootstrap.sh
       @@ -8,9 +8,9 @@ CONFIG='fdm foot git mpd mutt ncmpcpp qutebrowser sfeed senpai sway waybar'
        AUR='paru'
        
        link() {
       -        for f in $FILES; do ln -fs "$DOTFILES/$f" "$HOME/.$f"; done
       -        for f in $ROOT; do ln -fTs "$DOTFILES/$f" "$HOME/$f"; done
       -        for f in $CONFIG; do ln -fTs "$DOTFILES/$f" "$HOME/.config/$f"; done
       +        for f in $FILES; do ln -sfn "$DOTFILES/$f" "$HOME/.$f"; done
       +        for f in $ROOT; do ln -sfn "$DOTFILES/$f" "$HOME/$f"; done
       +        for f in $CONFIG; do ln -sfn "$DOTFILES/$f" "$HOME/.config/$f"; done
        }
        
        unlink() {
       @@ -19,10 +19,6 @@ unlink() {
                for f in $CONFIG; do unlink "$HOME/.config/$f"; done
        }
        
       -aur_clean() {
       -        $AUR -Qtdq | $AUR -Rns -
       -}
       -
        backup() {
                crontab -l >"$DOTFILES"/crontab
                $AUR -Qqe >"$DOTFILES"/pkg/archlinux
       @@ -30,7 +26,6 @@ backup() {
        
        restore() {
                crontab "$DOTFILES/crontab"
       -        #$AUR -S --needed - <"$DOTFILES/pkg/archlinux"
        }
        
        testsh() {
 (DIR) diff --git a/pkg/archlinux b/pkg/archlinux
       @@ -13,7 +13,6 @@ binutils
        bison
        bluez-utils
        borg
       -brave-bin
        campdown
        castget
        checkbashisms
       @@ -96,6 +95,8 @@ paru
        pass
        pass-audit-git
        patch
       +perl-authen-sasl
       +perl-io-socket-ssl
        pipewire-alsa
        pipewire-jack
        pipewire-pulse
 (DIR) diff --git a/profile b/profile
       @@ -4,6 +4,14 @@ if [ -d "$HOME/bin" ]; then
        fi
        
        # xdg related exports
       +if test -z "${XDG_RUNTIME_DIR}"; then
       +        export XDG_RUNTIME_DIR=/tmp/$(id -u)-runtime-dir
       +        if ! test -d "${XDG_RUNTIME_DIR}"; then
       +                mkdir "${XDG_RUNTIME_DIR}"
       +                chmod 0700 "${XDG_RUNTIME_DIR}"
       +        fi
       +fi
       +
        export XDG_CONFIG_HOME="$HOME/.config"
        export XDG_DOWNLOAD_DIR="$HOME/tmp"
        export XDG_CACHE_HOME="$HOME/.cache"
 (DIR) diff --git a/suckless/dmenu/Makefile b/suckless/dmenu/Makefile
       @@ -0,0 +1,39 @@
       +REPOSITORY = http://git.suckless.org/dmenu
       +SRC_DIR = src
       +PINNED_REVISION = HEAD
       +PATCH_DIR = patches
       +
       +all: $(SRC_DIR)
       +
       +clean: reset
       +        @if test -d $(SRC_DIR); then \
       +                $(MAKE) -C "${SRC_DIR}" -s clean; \
       +                git -C "${SRC_DIR}" clean -f; \
       +        fi
       +
       +$(SRC_DIR): clone reset
       +        @cp config.h $@
       +        $(MAKE) -C "${SRC_DIR}" -s
       +
       +patch: $(PATCH_DIR)/*
       +        @for file in $^ ; do \
       +                patch -d "${SRC_DIR}" < $${file}; \
       +        done
       +reset:
       +        @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
       +                git -C "${SRC_DIR}" reset --hard $(PINNED_REVISION); \
       +        fi
       +
       +clone:
       +        @if ! test -d $(SRC_DIR); then \
       +                git clone $(REPOSITORY) $(SRC_DIR); \
       +        fi
       +
       +update: clean
       +        @git -C "${SRC_DIR}" pull
       +
       +install:
       +        $(MAKE) -C "${SRC_DIR}" -s install
       +
       +
       +.PHONY: all clean update install reset clone
 (DIR) diff --git a/suckless/dmenu/config.h b/suckless/dmenu/config.h
       @@ -0,0 +1,13 @@
       +static int topbar = 1;
       +static const char *fonts[] = {
       +        "Hack:pixelsize=14"
       +};
       +static const char *prompt      = "run »";
       +static const char *colors[SchemeLast][2] = {
       +        [SchemeNorm] = { "#ffd7af", "#222222" },
       +        [SchemeSel] = { "#eeeeee", "#008000" },
       +        [SchemeOut] = { "#000000", "#00ffff" },
       +};
       +
       +static unsigned int lines = 0;
       +static const char worddelimiters[] = " ";
 (DIR) diff --git a/suckless/dmenu/patches/01-dmenu-border-4.9.diff b/suckless/dmenu/patches/01-dmenu-border-4.9.diff
       @@ -0,0 +1,25 @@
       +diff -up dmenu-4.9-b/config.def.h dmenu-4.9-a/config.def.h
       +--- dmenu-4.9-b/config.def.h        2019-02-02 13:55:02.000000000 +0100
       ++++ dmenu-4.9-a/config.def.h        2019-05-19 02:10:12.740040403 +0200
       +@@ -21,3 +21,6 @@ static unsigned int lines      = 0;
       +  * for example: " /?\"&[]"
       +  */
       + static const char worddelimiters[] = " ";
       ++
       ++/* Size of the window border */
       ++static const unsigned int border_width = 5;
       +diff -up dmenu-4.9-b/dmenu.c dmenu-4.9-a/dmenu.c
       +--- dmenu-4.9-b/dmenu.c        2019-02-02 13:55:02.000000000 +0100
       ++++ dmenu-4.9-a/dmenu.c        2019-05-19 02:11:20.966710117 +0200
       +@@ -654,9 +654,10 @@ setup(void)
       +         swa.override_redirect = True;
       +         swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
       +         swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
       +-        win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
       ++        win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
       +                             CopyFromParent, CopyFromParent, CopyFromParent,
       +                             CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
       ++        XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
       +         XSetClassHint(dpy, win, &ch);
       + 
       +         /* open input methods */
 (DIR) diff --git a/suckless/dmenu/patches/02-dmenu-center-20200111-8cd37e1.diff b/suckless/dmenu/patches/02-dmenu-center-20200111-8cd37e1.diff
       @@ -0,0 +1,120 @@
       +From 8cd37e1ab9e7cb025224aeb3543f1a5be8bceb93 Mon Sep 17 00:00:00 2001
       +From: Nihal Jere <nihal@nihaljere.xyz>
       +Date: Sat, 11 Jan 2020 21:16:08 -0600
       +Subject: [PATCH] center patch now has adjustable minimum width
       +
       +---
       + config.def.h |  2 ++
       + dmenu.1      |  3 +++
       + dmenu.c      | 39 ++++++++++++++++++++++++++++++++-------
       + 3 files changed, 37 insertions(+), 7 deletions(-)
       +
       +diff --git a/config.def.h b/config.def.h
       +index 1edb647..88ef264 100644
       +--- a/config.def.h
       ++++ b/config.def.h
       +@@ -2,6 +2,8 @@
       + /* Default settings; can be overriden by command line. */
       + 
       + static int topbar = 1;                      /* -b  option; if 0, dmenu appears at bottom     */
       ++static int centered = 0;                    /* -c option; centers dmenu on screen */
       ++static int min_width = 500;                    /* minimum width when centered */
       + /* -fn option overrides fonts[0]; default X11 font or font set */
       + static const char *fonts[] = {
       +         "monospace:size=10"
       +diff --git a/dmenu.1 b/dmenu.1
       +index 323f93c..c036baa 100644
       +--- a/dmenu.1
       ++++ b/dmenu.1
       +@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL.
       + .B \-b
       + dmenu appears at the bottom of the screen.
       + .TP
       ++.B \-c
       ++dmenu appears centered on the screen.
       ++.TP
       + .B \-f
       + dmenu grabs the keyboard before reading stdin if not reading from a tty. This
       + is faster, but will lock up X until stdin reaches end\-of\-file.
       +diff --git a/dmenu.c b/dmenu.c
       +index 65f25ce..041c7f8 100644
       +--- a/dmenu.c
       ++++ b/dmenu.c
       +@@ -89,6 +89,15 @@ calcoffsets(void)
       +                         break;
       + }
       + 
       ++static int
       ++max_textw(void)
       ++{
       ++        int len = 0;
       ++        for (struct item *item = items; item && item->text; item++)
       ++                len = MAX(TEXTW(item->text), len);
       ++        return len;
       ++}
       ++
       + static void
       + cleanup(void)
       + {
       +@@ -611,6 +620,7 @@ setup(void)
       +         bh = drw->fonts->h + 2;
       +         lines = MAX(lines, 0);
       +         mh = (lines + 1) * bh;
       ++        promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
       + #ifdef XINERAMA
       +         i = 0;
       +         if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
       +@@ -637,9 +647,16 @@ setup(void)
       +                                 if (INTERSECT(x, y, 1, 1, info[i]))
       +                                         break;
       + 
       +-                x = info[i].x_org;
       +-                y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
       +-                mw = info[i].width;
       ++                if (centered) {
       ++                        mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width);
       ++                        x = info[i].x_org + ((info[i].width  - mw) / 2);
       ++                        y = info[i].y_org + ((info[i].height - mh) / 2);
       ++                } else {
       ++                        x = info[i].x_org;
       ++                        y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
       ++                        mw = info[i].width;
       ++                }
       ++
       +                 XFree(info);
       +         } else
       + #endif
       +@@ -647,11 +664,17 @@ setup(void)
       +                 if (!XGetWindowAttributes(dpy, parentwin, &wa))
       +                         die("could not get embedding window attributes: 0x%lx",
       +                             parentwin);
       +-                x = 0;
       +-                y = topbar ? 0 : wa.height - mh;
       +-                mw = wa.width;
       ++
       ++                if (centered) {
       ++                        mw = MIN(MAX(max_textw() + promptw, min_width), wa.width);
       ++                        x = (wa.width  - mw) / 2;
       ++                        y = (wa.height - mh) / 2;
       ++                } else {
       ++                        x = 0;
       ++                        y = topbar ? 0 : wa.height - mh;
       ++                        mw = wa.width;
       ++                }
       +         }
       +-        promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
       +         inputw = MIN(inputw, mw/3);
       +         match();
       + 
       +@@ -709,6 +732,8 @@ main(int argc, char *argv[])
       +                         topbar = 0;
       +                 else if (!strcmp(argv[i], "-f"))   /* grabs keyboard before reading stdin */
       +                         fast = 1;
       ++                else if (!strcmp(argv[i], "-c"))   /* centers dmenu on screen */
       ++                        centered = 1;
       +                 else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
       +                         fstrncmp = strncasecmp;
       +                         fstrstr = cistrstr;
       +-- 
       +2.24.1
       +
 (DIR) diff --git a/suckless/dwm/Makefile b/suckless/dwm/Makefile
       @@ -0,0 +1,35 @@
       +REPOSITORY = http://git.suckless.org/dwm
       +SRC_DIR = src
       +PINNED_REVISION = HEAD
       +
       +all: $(SRC_DIR)
       +
       +clean: reset
       +        @if test -d $(SRC_DIR); then \
       +                cd $(SRC_DIR); \
       +                $(MAKE) -s clean; \
       +                git clean -f; \
       +        fi
       +
       +$(SRC_DIR): clone reset
       +        @cp config.h $@
       +        @cd $@ && $(MAKE) -s
       +
       +reset:
       +        @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
       +                cd $(SRC_DIR) && git reset --hard $(PINNED_REVISION); \
       +        fi
       +
       +clone:
       +        @if ! test -d $(SRC_DIR); then \
       +                git clone $(REPOSITORY) $(SRC_DIR); \
       +        fi
       +
       +update: clean
       +        @cd $(SRC_DIR) && git pull
       +
       +install:
       +        $(MAKE) -C "${SRC_DIR}" -s install
       +
       +
       +.PHONY: all clean update install reset clone
 (DIR) diff --git a/suckless/dwm/config.h b/suckless/dwm/config.h
       @@ -0,0 +1,195 @@
       +/* See LICENSE file for copyright and license details. */
       +
       +/* appearance */
       +static const unsigned int borderpx  = 2;
       +static const unsigned int snap      = 32;
       +static const int lockfullscreen            = 1;
       +static const int showbar            = 1;
       +static const int topbar             = 1;
       +static const char *fonts[]          = { "Hack:size=10" };
       +static const char dmenufont[]       = "Hack:size=10";
       +static const char col_gray1[]       = "#222222";
       +static const char col_gray2[]       = "#444444";
       +static const char col_gray3[]       = "#bbbbbb";
       +static const char col_gray4[]       = "#eeeeee";
       +static const char col_cyan[]        = "#222222";
       +static const char *colors[][3]      = {
       +        /*               fg         bg         border   */
       +        [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
       +        [SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
       +};
       +
       +
       +/* custom functions */
       +static void togglefullscreen(const Arg *arg);
       +static void bstack(Monitor *m);
       +static void centeredfloatingmaster(Monitor *m);
       +
       +/* custom defines for mouse buttons */
       +/* only 1-5 are defined in X11/X.h */
       +#define Button8 8
       +#define Button9 9
       +
       +/* tagging */
       +static const char *tags[] = { "1", "2", "3", "4", "5" };
       +
       +static Rule rules[] = {
       +        /* class      instance    title       tags mask     isfloating   monitor */
       +        { NULL,       NULL,       NULL,       0,            False,       -1 },
       +};
       +
       +/* layout(s) */
       +static const float mfact     = 0.65;
       +static const int nmaster     = 1;
       +static const int resizehints = 0;
       +
       +static const Layout layouts[] = {
       +        { ">M>",      centeredfloatingmaster },
       +        { "[]=",      tile },
       +        { "TTT",      bstack },
       +        { "><>",      NULL },
       +};
       +
       +#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 SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
       +
       +/* commands */
       +static char dmenumon[2] = "0";
       +static const char *dmenucmd[] = { "dmenu_run", NULL };
       +static const char *termcmd[]  = { "st", NULL };
       +static const char *webcmd[]  = { "firefox", NULL };
       +static const char *ytcmd[]  = { "ytfzf", "-D", NULL };
       +static const char *gamecmd[]  = { "/home/jay/bin/game_select.sh", NULL };
       +static const char *volup[] = { "amixer", "set", "Master", "10%+", NULL };
       +static const char *voldown[] = { "amixer", "set", "Master", "10%-", NULL };
       +
       +
       +static Key keys[] = {
       +        /* modifier                     key        function        argument */
       +        { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
       +        { MODKEY,                       XK_space,  spawn,          {.v = termcmd } },
       +        { MODKEY,                       XK_f,      spawn,          {.v = webcmd } },
       +        { MODKEY,                       XK_y,      spawn,          {.v = ytcmd } },
       +        { MODKEY,                       XK_g,      spawn,          {.v = gamecmd } },
       +        { MODKEY,                       XK_u,      spawn,          {.v = volup } },
       +        { MODKEY,                       XK_d,      spawn,          {.v = voldown } },
       +        { MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
       +        { MODKEY,                       XK_k,      focusstack,     {.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_m,      togglefullscreen, {0} },
       +        { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
       +        { MODKEY,                        XK_comma,  tagmon,         {.i = +1 } },
       +        { MODKEY,                       XK_b,      togglebar,      {0} },
       +        { MODKEY,                       XK_x,      setlayout,      {.v = &layouts[0]} },
       +        { MODKEY|ShiftMask,             XK_x,      setlayout,      {.v = &layouts[1]} },
       +        TAGKEYS(                        XK_1,                      0)
       +        TAGKEYS(                        XK_2,                      1)
       +        TAGKEYS(                        XK_3,                      2)
       +        TAGKEYS(                        XK_4,                      3)
       +        TAGKEYS(                        XK_5,                      4)
       +        { MODKEY|ShiftMask,             XK_q,      quit,           {0} },
       +};
       +
       +/* button definitions */
       +static Button buttons[] = {
       +               { ClkRootWin,        0,              Button8,        spawn,          {.v = voldown } },
       +               { ClkRootWin,        0,              Button9,        spawn,          {.v = volup } },
       +        };
       +
       +void
       +togglefullscreen(const Arg *arg)
       +{
       +        if (!selmon->sel)
       +                return;
       +        setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
       +}
       +
       +static void
       +bstack(Monitor *m) {
       +        int w, h, mh, mx, tx, ty, tw;
       +        unsigned int i, n;
       +        Client *c;
       +
       +        for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
       +        if (n == 0)
       +                return;
       +        if (n > m->nmaster) {
       +                mh = m->nmaster ? m->mfact * m->wh : 0;
       +                tw = m->ww / (n - m->nmaster);
       +                ty = m->wy + mh;
       +        } else {
       +                mh = m->wh;
       +                tw = m->ww;
       +                ty = m->wy;
       +        }
       +        for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
       +                if (i < m->nmaster) {
       +                        w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
       +                        resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0);
       +                        mx += WIDTH(c);
       +                } else {
       +                        h = m->wh - mh;
       +                        resize(c, tx, ty, tw - (2 * c->bw), h - (2 * c->bw), 0);
       +                        if (tw != m->ww)
       +                                tx += WIDTH(c);
       +                }
       +        }
       +}
       +
       +void
       +centeredfloatingmaster(Monitor *m)
       +{
       +        unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
       +        Client *c;
       +
       +        /* count number of clients in the selected monitor */
       +        for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
       +        if (n == 0)
       +                return;
       +
       +        /* initialize nmaster area */
       +        if (n > m->nmaster) {
       +                /* go mfact box in the center if more than nmaster clients */
       +                if (m->ww > m->wh) {
       +                        mw = m->nmaster ? m->ww * m->mfact : 0;
       +                        mh = m->nmaster ? m->wh * 0.9 : 0;
       +                } else {
       +                        mh = m->nmaster ? m->wh * m->mfact : 0;
       +                        mw = m->nmaster ? m->ww * 0.9 : 0;
       +                }
       +                mx = mxo = (m->ww - mw) / 2;
       +                my = myo = (m->wh - mh) / 2;
       +        } else {
       +                /* go fullscreen if all clients are in the master area */
       +                mh = m->wh;
       +                mw = m->ww;
       +                mx = mxo = 0;
       +                my = myo = 0;
       +        }
       +
       +        for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
       +        if (i < m->nmaster) {
       +                /* nmaster clients are stacked horizontally, in the center
       +                 * of the screen */
       +                w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i);
       +                resize(c, m->wx + mx, m->wy + my, w - (2*c->bw),
       +                       mh - (2*c->bw), 0);
       +                mx += WIDTH(c);
       +        } else {
       +                /* stack clients are stacked horizontally */
       +                w = (m->ww - tx) / (n - i);
       +                resize(c, m->wx + tx, m->wy, w - (2*c->bw),
       +                       m->wh - (2*c->bw), 0);
       +                tx += WIDTH(c);
       +        }
       +}
 (DIR) diff --git a/suckless/herbe/Makefile b/suckless/herbe/Makefile
       @@ -0,0 +1,40 @@
       +REPOSITORY = https://github.com/dudik/herbe.git
       +SRC_DIR = src
       +PINNED_REVISION = HEAD
       +PATCH_DIR = patches
       +
       +all: $(SRC_DIR)
       +
       +clean: reset
       +        @if test -d $(SRC_DIR); then \
       +                $(MAKE) -C "${SRC_DIR}" -s clean; \
       +                git -C "${SRC_DIR}" clean -f; \
       +        fi
       +
       +$(SRC_DIR): clone reset
       +        @cp config.h $@
       +        $(MAKE) -C "${SRC_DIR}" -s
       +
       +reset:
       +        @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
       +                git -C "${SRC_DIR}" reset --hard $(PINNED_REVISION); \
       +        fi
       +
       +patch: $(PATCH_DIR)/*
       +        @for file in $^ ; do \
       +                patch -d "${SRC_DIR}" < $${file}; \
       +        done
       +
       +clone:
       +        @if ! test -d $(SRC_DIR); then \
       +                git clone $(REPOSITORY) $(SRC_DIR); \
       +        fi
       +
       +update: clean
       +        @git -C "${SRC_DIR}" pull
       +
       +install:
       +        $(MAKE) -C "${SRC_DIR}" -s install
       +
       +
       +.PHONY: all clean update install reset clone
 (DIR) diff --git a/suckless/herbe/config.h b/suckless/herbe/config.h
       @@ -0,0 +1,19 @@
       +static const char *background_color = "#222222";
       +static const char *border_color = "#008000";
       +static const char *font_color = "#ffd7af";
       +static const char *font_pattern = "Hack:pixelsize=12";
       +static unsigned line_spacing = 5;
       +static unsigned int padding = 12;
       +
       +static unsigned int width = 300;
       +static unsigned int border_size = 3;
       +static unsigned int pos_x = 30;
       +static unsigned int pos_y = 60;
       +
       +enum corners { TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT };
       +enum corners corner = TOP_RIGHT;
       +
       +static unsigned int duration = 5; /* in seconds */
       +
       +#define DISMISS_BUTTON Button1
       +#define ACTION_BUTTON Button3
 (DIR) diff --git a/suckless/st/Makefile b/suckless/st/Makefile
       @@ -0,0 +1,39 @@
       +REPOSITORY = http://git.suckless.org/st
       +SRC_DIR = src
       +PINNED_REVISION = HEAD
       +PATCH_DIR = patches
       +
       +all: $(SRC_DIR)
       +
       +clean: reset
       +        @if test -d $(SRC_DIR); then \
       +                $(MAKE) -C "${SRC_DIR}" -s clean; \
       +                git -C "${SRC_DIR}" clean -f; \
       +        fi
       +
       +$(SRC_DIR): clone reset patch
       +        @cp config.h $@
       +        $(MAKE) -C "${SRC_DIR}" -s
       +
       +patch: $(PATCH_DIR)/*
       +        @for file in $^ ; do \
       +                patch -d "${SRC_DIR}" < $${file}; \
       +        done
       +reset:
       +        @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
       +                git -C "${SRC_DIR}" reset --hard $(PINNED_REVISION); \
       +        fi
       +
       +clone:
       +        @if ! test -d $(SRC_DIR); then \
       +                git clone $(REPOSITORY) $(SRC_DIR); \
       +        fi
       +
       +update: clean
       +        @git -C "${SRC_DIR}" pull
       +
       +install:
       +        $(MAKE) -C "${SRC_DIR}" -s install
       +
       +
       +.PHONY: all clean update install reset clone
 (DIR) diff --git a/suckless/st/config.h b/suckless/st/config.h
       @@ -0,0 +1,476 @@
       +/* See LICENSE file for copyright and license details. */
       +
       +/*
       + * appearance
       + *
       + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
       + */
       +static char *font = "Liberation Mono:pixelsize=18:antialias=true:autohint=true";
       +static int borderpx = 2;
       +
       +/*
       + * 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/sh";
       +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[] = {
       +        /* 8 normal colors */
       +        "black",
       +        "red3",
       +        "green3",
       +        "yellow3",
       +        "blue2",
       +        "magenta3",
       +        "cyan3",
       +        "gray90",
       +
       +        /* 8 bright colors */
       +        "gray50",
       +        "red",
       +        "green",
       +        "yellow",
       +        "#5c5cff",
       +        "magenta",
       +        "cyan",
       +        "white",
       +
       +        [255] = 0,
       +
       +        /* more colors can be added after 255 to use with DefaultXX */
       +        "#cccccc",
       +        "#555555",
       +        "gray90", /* default foreground colour */
       +        "black", /* default background colour */
       +};
       +
       +
       +/*
       + * Default colors (colorname index)
       + * foreground, background, cursor, reverse cursor
       + */
       +unsigned int defaultfg = 258;
       +unsigned int defaultbg = 259;
       +unsigned int defaultcs = 256;
       +static unsigned int defaultrcs = 257;
       +
       +/*
       + * Default shape of cursor
       + * 2: Block ("█")
       + * 4: Underline ("_")
       + * 6: Bar ("|")
       + * 7: Snowman ("☃")
       + */
       +static unsigned int cursorshape = 2;
       +
       +/*
       + * 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;
       +
       +/*
       + * Internal mouse shortcuts.
       + * Beware that overloading Button1 will disable the selection.
       + */
       +static MouseShortcut mshortcuts[] = {
       +        /* mask                 button   function        argument       release */
       +        { 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[P",       -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[P",       -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{|}~";
 (DIR) diff --git a/suckless/st/patches/01-st-scrollback-20210507-4536f46.diff b/suckless/st/patches/01-st-scrollback-20210507-4536f46.diff
       @@ -0,0 +1,351 @@
       +diff --git a/config.def.h b/config.def.h
       +index 6f05dce..93cbcc0 100644
       +--- a/config.def.h
       ++++ b/config.def.h
       +@@ -199,6 +199,8 @@ static Shortcut shortcuts[] = {
       +         { 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} },
       + };
       + 
       + /*
       +diff --git a/st.c b/st.c
       +index ebdf360..817cc47 100644
       +--- a/st.c
       ++++ b/st.c
       +@@ -35,6 +35,7 @@
       + #define ESC_ARG_SIZ   16
       + #define STR_BUF_SIZ   ESC_BUF_SIZ
       + #define STR_ARG_SIZ   ESC_ARG_SIZ
       ++#define HISTSIZE      2000
       + 
       + /* macros */
       + #define IS_SET(flag)                ((term.mode & (flag)) != 0)
       +@@ -42,6 +43,9 @@
       + #define ISCONTROLC1(c)                (BETWEEN(c, 0x80, 0x9f))
       + #define ISCONTROL(c)                (ISCONTROLC0(c) || ISCONTROLC1(c))
       + #define ISDELIM(u)                (u && wcschr(worddelimiters, u))
       ++#define TLINE(y)                ((y) < term.scr ? term.hist[((y) + term.histi - \
       ++                                term.scr + HISTSIZE + 1) % HISTSIZE] : \
       ++                                term.line[(y) - term.scr])
       + 
       + enum term_mode {
       +         MODE_WRAP        = 1 << 0,
       +@@ -115,6 +119,9 @@ typedef struct {
       +         int col;      /* nb col */
       +         Line *line;   /* screen */
       +         Line *alt;    /* alternate screen */
       ++        Line hist[HISTSIZE]; /* history buffer */
       ++        int histi;    /* history index */
       ++        int scr;      /* scroll back */
       +         int *dirty;   /* dirtyness of lines */
       +         TCursor c;    /* cursor */
       +         int ocx;      /* old cursor col */
       +@@ -184,8 +191,8 @@ static void tnewline(int);
       + static void tputtab(int);
       + static void tputc(Rune);
       + static void treset(void);
       +-static void tscrollup(int, int);
       +-static void tscrolldown(int, int);
       ++static void tscrollup(int, int, int);
       ++static void tscrolldown(int, int, int);
       + static void tsetattr(const int *, int);
       + static void tsetchar(Rune, const Glyph *, int, int);
       + static void tsetdirt(int, int);
       +@@ -416,10 +423,10 @@ tlinelen(int y)
       + {
       +         int i = term.col;
       + 
       +-        if (term.line[y][i - 1].mode & ATTR_WRAP)
       ++        if (TLINE(y)[i - 1].mode & ATTR_WRAP)
       +                 return i;
       + 
       +-        while (i > 0 && term.line[y][i - 1].u == ' ')
       ++        while (i > 0 && TLINE(y)[i - 1].u == ' ')
       +                 --i;
       + 
       +         return i;
       +@@ -528,7 +535,7 @@ selsnap(int *x, int *y, int direction)
       +                  * Snap around if the word wraps around at the end or
       +                  * beginning of a line.
       +                  */
       +-                prevgp = &term.line[*y][*x];
       ++                prevgp = &TLINE(*y)[*x];
       +                 prevdelim = ISDELIM(prevgp->u);
       +                 for (;;) {
       +                         newx = *x + direction;
       +@@ -543,14 +550,14 @@ selsnap(int *x, int *y, int direction)
       +                                         yt = *y, xt = *x;
       +                                 else
       +                                         yt = newy, xt = newx;
       +-                                if (!(term.line[yt][xt].mode & ATTR_WRAP))
       ++                                if (!(TLINE(yt)[xt].mode & ATTR_WRAP))
       +                                         break;
       +                         }
       + 
       +                         if (newx >= tlinelen(newy))
       +                                 break;
       + 
       +-                        gp = &term.line[newy][newx];
       ++                        gp = &TLINE(newy)[newx];
       +                         delim = ISDELIM(gp->u);
       +                         if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
       +                                         || (delim && gp->u != prevgp->u)))
       +@@ -571,14 +578,14 @@ selsnap(int *x, int *y, int direction)
       +                 *x = (direction < 0) ? 0 : term.col - 1;
       +                 if (direction < 0) {
       +                         for (; *y > 0; *y += direction) {
       +-                                if (!(term.line[*y-1][term.col-1].mode
       ++                                if (!(TLINE(*y-1)[term.col-1].mode
       +                                                 & ATTR_WRAP)) {
       +                                         break;
       +                                 }
       +                         }
       +                 } else if (direction > 0) {
       +                         for (; *y < term.row-1; *y += direction) {
       +-                                if (!(term.line[*y][term.col-1].mode
       ++                                if (!(TLINE(*y)[term.col-1].mode
       +                                                 & ATTR_WRAP)) {
       +                                         break;
       +                                 }
       +@@ -609,13 +616,13 @@ getsel(void)
       +                 }
       + 
       +                 if (sel.type == SEL_RECTANGULAR) {
       +-                        gp = &term.line[y][sel.nb.x];
       ++                        gp = &TLINE(y)[sel.nb.x];
       +                         lastx = sel.ne.x;
       +                 } else {
       +-                        gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0];
       ++                        gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0];
       +                         lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
       +                 }
       +-                last = &term.line[y][MIN(lastx, linelen-1)];
       ++                last = &TLINE(y)[MIN(lastx, linelen-1)];
       +                 while (last >= gp && last->u == ' ')
       +                         --last;
       + 
       +@@ -850,6 +857,9 @@ void
       + ttywrite(const char *s, size_t n, int may_echo)
       + {
       +         const char *next;
       ++        Arg arg = (Arg) { .i = term.scr };
       ++
       ++        kscrolldown(&arg);
       + 
       +         if (may_echo && IS_SET(MODE_ECHO))
       +                 twrite(s, n, 1);
       +@@ -1061,13 +1071,53 @@ tswapscreen(void)
       + }
       + 
       + void
       +-tscrolldown(int orig, int n)
       ++kscrolldown(const Arg* a)
       ++{
       ++        int n = a->i;
       ++
       ++        if (n < 0)
       ++                n = term.row + n;
       ++
       ++        if (n > term.scr)
       ++                n = term.scr;
       ++
       ++        if (term.scr > 0) {
       ++                term.scr -= n;
       ++                selscroll(0, -n);
       ++                tfulldirt();
       ++        }
       ++}
       ++
       ++void
       ++kscrollup(const Arg* a)
       ++{
       ++        int n = a->i;
       ++
       ++        if (n < 0)
       ++                n = term.row + n;
       ++
       ++        if (term.scr <= HISTSIZE-n) {
       ++                term.scr += n;
       ++                selscroll(0, n);
       ++                tfulldirt();
       ++        }
       ++}
       ++
       ++void
       ++tscrolldown(int orig, int n, int copyhist)
       + {
       +         int i;
       +         Line temp;
       + 
       +         LIMIT(n, 0, term.bot-orig+1);
       + 
       ++        if (copyhist) {
       ++                term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE;
       ++                temp = term.hist[term.histi];
       ++                term.hist[term.histi] = term.line[term.bot];
       ++                term.line[term.bot] = temp;
       ++        }
       ++
       +         tsetdirt(orig, term.bot-n);
       +         tclearregion(0, term.bot-n+1, term.col-1, term.bot);
       + 
       +@@ -1077,17 +1127,28 @@ tscrolldown(int orig, int n)
       +                 term.line[i-n] = temp;
       +         }
       + 
       +-        selscroll(orig, n);
       ++        if (term.scr == 0)
       ++                selscroll(orig, n);
       + }
       + 
       + void
       +-tscrollup(int orig, int n)
       ++tscrollup(int orig, int n, int copyhist)
       + {
       +         int i;
       +         Line temp;
       + 
       +         LIMIT(n, 0, term.bot-orig+1);
       + 
       ++        if (copyhist) {
       ++                term.histi = (term.histi + 1) % HISTSIZE;
       ++                temp = term.hist[term.histi];
       ++                term.hist[term.histi] = term.line[orig];
       ++                term.line[orig] = temp;
       ++        }
       ++
       ++        if (term.scr > 0 && term.scr < HISTSIZE)
       ++                term.scr = MIN(term.scr + n, HISTSIZE-1);
       ++
       +         tclearregion(0, orig, term.col-1, orig+n-1);
       +         tsetdirt(orig+n, term.bot);
       + 
       +@@ -1097,7 +1158,8 @@ tscrollup(int orig, int n)
       +                 term.line[i+n] = temp;
       +         }
       + 
       +-        selscroll(orig, -n);
       ++        if (term.scr == 0)
       ++                selscroll(orig, -n);
       + }
       + 
       + void
       +@@ -1126,7 +1188,7 @@ tnewline(int first_col)
       +         int y = term.c.y;
       + 
       +         if (y == term.bot) {
       +-                tscrollup(term.top, 1);
       ++                tscrollup(term.top, 1, 1);
       +         } else {
       +                 y++;
       +         }
       +@@ -1291,14 +1353,14 @@ void
       + tinsertblankline(int n)
       + {
       +         if (BETWEEN(term.c.y, term.top, term.bot))
       +-                tscrolldown(term.c.y, n);
       ++                tscrolldown(term.c.y, n, 0);
       + }
       + 
       + void
       + tdeleteline(int n)
       + {
       +         if (BETWEEN(term.c.y, term.top, term.bot))
       +-                tscrollup(term.c.y, n);
       ++                tscrollup(term.c.y, n, 0);
       + }
       + 
       + int32_t
       +@@ -1735,11 +1797,11 @@ csihandle(void)
       +                 break;
       +         case 'S': /* SU -- Scroll <n> line up */
       +                 DEFAULT(csiescseq.arg[0], 1);
       +-                tscrollup(term.top, csiescseq.arg[0]);
       ++                tscrollup(term.top, csiescseq.arg[0], 0);
       +                 break;
       +         case 'T': /* SD -- Scroll <n> line down */
       +                 DEFAULT(csiescseq.arg[0], 1);
       +-                tscrolldown(term.top, csiescseq.arg[0]);
       ++                tscrolldown(term.top, csiescseq.arg[0], 0);
       +                 break;
       +         case 'L': /* IL -- Insert <n> blank lines */
       +                 DEFAULT(csiescseq.arg[0], 1);
       +@@ -2251,7 +2313,7 @@ eschandle(uchar ascii)
       +                 return 0;
       +         case 'D': /* IND -- Linefeed */
       +                 if (term.c.y == term.bot) {
       +-                        tscrollup(term.top, 1);
       ++                        tscrollup(term.top, 1, 1);
       +                 } else {
       +                         tmoveto(term.c.x, term.c.y+1);
       +                 }
       +@@ -2264,7 +2326,7 @@ eschandle(uchar ascii)
       +                 break;
       +         case 'M': /* RI -- Reverse index */
       +                 if (term.c.y == term.top) {
       +-                        tscrolldown(term.top, 1);
       ++                        tscrolldown(term.top, 1, 1);
       +                 } else {
       +                         tmoveto(term.c.x, term.c.y-1);
       +                 }
       +@@ -2474,7 +2536,7 @@ twrite(const char *buf, int buflen, int show_ctrl)
       + void
       + tresize(int col, int row)
       + {
       +-        int i;
       ++        int i, j;
       +         int minrow = MIN(row, term.row);
       +         int mincol = MIN(col, term.col);
       +         int *bp;
       +@@ -2511,6 +2573,14 @@ tresize(int col, int row)
       +         term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
       +         term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
       + 
       ++        for (i = 0; i < HISTSIZE; i++) {
       ++                term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph));
       ++                for (j = mincol; j < col; j++) {
       ++                        term.hist[i][j] = term.c.attr;
       ++                        term.hist[i][j].u = ' ';
       ++                }
       ++        }
       ++
       +         /* resize each row to new width, zero-pad if needed */
       +         for (i = 0; i < minrow; i++) {
       +                 term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
       +@@ -2569,7 +2639,7 @@ drawregion(int x1, int y1, int x2, int y2)
       +                         continue;
       + 
       +                 term.dirty[y] = 0;
       +-                xdrawline(term.line[y], x1, y, x2);
       ++                xdrawline(TLINE(y), x1, y, x2);
       +         }
       + }
       + 
       +@@ -2590,8 +2660,9 @@ draw(void)
       +                 cx--;
       + 
       +         drawregion(0, 0, term.col, term.row);
       +-        xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
       +-                        term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
       ++        if (term.scr == 0)
       ++                xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
       ++                                term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
       +         term.ocx = cx;
       +         term.ocy = term.c.y;
       +         xfinishdraw();
       +diff --git a/st.h b/st.h
       +index fa2eddf..adda2db 100644
       +--- a/st.h
       ++++ b/st.h
       +@@ -81,6 +81,8 @@ void die(const char *, ...);
       + void redraw(void);
       + void draw(void);
       + 
       ++void kscrolldown(const Arg *);
       ++void kscrollup(const Arg *);
       + void printscreen(const Arg *);
       + void printsel(const Arg *);
       + void sendbreak(const Arg *);
 (DIR) diff --git a/suckless/st/patches/02-st-w3m-hack.diff b/suckless/st/patches/02-st-w3m-hack.diff
       @@ -0,0 +1,12 @@
       +diff --git a/x.c b/x.c
       +index e5f1737..b6ae162 100644
       +--- a/x.c
       ++++ b/x.c
       +@@ -1594,6 +1594,8 @@ xsettitle(char *p)
       + int
       + xstartdraw(void)
       + {
       ++        if (IS_SET(MODE_VISIBLE))
       ++                XCopyArea(xw.dpy, xw.win, xw.buf, dc.gc, 0, 0, win.w, win.h, 0, 0);
       +         return IS_SET(MODE_VISIBLE);
       + }