dwm

Mahdi's build of dwm
git clone git://mahdi.pw/dwm.git
Log | Files | Refs | README | LICENSE

commit a3bffe3022e88d7d085f962bad2a4586840ff4cb
parent 2f2814df7f210e9048fe94a3914d0d6e8f3dba9f
Author: Mahdi Mirzade <me@mahdi.pw>
Date:   Sun, 22 May 2022 19:26:03 +0430

Lighten the build, other changes

Diffstat:
MMakefile | 5+++--
Mconfig.h | 163++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mconfig.mk | 3+--
Mdrw.c | 11++++++-----
Mdwm.c | 413+++++++++++++++++++++----------------------------------------------------------
Dpatches/dwm-gaplessgrid-20160731-56a31dc.diff | 43-------------------------------------------
Dpatches/dwm-swallow-20201211-61bb8b2.diff | 412-------------------------------------------------------------------------------
Dpatches/dwm-underlinetags-6.2.diff | 27---------------------------
8 files changed, 199 insertions(+), 878 deletions(-)

diff --git a/Makefile b/Makefile @@ -43,8 +43,9 @@ install: all mkdir -p ${DESTDIR}${MANPREFIX}/man1 sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 - mkdir -p $(DESTDIR)$(PREFIX)/share/xsessions - cp -f dwm.desktop $(DESTDIR)$(PREFIX)/share/xsessions + mkdir -p /usr/share/xsessions + cp -f dwm.desktop /usr/share/xsessions + chmod 644 /usr/share/xsessions/dwm.desktop uninstall: rm -f ${DESTDIR}${PREFIX}/bin/dwm\ diff --git a/config.h b/config.h @@ -4,23 +4,23 @@ #include <X11/XF86keysym.h> /* For XF86 multimedia binds */ /* appearance */ -static const char *fonts[] = { "monospace:size=8", "Vazir:size=8" }; +static const char *fonts[] = { "monospace:size=9", "Vazir:size=9" }; static const unsigned int borderpx = 0; /* border pixel of windows */ -static const unsigned int gappx = 5; /* gaps between windows */ +static const unsigned int gappx = 10; /* gaps between windows */ static const unsigned int snap = 32; /* snap pixel */ -static const unsigned int systraypinning= 0; /* 0: sloppy systray follows selected monitor, 0: pin systray to monitor X */ -static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */ +static const unsigned int systraypinning= 1; /* 0: sloppy systray follows selected monitor, 1: pin systray to monitor X */ +static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, 1: systray on left of status text */ +static const unsigned int systraypadding= 0; /* systray vertical padding */ static const unsigned int systrayspacing= 2; /* systray spacing */ -static const int systraypinningfailfirst= 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -static const int showsystray = 1; /* 0 means no systray */ -static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ +static const int systraypinningfailfirst= 1; /* 1: if pinning fails, display systray on the first monitor, 0: display systray on the last monitor*/ +static const int showsystray = 0; /* 0 means no systray */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ -static const int barheight = 20; /* 0 means that dwm will calculate bar height, >= 1 means dwm will barheight as bar height */ +static const int barheight = 3; /* Spacing around the bar's font */ static const int hidevacanttags = 1; /* 1 means hide empty tags / 0: show every tag */ static const int hidetagindicator = 1; /* 1 means hide default top-left square-shaped tag indicator */ -static const int centeredwindowname = 0; /* 1 means center the WM_NAME of the currently selected window on the status bar */ -static const unsigned int colorfultag = 1; /* 0 means use SchemeSel for selected tag */ +static const int truecenteredtitle = 0; /* 1 means center the WM_NAME of the currently selected window on the status bar */ +static const unsigned int colorfultag = 0; /* 0 means use SchemeSel for selected tag */ static char fgcolor[] = "#D8DEE9"; static char bgcolor[] = "#2E3440"; static char color0[] = "#3B4252"; @@ -41,74 +41,74 @@ static char color14[] = "#8FBCBB"; static char color15[] = "#ECEFF4"; static const char *colors[][3] = { /* fg bg border */ - [SchemeNorm] = { color7, bgcolor, bgcolor }, - [SchemeSel] = { fgcolor, color0, color0 }, - [SchemeTag] = { color0, bgcolor, bgcolor }, - [SchemeTag1] = { color1, bgcolor, bgcolor }, - [SchemeTag2] = { color2, bgcolor, bgcolor }, - [SchemeTag3] = { color3, bgcolor, bgcolor }, - [SchemeTag4] = { color4, bgcolor, bgcolor }, - [SchemeTag5] = { color5, bgcolor, bgcolor }, - [SchemeTag6] = { color6, bgcolor, bgcolor }, - [SchemeTag7] = { color9, bgcolor, bgcolor }, - [SchemeTag8] = { color10, bgcolor, bgcolor }, - [SchemeTag9] = { color11, bgcolor, bgcolor }, - [SchemeLayout] = { color14, bgcolor, bgcolor }, - + [SchemeNorm] = { color12, color0, color8 }, + [SchemeSel] = { color0, color12, color12 }, + [SchemeLayout] = { color12, color0, color8 }, }; +/* if colorfultag == 1: */ +static const char *colortags[][2] = { + { color1, color0 }, + { color2, color0 }, + { color3, color0 }, + { color4, color0 }, + { color5, color0 }, + { color6, color0 }, + { color9, color0 }, + { color10, color0 }, + { color11, color0 }, +}; +//static const char *colortags_sel[][2] = { +// { color1, color8 }, +// { color2, color8 }, +// { color3, color8 }, +// { color4, color8 }, +// { color5, color8 }, +// { color6, color8 }, +// { color9, color8 }, +// { color10, color8 }, +// { color11, color8 }, +//}; +static const char *colortags_sel[][2] = { + { color0, color1 }, + { color0, color2 }, + { color0, color3 }, + { color0, color4 }, + { color0, color5 }, + { color0, color6 }, + { color0, color9 }, + { color0, color10 }, + { color0, color11 }, +}; /* tagging */ static const char *tags[] = { "𐎠", "𐎡", "𐎢", "𐎣", "𐎤", "𐎥", "𐎦", "𐎧", "𐎨" }; //static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -static const int tagschemes[] = { SchemeTag1, SchemeTag2, SchemeTag3, - SchemeTag4, SchemeTag5, SchemeTag6, - SchemeTag7, SchemeTag8, SchemeTag9, -}; - -static const char *tagsel[][2] = { - { color1, bgcolor }, - { color2, bgcolor }, - { color3, bgcolor }, - { color4, bgcolor }, - { color5, bgcolor }, - { color6, bgcolor }, - { color9, bgcolor }, - { color10, bgcolor }, - { color11, bgcolor }, -}; - -static const unsigned int ulinepad = 5; /* horizontal padding between the underline and tag */ -static const unsigned int ulinestroke = 1; /* thickness / height of the underline */ -static const unsigned int ulinevoffset = 1; /* how far above the bottom of the bar the line should appear */ -static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ - static const Rule rules[] = { /* xprop(1): * WM_CLASS(STRING) = instance, class * WM_NAME(STRING) = title */ - /* class instance title tags mask isfloating isterminal noswallow monitor */ - { "mpv", NULL, NULL, 0, 1, 0, 0, -1 }, - { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, - { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 }, - { "st-float", NULL, NULL, 0, 1, 1, 0, -1 }, - { "st-256color",NULL, NULL, 0, 0, 1, 0, -1 }, - { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ + /* class instance title tags mask isfloating monitor */ + //{ "mpv", NULL, NULL, 0, 1, -1 }, + //{ "Gimp", NULL, NULL, 0, 1, -1 }, + //{ "Firefox", NULL, NULL, 1 << 8, 0, -1 }, + { "st-float", NULL, NULL, 0, 1, -1 }, + { NULL, "st-float", NULL, 0, 1, -1 }, + { NULL, NULL, "Event Tester", 0, 0, -1 }, /* xev */ }; /* layout(s) */ -static const float mfact = 0.5; /* 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 */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ +static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ //static const Layout layouts[] = { // /* symbol arrange function */ // { "Tile", tile }, /* first entry is default */ // { "Monocle", monocle }, -// { "Grid", grid }, // { "Float", NULL }, /* no layout function means floating behavior */ // { NULL, NULL }, //}; @@ -117,7 +117,6 @@ static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, /* first entry is default */ { "[M]", monocle }, - { ":::", grid }, { "><>", NULL }, /* no layout function means floating behavior */ { NULL, NULL }, }; @@ -138,9 +137,11 @@ static const Layout layouts[] = { /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-i", "-c", "-l", "20", "-bw", "4", NULL }; -static const char *termcmd[] = { "tabbed", "-c", "-r", "2", "st", "-w", "''", NULL }; -static const char *termcmdfloat[] = { "st", "-c", "st-float", NULL }; +static const char *dmenucmd[] = { "dmenu_run", "-i", "-p", "Run:", NULL }; +//static const char *termcmd[] = { "st", NULL }; +//static const char *termcmdfloat[] = { "st", "-c", "st-float", NULL }; +static const char *termcmd[] = { "tabbed", "-cd", "-r", "2", "st", "-w", "''", NULL }; +static const char *termcmdfloat[] = { "tabbed", "-cd", "-n", "st-float", "-r", "2", "st", "-w", "''", NULL }; static Key keys[] = { /* modifier key function argument */ @@ -148,7 +149,7 @@ static Key keys[] = { { MODKEY, XK_c, spawn, {.v = dmenucmd } }, { MODKEY, XK_Return, spawn, {.v = termcmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmdfloat } }, - { MODKEY|ShiftMask, XK_b, spawn, SHCMD("dmenu_bar") }, + { MODKEY|ShiftMask, XK_b, spawn, SHCMD("dwm_bar -M") }, { MODKEY, XK_b, togglebar, {0} }, { MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } }, @@ -160,11 +161,9 @@ static Key keys[] = { { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, { MODKEY, XK_space, zoom, {0} }, { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XK_m, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_g, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[3]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[2]} }, { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } }, { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } }, { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, @@ -191,15 +190,19 @@ static Key keys[] = { TAGKEYS( XK_7, 6) TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_r, quit, {1} }, - { MODKEY|ShiftMask, XK_q, quit, {0} }, - { MODKEY, XK_q, spawn, SHCMD("powermenu") }, + { MODKEY|ShiftMask, XK_r, restart, {0} }, + { MODKEY, XK_q, killclient, {0} }, + { MODKEY|ControlMask, XK_q, quit, {0} }, + { MODKEY|ShiftMask, XK_q, spawn, SHCMD("powermenu") }, { MODKEY, XK_r, spawn, SHCMD("dmenurecord") }, { MODKEY, XK_w, spawn, SHCMD("surf-open") }, - //{ MODKEY|ControlMask, XK_w, spawn, SHCMD("qutebrowser \":open -p\"") }, - { MODKEY|ShiftMask, XK_m, spawn, SHCMD("dmenu_mpd") }, - { MODKEY|ShiftMask, XK_w, spawn, SHCMD("st -c \"st-float\" -g \"100x20\" -e sh -c \"set-bg -s\"") }, + { MODKEY|ControlMask, XK_w, spawn, SHCMD("surf") }, + { MODKEY|ShiftMask, XK_m, spawn, SHCMD("dmenu_man") }, + { MODKEY|ShiftMask, XK_w, spawn, SHCMD("st -c \"st-float\" -g \"100x20\" -e sh -c \"SET_BG_SELECT=1 set-bg\"") }, + { MODKEY|ShiftMask, XK_u, spawn, SHCMD("update") }, { MODKEY|ShiftMask, XK_t, spawn, SHCMD("set-theme -s") }, + { MODKEY|ShiftMask, XK_g, spawn, SHCMD("gtt") }, + { MODKEY|ShiftMask, XK_y, spawn, SHCMD("myt -d") }, { MODKEY|ControlMask, XK_l, spawn, SHCMD("lock") }, { MODKEY, XK_grave, spawn, SHCMD("emoji insert") }, { ControlMask, XK_grave, spawn, SHCMD("emoji clipboard") }, @@ -216,8 +219,8 @@ static Key keys[] = { { ShiftMask, XF86XK_AudioPause, spawn, SHCMD("media-controller pause-all") }, { ShiftMask, XF86XK_AudioNext, spawn, SHCMD("media-controller seek-fwd") }, { ShiftMask, XF86XK_AudioPrev, spawn, SHCMD("media-controller seek-bwd") }, - { 0, XF86XK_MonBrightnessUp, spawn, SHCMD("backlight up") }, - { 0, XF86XK_MonBrightnessDown, spawn, SHCMD("backlight down") }, + { 0, XF86XK_MonBrightnessUp, spawn, SHCMD("bl -i") }, + { 0, XF86XK_MonBrightnessDown, spawn, SHCMD("bl -d") }, { 0, XF86XK_AudioRaiseVolume, spawn, SHCMD("volume up") }, { 0, XF86XK_AudioLowerVolume, spawn, SHCMD("volume down") }, { 0, XF86XK_AudioMute, spawn, SHCMD("volume mute") }, @@ -239,8 +242,8 @@ static Button buttons[] = { * into a floating position). */ { ClkClientWin, MODKEY, Button1, moveorplace, {.i = 1} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkTagBar, 0, Button1, view, {0} }, { ClkTagBar, 0, Button3, toggleview, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} }, @@ -248,13 +251,11 @@ static Button buttons[] = { { ClkTagBar, 0, Button4, shiftview, {.i = -1} }, { ClkTagBar, 0, Button5, shiftview, {.i = +1} }, { ClkLtSymbol, 0, Button1, cyclelayout, {.i = +1} }, - { ClkLtSymbol, 0, Button2, setlayout, {.v = &layouts[0]} }, { ClkLtSymbol, 0, Button3, cyclelayout, {.i = -1} }, + { ClkLtSymbol, 0, Button2, setlayout, {.v = &layouts[0]} }, { ClkLtSymbol, 0, Button4, cyclelayout, {.i = -1} }, { ClkLtSymbol, 0, Button5, cyclelayout, {.i = +1} }, - { ClkWinTitle, 0, Button1, zoom, {0} }, - { ClkWinTitle, 0, Button2, spawn, {.v = termcmd} }, - { ClkWinTitle, 0, Button3, togglesticky, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkStatusText, 0, Button3, spawn, SHCMD("dmenu_bar") }, + { ClkWinTitle, 0, Button2, togglesticky, {0} }, + { ClkStatusText, 0, Button3, spawn, SHCMD("dwm_bar -M") }, }; + diff --git a/config.mk b/config.mk @@ -21,13 +21,12 @@ FREETYPELIBS = -lfontconfig -lXft FREETYPEINC = /usr/include/freetype2 # OpenBSD (uncomment) #FREETYPEINC = ${X11INC}/freetype2 -#KVMLIB = -lkvm BDLIBS = -lfribidi # includes and libs INCS = -I${X11INC} -I${FREETYPEINC} -I$(BDINC) -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} $(BDLIBS) -lX11-xcb -lxcb -lxcb-res ${KVMLIB} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} $(BDLIBS) # flags CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/drw.c b/drw.c @@ -140,11 +140,11 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) * 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; - //} + 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; @@ -434,3 +434,4 @@ drw_cur_free(Drw *drw, Cur *cursor) XFreeCursor(drw->dpy, cursor->cursor); free(cursor); } + diff --git a/dwm.c b/dwm.c @@ -42,12 +42,6 @@ #endif /* XINERAMA */ #include <X11/Xft/Xft.h> #include <fribidi.h> -#include <X11/Xlib-xcb.h> -#include <xcb/res.h> -#ifdef __OpenBSD__ -#include <sys/sysctl.h> -#include <kvm.h> -#endif /* __OpenBSD */ #include "drw.h" #include "util.h" @@ -97,11 +91,11 @@ /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel, SchemeTag, SchemeTag1, SchemeTag2, SchemeTag3, SchemeTag4, SchemeTag5, SchemeTag6, SchemeTag7, SchemeTag8, SchemeTag9, SchemeLayout }; /* color schemes */ +enum { SchemeNorm, SchemeSel, SchemeLayout }; /* color schemes */ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ + NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetLast }; /* EWMH atoms */ enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, @@ -132,11 +126,10 @@ struct Client { int basew, baseh, incw, inch, maxw, maxh, minw, minh; int bw, oldbw; unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky, isterminal, noswallow, beingmoved; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky, beingmoved; pid_t pid; Client *next; Client *snext; - Client *swallowing; Monitor *mon; Window win; }; @@ -182,8 +175,6 @@ typedef struct { const char *title; unsigned int tags; int isfloating; - int isterminal; - int noswallow; int monitor; } Rule; @@ -236,6 +227,7 @@ static void detach(Client *c); static void detachstack(Client *c); static void drawbar(Monitor *m); static void drawbars(void); +static int drawstatusbar(Monitor *m, int bh, char* text); static void enternotify(XEvent *e); static void expose(XEvent *e); static void focus(Client *c); @@ -245,7 +237,6 @@ static void focusnthmon(const Arg *arg); static void focusstack(const Arg *arg); static void grabbuttons(Client *c, int focused); static void grabkeys(void); -static void grid(Monitor *m); static void incnmaster(const Arg *arg); static void keypress(XEvent *e); static void killclient(const Arg *arg); @@ -261,6 +252,7 @@ static void movestack(const Arg *arg); static void placemouse(const Arg *arg); static void pop(Client *); static void propertynotify(XEvent *e); +static void restart(const Arg *arg); static void quit(const Arg *arg); static void removesystrayicon(Client *i); static void resize(Client *c, int x, int y, int w, int h, int interact); @@ -273,6 +265,7 @@ static void run(void); static void scan(void); static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); +static void setclienttagprop(Client *c); static void setfocus(Client *c); static void setfullscreen(Client *c, int fullscreen); static void setgaps(const Arg *arg); @@ -286,6 +279,7 @@ static void sigchld(int unused); static void sighup(int unused); static void sigterm(int unused); static void spawn(const Arg *arg); +static Monitor *systraytomon(Monitor *m); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tagnthmon(const Arg *arg); @@ -316,12 +310,6 @@ static void warp(const Client *c); static void xrdb(const Arg *arg); static void zoom(const Arg *arg); -static pid_t getparentprocess(pid_t p); -static int isdescprocess(pid_t p, pid_t c); -static Client *swallowingclient(Window w); -static Client *termforwin(const Client *c); -static pid_t winpid(Window w); - /* variables */ static Systray *systray = NULL; static const char broken[] = "broken"; @@ -351,18 +339,17 @@ static void (*handler[LASTEvent]) (XEvent *) = { [UnmapNotify] = unmapnotify }; static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; -static int restart = 0; +static int restartsig = 0; static int running = 1; static Cur *cursor[CurLast]; static Clr **scheme; static Clr **tagscheme; +static Clr **tagscheme_sel; static Display *dpy; static Drw *drw; static Monitor *mons, *selmon; static Window root, wmcheckwin; -static xcb_connection_t *xcon; - /* configuration, allows nested code to access above variables */ #include "config.h" @@ -379,7 +366,7 @@ apply_fribidi(const char *str) FriBidiParType base = FRIBIDI_PAR_ON; FriBidiCharSet charset; fribidi_boolean result; - + fribidi_text[0] = 0; if (len>0) { @@ -412,8 +399,6 @@ applyrules(Client *c) && (!r->class || strstr(class, r->class)) && (!r->instance || strstr(instance, r->instance))) { - c->isterminal = r->isterminal; - c->noswallow = r->noswallow; c->isfloating = r->isfloating; c->tags |= r->tags; for (m = mons; m && m->num != r->monitor; m = m->next); @@ -540,53 +525,6 @@ attachstack(Client *c) } void -swallow(Client *p, Client *c) -{ - - if (c->noswallow || c->isterminal) - return; - if (c->noswallow && !swallowfloating && c->isfloating) - return; - - detach(c); - detachstack(c); - - setclientstate(c, WithdrawnState); - XUnmapWindow(dpy, p->win); - - p->swallowing = c; - c->mon = p->mon; - - Window w = p->win; - p->win = c->win; - c->win = w; - updatetitle(p); - XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); - arrange(p->mon); - configure(p); - updateclientlist(); -} - -void -unswallow(Client *c) -{ - c->win = c->swallowing->win; - - free(c->swallowing); - c->swallowing = NULL; - - /* unfullscreen the client */ - setfullscreen(c, 0); - updatetitle(c); - arrange(c->mon); - XMapWindow(dpy, c->win); - XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); - setclientstate(c, NormalState); - focus(NULL); - arrange(c->mon); -} - -void buttonpress(XEvent *e) { unsigned int i, x, click; @@ -907,8 +845,6 @@ destroynotify(XEvent *e) if ((c = wintoclient(ev->window))) unmanage(c, 1); - else if ((c = swallowingclient(ev->window))) - unmanage(c->swallowing, 1); else if ((c = wintosystrayicon(ev->window))) { removesystrayicon(c); resizebarwin(selmon); @@ -992,7 +928,7 @@ drawstatusbar(Monitor *m, int bh, char* stext) { isCode = 0; text = p; - w += 2; /* 1px padding on both sides */ + w += systraypadding * 2; /* Xpx padding on both sides */ ret = m->ww - w; x = m->ww - w - getsystraywidth(); @@ -1111,14 +1047,14 @@ drawbar(Monitor *m) if (hidevacanttags) /* Do not draw vacant tags */ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) continue; if (colorfultag) - drw_setscheme(drw, scheme[occ & 1 << i ? (m->colorfultag ? tagschemes[i] : SchemeSel) : SchemeTag]); + //drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : scheme[SchemeNorm])); + //drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme_sel[i] : tagscheme[i])); + drw_setscheme(drw, (occ & 1 << i ? (m->tagset[m->seltags] & 1 << i ? tagscheme_sel[i] : tagscheme[i]) : scheme[SchemeNorm])); else drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); apply_fribidi(tags[i]); w = TEXTW(fribidi_text); drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, urg & 1 << i); - if (ulineall || m->tagset[m->seltags] & 1 << i) /* if there are conflicts, just move these lines directly underneath both 'drw_setscheme' and 'drw_text' :) */ - drw_rect(drw, x + ulinepad, bh - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0); if (!hidetagindicator) /* Do not draw top-left tag indicators */ if (occ & 1 << i) drw_rect(drw, x + boxs, boxs, boxw, boxw, @@ -1135,14 +1071,13 @@ drawbar(Monitor *m) if (m->sel) { drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); apply_fribidi(m->sel->name); - /* fix overflow when window name is bigger than window width */ - int mid = (m->ww - (int)TEXTW(fribidi_text)) / 2 - x; - /* make sure name will not overlap on tags even when it is very long */ - mid = mid >= lrpad / 2 ? mid : lrpad / 2; - if (!centeredwindowname) - mid = lrpad / 2; + int mid = lrpad / 2; + if (truecenteredtitle) + if (TEXTW(fribidi_text) <= w) + mid = (w - TEXTW(fribidi_text)) / 2; + //mid = lrpad / 2; drw_text(drw, x, 0, w, bh, mid, fribidi_text, 0); - if (m->sel->isfloating) + if (m->sel->isfloating && !hidetagindicator) drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); } else { drw_setscheme(drw, scheme[SchemeNorm]); @@ -1547,13 +1482,12 @@ loadxrdb() void manage(Window w, XWindowAttributes *wa) { - Client *c, *t = NULL, *term = NULL; + Client *c, *t = NULL; Window trans = None; XWindowChanges wc; c = ecalloc(1, sizeof(Client)); c->win = w; - c->pid = winpid(w); /* geometry */ c->x = c->oldx = wa->x; c->y = c->oldy = wa->y; @@ -1568,7 +1502,6 @@ manage(Window w, XWindowAttributes *wa) } else { c->mon = selmon; applyrules(c); - term = termforwin(c); } if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) @@ -1588,6 +1521,26 @@ manage(Window w, XWindowAttributes *wa) updatewindowtype(c); updatesizehints(c); updatewmhints(c); + { + int format; + unsigned long *data, n, extra; + Monitor *m; + Atom atom; + if (XGetWindowProperty(dpy, c->win, netatom[NetClientInfo], 0L, 2L, False, XA_CARDINAL, + &atom, &format, &n, &extra, (unsigned char **)&data) == Success && n == 2) { + c->tags = *data; + for (m = mons; m; m = m->next) { + if (m->num == *(data+1)) { + c->mon = m; + break; + } + } + } + if (n > 0) + XFree(data); + } + setclienttagprop(c); + c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2; c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2; XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); @@ -1598,6 +1551,7 @@ manage(Window w, XWindowAttributes *wa) XRaiseWindow(dpy, c->win); attachbottom(c); attachstack(c); + setclienttagprop(c); XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, (unsigned char *) &(c->win), 1); XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ @@ -1607,8 +1561,6 @@ manage(Window w, XWindowAttributes *wa) c->mon->sel = c; arrange(c->mon); XMapWindow(dpy, c->win); - if (term) - swallow(term, c); focus(NULL); } @@ -1659,42 +1611,6 @@ monocle(Monitor *m) } void -grid(Monitor *m) { - unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; - Client *c; - - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) ; - if(n == 0) - return; - - /* grid dimensions */ - for(cols = 0; cols <= n/2; cols++) - if(cols*cols >= n) - break; - if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ - cols = 2; - rows = n/cols; - - /* window geometries */ - cw = cols ? m->ww / cols : m->ww; - cn = 0; /* current column number */ - rn = 0; /* current row number */ - for(i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { - if(i/rows + 1 > cols - n%cols) - rows = n/cols + 1; - ch = rows ? m->wh / rows : m->wh; - cx = m->wx + cn*cw; - cy = m->wy + rn*ch; - resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); - rn++; - if(rn >= rows) { - rn = 0; - cn++; - } - } -} - -void motionnotify(XEvent *e) { static Monitor *mon = NULL; @@ -1977,9 +1893,15 @@ propertynotify(XEvent *e) } void +restart(const Arg *arg) +{ + restartsig = 1; + quit(arg); +} + +void quit(const Arg *arg) { - if(arg->i) restart = 1; running = 0; } @@ -2364,8 +2286,7 @@ setup(void) if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); lrpad = drw->fonts->h; - //bh = drw->fonts->h + 2; - bh = barheight ? barheight : drw->fonts->h + 2; + bh = drw->fonts->h + barheight * 2; updategeom(); /* init atoms */ utf8string = XInternAtom(dpy, "UTF8_STRING", False); @@ -2386,6 +2307,7 @@ setup(void) netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False); xatom[Manager] = XInternAtom(dpy, "MANAGER", False); xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); @@ -2394,15 +2316,20 @@ setup(void) cursor[CurResize] = drw_cur_create(drw, XC_sizing); cursor[CurMove] = drw_cur_create(drw, XC_fleur); /* init appearance */ - if (LENGTH(tags) > LENGTH(tagsel)) - die("too few color schemes for the tags"); + if (colorfultag) { + if (LENGTH(tags) > LENGTH(colortags) || LENGTH(tags) > LENGTH(colortags_sel)) + die("too few color schemes for the tags"); + tagscheme = ecalloc(LENGTH(colortags), sizeof(Clr *)); + for (i = 0; i < LENGTH(colortags); i++) + tagscheme[i] = drw_scm_create(drw, colortags[i], 2); + tagscheme_sel = ecalloc(LENGTH(colortags_sel), sizeof(Clr *)); + for (i = 0; i < LENGTH(colortags_sel); i++) + tagscheme_sel[i] = drw_scm_create(drw, colortags_sel[i], 2); + } scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); for (i = 0; i < LENGTH(colors); i++) scheme[i] = drw_scm_create(drw, colors[i], 3); - tagscheme = ecalloc(LENGTH(tagsel), sizeof(Clr *)); - for (i = 0; i < LENGTH(tagsel); i++) - tagscheme[i] = drw_scm_create(drw, tagsel[i], 2); /* init system tray */ updatesystray(); /* init bars */ @@ -2420,6 +2347,7 @@ setup(void) XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, PropModeReplace, (unsigned char *) netatom, NetLast); XDeleteProperty(dpy, root, netatom[NetClientList]); + XDeleteProperty(dpy, root, netatom[NetClientInfo]); /* select events */ wa.cursor = cursor[CurNormal]->cursor; wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask @@ -2502,10 +2430,22 @@ spawn(const Arg *arg) } void +setclienttagprop(Client *c) +{ + long data[] = { (long) c->tags, (long) c->mon->num }; + XChangeProperty(dpy, c->win, netatom[NetClientInfo], XA_CARDINAL, 32, + PropModeReplace, (unsigned char *) data, 2); +} + + +void tag(const Arg *arg) { + Client *c; if (selmon->sel && arg->ui & TAGMASK) { + c = selmon->sel; selmon->sel->tags = arg->ui & TAGMASK; + setclienttagprop(c); focus(NULL); arrange(selmon); } @@ -2615,6 +2555,7 @@ toggletag(const Arg *arg) newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); if (newtags) { selmon->sel->tags = newtags; + setclienttagprop(selmon->sel); focus(NULL); arrange(selmon); } @@ -2651,20 +2592,6 @@ unmanage(Client *c, int destroyed) Monitor *m = c->mon; XWindowChanges wc; - if (c->swallowing) { - unswallow(c); - return; - } - - Client *s = swallowingclient(c->win); - if (s) { - free(s->swallowing); - s->swallowing = NULL; - arrange(m); - focus(NULL); - return; - } - detach(c); detachstack(c); if (!destroyed) { @@ -2679,12 +2606,9 @@ unmanage(Client *c, int destroyed) XUngrabServer(dpy); } free(c); - - if (!s) { - arrange(m); - focus(NULL); - updateclientlist(); - } + focus(NULL); + updateclientlist(); + arrange(m); } void @@ -3079,136 +3003,6 @@ view(const Arg *arg) arrange(selmon); } -pid_t -winpid(Window w) -{ - - pid_t result = 0; - -#ifdef __linux__ - xcb_res_client_id_spec_t spec = {0}; - spec.client = w; - spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; - - xcb_generic_error_t *e = NULL; - xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); - xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); - - if (!r) - return (pid_t)0; - - xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); - for (; i.rem; xcb_res_client_id_value_next(&i)) { - spec = i.data->spec; - if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { - uint32_t *t = xcb_res_client_id_value_value(i.data); - result = *t; - break; - } - } - - free(r); - - if (result == (pid_t)-1) - result = 0; - -#endif /* __linux__ */ - -#ifdef __OpenBSD__ - Atom type; - int format; - unsigned long len, bytes; - unsigned char *prop; - pid_t ret; - - if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 0), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop) - return 0; - - ret = *(pid_t*)prop; - XFree(prop); - result = ret; - -#endif /* __OpenBSD__ */ - return result; -} - -pid_t -getparentprocess(pid_t p) -{ - unsigned int v = 0; - -#ifdef __linux__ - FILE *f; - char buf[256]; - snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); - - if (!(f = fopen(buf, "r"))) - return 0; - - fscanf(f, "%*u %*s %*c %u", &v); - fclose(f); -#endif /* __linux__*/ - -#ifdef __OpenBSD__ - int n; - kvm_t *kd; - struct kinfo_proc *kp; - - kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL); - if (!kd) - return 0; - - kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n); - v = kp->p_ppid; -#endif /* __OpenBSD__ */ - - return (pid_t)v; -} - -int -isdescprocess(pid_t p, pid_t c) -{ - while (p != c && c != 0) - c = getparentprocess(c); - - return (int)c; -} - -Client * -termforwin(const Client *w) -{ - Client *c; - Monitor *m; - - if (!w->pid || w->isterminal) - return NULL; - - for (m = mons; m; m = m->next) { - for (c = m->clients; c; c = c->next) { - if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) - return c; - } - } - - return NULL; -} - -Client * -swallowingclient(Window w) -{ - Client *c; - Monitor *m; - - for (m = mons; m; m = m->next) { - for (c = m->clients; c; c = c->next) { - if (c->swallowing && c->swallowing->win == w) - return c; - } - } - - return NULL; -} - void warp(const Client *c) { @@ -3312,28 +3106,20 @@ xrdb(const Arg *arg) { loadxrdb(); int i; - for (i=0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); + if (colorfultag) { + tagscheme = ecalloc(LENGTH(colortags), sizeof(Clr *)); + for (i = 0; i < LENGTH(colortags); i++) + tagscheme[i] = drw_scm_create(drw, colortags[i], 2); + tagscheme_sel = ecalloc(LENGTH(colortags_sel), sizeof(Clr *)); + for (i = 0; i < LENGTH(colortags_sel); i++) + tagscheme_sel[i] = drw_scm_create(drw, colortags_sel[i], 2); + } + for (i=0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); focus(NULL); arrange(NULL); } -Monitor * -systraytomon(Monitor *m) { - Monitor *t; - int i, n; - if(!systraypinning) { - if(!m) - return selmon; - return m == selmon ? m : NULL; - } - for(n = 1, t = mons; t && t->next; n++, t = t->next) ; - for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; - if(systraypinningfailfirst && n < systraypinning) - return mons; - return t; -} - void movestack(const Arg *arg) { Client *c = NULL, *p = NULL, *pc = NULL, *i; @@ -3412,6 +3198,22 @@ shiftview(const Arg *arg) } } +Monitor * +systraytomon(Monitor *m) { + Monitor *t; + int i, n; + if(!systraypinning) { + if(!m) + return selmon; + return m == selmon ? m : NULL; + } + for(n = 1, t = mons; t && t->next; n++, t = t->next) ; + for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; + if(systraypinningfailfirst && n < systraypinning) + return mons; + return t; +} + void zoom(const Arg *arg) { @@ -3437,8 +3239,6 @@ main(int argc, char *argv[]) fputs("warning: no locale support\n", stderr); if (!(dpy = XOpenDisplay(NULL))) die("dwm: cannot open display"); - if (!(xcon = XGetXCBConnection(dpy))) - die("dwm: cannot get xcb connection\n"); if (argc > 1 && !strcmp("-s", argv[1])) { XStoreName(dpy, RootWindow(dpy, DefaultScreen(dpy)), argv[2]); XCloseDisplay(dpy); @@ -3449,13 +3249,14 @@ main(int argc, char *argv[]) loadxrdb(); setup(); #ifdef __OpenBSD__ - if (pledge("stdio rpath proc exec ps", NULL) == -1) + if (pledge("stdio rpath proc exec", NULL) == -1) die("pledge"); #endif /* __OpenBSD__ */ scan(); run(); - if(restart) execvp(argv[0], argv); + if(restartsig) execvp(argv[0], argv); cleanup(); XCloseDisplay(dpy); return EXIT_SUCCESS; } + diff --git a/patches/dwm-gaplessgrid-20160731-56a31dc.diff b/patches/dwm-gaplessgrid-20160731-56a31dc.diff @@ -1,43 +0,0 @@ -URL: http://dwm.suckless.org/patches/gapless_grid -Add gapless grid layout. - -Index: dwm/gaplessgrid.c -=================================================================== ---- /dev/null -+++ dwm/gaplessgrid.c -@@ -0,0 +1,35 @@ -+void -+gaplessgrid(Monitor *m) { -+ unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; -+ Client *c; -+ -+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) ; -+ if(n == 0) -+ return; -+ -+ /* grid dimensions */ -+ for(cols = 0; cols <= n/2; cols++) -+ if(cols*cols >= n) -+ break; -+ if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ -+ cols = 2; -+ rows = n/cols; -+ -+ /* window geometries */ -+ cw = cols ? m->ww / cols : m->ww; -+ cn = 0; /* current column number */ -+ rn = 0; /* current row number */ -+ for(i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { -+ if(i/rows + 1 > cols - n%cols) -+ rows = n/cols + 1; -+ ch = rows ? m->wh / rows : m->wh; -+ cx = m->wx + cn*cw; -+ cy = m->wy + rn*ch; -+ resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); -+ rn++; -+ if(rn >= rows) { -+ rn = 0; -+ cn++; -+ } -+ } -+} diff --git a/patches/dwm-swallow-20201211-61bb8b2.diff b/patches/dwm-swallow-20201211-61bb8b2.diff @@ -1,412 +0,0 @@ -From f0cdf40e0a7126838d051eb84d84b91421b771d6 Mon Sep 17 00:00:00 2001 -From: 0x1bi <ben@0x1bi.net> -Date: Fri, 11 Dec 2020 10:16:25 -0500 -Subject: [PATCH] fix swallow for openbsd - ---- - config.def.h | 9 +- - config.mk | 3 +- - dwm.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++-- - 3 files changed, 237 insertions(+), 10 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..fe51476 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -3,6 +3,7 @@ - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ -+static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ - static const char *fonts[] = { "monospace:size=10" }; -@@ -26,9 +27,11 @@ static const Rule rules[] = { - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ -- /* class instance title tags mask isfloating monitor */ -- { "Gimp", NULL, NULL, 0, 1, -1 }, -- { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, -+ /* class instance title tags mask isfloating isterminal noswallow monitor */ -+ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 }, -+ { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 }, -+ { "St", NULL, NULL, 0, 0, 1, 0, -1 }, -+ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ - }; - - /* layout(s) */ -diff --git a/config.mk b/config.mk -index 7084c33..ff9e508 100644 ---- a/config.mk -+++ b/config.mk -@@ -19,10 +19,11 @@ FREETYPELIBS = -lfontconfig -lXft - FREETYPEINC = /usr/include/freetype2 - # OpenBSD (uncomment) - #FREETYPEINC = ${X11INC}/freetype2 -+#KVMLIB = -lkvm - - # includes and libs - INCS = -I${X11INC} -I${FREETYPEINC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB} - - # flags - CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff --git a/dwm.c b/dwm.c -index 664c527..0b20086 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -40,6 +40,12 @@ - #include <X11/extensions/Xinerama.h> - #endif /* XINERAMA */ - #include <X11/Xft/Xft.h> -+#include <X11/Xlib-xcb.h> -+#include <xcb/res.h> -+#ifdef __OpenBSD__ -+#include <sys/sysctl.h> -+#include <kvm.h> -+#endif /* __OpenBSD */ - - #include "drw.h" - #include "util.h" -@@ -92,9 +98,11 @@ struct Client { - int basew, baseh, incw, inch, maxw, maxh, minw, minh; - int bw, oldbw; - unsigned int tags; -- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; -+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow; -+ pid_t pid; - Client *next; - Client *snext; -+ Client *swallowing; - Monitor *mon; - Window win; - }; -@@ -138,6 +146,8 @@ typedef struct { - const char *title; - unsigned int tags; - int isfloating; -+ int isterminal; -+ int noswallow; - int monitor; - } Rule; - -@@ -235,6 +245,12 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee); - static int xerrorstart(Display *dpy, XErrorEvent *ee); - static void zoom(const Arg *arg); - -+static pid_t getparentprocess(pid_t p); -+static int isdescprocess(pid_t p, pid_t c); -+static Client *swallowingclient(Window w); -+static Client *termforwin(const Client *c); -+static pid_t winpid(Window w); -+ - /* variables */ - static const char broken[] = "broken"; - static char stext[256]; -@@ -269,6 +285,8 @@ static Drw *drw; - static Monitor *mons, *selmon; - static Window root, wmcheckwin; - -+static xcb_connection_t *xcon; -+ - /* configuration, allows nested code to access above variables */ - #include "config.h" - -@@ -298,6 +316,8 @@ applyrules(Client *c) - && (!r->class || strstr(class, r->class)) - && (!r->instance || strstr(instance, r->instance))) - { -+ c->isterminal = r->isterminal; -+ c->noswallow = r->noswallow; - c->isfloating = r->isfloating; - c->tags |= r->tags; - for (m = mons; m && m->num != r->monitor; m = m->next); -@@ -414,6 +434,53 @@ attachstack(Client *c) - c->mon->stack = c; - } - -+void -+swallow(Client *p, Client *c) -+{ -+ -+ if (c->noswallow || c->isterminal) -+ return; -+ if (c->noswallow && !swallowfloating && c->isfloating) -+ return; -+ -+ detach(c); -+ detachstack(c); -+ -+ setclientstate(c, WithdrawnState); -+ XUnmapWindow(dpy, p->win); -+ -+ p->swallowing = c; -+ c->mon = p->mon; -+ -+ Window w = p->win; -+ p->win = c->win; -+ c->win = w; -+ updatetitle(p); -+ XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); -+ arrange(p->mon); -+ configure(p); -+ updateclientlist(); -+} -+ -+void -+unswallow(Client *c) -+{ -+ c->win = c->swallowing->win; -+ -+ free(c->swallowing); -+ c->swallowing = NULL; -+ -+ /* unfullscreen the client */ -+ setfullscreen(c, 0); -+ updatetitle(c); -+ arrange(c->mon); -+ XMapWindow(dpy, c->win); -+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); -+ setclientstate(c, NormalState); -+ focus(NULL); -+ arrange(c->mon); -+} -+ - void - buttonpress(XEvent *e) - { -@@ -653,6 +720,9 @@ destroynotify(XEvent *e) - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); -+ -+ else if ((c = swallowingclient(ev->window))) -+ unmanage(c->swallowing, 1); - } - - void -@@ -1018,12 +1088,13 @@ killclient(const Arg *arg) - void - manage(Window w, XWindowAttributes *wa) - { -- Client *c, *t = NULL; -+ Client *c, *t = NULL, *term = NULL; - Window trans = None; - XWindowChanges wc; - - c = ecalloc(1, sizeof(Client)); - c->win = w; -+ c->pid = winpid(w); - /* geometry */ - c->x = c->oldx = wa->x; - c->y = c->oldy = wa->y; -@@ -1038,6 +1109,7 @@ manage(Window w, XWindowAttributes *wa) - } else { - c->mon = selmon; - applyrules(c); -+ term = termforwin(c); - } - - if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) -@@ -1074,6 +1146,8 @@ manage(Window w, XWindowAttributes *wa) - c->mon->sel = c; - arrange(c->mon); - XMapWindow(dpy, c->win); -+ if (term) -+ swallow(term, c); - focus(NULL); - } - -@@ -1768,6 +1842,20 @@ unmanage(Client *c, int destroyed) - Monitor *m = c->mon; - XWindowChanges wc; - -+ if (c->swallowing) { -+ unswallow(c); -+ return; -+ } -+ -+ Client *s = swallowingclient(c->win); -+ if (s) { -+ free(s->swallowing); -+ s->swallowing = NULL; -+ arrange(m); -+ focus(NULL); -+ return; -+ } -+ - detach(c); - detachstack(c); - if (!destroyed) { -@@ -1782,9 +1870,12 @@ unmanage(Client *c, int destroyed) - XUngrabServer(dpy); - } - free(c); -- focus(NULL); -- updateclientlist(); -- arrange(m); -+ -+ if (!s) { -+ arrange(m); -+ focus(NULL); -+ updateclientlist(); -+ } - } - - void -@@ -2047,6 +2138,136 @@ view(const Arg *arg) - arrange(selmon); - } - -+pid_t -+winpid(Window w) -+{ -+ -+ pid_t result = 0; -+ -+#ifdef __linux__ -+ xcb_res_client_id_spec_t spec = {0}; -+ spec.client = w; -+ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; -+ -+ xcb_generic_error_t *e = NULL; -+ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); -+ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); -+ -+ if (!r) -+ return (pid_t)0; -+ -+ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); -+ for (; i.rem; xcb_res_client_id_value_next(&i)) { -+ spec = i.data->spec; -+ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { -+ uint32_t *t = xcb_res_client_id_value_value(i.data); -+ result = *t; -+ break; -+ } -+ } -+ -+ free(r); -+ -+ if (result == (pid_t)-1) -+ result = 0; -+ -+#endif /* __linux__ */ -+ -+#ifdef __OpenBSD__ -+ Atom type; -+ int format; -+ unsigned long len, bytes; -+ unsigned char *prop; -+ pid_t ret; -+ -+ if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 0), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop) -+ return 0; -+ -+ ret = *(pid_t*)prop; -+ XFree(prop); -+ result = ret; -+ -+#endif /* __OpenBSD__ */ -+ return result; -+} -+ -+pid_t -+getparentprocess(pid_t p) -+{ -+ unsigned int v = 0; -+ -+#ifdef __linux__ -+ FILE *f; -+ char buf[256]; -+ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); -+ -+ if (!(f = fopen(buf, "r"))) -+ return 0; -+ -+ fscanf(f, "%*u %*s %*c %u", &v); -+ fclose(f); -+#endif /* __linux__*/ -+ -+#ifdef __OpenBSD__ -+ int n; -+ kvm_t *kd; -+ struct kinfo_proc *kp; -+ -+ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL); -+ if (!kd) -+ return 0; -+ -+ kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n); -+ v = kp->p_ppid; -+#endif /* __OpenBSD__ */ -+ -+ return (pid_t)v; -+} -+ -+int -+isdescprocess(pid_t p, pid_t c) -+{ -+ while (p != c && c != 0) -+ c = getparentprocess(c); -+ -+ return (int)c; -+} -+ -+Client * -+termforwin(const Client *w) -+{ -+ Client *c; -+ Monitor *m; -+ -+ if (!w->pid || w->isterminal) -+ return NULL; -+ -+ for (m = mons; m; m = m->next) { -+ for (c = m->clients; c; c = c->next) { -+ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) -+ return c; -+ } -+ } -+ -+ return NULL; -+} -+ -+Client * -+swallowingclient(Window w) -+{ -+ Client *c; -+ Monitor *m; -+ -+ for (m = mons; m; m = m->next) { -+ for (c = m->clients; c; c = c->next) { -+ if (c->swallowing && c->swallowing->win == w) -+ return c; -+ } -+ } -+ -+ return NULL; -+} -+ - Client * - wintoclient(Window w) - { -@@ -2138,10 +2359,12 @@ main(int argc, char *argv[]) - fputs("warning: no locale support\n", stderr); - if (!(dpy = XOpenDisplay(NULL))) - die("dwm: cannot open display"); -+ if (!(xcon = XGetXCBConnection(dpy))) -+ die("dwm: cannot get xcb connection\n"); - checkotherwm(); - setup(); - #ifdef __OpenBSD__ -- if (pledge("stdio rpath proc exec", NULL) == -1) -+ if (pledge("stdio rpath proc exec ps", NULL) == -1) - die("pledge"); - #endif /* __OpenBSD__ */ - scan(); --- -2.28.0 - diff --git a/patches/dwm-underlinetags-6.2.diff b/patches/dwm-underlinetags-6.2.diff @@ -1,27 +0,0 @@ -diff -pu dwm.git/config.def.h dwm.underlinetags/config.def.h ---- dwm.git/config.def.h 2021-02-27 20:04:32.030570909 -0600 -+++ dwm.underlinetags/config.def.h 2021-03-16 16:42:26.278703624 -0500 -@@ -21,6 +21,11 @@ static const char *colors[][3] = { - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -+static const unsigned int ulinepad = 5; /* horizontal padding between the underline and tag */ -+static const unsigned int ulinestroke = 2; /* thickness / height of the underline */ -+static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */ -+static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ -+ - static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class -diff -pu dwm.git/dwm.c dwm.underlinetags/dwm.c ---- dwm.git/dwm.c 2021-02-27 20:04:32.030570909 -0600 -+++ dwm.underlinetags/dwm.c 2021-03-16 16:41:21.468077151 -0500 -@@ -719,6 +719,8 @@ drawbar(Monitor *m) - w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); -+ if (ulineall || m->tagset[m->seltags] & 1 << i) /* if there are conflicts, just move these lines directly underneath both 'drw_setscheme' and 'drw_text' :) */ -+ drw_rect(drw, x + ulinepad, bh - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0); - if (occ & 1 << i) - drw_rect(drw, x + boxs, boxs, boxw, boxw, - m == selmon && selmon->sel && selmon->sel->tags & 1 << i,