@@ -0,0 +1,36 @@ | |||||
! special | |||||
*.foreground: #e3e3e3 | |||||
*.background: #1d212a | |||||
*.cursorColor: #e3e3e3 | |||||
! black | |||||
*.color0: #1d212a | |||||
*.color8: #585e74 | |||||
! red | |||||
*.color1: #fc8993 | |||||
*.color9: #fb9199 | |||||
! green | |||||
*.color2: #89e19c | |||||
*.color10: #8de19f | |||||
! yellow | |||||
*.color3: #fbdf90 | |||||
*.color11: #ffe28e | |||||
! blue | |||||
*.color4: #a7bdfb | |||||
*.color12: #afc3fb | |||||
! magenta | |||||
*.color5: #d990cd | |||||
*.color13: #df95d3 | |||||
! cyan | |||||
*.color6: #81d4ee | |||||
*.color14: #81d4ee | |||||
! white | |||||
*.color7: #e3e3e3 | |||||
*.color15: #e3e3e3 |
@@ -7,6 +7,11 @@ static const unsigned int snap = 32; /* snap pixel */ | |||||
static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ | static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ | ||||
static const int showbar = 1; /* 0 means no bar */ | static const int showbar = 1; /* 0 means no bar */ | ||||
static const int topbar = 1; /* 0 means bottom bar */ | static const int topbar = 1; /* 0 means bottom bar */ | ||||
static const int vertpad = 10; /* vertical padding of bar */ | |||||
static const int sidepad = 10; /* horizontal padding of bar */ | |||||
static const int user_bh = 0; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */ | |||||
static const int horizpadbar = 10; /* horizontal padding for statusbar */ | |||||
static const int vertpadbar = 10; /* vertical padding for statusbar */ | |||||
/* Display modes of the tab bar: never shown, always shown, shown only in */ | /* Display modes of the tab bar: never shown, always shown, shown only in */ | ||||
/* monocle mode in presence of several windows. */ | /* monocle mode in presence of several windows. */ | ||||
@@ -16,16 +21,17 @@ static const int showtab = showtab_auto; /* Default tab bar show mode | |||||
static const Bool toptab = False; /* False means bottom tab bar */ | static const Bool toptab = False; /* False means bottom tab bar */ | ||||
static const char *fonts[] = { "fontawesome:size=15", "DejaVuSansMono Nerd Font Mono:size=13"} ; | static const char *fonts[] = { "fontawesome:size=15", "DejaVuSansMono Nerd Font Mono:size=13"} ; | ||||
static const char dmenufont[] = "monospace:size=13"; | |||||
static const char col_gray1[] = "#222222"; | static const char col_gray1[] = "#222222"; | ||||
static const char col_gray2[] = "#444444"; | |||||
static const char col_gray2[] = "#666666"; | |||||
static const char col_gray3[] = "#bbbbbb"; | static const char col_gray3[] = "#bbbbbb"; | ||||
static const char col_gray4[] = "#eeeeee"; | static const char col_gray4[] = "#eeeeee"; | ||||
static const char col_cyan[] = "#630fe8"; | |||||
static const char col_cyan[] = "#7733ee"; | |||||
static const char col_borderbar[] = "#222222"; | |||||
static const char *colors[][3] = { | static const char *colors[][3] = { | ||||
/* fg bg border */ | |||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | |||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |||||
/* fg bg border */ | |||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | |||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |||||
[SchemeDis] = { col_gray2, col_gray1, col_gray2 }, | |||||
}; | }; | ||||
static const char *const autostart[] = { | static const char *const autostart[] = { | ||||
@@ -42,6 +48,23 @@ static const char *tags[] = { "", "", "", "", "", "", "", " | |||||
static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 2, 0, 2, 2}; | static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 2, 0, 2, 2}; | ||||
static const char *tagsel[][2] = { | |||||
{ "#d990cd", col_gray1 }, | |||||
{ "#fbdf90", col_gray1 }, | |||||
{ "#81d4ee", col_gray1 }, | |||||
{ "#89e19c", col_gray1 }, | |||||
{ "#d990cd", col_gray1 }, | |||||
{ "#fbdf90", col_gray1 }, | |||||
{ "#81d4ee", col_gray1 }, | |||||
{ "#89e19c", col_gray1 }, | |||||
{ "#d990cd", col_gray1 }, | |||||
}; | |||||
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[] = { | static const Rule rules[] = { | ||||
/* xprop(1): | /* xprop(1): | ||||
* WM_CLASS(STRING) = instance, class | * WM_CLASS(STRING) = instance, class | ||||
@@ -90,7 +113,7 @@ static const Layout layouts[] = { | |||||
/* commands */ | /* commands */ | ||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ | ||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; | |||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, NULL }; | |||||
static const char *termcmd[] = { "st", NULL }; | static const char *termcmd[] = { "st", NULL }; | ||||
#include <X11/XF86keysym.h> | #include <X11/XF86keysym.h> | ||||
@@ -171,7 +194,6 @@ static Button buttons[] = { | |||||
/* click event mask button function argument */ | /* click event mask button function argument */ | ||||
{ ClkLtSymbol, 0, Button1, setlayout, {0} }, | { ClkLtSymbol, 0, Button1, setlayout, {0} }, | ||||
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, | ||||
{ ClkWinTitle, 0, Button2, zoom, {0} }, | |||||
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, | { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, | ||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} }, | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, | ||||
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} }, | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, | ||||
@@ -2,47 +2,86 @@ | |||||
/* appearance */ | /* appearance */ | ||||
static const unsigned int borderpx = 2; /* border pixel of windows */ | static const unsigned int borderpx = 2; /* border pixel of windows */ | ||||
static const unsigned int gappx = 15; | |||||
static const unsigned int gappx = 10; | |||||
static const unsigned int snap = 32; /* snap pixel */ | static const unsigned int snap = 32; /* snap pixel */ | ||||
static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ | static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ | ||||
static const int showbar = 1; /* 0 means no bar */ | static const int showbar = 1; /* 0 means no bar */ | ||||
static const int topbar = 1; /* 0 means bottom bar */ | static const int topbar = 1; /* 0 means bottom bar */ | ||||
static const int user_bh = 0; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */ | |||||
static const int horizpadbar = 10; /* horizontal padding for statusbar */ | |||||
static const int vertpadbar = 10; /* vertical padding for statusbar */ | |||||
/* Display modes of the tab bar: never shown, always shown, shown only in */ | |||||
/* monocle mode in presence of several windows. */ | |||||
/* Modes after showtab_nmodes are disabled */ | |||||
enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; | |||||
static const int showtab = showtab_auto; /* Default tab bar show mode */ | |||||
static const Bool toptab = False; /* False means bottom tab bar */ | |||||
static const char *fonts[] = { "fontawesome:size=15", "DejaVuSansMono Nerd Font Mono:size=13"} ; | static const char *fonts[] = { "fontawesome:size=15", "DejaVuSansMono Nerd Font Mono:size=13"} ; | ||||
static const char dmenufont[] = "monospace:size=13"; | |||||
static const char col_gray1[] = "#222222"; | static const char col_gray1[] = "#222222"; | ||||
static const char col_gray2[] = "#444444"; | |||||
static const char col_gray2[] = "#666666"; | |||||
static const char col_gray3[] = "#bbbbbb"; | static const char col_gray3[] = "#bbbbbb"; | ||||
static const char col_gray4[] = "#eeeeee"; | static const char col_gray4[] = "#eeeeee"; | ||||
static const char col_cyan[] = "#41008c"; | |||||
static const char col_cyan[] = "#7733ee"; | |||||
static const char col_borderbar[] = "#222222"; | |||||
static const char *colors[][3] = { | static const char *colors[][3] = { | ||||
/* fg bg border */ | |||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | |||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |||||
/* fg bg border */ | |||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | |||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |||||
[SchemeDis] = { col_gray2, col_gray1, col_gray2 }, | |||||
}; | }; | ||||
static const char *const autostart[] = { | static const char *const autostart[] = { | ||||
"sh", "-c", "sh ~/scripts/xinit.sh", NULL, | "sh", "-c", "sh ~/scripts/xinit.sh", NULL, | ||||
"dunst", NULL, | |||||
"slstatus", NULL, | |||||
NULL /* terminate */ | NULL /* terminate */ | ||||
}; | }; | ||||
/* tagging */ | /* tagging */ | ||||
static const char *tags[] = { "", "", "", "", "", "", "", "", "" }; | |||||
static const char *tags[] = { "", "", "", "", "", "", "", "", "" }; | |||||
/* default layout per tags */ | |||||
/* The first element is for all-tag view, following i-th element corresponds to */ | |||||
/* tags[i]. Layout is referred using the layouts array index.*/ | |||||
static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 2, 0, 2, 2}; | |||||
static const char *tagsel[][2] = { | |||||
{ "#d990cd", col_gray1 }, | |||||
{ "#fbdf90", col_gray1 }, | |||||
{ "#81d4ee", col_gray1 }, | |||||
{ "#89e19c", col_gray1 }, | |||||
{ "#d990cd", col_gray1 }, | |||||
{ "#fbdf90", col_gray1 }, | |||||
{ "#81d4ee", col_gray1 }, | |||||
{ "#89e19c", col_gray1 }, | |||||
{ "#d990cd", col_gray1 }, | |||||
}; | |||||
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[] = { | static const Rule rules[] = { | ||||
/* xprop(1): | /* xprop(1): | ||||
* WM_CLASS(STRING) = instance, class | * WM_CLASS(STRING) = instance, class | ||||
* WM_NAME(STRING) = title | * WM_NAME(STRING) = title | ||||
*/ | */ | ||||
/* class instance title tags mask iscentered isfloating monitor */ | |||||
{ "Gimp", NULL, NULL, 0, 0, 1, -1 }, | |||||
{ "Firefox", NULL, NULL, 1 << 8, 0, 0, -1 }, | |||||
/* class instance title tags mask iscentered isfloating isterminal noswallow monitor */ | |||||
{ "Gimp", NULL, NULL, 0,0, 1, 0, 0, -1 }, | |||||
{ "Firefox", NULL, NULL, 1 << 8,0, 0, 0, -1, -1 }, | |||||
{ "St", NULL, NULL, 0,0, 0, 1, 0, -1 }, | |||||
{ NULL, NULL, "Event Tester", 0,0, 0, 0, 1, -1 }, /* xev */ | |||||
/* class instance title tags mask iscentered isfloating isterminal noswallow monitor */ | |||||
{ "Gimp", NULL, NULL, 1 << 7, 0, 1, 0, 0, -1 }, | |||||
{ "LibreWolf", NULL, NULL, 1 << 2, 0, 0, 0, -1, -1 }, | |||||
{ "firefox", NULL, NULL, 1 << 2, 0, 0, 0, -1, -1 }, | |||||
{ "Brave-browser", NULL, NULL, 1 << 2, 0, 0, 0, -1, -1 }, | |||||
{ "St", NULL, NULL, 0, 0, 0, 1, 0, -1 }, | |||||
{ "zoom", NULL, NULL, 1 << 1, 0, 0, 0, -1, -1 }, | |||||
{ "cmus", NULL, NULL, 1 << 3, 0, 0, 0, -1, -1 }, | |||||
{ "TelegramDesktop", NULL, NULL, 1 << 4, 0, 0, 0, -1, -1 }, | |||||
{ "Discord", NULL, NULL, 1 << 4, 0, 0, 0, -1, -1 }, | |||||
{ "cpsrc", NULL, NULL, 1 << 1, 0, 0, 0, -1, -1 }, | |||||
{ "Emacs", NULL, NULL, 1 << 1, 0, 0, 0, -1, -1 }, | |||||
{ NULL, NULL, "Event Tester", 0, 0, 0, 0, 1, -1 }, /* xev */ | |||||
}; | }; | ||||
/* layout(s) */ | /* layout(s) */ | ||||
@@ -72,73 +111,79 @@ static const Layout layouts[] = { | |||||
/* commands */ | /* commands */ | ||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ | ||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; | |||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, NULL }; | |||||
static const char *termcmd[] = { "st", NULL }; | static const char *termcmd[] = { "st", NULL }; | ||||
#include <X11/XF86keysym.h> | #include <X11/XF86keysym.h> | ||||
static Key keys[] = { | static Key keys[] = { | ||||
/* modifier key function argument */ | |||||
{ 0, XK_Print, spawn, SHCMD("~/scripts/screenshot.sh") }, | |||||
{ 0, XF86XK_PowerOff, spawn, SHCMD("~/scripts/poweroff.sh") }, | |||||
{ 0, XF86XK_AudioMute, spawn, SHCMD("pulsemixer --toggle-mute") }, | |||||
{ 0, XF86XK_AudioRaiseVolume, spawn, SHCMD("amixer -c 1 sset Master 1+") }, | |||||
{ 0, XF86XK_AudioLowerVolume, spawn, SHCMD("amixer -c 1 sset Master 1-") }, | |||||
{ 0, XF86XK_AudioPrev, spawn, SHCMD("cmus-remote --prev") }, | |||||
{ 0, XF86XK_AudioNext, spawn, SHCMD("cmus-remote --next") }, | |||||
{ 0, XF86XK_AudioPause, spawn, SHCMD("cmus-remote --pause") }, | |||||
{ 0, XF86XK_AudioPlay, spawn, SHCMD("cmus-remote --pause") }, | |||||
{ 0, XF86XK_AudioStop, spawn, SHCMD("cmus-remote --stop") }, | |||||
{ 0, XF86XK_AudioRewind, spawn, SHCMD("cmus-remote --seek -10") }, | |||||
{ 0, XF86XK_AudioForward, spawn, SHCMD("cmus-remote --seek +10") }, | |||||
{ 0, XF86XK_MonBrightnessUp, spawn, SHCMD("brightnessctl s +5%")}, | |||||
{ 0, XF86XK_MonBrightnessDown, spawn, SHCMD("brightnessctl s 5%-")}, | |||||
{ MODKEY|ShiftMask, XK_space, togglealwaysontop, {0} }, | |||||
{ MODKEY, XK_w, spawn, SHCMD("firefox") }, | |||||
{ MODKEY|ShiftMask, XK_l, spawn, SHCMD("slock") }, | |||||
{ MODKEY|ShiftMask, XK_m, spawn, SHCMD("st ~/scripts/autostart.sh") }, | |||||
{ MODKEY|ShiftMask, XK_j, spawn, SHCMD("joplin-desktop") }, | |||||
{ MODKEY|ShiftMask, XK_s, spawn, SHCMD("~/scripts/screenshot.sh 1") }, | |||||
{ MODKEY|ShiftMask, XK_n, spawn, SHCMD("connman-gtk") }, | |||||
{ MODKEY|ShiftMask, XK_x, spawn, SHCMD("mixer.sh") }, | |||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } }, | |||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, | |||||
{ MODKEY, XK_b, togglebar, {0} }, | |||||
{ MODKEY, XK_j, focusstack, {.i = +1 } }, | |||||
{ MODKEY, XK_k, focusstack, {.i = -1 } }, | |||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } }, | |||||
{ MODKEY, XK_d, incnmaster, {.i = -1 } }, | |||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} }, | |||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} }, | |||||
{ MODKEY, XK_Return, zoom, {0} }, | |||||
{ MODKEY, XK_Tab, view, {0} }, | |||||
{ MODKEY|ShiftMask, XK_c, killclient, {0} }, | |||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, | |||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, | |||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, | |||||
{ MODKEY, XK_u, setlayout, {.v = &layouts[3]} }, | |||||
{ MODKEY, XK_o, setlayout, {.v = &layouts[4]} }, | |||||
{ MODKEY, XK_space, setlayout, {0} }, | |||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} }, | |||||
{ MODKEY, XK_0, view, {.ui = ~0 } }, | |||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, | |||||
{ MODKEY, XK_comma, focusmon, {.i = -1 } }, | |||||
{ MODKEY, XK_period, focusmon, {.i = +1 } }, | |||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, | |||||
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, | |||||
{ MODKEY, XK_minus, setgaps, {.i = -5 } }, | |||||
{ MODKEY, XK_equal, setgaps, {.i = +5 } }, | |||||
{ MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, | |||||
TAGKEYS( XK_1, 0) | |||||
TAGKEYS( XK_2, 1) | |||||
TAGKEYS( XK_3, 2) | |||||
TAGKEYS( XK_4, 3) | |||||
TAGKEYS( XK_5, 4) | |||||
TAGKEYS( XK_6, 5) | |||||
TAGKEYS( XK_7, 6) | |||||
TAGKEYS( XK_8, 7) | |||||
TAGKEYS( XK_9, 8) | |||||
{ MODKEY|ShiftMask, XK_q, quit, {0} }, | |||||
/* modifier key function argument */ | |||||
{ 0, XK_Print, spawn, SHCMD("~/scripts/screenshot.sh") }, | |||||
{ 0, XF86XK_PowerOff, spawn, SHCMD("~/scripts/poweroff.sh") }, | |||||
{ 0, XF86XK_AudioMute, spawn, SHCMD("pulsemixer --toggle-mute") }, | |||||
{ 0, XF86XK_AudioRaiseVolume, spawn, SHCMD("amixer set Master 1%+") }, | |||||
{ 0, XF86XK_AudioLowerVolume, spawn, SHCMD("amixer set Master 1%-") }, | |||||
{ 0, XF86XK_AudioPrev, spawn, SHCMD("cmus-remote --prev") }, | |||||
{ 0, XF86XK_AudioNext, spawn, SHCMD("cmus-remote --next") }, | |||||
{ 0, XF86XK_AudioPause, spawn, SHCMD("cmus-remote --pause") }, | |||||
{ 0, XF86XK_AudioPlay, spawn, SHCMD("cmus-remote --pause") }, | |||||
{ 0, XF86XK_AudioStop, spawn, SHCMD("cmus-remote --stop") }, | |||||
{ 0, XF86XK_AudioRewind, spawn, SHCMD("cmus-remote --seek -10") }, | |||||
{ 0, XF86XK_AudioForward, spawn, SHCMD("cmus-remote --seek +10") }, | |||||
{ 0, XF86XK_MonBrightnessUp, spawn, SHCMD("brightnessctl s +5%")}, | |||||
{ 0, XF86XK_MonBrightnessDown, spawn, SHCMD("brightnessctl s 5%-")}, | |||||
{ ControlMask, XK_space, spawn, SHCMD("dunstctl close") }, | |||||
{ ControlMask|ShiftMask, XK_space, spawn, SHCMD("dunstctl close-all") }, | |||||
{ MODKEY|ShiftMask, XK_space, togglealwaysontop, {0} }, | |||||
{ MODKEY, XK_w, spawn, SHCMD("firefox") }, | |||||
{ MODKEY, XK_c, spawn, SHCMD("~/scripts/showcal.sh") }, | |||||
{ MODKEY|ShiftMask, XK_l, spawn, SHCMD("slock.sh") }, | |||||
{ MODKEY|ShiftMask, XK_e, spawn, SHCMD("emacsclient --create-frame") }, | |||||
{ MODKEY|ShiftMask, XK_m, spawn, SHCMD("~/scripts/autostart.sh") }, | |||||
{ MODKEY|ShiftMask, XK_j, spawn, SHCMD("screenkey.sh") }, | |||||
{ MODKEY|ShiftMask, XK_s, spawn, SHCMD("~/scripts/screenshot.sh 1") }, | |||||
{ MODKEY|ShiftMask, XK_n, spawn, SHCMD("~/scripts/network.sh") }, | |||||
{ MODKEY|ShiftMask, XK_x, spawn, SHCMD("mixer.sh") }, | |||||
{ MODKEY|ShiftMask, XK_t, spawn, SHCMD("telegram-desktop") }, | |||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } }, | |||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, | |||||
{ MODKEY, XK_b, togglebar, {0} }, | |||||
{ MODKEY, XK_w, tabmode, {-1} }, | |||||
{ MODKEY, XK_j, focusstack, {.i = +1 } }, | |||||
{ MODKEY, XK_k, focusstack, {.i = -1 } }, | |||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } }, | |||||
{ MODKEY, XK_d, incnmaster, {.i = -1 } }, | |||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} }, | |||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} }, | |||||
{ MODKEY, XK_Return, zoom, {0} }, | |||||
{ MODKEY, XK_Tab, view, {0} }, | |||||
{ MODKEY|ShiftMask, XK_c, killclient, {0} }, | |||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, | |||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, | |||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, | |||||
{ MODKEY, XK_u, setlayout, {.v = &layouts[3]} }, | |||||
{ MODKEY, XK_o, setlayout, {.v = &layouts[4]} }, | |||||
{ MODKEY, XK_space, setlayout, {0} }, | |||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} }, | |||||
{ MODKEY, XK_0, view, {.ui = ~0 } }, | |||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, | |||||
{ MODKEY, XK_comma, focusmon, {.i = -1 } }, | |||||
{ MODKEY, XK_period, focusmon, {.i = +1 } }, | |||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, | |||||
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, | |||||
{ MODKEY, XK_minus, setgaps, {.i = -5 } }, | |||||
{ MODKEY, XK_equal, setgaps, {.i = +5 } }, | |||||
{ MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, | |||||
TAGKEYS( XK_1, 0) | |||||
TAGKEYS( XK_2, 1) | |||||
TAGKEYS( XK_3, 2) | |||||
TAGKEYS( XK_4, 3) | |||||
TAGKEYS( XK_5, 4) | |||||
TAGKEYS( XK_6, 5) | |||||
TAGKEYS( XK_7, 6) | |||||
TAGKEYS( XK_8, 7) | |||||
TAGKEYS( XK_9, 8) | |||||
{ MODKEY|ShiftMask, XK_q, quit, {0} }, | |||||
}; | }; | ||||
/* button definitions */ | /* button definitions */ | ||||
@@ -147,7 +192,6 @@ static Button buttons[] = { | |||||
/* click event mask button function argument */ | /* click event mask button function argument */ | ||||
{ ClkLtSymbol, 0, Button1, setlayout, {0} }, | { ClkLtSymbol, 0, Button1, setlayout, {0} }, | ||||
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, | ||||
{ ClkWinTitle, 0, Button2, zoom, {0} }, | |||||
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, | { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, | ||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} }, | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, | ||||
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} }, | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, | ||||
@@ -156,5 +200,6 @@ static Button buttons[] = { | |||||
{ ClkTagBar, 0, Button3, toggleview, {0} }, | { ClkTagBar, 0, Button3, toggleview, {0} }, | ||||
{ ClkTagBar, MODKEY, Button1, tag, {0} }, | { ClkTagBar, MODKEY, Button1, tag, {0} }, | ||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} }, | { ClkTagBar, MODKEY, Button3, toggletag, {0} }, | ||||
{ ClkTabBar, 0, Button1, focuswin, {0} }, | |||||
}; | }; | ||||
@@ -1,33 +1,11 @@ | |||||
--- config.def.h | |||||
+++ config.def.h | |||||
@@ -5,6 +5,14 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ | |||||
--- config.def.h 2019-12-10 17:24:37.944708263 +1300 | |||||
+++ config.def.h 2019-12-10 17:44:38.447670711 +1300 | |||||
@@ -5,6 +5,8 @@ static const unsigned int borderpx = 1; | |||||
static const unsigned int snap = 32; /* snap pixel */ | static const unsigned int snap = 32; /* snap pixel */ | ||||
static const int showbar = 1; /* 0 means no bar */ | static const int showbar = 1; /* 0 means no bar */ | ||||
static const int topbar = 1; /* 0 means bottom bar */ | static const int topbar = 1; /* 0 means bottom bar */ | ||||
+ | |||||
+/* Display modes of the tab bar: never shown, always shown, shown only in */ | |||||
+/* monocle mode in presence of several windows. */ | |||||
+/* Modes after showtab_nmodes are disabled */ | |||||
+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; | |||||
+static const int showtab = showtab_auto; /* Default tab bar show mode */ | |||||
+static const Bool toptab = False; /* False means bottom tab bar */ | |||||
+ | |||||
+static const int vertpad = 10; /* vertical padding of bar */ | |||||
+static const int sidepad = 10; /* horizontal padding of bar */ | |||||
static const char *fonts[] = { "monospace:size=10" }; | static const char *fonts[] = { "monospace:size=10" }; | ||||
static const char dmenufont[] = "monospace:size=10"; | static const char dmenufont[] = "monospace:size=10"; | ||||
static const char col_gray1[] = "#222222"; | static const char col_gray1[] = "#222222"; | ||||
@@ -18,9 +26,15 @@ static const char *colors[SchemeLast][3] = { | |||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |||||
}; | |||||
+ | |||||
/* tagging */ | |||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; | |||||
+/* default layout per tags */ | |||||
+/* The first element is for all-tag view, following i-th element corresponds to */ | |||||
+/* tags[i]. Layout is referred using the layouts array index.*/ | |||||
+static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | |||||
+ | |||||
static const Rule rules[] = { | |||||
/* xprop(1): | |||||
* WM_CLASS(STRING) = instance, class |
@@ -7,6 +7,11 @@ static const unsigned int snap = 32; /* snap pixel */ | |||||
static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ | static const int swallowfloating = 0; /* 1 means swallow floating windows by default */ | ||||
static const int showbar = 1; /* 0 means no bar */ | static const int showbar = 1; /* 0 means no bar */ | ||||
static const int topbar = 1; /* 0 means bottom bar */ | static const int topbar = 1; /* 0 means bottom bar */ | ||||
static const int vertpad = 10; /* vertical padding of bar */ | |||||
static const int sidepad = 10; /* horizontal padding of bar */ | |||||
static const int user_bh = 0; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */ | |||||
static const int horizpadbar = 10; /* horizontal padding for statusbar */ | |||||
static const int vertpadbar = 10; /* vertical padding for statusbar */ | |||||
/* Display modes of the tab bar: never shown, always shown, shown only in */ | /* Display modes of the tab bar: never shown, always shown, shown only in */ | ||||
/* monocle mode in presence of several windows. */ | /* monocle mode in presence of several windows. */ | ||||
@@ -16,16 +21,17 @@ static const int showtab = showtab_auto; /* Default tab bar show mode | |||||
static const Bool toptab = False; /* False means bottom tab bar */ | static const Bool toptab = False; /* False means bottom tab bar */ | ||||
static const char *fonts[] = { "fontawesome:size=15", "DejaVuSansMono Nerd Font Mono:size=13"} ; | static const char *fonts[] = { "fontawesome:size=15", "DejaVuSansMono Nerd Font Mono:size=13"} ; | ||||
static const char dmenufont[] = "monospace:size=13"; | |||||
static const char col_gray1[] = "#222222"; | static const char col_gray1[] = "#222222"; | ||||
static const char col_gray2[] = "#444444"; | |||||
static const char col_gray2[] = "#666666"; | |||||
static const char col_gray3[] = "#bbbbbb"; | static const char col_gray3[] = "#bbbbbb"; | ||||
static const char col_gray4[] = "#eeeeee"; | static const char col_gray4[] = "#eeeeee"; | ||||
static const char col_cyan[] = "#630fe8"; | |||||
static const char col_cyan[] = "#7733ee"; | |||||
static const char col_borderbar[] = "#222222"; | |||||
static const char *colors[][3] = { | static const char *colors[][3] = { | ||||
/* fg bg border */ | |||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | |||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |||||
/* fg bg border */ | |||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | |||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |||||
[SchemeDis] = { col_gray2, col_gray1, col_gray2 }, | |||||
}; | }; | ||||
static const char *const autostart[] = { | static const char *const autostart[] = { | ||||
@@ -42,6 +48,23 @@ static const char *tags[] = { "", "", "", "", "", "", "", " | |||||
static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 2, 0, 2, 2}; | static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 2, 0, 2, 2}; | ||||
static const char *tagsel[][2] = { | |||||
{ "#d990cd", col_gray1 }, | |||||
{ "#fbdf90", col_gray1 }, | |||||
{ "#81d4ee", col_gray1 }, | |||||
{ "#89e19c", col_gray1 }, | |||||
{ "#d990cd", col_gray1 }, | |||||
{ "#fbdf90", col_gray1 }, | |||||
{ "#81d4ee", col_gray1 }, | |||||
{ "#89e19c", col_gray1 }, | |||||
{ "#d990cd", col_gray1 }, | |||||
}; | |||||
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[] = { | static const Rule rules[] = { | ||||
/* xprop(1): | /* xprop(1): | ||||
* WM_CLASS(STRING) = instance, class | * WM_CLASS(STRING) = instance, class | ||||
@@ -90,7 +113,7 @@ static const Layout layouts[] = { | |||||
/* commands */ | /* commands */ | ||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ | ||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; | |||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, NULL }; | |||||
static const char *termcmd[] = { "st", NULL }; | static const char *termcmd[] = { "st", NULL }; | ||||
#include <X11/XF86keysym.h> | #include <X11/XF86keysym.h> | ||||
@@ -171,7 +194,6 @@ static Button buttons[] = { | |||||
/* click event mask button function argument */ | /* click event mask button function argument */ | ||||
{ ClkLtSymbol, 0, Button1, setlayout, {0} }, | { ClkLtSymbol, 0, Button1, setlayout, {0} }, | ||||
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, | ||||
{ ClkWinTitle, 0, Button2, zoom, {0} }, | |||||
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, | { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, | ||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} }, | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, | ||||
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} }, | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, | ||||
@@ -1,59 +0,0 @@ | |||||
diff --git a/config.def.h b/config.def.h | |||||
index 1c0b587..3fb5cf8 100644 | |||||
--- a/config.def.h | |||||
+++ b/config.def.h | |||||
@@ -21,6 +21,18 @@ static const char *colors[][3] = { | |||||
/* tagging */ | |||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; | |||||
+static const char *tagsel[][2] = { | |||||
+ { "#ffffff", "#ff0000" }, | |||||
+ { "#ffffff", "#ff7f00" }, | |||||
+ { "#000000", "#ffff00" }, | |||||
+ { "#000000", "#00ff00" }, | |||||
+ { "#ffffff", "#0000ff" }, | |||||
+ { "#ffffff", "#4b0082" }, | |||||
+ { "#ffffff", "#9400d3" }, | |||||
+ { "#000000", "#ffffff" }, | |||||
+ { "#ffffff", "#000000" }, | |||||
+}; | |||||
+ | |||||
static const Rule rules[] = { | |||||
/* xprop(1): | |||||
* WM_CLASS(STRING) = instance, class | |||||
diff --git a/dwm.c b/dwm.c | |||||
index b0b3466..c16d5f5 100644 | |||||
--- a/dwm.c | |||||
+++ b/dwm.c | |||||
@@ -264,6 +264,7 @@ static Atom wmatom[WMLast], netatom[NetLast]; | |||||
static int running = 1; | |||||
static Cur *cursor[CurLast]; | |||||
static Clr **scheme; | |||||
+static Clr **tagscheme; | |||||
static Display *dpy; | |||||
static Drw *drw; | |||||
static Monitor *mons, *selmon; | |||||
@@ -717,7 +718,7 @@ drawbar(Monitor *m) | |||||
x = 0; | |||||
for (i = 0; i < LENGTH(tags); i++) { | |||||
w = TEXTW(tags[i]); | |||||
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); | |||||
+ drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : scheme[SchemeNorm])); | |||||
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); | |||||
if (occ & 1 << i) | |||||
drw_rect(drw, x + boxs, boxs, boxw, boxw, | |||||
@@ -1568,9 +1569,14 @@ 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"); | |||||
scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); | |||||
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 bars */ | |||||
updatebars(); | |||||
updatestatus(); |
@@ -1,808 +0,0 @@ | |||||
diff --git a/config.def.h b/config.def.h | |||||
index fd77a07..8cc91c0 100644 | |||||
--- a/config.def.h | |||||
+++ b/config.def.h | |||||
@@ -5,6 +5,14 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ | |||||
static const unsigned int snap = 32; /* snap pixel */ | |||||
static const int showbar = 1; /* 0 means no bar */ | |||||
static const int topbar = 1; /* 0 means bottom bar */ | |||||
+ | |||||
+/* Display modes of the tab bar: never shown, always shown, shown only in */ | |||||
+/* monocle mode in presence of several windows. */ | |||||
+/* Modes after showtab_nmodes are disabled */ | |||||
+enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always}; | |||||
+static const int showtab = showtab_auto; /* Default tab bar show mode */ | |||||
+static const Bool toptab = False; /* False means bottom tab bar */ | |||||
+ | |||||
static const char *fonts[] = { "monospace:size=10" }; | |||||
static const char dmenufont[] = "monospace:size=10"; | |||||
static const char col_gray1[] = "#222222"; | |||||
@@ -18,9 +26,15 @@ static const char *colors[SchemeLast][3] = { | |||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan }, | |||||
}; | |||||
+ | |||||
/* tagging */ | |||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; | |||||
+/* default layout per tags */ | |||||
+/* The first element is for all-tag view, following i-th element corresponds to */ | |||||
+/* tags[i]. Layout is referred using the layouts array index.*/ | |||||
+static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | |||||
+ | |||||
static const Rule rules[] = { | |||||
/* xprop(1): | |||||
* WM_CLASS(STRING) = instance, class | |||||
@@ -64,6 +78,7 @@ static Key keys[] = { | |||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } }, | |||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, | |||||
{ MODKEY, XK_b, togglebar, {0} }, | |||||
+ { MODKEY, XK_w, tabmode, {-1} }, | |||||
{ MODKEY, XK_j, focusstack, {.i = +1 } }, | |||||
{ MODKEY, XK_k, focusstack, {.i = -1 } }, | |||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } }, | |||||
@@ -111,5 +126,6 @@ static Button buttons[] = { | |||||
{ ClkTagBar, 0, Button3, toggleview, {0} }, | |||||
{ ClkTagBar, MODKEY, Button1, tag, {0} }, | |||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} }, | |||||
+ { ClkTabBar, 0, Button1, focuswin, {0} }, | |||||
}; | |||||
diff --git a/dwm.1 b/dwm.1 | |||||
index 6687011..077d92b 100644 | |||||
--- a/dwm.1 | |||||
+++ b/dwm.1 | |||||
@@ -19,14 +19,22 @@ layout applied. | |||||
Windows are grouped by tags. Each window can be tagged with one or multiple | |||||
tags. Selecting certain tags displays all windows with these tags. | |||||
.P | |||||
-Each screen contains a small status bar which displays all available tags, the | |||||
-layout, the title of the focused window, and the text read from the root window | |||||
-name property, if the screen is focused. A floating window is indicated with an | |||||
-empty square and a maximised floating window is indicated with a filled square | |||||
-before the windows title. The selected tags are indicated with a different | |||||
-color. The tags of the focused window are indicated with a filled square in the | |||||
-top left corner. The tags which are applied to one or more windows are | |||||
-indicated with an empty square in the top left corner. | |||||
+Each screen contains two small status bars. | |||||
+.P | |||||
+One bar displays all available tags, the layout, the title of the focused | |||||
+window, and the text read from the root window name property, if the screen is | |||||
+focused. A floating window is indicated with an empty square and a maximised | |||||
+floating window is indicated with a filled square before the windows title. The | |||||
+selected tags are indicated with a different color. The tags of the focused | |||||
+window are indicated with a filled square in the top left corner. The tags | |||||
+which are applied to one or more windows are indicated with an empty square in | |||||
+the top left corner. | |||||
+.P | |||||
+Another bar contains a tab for each window of the current view and allows | |||||
+navigation between windows, especially in the monocle mode. The different | |||||
+display modes of this bar are described under the Mod1\-w Keybord command | |||||
+section. When a single tag is selected, that tag is indicated in the left corner | |||||
+of the tab bar. | |||||
.P | |||||
dwm draws a small border around windows to indicate the focus state. | |||||
.SH OPTIONS | |||||
@@ -43,7 +51,8 @@ command. | |||||
.TP | |||||
.B Button1 | |||||
click on a tag label to display all windows with that tag, click on the layout | |||||
-label toggles between tiled and floating layout. | |||||
+label toggles between tiled and floating layout, click on a window name in the | |||||
+tab bar brings focus to that window. | |||||
.TP | |||||
.B Button3 | |||||
click on a tag label adds/removes all windows with that tag to/from the view. | |||||
@@ -104,6 +113,12 @@ Increase master area size. | |||||
.B Mod1\-h | |||||
Decrease master area size. | |||||
.TP | |||||
+.B Mod1\-w | |||||
+Cycle over the tab bar display modes: never displayed, always displayed, | |||||
+displayed only in monocle mode when the view contains than one window (auto | |||||
+mode). Some display modes can be disabled in the configuration, config.h. In | |||||
+the default configuration only "never" and "auto" display modes are enabled. | |||||
+.TP | |||||
.B Mod1\-Return | |||||
Zooms/cycles focused window to/from master area (tiled layouts only). | |||||
.TP | |||||
diff --git a/dwm.c b/dwm.c | |||||
index b2bc9bd..0c34020 100644 | |||||
--- a/dwm.c | |||||
+++ b/dwm.c | |||||
@@ -65,7 +65,7 @@ enum { NetSupported, NetWMName, NetWMState, | |||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType, | |||||
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ | |||||
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ | |||||
-enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, | |||||
+enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, | |||||
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ | |||||
typedef union { | |||||
@@ -112,25 +112,35 @@ typedef struct { | |||||
void (*arrange)(Monitor *); | |||||
} Layout; | |||||
+#define MAXTABS 50 | |||||
+ | |||||
+typedef struct Pertag Pertag; | |||||
struct Monitor { | |||||
char ltsymbol[16]; | |||||
float mfact; | |||||
int nmaster; | |||||
int num; | |||||
int by; /* bar geometry */ | |||||
+ int ty; /* tab bar geometry */ | |||||
int mx, my, mw, mh; /* screen size */ | |||||
int wx, wy, ww, wh; /* window area */ | |||||
unsigned int seltags; | |||||
unsigned int sellt; | |||||
unsigned int tagset[2]; | |||||
int showbar; | |||||
+ int showtab; | |||||
int topbar; | |||||
+ int toptab; | |||||
Client *clients; | |||||
Client *sel; | |||||
Client *stack; | |||||
Monitor *next; | |||||
Window barwin; | |||||
+ Window tabwin; | |||||
+ int ntabs; | |||||
+ int tab_widths[MAXTABS]; | |||||
const Layout *lt[2]; | |||||
+ Pertag *pertag; | |||||
}; | |||||
typedef struct { | |||||
@@ -165,12 +175,15 @@ static void detachstack(Client *c); | |||||
static Monitor *dirtomon(int dir); | |||||
static void drawbar(Monitor *m); | |||||
static void drawbars(void); | |||||
+static void drawtab(Monitor *m); | |||||
+static void drawtabs(void); | |||||
static void enternotify(XEvent *e); | |||||
static void expose(XEvent *e); | |||||
static void focus(Client *c); | |||||
static void focusin(XEvent *e); | |||||
static void focusmon(const Arg *arg); | |||||
static void focusstack(const Arg *arg); | |||||
+static void focuswin(const Arg* arg); | |||||
static int getrootptr(int *x, int *y); | |||||
static long getstate(Window w); | |||||
static int gettextprop(Window w, Atom atom, char *text, unsigned int size); | |||||
@@ -207,6 +220,7 @@ static void setup(void); | |||||
static void showhide(Client *c); | |||||
static void sigchld(int unused); | |||||
static void spawn(const Arg *arg); | |||||
+static void tabmode(const Arg *arg); | |||||
static void tag(const Arg *arg); | |||||
static void tagmon(const Arg *arg); | |||||
static void tile(Monitor *); | |||||
@@ -241,6 +255,7 @@ static char stext[256]; | |||||
static int screen; | |||||
static int sw, sh; /* X display screen geometry width, height */ | |||||
static int bh, blw = 0; /* bar geometry */ | |||||
+static int th = 0; /* tab bar geometry */ | |||||
static int lrpad; /* sum of left and right padding for text */ | |||||
static int (*xerrorxlib)(Display *, XErrorEvent *); | |||||
static unsigned int numlockmask = 0; | |||||
@@ -272,6 +287,16 @@ static Window root; | |||||
/* configuration, allows nested code to access above variables */ | |||||
#include "config.h" | |||||
+struct Pertag { | |||||
+ unsigned int curtag, prevtag; /* current and previous tag */ | |||||
+ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ | |||||
+ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ | |||||
+ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ | |||||
+ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ | |||||
+ Bool showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ | |||||
+ Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ | |||||
+}; | |||||
+ | |||||
/* compile-time check if all tags fit into an unsigned int bit array. */ | |||||
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; | |||||
@@ -395,6 +420,8 @@ arrange(Monitor *m) | |||||
void | |||||
arrangemon(Monitor *m) | |||||
{ | |||||
+ updatebarpos(m); | |||||
+ XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th); | |||||
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); | |||||
if (m->lt[m->sellt]->arrange) | |||||
m->lt[m->sellt]->arrange(m); | |||||
@@ -444,14 +471,33 @@ buttonpress(XEvent *e) | |||||
click = ClkStatusText; | |||||
else | |||||
click = ClkWinTitle; | |||||
- } else if ((c = wintoclient(ev->window))) { | |||||
+ } | |||||
+ if(ev->window == selmon->tabwin) { | |||||
+ i = 0; x = 0; | |||||
+ for(c = selmon->clients; c; c = c->next){ | |||||
+ if(!ISVISIBLE(c)) continue; | |||||
+ x += selmon->tab_widths[i]; | |||||
+ if (ev->x > x) | |||||
+ ++i; | |||||
+ else | |||||
+ break; | |||||
+ if(i >= m->ntabs) break; | |||||
+ } | |||||
+ if(c) { | |||||
+ click = ClkTabBar; | |||||
+ arg.ui = i; | |||||
+ } | |||||
+ } | |||||
+ else if((c = wintoclient(ev->window))) { | |||||
focus(c); | |||||
click = ClkClientWin; | |||||
} | |||||
- for (i = 0; i < LENGTH(buttons); i++) | |||||
- if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button | |||||
- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) | |||||
- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); | |||||
+ for(i = 0; i < LENGTH(buttons); i++) | |||||
+ if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button | |||||
+ && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){ | |||||
+ buttons[i].func(((click == ClkTagBar || click == ClkTabBar) | |||||
+ && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); | |||||
+ } | |||||
} | |||||
void | |||||
@@ -476,8 +522,8 @@ cleanup(void) | |||||
view(&a); | |||||
selmon->lt[selmon->sellt] = &foo; | |||||
for (m = mons; m; m = m->next) | |||||
- while (m->stack) | |||||
- unmanage(m->stack, 0); | |||||
+ while(m->stack) | |||||
+ unmanage(m->stack, False); | |||||
XUngrabKey(dpy, AnyKey, AnyModifier, root); | |||||
while (mons) | |||||
cleanupmon(mons); | |||||
@@ -504,6 +550,8 @@ cleanupmon(Monitor *mon) | |||||
} | |||||
XUnmapWindow(dpy, mon->barwin); | |||||
XDestroyWindow(dpy, mon->barwin); | |||||
+ XUnmapWindow(dpy, mon->tabwin); | |||||
+ XDestroyWindow(dpy, mon->tabwin); | |||||
free(mon); | |||||
} | |||||
@@ -525,6 +573,7 @@ clientmessage(XEvent *e) | |||||
{ | |||||
XClientMessageEvent *cme = &e->xclient; | |||||
Client *c = wintoclient(cme->window); | |||||
+ int i; | |||||
if (!c) | |||||
return; | |||||
@@ -536,6 +585,8 @@ clientmessage(XEvent *e) | |||||
if (!ISVISIBLE(c)) { | |||||
c->mon->seltags ^= 1; | |||||
c->mon->tagset[c->mon->seltags] = c->tags; | |||||
+ for(i=0; !(c->tags & 1 << i); i++); | |||||
+ view(&(Arg){.ui = 1 << i}); | |||||
} | |||||
pop(c); | |||||
} | |||||
@@ -564,11 +615,10 @@ void | |||||
configurenotify(XEvent *e) | |||||
{ | |||||
Monitor *m; | |||||
- Client *c; | |||||
XConfigureEvent *ev = &e->xconfigure; | |||||
int dirty; | |||||
- /* TODO: updategeom handling sucks, needs to be simplified */ | |||||
+ // TODO: updategeom handling sucks, needs to be simplified | |||||
if (ev->window == root) { | |||||
dirty = (sw != ev->width || sh != ev->height); | |||||
sw = ev->width; | |||||
@@ -576,10 +626,9 @@ configurenotify(XEvent *e) | |||||
if (updategeom() || dirty) { | |||||
drw_resize(drw, sw, bh); | |||||
updatebars(); | |||||
- for (m = mons; m; m = m->next) { | |||||
- for (c = m->clients; c; c = c->next) | |||||
- if (c->isfullscreen) | |||||
- resizeclient(c, m->mx, m->my, m->mw, m->mh); | |||||
+ //refreshing display of status bar. The tab bar is handled by the arrange() | |||||
+ //method, which is called below | |||||
+ for (m = mons; m; m = m->next){ | |||||
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); | |||||
} | |||||
focus(NULL); | |||||
@@ -644,16 +693,41 @@ Monitor * | |||||
createmon(void) | |||||
{ | |||||
Monitor *m; | |||||
+ int i; | |||||
m = ecalloc(1, sizeof(Monitor)); | |||||
m->tagset[0] = m->tagset[1] = 1; | |||||
m->mfact = mfact; | |||||
m->nmaster = nmaster; | |||||
m->showbar = showbar; | |||||
+ m->showtab = showtab; | |||||
m->topbar = topbar; | |||||
- m->lt[0] = &layouts[0]; | |||||
+ m->toptab = toptab; | |||||
+ m->ntabs = 0; | |||||
+ m->lt[0] = &layouts[def_layouts[1] % LENGTH(layouts)]; | |||||
m->lt[1] = &layouts[1 % LENGTH(layouts)]; | |||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); | |||||
+ if(!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag)))) | |||||
+ die("fatal: could not malloc() %u bytes\n", sizeof(Pertag)); | |||||
+ m->pertag->curtag = m->pertag->prevtag = 1; | |||||
+ for(i=0; i <= LENGTH(tags); i++) { | |||||
+ /* init nmaster */ | |||||
+ m->pertag->nmasters[i] = m->nmaster; | |||||
+ | |||||
+ /* init mfacts */ | |||||
+ m->pertag->mfacts[i] = m->mfact; | |||||
+ | |||||
+ /* init layouts */ | |||||
+ m->pertag->ltidxs[i][0] = &layouts[def_layouts[i % LENGTH(def_layouts)] % LENGTH(layouts)]; | |||||
+ m->pertag->ltidxs[i][1] = m->lt[1]; | |||||
+ m->pertag->sellts[i] = m->sellt; | |||||
+ | |||||
+ /* init showbar */ | |||||
+ m->pertag->showbars[i] = m->showbar; | |||||
+ | |||||
+ /* swap focus and zoomswap*/ | |||||
+ m->pertag->prevzooms[i] = NULL; | |||||
+ } | |||||
return m; | |||||
} | |||||
@@ -765,6 +839,104 @@ drawbars(void) | |||||
} | |||||
void | |||||
+drawtabs(void) { | |||||
+ Monitor *m; | |||||
+ | |||||
+ for(m = mons; m; m = m->next) | |||||
+ drawtab(m); | |||||
+} | |||||
+ | |||||
+static int | |||||
+cmpint(const void *p1, const void *p2) { | |||||
+ /* The actual arguments to this function are "pointers to | |||||
+ pointers to char", but strcmp(3) arguments are "pointers | |||||
+ to char", hence the following cast plus dereference */ | |||||
+ return *((int*) p1) > * (int*) p2; | |||||
+} | |||||
+ | |||||
+ | |||||
+void | |||||
+drawtab(Monitor *m) { | |||||
+ Client *c; | |||||
+ int i; | |||||
+ int itag = -1; | |||||
+ char view_info[50]; | |||||
+ int view_info_w = 0; | |||||
+ int sorted_label_widths[MAXTABS]; | |||||
+ int tot_width; | |||||
+ int maxsize = bh; | |||||
+ int x = 0; | |||||
+ int w = 0; | |||||
+ | |||||
+ //view_info: indicate the tag which is displayed in the view | |||||
+ for(i = 0; i < LENGTH(tags); ++i){ | |||||
+ if((selmon->tagset[selmon->seltags] >> i) & 1) { | |||||
+ if(itag >=0){ //more than one tag selected | |||||
+ itag = -1; | |||||
+ break; | |||||
+ } | |||||
+ itag = i; | |||||
+ } | |||||
+ } | |||||
+ if(0 <= itag && itag < LENGTH(tags)){ | |||||
+ snprintf(view_info, sizeof view_info, "[%s]", tags[itag]); | |||||
+ } else { | |||||
+ strncpy(view_info, "[...]", sizeof view_info); | |||||
+ } | |||||
+ view_info[sizeof(view_info) - 1 ] = 0; | |||||
+ view_info_w = TEXTW(view_info); | |||||
+ tot_width = view_info_w; | |||||
+ | |||||
+ /* Calculates number of labels and their width */ | |||||
+ m->ntabs = 0; | |||||
+ for(c = m->clients; c; c = c->next){ | |||||
+ if(!ISVISIBLE(c)) continue; | |||||
+ m->tab_widths[m->ntabs] = TEXTW(c->name); | |||||
+ tot_width += m->tab_widths[m->ntabs]; | |||||
+ ++m->ntabs; | |||||
+ if(m->ntabs >= MAXTABS) break; | |||||
+ } | |||||
+ | |||||
+ if(tot_width > m->ww){ //not enough space to display the labels, they need to be truncated | |||||
+ memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); | |||||
+ qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); | |||||
+ tot_width = view_info_w; | |||||
+ for(i = 0; i < m->ntabs; ++i){ | |||||
+ if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww) | |||||
+ break; | |||||
+ tot_width += sorted_label_widths[i]; | |||||
+ } | |||||
+ maxsize = (m->ww - tot_width) / (m->ntabs - i); | |||||
+ } else{ | |||||
+ maxsize = m->ww; | |||||
+ } | |||||
+ i = 0; | |||||
+ for(c = m->clients; c; c = c->next){ | |||||
+ if(!ISVISIBLE(c)) continue; | |||||
+ if(i >= m->ntabs) break; | |||||
+ if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; | |||||
+ w = m->tab_widths[i]; | |||||
+ drw_setscheme(drw, (c == m->sel) ? scheme[SchemeSel] : scheme[SchemeNorm]); | |||||
+ drw_text(drw, x, 0, w, th, lrpad / 2, c->name, 0); | |||||
+ x += w; | |||||
+ ++i; | |||||
+ } | |||||
+ | |||||
+ drw_setscheme(drw, scheme[SchemeNorm]); | |||||
+ | |||||
+ /* cleans interspace between window names and current viewed tag label */ | |||||
+ w = m->ww - view_info_w - x; | |||||
+ drw_text(drw, x, 0, w, th, lrpad / 2, "", 0); | |||||
+ | |||||
+ /* view info */ | |||||
+ x += w; | |||||
+ w = view_info_w; | |||||
+ drw_text(drw, x, 0, w, th, lrpad / 2, view_info, 0); | |||||
+ | |||||
+ drw_map(drw, m->tabwin, 0, 0, m->ww, th); | |||||
+} | |||||
+ | |||||
+void | |||||
enternotify(XEvent *e) | |||||
{ | |||||
Client *c; | |||||
@@ -789,8 +961,10 @@ expose(XEvent *e) | |||||
Monitor *m; | |||||
XExposeEvent *ev = &e->xexpose; | |||||
- if (ev->count == 0 && (m = wintomon(ev->window))) | |||||
+ if (ev->count == 0 && (m = wintomon(ev->window))){ | |||||
drawbar(m); | |||||
+ drawtab(m); | |||||
+ } | |||||
} | |||||
void | |||||
@@ -817,6 +991,7 @@ focus(Client *c) | |||||
} | |||||
selmon->sel = c; | |||||
drawbars(); | |||||
+ drawtabs(); | |||||
} | |||||
/* there are some broken focus acquiring clients */ | |||||
@@ -870,6 +1045,19 @@ focusstack(const Arg *arg) | |||||
} | |||||
} | |||||
+void | |||||
+focuswin(const Arg* arg){ | |||||
+ int iwin = arg->i; | |||||
+ Client* c = NULL; | |||||
+ for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ | |||||
+ if(ISVISIBLE(c)) --iwin; | |||||
+ }; | |||||
+ if(c) { | |||||
+ focus(c); | |||||
+ restack(selmon); | |||||
+ } | |||||
+} | |||||
+ | |||||
Atom | |||||
getatomprop(Client *c, Atom prop) | |||||
{ | |||||
@@ -983,7 +1171,7 @@ grabkeys(void) | |||||
void | |||||
incnmaster(const Arg *arg) | |||||
{ | |||||
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); | |||||
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); | |||||
arrange(selmon); | |||||
} | |||||
@@ -1142,7 +1330,7 @@ motionnotify(XEvent *e) | |||||
if (ev->window != root) | |||||
return; | |||||
if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { | |||||
- unfocus(selmon->sel, 1); | |||||
+ unfocus(selmon->sel, True); | |||||
selmon = m; | |||||
focus(NULL); | |||||
} | |||||
@@ -1162,11 +1350,13 @@ movemouse(const Arg *arg) | |||||
return; | |||||
if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ | |||||
return; | |||||
+ if(c->isfullscreen) /* no support moving fullscreen windows by mouse */ | |||||
+ return; | |||||
restack(selmon); | |||||
ocx = c->x; | |||||
ocy = c->y; | |||||
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, | |||||
- None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) | |||||
+ None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) | |||||
return; | |||||
if (!getrootptr(&x, &y)) | |||||
return; | |||||
@@ -1253,12 +1443,14 @@ propertynotify(XEvent *e) | |||||
case XA_WM_HINTS: | |||||
updatewmhints(c); | |||||
drawbars(); | |||||
+ drawtabs(); | |||||
break; | |||||
} | |||||
if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { | |||||
updatetitle(c); | |||||
if (c == c->mon->sel) | |||||
drawbar(c->mon); | |||||
+ drawtab(c->mon); | |||||
} | |||||
if (ev->atom == netatom[NetWMWindowType]) | |||||
updatewindowtype(c); | |||||
@@ -1320,11 +1512,13 @@ resizemouse(const Arg *arg) | |||||
return; | |||||
if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ | |||||
return; | |||||
+ if(c->isfullscreen) /* no support resizing fullscreen windows by mouse */ | |||||
+ return; | |||||
restack(selmon); | |||||
ocx = c->x; | |||||
ocy = c->y; | |||||
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, | |||||
- None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) | |||||
+ None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) | |||||
return; | |||||
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); | |||||
do { | |||||
@@ -1372,6 +1566,7 @@ restack(Monitor *m) | |||||
XWindowChanges wc; | |||||
drawbar(m); | |||||
+ drawtab(m); | |||||
if (!m->sel) | |||||
return; | |||||
if (m->sel->isfloating || !m->lt[m->sellt]->arrange) | |||||
@@ -1480,11 +1675,11 @@ sendevent(Client *c, Atom proto) | |||||
void | |||||
setfocus(Client *c) | |||||
{ | |||||
- if (!c->neverfocus) { | |||||
+ if(!c->neverfocus) { | |||||
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); | |||||
XChangeProperty(dpy, root, netatom[NetActiveWindow], | |||||
- XA_WINDOW, 32, PropModeReplace, | |||||
- (unsigned char *) &(c->win), 1); | |||||
+ XA_WINDOW, 32, PropModeReplace, | |||||
+ (unsigned char *) &(c->win), 1); | |||||
} | |||||
sendevent(c, wmatom[WMTakeFocus]); | |||||
} | |||||
@@ -1520,10 +1715,13 @@ setfullscreen(Client *c, int fullscreen) | |||||
void | |||||
setlayout(const Arg *arg) | |||||
{ | |||||
- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) | |||||
- selmon->sellt ^= 1; | |||||
- if (arg && arg->v) | |||||
- selmon->lt[selmon->sellt] = (Layout *)arg->v; | |||||
+ if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) { | |||||
+ selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; | |||||
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; | |||||
+ } | |||||
+ if(arg && arg->v) | |||||
+ selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; | |||||
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; | |||||
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); | |||||
if (selmon->sel) | |||||
arrange(selmon); | |||||
@@ -1542,7 +1740,7 @@ setmfact(const Arg *arg) | |||||
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; | |||||
if (f < 0.1 || f > 0.9) | |||||
return; | |||||
- selmon->mfact = f; | |||||
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; | |||||
arrange(selmon); | |||||
} | |||||
@@ -1564,6 +1762,7 @@ setup(void) | |||||
die("no fonts could be loaded.\n"); | |||||
lrpad = drw->fonts->h; | |||||
bh = drw->fonts->h + 2; | |||||
+ th = bh; | |||||
updategeom(); | |||||
/* init atoms */ | |||||
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | |||||
@@ -1631,10 +1830,10 @@ sigchld(int unused) | |||||
void | |||||
spawn(const Arg *arg) | |||||
{ | |||||
- if (arg->v == dmenucmd) | |||||
+ if(arg->v == dmenucmd) | |||||
dmenumon[0] = '0' + selmon->num; | |||||
- if (fork() == 0) { | |||||
- if (dpy) | |||||
+ if(fork() == 0) { | |||||
+ if(dpy) | |||||
close(ConnectionNumber(dpy)); | |||||
setsid(); | |||||
execvp(((char **)arg->v)[0], (char **)arg->v); | |||||
@@ -1691,18 +1890,29 @@ tile(Monitor *m) | |||||
void | |||||
togglebar(const Arg *arg) | |||||
{ | |||||
- selmon->showbar = !selmon->showbar; | |||||
+ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; | |||||
updatebarpos(selmon); | |||||
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); | |||||
arrange(selmon); | |||||
} | |||||
void | |||||
+tabmode(const Arg *arg) | |||||
+{ | |||||
+ if(arg && arg->i >= 0) | |||||
+ selmon->showtab = arg->ui % showtab_nmodes; | |||||
+ else | |||||
+ selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; | |||||
+ arrange(selmon); | |||||
+} | |||||
+ | |||||
+ | |||||
+void | |||||
togglefloating(const Arg *arg) | |||||
{ | |||||
- if (!selmon->sel) | |||||
+ if(!selmon->sel) | |||||
return; | |||||
- if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ | |||||
+ if(selmon->sel->isfullscreen) /* no support for fullscreen windows */ | |||||
return; | |||||
selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; | |||||
if (selmon->sel->isfloating) | |||||
@@ -1730,9 +1940,29 @@ void | |||||
toggleview(const Arg *arg) | |||||
{ | |||||
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); | |||||
+ int i; | |||||
if (newtagset) { | |||||
+ if(newtagset == ~0) { | |||||
+ selmon->pertag->prevtag = selmon->pertag->curtag; | |||||
+ selmon->pertag->curtag = 0; | |||||
+ } | |||||
+ /* test if the user did not select the same tag */ | |||||
+ if(!(newtagset & 1 << (selmon->pertag->curtag - 1))) { | |||||
+ selmon->pertag->prevtag = selmon->pertag->curtag; | |||||
+ for (i=0; !(newtagset & 1 << i); i++) ; | |||||
+ selmon->pertag->curtag = i + 1; | |||||
+ } | |||||
selmon->tagset[selmon->seltags] = newtagset; | |||||
+ | |||||
+ /* apply settings for this view */ | |||||
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; | |||||
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; | |||||
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; | |||||
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; | |||||
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; | |||||
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) | |||||
+ togglebar(NULL); | |||||
focus(NULL); | |||||
arrange(selmon); | |||||
} | |||||
@@ -1808,20 +2038,44 @@ updatebars(void) | |||||
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); | |||||
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); | |||||
XMapRaised(dpy, m->barwin); | |||||
+ m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen), | |||||
+ CopyFromParent, DefaultVisual(dpy, screen), | |||||
+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); | |||||
+ XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); | |||||
+ XMapRaised(dpy, m->tabwin); | |||||
} | |||||
} | |||||
void | |||||
updatebarpos(Monitor *m) | |||||
{ | |||||
+ Client *c; | |||||
+ int nvis = 0; | |||||
+ | |||||
m->wy = m->my; | |||||
m->wh = m->mh; | |||||
if (m->showbar) { | |||||
m->wh -= bh; | |||||
m->by = m->topbar ? m->wy : m->wy + m->wh; | |||||
- m->wy = m->topbar ? m->wy + bh : m->wy; | |||||
- } else | |||||
+ if ( m->topbar ) | |||||
+ m->wy += bh; | |||||
+ } else { | |||||
m->by = -bh; | |||||
+ } | |||||
+ | |||||
+ for(c = m->clients; c; c = c->next){ | |||||
+ if(ISVISIBLE(c)) ++nvis; | |||||
+ } | |||||
+ | |||||
+ if(m->showtab == showtab_always | |||||
+ || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){ | |||||
+ m->wh -= th; | |||||
+ m->ty = m->toptab ? m->wy : m->wy + m->wh; | |||||
+ if ( m->toptab ) | |||||
+ m->wy += th; | |||||
+ } else { | |||||
+ m->ty = -th; | |||||
+ } | |||||
} | |||||
void | |||||
@@ -2003,9 +2257,9 @@ updatewindowtype(Client *c) | |||||
Atom wtype = getatomprop(c, netatom[NetWMWindowType]); | |||||
if (state == netatom[NetWMFullscreen]) | |||||
- setfullscreen(c, 1); | |||||
+ setfullscreen(c, True); | |||||
if (wtype == netatom[NetWMWindowTypeDialog]) | |||||
- c->isfloating = 1; | |||||
+ c->isfloating = True; | |||||
} | |||||
void | |||||
@@ -2030,11 +2284,33 @@ updatewmhints(Client *c) | |||||
void | |||||
view(const Arg *arg) | |||||
{ | |||||
- if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) | |||||
+ int i; | |||||
+ unsigned int tmptag; | |||||
+ | |||||
+ if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) | |||||
return; | |||||
selmon->seltags ^= 1; /* toggle sel tagset */ | |||||
- if (arg->ui & TAGMASK) | |||||
+ if(arg->ui & TAGMASK) { | |||||
+ selmon->pertag->prevtag = selmon->pertag->curtag; | |||||
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; | |||||
+ if(arg->ui == ~0) | |||||
+ selmon->pertag->curtag = 0; | |||||
+ else { | |||||
+ for (i=0; !(arg->ui & 1 << i); i++) ; | |||||
+ selmon->pertag->curtag = i + 1; | |||||
+ } | |||||
+ } else { | |||||
+ tmptag = selmon->pertag->prevtag; | |||||
+ selmon->pertag->prevtag = selmon->pertag->curtag; | |||||
+ selmon->pertag->curtag = tmptag; | |||||
+ } | |||||
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; | |||||
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; | |||||
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; | |||||
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; | |||||
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; | |||||
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) | |||||
+ togglebar(NULL); | |||||
focus(NULL); | |||||
arrange(selmon); | |||||
} | |||||
@@ -2062,7 +2338,7 @@ wintomon(Window w) | |||||
if (w == root && getrootptr(&x, &y)) | |||||
return recttomon(x, y, 1, 1); | |||||
for (m = mons; m; m = m->next) | |||||
- if (w == m->barwin) | |||||
+ if(w == m->barwin || w == m->tabwin) | |||||
return m; | |||||
if ((c = wintoclient(w))) | |||||
return c->mon; |
@@ -1,176 +0,0 @@ | |||||
.TH DWM 1 dwm\-VERSION | |||||
.SH NAME | |||||
dwm \- dynamic window manager | |||||
.SH SYNOPSIS | |||||
.B dwm | |||||
.RB [ \-v ] | |||||
.SH DESCRIPTION | |||||
dwm is a dynamic window manager for X. It manages windows in tiled, monocle | |||||
and floating layouts. Either layout can be applied dynamically, optimising the | |||||
environment for the application in use and the task performed. | |||||
.P | |||||
In tiled layouts windows are managed in a master and stacking area. The master | |||||
area on the left contains one window by default, and the stacking area on the | |||||
right contains all other windows. The number of master area windows can be | |||||
adjusted from zero to an arbitrary number. In monocle layout all windows are | |||||
maximised to the screen size. In floating layout windows can be resized and | |||||
moved freely. Dialog windows are always managed floating, regardless of the | |||||
layout applied. | |||||
.P | |||||
Windows are grouped by tags. Each window can be tagged with one or multiple | |||||
tags. Selecting certain tags displays all windows with these tags. | |||||
.P | |||||
Each screen contains a small status bar which displays all available tags, the | |||||
layout, the title of the focused window, and the text read from the root window | |||||
name property, if the screen is focused. A floating window is indicated with an | |||||
empty square and a maximised floating window is indicated with a filled square | |||||
before the windows title. The selected tags are indicated with a different | |||||
color. The tags of the focused window are indicated with a filled square in the | |||||
top left corner. The tags which are applied to one or more windows are | |||||
indicated with an empty square in the top left corner. | |||||
.P | |||||
dwm draws a small border around windows to indicate the focus state. | |||||
.SH OPTIONS | |||||
.TP | |||||
.B \-v | |||||
prints version information to standard output, then exits. | |||||
.SH USAGE | |||||
.SS Status bar | |||||
.TP | |||||
.B X root window name | |||||
is read and displayed in the status text area. It can be set with the | |||||
.BR xsetroot (1) | |||||
command. | |||||
.TP | |||||
.B Button1 | |||||
click on a tag label to display all windows with that tag, click on the layout | |||||
label toggles between tiled and floating layout. | |||||
.TP | |||||
.B Button3 | |||||
click on a tag label adds/removes all windows with that tag to/from the view. | |||||
.TP | |||||
.B Mod1\-Button1 | |||||
click on a tag label applies that tag to the focused window. | |||||
.TP | |||||
.B Mod1\-Button3 | |||||
click on a tag label adds/removes that tag to/from the focused window. | |||||
.SS Keyboard commands | |||||
.TP | |||||
.B Mod1\-Shift\-Return | |||||
Start | |||||
.BR st(1). | |||||
.TP | |||||
.B Mod1\-p | |||||
Spawn | |||||
.BR dmenu(1) | |||||
for launching other programs. | |||||
.TP | |||||
.B Mod1\-, | |||||
Focus previous screen, if any. | |||||
.TP | |||||
.B Mod1\-. | |||||
Focus next screen, if any. | |||||
.TP | |||||
.B Mod1\-Shift\-, | |||||
Send focused window to previous screen, if any. | |||||
.TP | |||||
.B Mod1\-Shift\-. | |||||
Send focused window to next screen, if any. | |||||
.TP | |||||
.B Mod1\-b | |||||
Toggles bar on and off. | |||||
.TP | |||||
.B Mod1\-t | |||||
Sets tiled layout. | |||||
.TP | |||||
.B Mod1\-f | |||||
Sets floating layout. | |||||
.TP | |||||
.B Mod1\-m | |||||
Sets monocle layout. | |||||
.TP | |||||
.B Mod1\-space | |||||
Toggles between current and previous layout. | |||||
.TP | |||||
.B Mod1\-j | |||||
Focus next window. | |||||
.TP | |||||
.B Mod1\-k | |||||
Focus previous window. | |||||
.TP | |||||
.B Mod1\-i | |||||
Increase number of windows in master area. | |||||
.TP | |||||
.B Mod1\-d | |||||
Decrease number of windows in master area. | |||||
.TP | |||||
.B Mod1\-l | |||||
Increase master area size. | |||||
.TP | |||||
.B Mod1\-h | |||||
Decrease master area size. | |||||
.TP | |||||
.B Mod1\-Return | |||||
Zooms/cycles focused window to/from master area (tiled layouts only). | |||||
.TP | |||||
.B Mod1\-Shift\-c | |||||
Close focused window. | |||||
.TP | |||||
.B Mod1\-Shift\-space | |||||
Toggle focused window between tiled and floating state. | |||||
.TP | |||||
.B Mod1\-Tab | |||||
Toggles to the previously selected tags. | |||||
.TP | |||||
.B Mod1\-Shift\-[1..n] | |||||
Apply nth tag to focused window. | |||||
.TP | |||||
.B Mod1\-Shift\-0 | |||||
Apply all tags to focused window. | |||||
.TP | |||||
.B Mod1\-Control\-Shift\-[1..n] | |||||
Add/remove nth tag to/from focused window. | |||||
.TP | |||||
.B Mod1\-[1..n] | |||||
View all windows with nth tag. | |||||
.TP | |||||
.B Mod1\-0 | |||||
View all windows with any tag. | |||||
.TP | |||||
.B Mod1\-Control\-[1..n] | |||||
Add/remove all windows with nth tag to/from the view. | |||||
.TP | |||||
.B Mod1\-Shift\-q | |||||
Quit dwm. | |||||
.SS Mouse commands | |||||
.TP | |||||
.B Mod1\-Button1 | |||||
Move focused window while dragging. Tiled windows will be toggled to the floating state. | |||||
.TP | |||||
.B Mod1\-Button2 | |||||
Toggles focused window between floating and tiled state. | |||||
.TP | |||||
.B Mod1\-Button3 | |||||
Resize focused window while dragging. Tiled windows will be toggled to the floating state. | |||||
.SH CUSTOMIZATION | |||||
dwm is customized by creating a custom config.h and (re)compiling the source | |||||
code. This keeps it fast, secure and simple. | |||||
.SH SEE ALSO | |||||
.BR dmenu (1), | |||||
.BR st (1) | |||||
.SH ISSUES | |||||
Java applications which use the XToolkit/XAWT backend may draw grey windows | |||||
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early | |||||
JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds | |||||
are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the | |||||
environment variable | |||||
.BR AWT_TOOLKIT=MToolkit | |||||
(to use the older Motif backend instead) or running | |||||
.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D | |||||
or | |||||
.B wmname LG3D | |||||
(to pretend that a non-reparenting window manager is running that the | |||||
XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable | |||||
.BR _JAVA_AWT_WM_NONREPARENTING=1 . | |||||
.SH BUGS | |||||
Send all bug reports with a patch to hackers@suckless.org. |
@@ -65,12 +65,12 @@ | |||||
/* enums */ | /* enums */ | ||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ | enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ | ||||
enum { SchemeNorm, SchemeSel }; /* color schemes */ | |||||
enum { SchemeNorm, SchemeSel, SchemeDis}; /* color schemes */ | |||||
enum { NetSupported, NetWMName, NetWMState, NetWMCheck, | enum { NetSupported, NetWMName, NetWMState, NetWMCheck, | ||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType, | NetWMFullscreen, NetActiveWindow, NetWMWindowType, | ||||
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ | NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ | ||||
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ | enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ | ||||
enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, | |||||
enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, | |||||
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ | ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ | ||||
typedef union { | typedef union { | ||||
@@ -280,6 +280,8 @@ static int sw, sh; /* X display screen geometry width, height */ | |||||
static int bh, blw = 0; /* bar geometry */ | static int bh, blw = 0; /* bar geometry */ | ||||
static int th = 0; /* tab bar geometry */ | static int th = 0; /* tab bar geometry */ | ||||
static int lrpad; /* sum of left and right padding for text */ | static int lrpad; /* sum of left and right padding for text */ | ||||
static int vp; /* vertical padding for bar */ | |||||
static int sp; /* side padding for bar */ | |||||
static int (*xerrorxlib)(Display *, XErrorEvent *); | static int (*xerrorxlib)(Display *, XErrorEvent *); | ||||
static unsigned int numlockmask = 0; | static unsigned int numlockmask = 0; | ||||
static void (*handler[LASTEvent]) (XEvent *) = { | static void (*handler[LASTEvent]) (XEvent *) = { | ||||
@@ -301,7 +303,8 @@ static void (*handler[LASTEvent]) (XEvent *) = { | |||||
static Atom wmatom[WMLast], netatom[NetLast]; | static Atom wmatom[WMLast], netatom[NetLast]; | ||||
static int running = 1; | static int running = 1; | ||||
static Cur *cursor[CurLast]; | static Cur *cursor[CurLast]; | ||||
static Clr **scheme; | |||||
static Clr **scheme, clrborder; | |||||
static Clr **tagscheme; | |||||
static Display *dpy; | static Display *dpy; | ||||
static Drw *drw; | static Drw *drw; | ||||
static Monitor *mons, *selmon; | static Monitor *mons, *selmon; | ||||
@@ -571,10 +574,8 @@ buttonpress(XEvent *e) | |||||
arg.ui = 1 << i; | arg.ui = 1 << i; | ||||
} else if (ev->x < x + blw) | } else if (ev->x < x + blw) | ||||
click = ClkLtSymbol; | click = ClkLtSymbol; | ||||
else if (ev->x > selmon->ww - TEXTW(stext)) | |||||
click = ClkStatusText; | |||||
else | else | ||||
click = ClkWinTitle; | |||||
click = ClkStatusText; | |||||
} | } | ||||
if(ev->window == selmon->tabwin) { | if(ev->window == selmon->tabwin) { | ||||
i = 0; x = 0; | i = 0; x = 0; | ||||
@@ -719,7 +720,7 @@ configurenotify(XEvent *e) | |||||
//refreshing display of status bar. The tab bar is handled by the arrange() | //refreshing display of status bar. The tab bar is handled by the arrange() | ||||
//method, which is called below | //method, which is called below | ||||
for (m = mons; m; m = m->next){ | for (m = mons; m; m = m->next){ | ||||
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); | |||||
XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh); | |||||
} | } | ||||
focus(NULL); | focus(NULL); | ||||
arrange(NULL); | arrange(NULL); | ||||
@@ -911,14 +912,14 @@ drawstatusbar(Monitor *m, int bh, char* stext) { | |||||
isCode = 0; | isCode = 0; | ||||
text = p; | text = p; | ||||
w += 2; /* 1px padding on both sides */ | |||||
ret = x = m->ww - w; | |||||
w += horizpadbar; | |||||
ret = x = m->ww - borderpx - w - 2 * sp; | |||||
drw_setscheme(drw, scheme[LENGTH(colors)]); | drw_setscheme(drw, scheme[LENGTH(colors)]); | ||||
drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; | drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; | ||||
drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; | drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; | ||||
drw_rect(drw, x, 0, w, bh, 1, 1); | |||||
x++; | |||||
drw_rect(drw, x, borderpx, w - 2 * sp, bh, 1, 1); | |||||
x += horizpadbar / 2; | |||||
/* process status text */ | /* process status text */ | ||||
i = -1; | i = -1; | ||||
@@ -928,7 +929,7 @@ drawstatusbar(Monitor *m, int bh, char* stext) { | |||||
text[i] = '\0'; | text[i] = '\0'; | ||||
w = TEXTW(text) - lrpad; | w = TEXTW(text) - lrpad; | ||||
drw_text(drw, x, 0, w, bh, 0, text, 0); | |||||
drw_text(drw, x, borderpx + vertpadbar / 2, w, bh - vertpadbar, 0, text, 0); | |||||
x += w; | x += w; | ||||
@@ -958,7 +959,7 @@ drawstatusbar(Monitor *m, int bh, char* stext) { | |||||
while (text[++i] != ','); | while (text[++i] != ','); | ||||
int rh = atoi(text + ++i); | int rh = atoi(text + ++i); | ||||
drw_rect(drw, rx + x, ry, rw, rh, 1, 0); | |||||
drw_rect(drw, rx + x, ry + borderpx + vertpadbar / 2, rw, rh, 1, 0); | |||||
} else if (text[i] == 'f') { | } else if (text[i] == 'f') { | ||||
x += atoi(text + ++i); | x += atoi(text + ++i); | ||||
} | } | ||||
@@ -972,7 +973,7 @@ drawstatusbar(Monitor *m, int bh, char* stext) { | |||||
if (!isCode) { | if (!isCode) { | ||||
w = TEXTW(text) - lrpad; | w = TEXTW(text) - lrpad; | ||||
drw_text(drw, x, 0, w, bh, 0, text, 0); | |||||
drw_text(drw, x, borderpx + vertpadbar / 2, w, bh - vertpadbar, 0, text, 0); | |||||
} | } | ||||
drw_setscheme(drw, scheme[SchemeNorm]); | drw_setscheme(drw, scheme[SchemeNorm]); | ||||
@@ -984,15 +985,20 @@ drawstatusbar(Monitor *m, int bh, char* stext) { | |||||
void | void | ||||
drawbar(Monitor *m) | drawbar(Monitor *m) | ||||
{ | { | ||||
int x, w, sw = 0; | |||||
int x, y = borderpx, w, sw = 0, stw = 0; | |||||
int th = bh - borderpx * 2; | |||||
int mw = m->ww - borderpx * 2; | |||||
int boxs = drw->fonts->h / 9; | int boxs = drw->fonts->h / 9; | ||||
int boxw = drw->fonts->h / 6 + 2; | int boxw = drw->fonts->h / 6 + 2; | ||||
unsigned int i, occ = 0, urg = 0; | unsigned int i, occ = 0, urg = 0; | ||||
Client *c; | Client *c; | ||||
XSetForeground(drw->dpy, drw->gc, clrborder.pixel); | |||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, 0, 0, m->ww, bh); | |||||
/* draw status first so it can be overdrawn by tags later */ | /* draw status first so it can be overdrawn by tags later */ | ||||
if (m == selmon) { /* status is only drawn on selected monitor */ | if (m == selmon) { /* status is only drawn on selected monitor */ | ||||
sw = m->ww - drawstatusbar(m, bh, stext); | |||||
sw = mw - drawstatusbar(m, th, stext); | |||||
} | } | ||||
for (c = m->clients; c; c = c->next) { | for (c = m->clients; c; c = c->next) { | ||||
@@ -1000,34 +1006,22 @@ drawbar(Monitor *m) | |||||
if (c->isurgent) | if (c->isurgent) | ||||
urg |= c->tags; | urg |= c->tags; | ||||
} | } | ||||
x = 0; | |||||
x = borderpx; | |||||
for (i = 0; i < LENGTH(tags); i++) { | for (i = 0; i < LENGTH(tags); i++) { | ||||
w = TEXTW(tags[i]); | 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 (occ & 1 << i) | |||||
drw_rect(drw, x + boxs, boxs, boxw, boxw, | |||||
m == selmon && selmon->sel && selmon->sel->tags & 1 << i, | |||||
urg & 1 << i); | |||||
drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : (occ & 1 << i ? tagscheme[i] : scheme[SchemeDis]))); | |||||
drw_text(drw, x, y, w, th, 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, th - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0); | |||||
x += w; | x += w; | ||||
} | } | ||||
w = blw = TEXTW(m->ltsymbol); | w = blw = TEXTW(m->ltsymbol); | ||||
drw_setscheme(drw, scheme[SchemeNorm]); | drw_setscheme(drw, scheme[SchemeNorm]); | ||||
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); | |||||
if ((w = m->ww - sw - x) > bh) { | |||||
if (m->sel) { | |||||
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); | |||||
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); | |||||
if (m->sel->isfloating) { | |||||
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); | |||||
if (m->sel->isalwaysontop) | |||||
drw_rect(drw, x + boxs, bh - boxw, boxw, boxw, 0, 0); | |||||
} | |||||
} else { | |||||
drw_setscheme(drw, scheme[SchemeNorm]); | |||||
drw_rect(drw, x, 0, w, bh, 1, 1); | |||||
} | |||||
x = drw_text(drw, x, y, w, th, lrpad / 2, m->ltsymbol, 0); | |||||
if ((w = mw - sw - stw - x) > th) { | |||||
drw_setscheme(drw, scheme[SchemeNorm]); | |||||
drw_rect(drw, x, y, w - 2 * sp, th, 1, 1); | |||||
} | } | ||||
drw_map(drw, m->barwin, 0, 0, m->ww, bh); | drw_map(drw, m->barwin, 0, 0, m->ww, bh); | ||||
} | } | ||||
@@ -1650,8 +1644,6 @@ propertynotify(XEvent *e) | |||||
} | } | ||||
if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { | if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { | ||||
updatetitle(c); | updatetitle(c); | ||||
if (c == c->mon->sel) | |||||
drawbar(c->mon); | |||||
drawtab(c->mon); | drawtab(c->mon); | ||||
} | } | ||||
if (ev->atom == netatom[NetWMWindowType]) | if (ev->atom == netatom[NetWMWindowType]) | ||||
@@ -1994,9 +1986,12 @@ setup(void) | |||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) | if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) | ||||
die("no fonts could be loaded."); | die("no fonts could be loaded."); | ||||
lrpad = drw->fonts->h; | lrpad = drw->fonts->h; | ||||
bh = drw->fonts->h + 2; | |||||
bh = user_bh ? user_bh : drw->fonts->h + 2 + vertpadbar + borderpx * 2; | |||||
th = bh; | th = bh; | ||||
updategeom(); | updategeom(); | ||||
sp = sidepad; | |||||
vp = (topbar == 1) ? vertpad : - vertpad; | |||||
/* init atoms */ | /* init atoms */ | ||||
utf8string = XInternAtom(dpy, "UTF8_STRING", False); | utf8string = XInternAtom(dpy, "UTF8_STRING", False); | ||||
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); | ||||
@@ -2017,13 +2012,20 @@ setup(void) | |||||
cursor[CurResize] = drw_cur_create(drw, XC_sizing); | cursor[CurResize] = drw_cur_create(drw, XC_sizing); | ||||
cursor[CurMove] = drw_cur_create(drw, XC_fleur); | cursor[CurMove] = drw_cur_create(drw, XC_fleur); | ||||
/* init appearance */ | /* init appearance */ | ||||
if (LENGTH(tags) > LENGTH(tagsel)) | |||||
die("too few color schemes for the tags"); | |||||
scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); | scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); | ||||
scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); | scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); | ||||
for (i = 0; i < LENGTH(colors); i++) | for (i = 0; i < LENGTH(colors); i++) | ||||
scheme[i] = drw_scm_create(drw, colors[i], 3); | scheme[i] = drw_scm_create(drw, colors[i], 3); | ||||
drw_clr_create(drw, &clrborder, col_borderbar); | |||||
tagscheme = ecalloc(LENGTH(tagsel), sizeof(Clr *)); | |||||
for (i = 0; i < LENGTH(tagsel); i++) | |||||
tagscheme[i] = drw_scm_create(drw, tagsel[i], 2); | |||||
/* init bars */ | /* init bars */ | ||||
updatebars(); | updatebars(); | ||||
updatestatus(); | updatestatus(); | ||||
updatebarpos(selmon); | |||||
/* supporting window for NetWMCheck */ | /* supporting window for NetWMCheck */ | ||||
wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); | wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); | ||||
XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, | XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, | ||||
@@ -2168,7 +2170,7 @@ togglebar(const Arg *arg) | |||||
{ | { | ||||
selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; | selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; | ||||
updatebarpos(selmon); | updatebarpos(selmon); | ||||
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); | |||||
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh); | |||||
arrange(selmon); | arrange(selmon); | ||||
} | } | ||||
@@ -2352,7 +2354,7 @@ updatebars(void) | |||||
for (m = mons; m; m = m->next) { | for (m = mons; m; m = m->next) { | ||||
if (m->barwin) | if (m->barwin) | ||||
continue; | continue; | ||||
m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), | |||||
m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, DefaultDepth(dpy, screen), | |||||
CopyFromParent, DefaultVisual(dpy, screen), | CopyFromParent, DefaultVisual(dpy, screen), | ||||
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); | CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); | ||||
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); | XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); | ||||
@@ -2375,12 +2377,12 @@ updatebarpos(Monitor *m) | |||||
m->wy = m->my; | m->wy = m->my; | ||||
m->wh = m->mh; | m->wh = m->mh; | ||||
if (m->showbar) { | if (m->showbar) { | ||||
m->wh -= bh; | |||||
m->by = m->topbar ? m->wy : m->wy + m->wh; | |||||
m->wh = m->wh - vertpad - bh; | |||||
m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad; | |||||
if ( m->topbar ) | if ( m->topbar ) | ||||
m->wy += bh; | |||||
m->wy += bh + vp; | |||||
} else { | } else { | ||||
m->by = -bh; | |||||
m->by = -bh - vp; | |||||
} | } | ||||
for(c = m->clients; c; c = c->next){ | for(c = m->clients; c; c = c->next){ | ||||
@@ -65,12 +65,12 @@ | |||||
/* enums */ | /* enums */ | ||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ | enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ | ||||
enum { SchemeNorm, SchemeSel }; /* color schemes */ | |||||
enum { SchemeNorm, SchemeSel, SchemeDis}; /* color schemes */ | |||||
enum { NetSupported, NetWMName, NetWMState, NetWMCheck, | enum { NetSupported, NetWMName, NetWMState, NetWMCheck, | ||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType, | NetWMFullscreen, NetActiveWindow, NetWMWindowType, | ||||
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ | NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ | ||||
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ | enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ | ||||
enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, | |||||
enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, | |||||
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ | ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ | ||||
typedef union { | typedef union { | ||||
@@ -185,6 +185,7 @@ static void detachstack(Client *c); | |||||
static Monitor *dirtomon(int dir); | static Monitor *dirtomon(int dir); | ||||
static void drawbar(Monitor *m); | static void drawbar(Monitor *m); | ||||
static void drawbars(void); | static void drawbars(void); | ||||
static int drawstatusbar(Monitor *m, int bh, char* text); | |||||
static void drawtab(Monitor *m); | static void drawtab(Monitor *m); | ||||
static void drawtabs(void); | static void drawtabs(void); | ||||
static void enternotify(XEvent *e); | static void enternotify(XEvent *e); | ||||
@@ -273,7 +274,7 @@ static pid_t winpid(Window w); | |||||
/* variables */ | /* variables */ | ||||
static const char broken[] = "broken"; | static const char broken[] = "broken"; | ||||
static char stext[256]; | |||||
static char stext[1024]; | |||||
static int screen; | static int screen; | ||||
static int sw, sh; /* X display screen geometry width, height */ | static int sw, sh; /* X display screen geometry width, height */ | ||||
static int bh, blw = 0; /* bar geometry */ | static int bh, blw = 0; /* bar geometry */ | ||||
@@ -300,7 +301,8 @@ static void (*handler[LASTEvent]) (XEvent *) = { | |||||
static Atom wmatom[WMLast], netatom[NetLast]; | static Atom wmatom[WMLast], netatom[NetLast]; | ||||
static int running = 1; | static int running = 1; | ||||
static Cur *cursor[CurLast]; | static Cur *cursor[CurLast]; | ||||
static Clr **scheme; | |||||
static Clr **scheme, clrborder; | |||||
static Clr **tagscheme; | |||||
static Display *dpy; | static Display *dpy; | ||||
static Drw *drw; | static Drw *drw; | ||||
static Monitor *mons, *selmon; | static Monitor *mons, *selmon; | ||||
@@ -570,10 +572,8 @@ buttonpress(XEvent *e) | |||||
arg.ui = 1 << i; | arg.ui = 1 << i; | ||||
} else if (ev->x < x + blw) | } else if (ev->x < x + blw) | ||||
click = ClkLtSymbol; | click = ClkLtSymbol; | ||||
else if (ev->x > selmon->ww - TEXTW(stext)) | |||||
click = ClkStatusText; | |||||
else | else | ||||
click = ClkWinTitle; | |||||
click = ClkStatusText; | |||||
} | } | ||||
if(ev->window == selmon->tabwin) { | if(ev->window == selmon->tabwin) { | ||||
i = 0; x = 0; | i = 0; x = 0; | ||||
@@ -634,7 +634,7 @@ cleanup(void) | |||||
cleanupmon(mons); | cleanupmon(mons); | ||||
for (i = 0; i < CurLast; i++) | for (i = 0; i < CurLast; i++) | ||||
drw_cur_free(drw, cursor[i]); | drw_cur_free(drw, cursor[i]); | ||||
for (i = 0; i < LENGTH(colors); i++) | |||||
for (i = 0; i < LENGTH(colors) + 1; i++) | |||||
free(scheme[i]); | free(scheme[i]); | ||||
XDestroyWindow(dpy, wmcheckwin); | XDestroyWindow(dpy, wmcheckwin); | ||||
drw_free(drw); | drw_free(drw); | ||||
@@ -872,20 +872,131 @@ dirtomon(int dir) | |||||
return m; | return m; | ||||
} | } | ||||
int | |||||
drawstatusbar(Monitor *m, int bh, char* stext) { | |||||
int ret, i, w, x, len; | |||||
short isCode = 0; | |||||
char *text; | |||||
char *p; | |||||
len = strlen(stext) + 1 ; | |||||
if (!(text = (char*) malloc(sizeof(char)*len))) | |||||
die("malloc"); | |||||
p = text; | |||||
memcpy(text, stext, len); | |||||
/* compute width of the status text */ | |||||
w = 0; | |||||
i = -1; | |||||
while (text[++i]) { | |||||
if (text[i] == '^') { | |||||
if (!isCode) { | |||||
isCode = 1; | |||||
text[i] = '\0'; | |||||
w += TEXTW(text) - lrpad; | |||||
text[i] = '^'; | |||||
if (text[++i] == 'f') | |||||
w += atoi(text + ++i); | |||||
} else { | |||||
isCode = 0; | |||||
text = text + i + 1; | |||||
i = -1; | |||||
} | |||||
} | |||||
} | |||||
if (!isCode) | |||||
w += TEXTW(text) - lrpad; | |||||
else | |||||
isCode = 0; | |||||
text = p; | |||||
w += horizpadbar; | |||||
ret = x = m->ww - borderpx - w; | |||||
drw_setscheme(drw, scheme[LENGTH(colors)]); | |||||
drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; | |||||
drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; | |||||
drw_rect(drw, x, borderpx, w, bh, 1, 1); | |||||
x += horizpadbar / 2; | |||||
/* process status text */ | |||||
i = -1; | |||||
while (text[++i]) { | |||||
if (text[i] == '^' && !isCode) { | |||||
isCode = 1; | |||||
text[i] = '\0'; | |||||
w = TEXTW(text) - lrpad; | |||||
drw_text(drw, x, borderpx + vertpadbar / 2, w, bh - vertpadbar, 0, text, 0); | |||||
x += w; | |||||
/* process code */ | |||||
while (text[++i] != '^') { | |||||
if (text[i] == 'c') { | |||||
char buf[8]; | |||||
memcpy(buf, (char*)text+i+1, 7); | |||||
buf[7] = '\0'; | |||||
drw_clr_create(drw, &drw->scheme[ColFg], buf); | |||||
i += 7; | |||||
} else if (text[i] == 'b') { | |||||
char buf[8]; | |||||
memcpy(buf, (char*)text+i+1, 7); | |||||
buf[7] = '\0'; | |||||
drw_clr_create(drw, &drw->scheme[ColBg], buf); | |||||
i += 7; | |||||
} else if (text[i] == 'd') { | |||||
drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; | |||||
drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; | |||||
} else if (text[i] == 'r') { | |||||
int rx = atoi(text + ++i); | |||||
while (text[++i] != ','); | |||||
int ry = atoi(text + ++i); | |||||
while (text[++i] != ','); | |||||
int rw = atoi(text + ++i); | |||||
while (text[++i] != ','); | |||||
int rh = atoi(text + ++i); | |||||
drw_rect(drw, rx + x, ry + borderpx + vertpadbar / 2, rw, rh, 1, 0); | |||||
} else if (text[i] == 'f') { | |||||
x += atoi(text + ++i); | |||||
} | |||||
} | |||||
text = text + i + 1; | |||||
i=-1; | |||||
isCode = 0; | |||||
} | |||||
} | |||||
if (!isCode) { | |||||
w = TEXTW(text) - lrpad; | |||||
drw_text(drw, x, borderpx + vertpadbar / 2, w, bh - vertpadbar, 0, text, 0); | |||||
} | |||||
drw_setscheme(drw, scheme[SchemeNorm]); | |||||
free(p); | |||||
return ret; | |||||
} | |||||
void | void | ||||
drawbar(Monitor *m) | drawbar(Monitor *m) | ||||
{ | { | ||||
int x, w, sw = 0; | |||||
int x, y = borderpx, w, sw = 0, stw = 0; | |||||
int th = bh - borderpx * 2; | |||||
int mw = m->ww - borderpx * 2; | |||||
int boxs = drw->fonts->h / 9; | int boxs = drw->fonts->h / 9; | ||||
int boxw = drw->fonts->h / 6 + 2; | int boxw = drw->fonts->h / 6 + 2; | ||||
unsigned int i, occ = 0, urg = 0; | unsigned int i, occ = 0, urg = 0; | ||||
Client *c; | Client *c; | ||||
XSetForeground(drw->dpy, drw->gc, clrborder.pixel); | |||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, 0, 0, m->ww, bh); | |||||
/* draw status first so it can be overdrawn by tags later */ | /* draw status first so it can be overdrawn by tags later */ | ||||
if (m == selmon) { /* status is only drawn on selected monitor */ | if (m == selmon) { /* status is only drawn on selected monitor */ | ||||
drw_setscheme(drw, scheme[SchemeNorm]); | |||||
sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ | |||||
drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); | |||||
sw = mw - drawstatusbar(m, th, stext); | |||||
} | } | ||||
for (c = m->clients; c; c = c->next) { | for (c = m->clients; c; c = c->next) { | ||||
@@ -893,34 +1004,22 @@ drawbar(Monitor *m) | |||||
if (c->isurgent) | if (c->isurgent) | ||||
urg |= c->tags; | urg |= c->tags; | ||||
} | } | ||||
x = 0; | |||||
x = borderpx; | |||||
for (i = 0; i < LENGTH(tags); i++) { | for (i = 0; i < LENGTH(tags); i++) { | ||||
w = TEXTW(tags[i]); | 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 (occ & 1 << i) | |||||
drw_rect(drw, x + boxs, boxs, boxw, boxw, | |||||
m == selmon && selmon->sel && selmon->sel->tags & 1 << i, | |||||
urg & 1 << i); | |||||
drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : (occ & 1 << i ? tagscheme[i] : scheme[SchemeDis]))); | |||||
drw_text(drw, x, y, w, th, 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, th - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0); | |||||
x += w; | x += w; | ||||
} | } | ||||
w = blw = TEXTW(m->ltsymbol); | w = blw = TEXTW(m->ltsymbol); | ||||
drw_setscheme(drw, scheme[SchemeNorm]); | drw_setscheme(drw, scheme[SchemeNorm]); | ||||
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); | |||||
if ((w = m->ww - sw - x) > bh) { | |||||
if (m->sel) { | |||||
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); | |||||
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); | |||||
if (m->sel->isfloating) { | |||||
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); | |||||
if (m->sel->isalwaysontop) | |||||
drw_rect(drw, x + boxs, bh - boxw, boxw, boxw, 0, 0); | |||||
} | |||||
} else { | |||||
drw_setscheme(drw, scheme[SchemeNorm]); | |||||
drw_rect(drw, x, 0, w, bh, 1, 1); | |||||
} | |||||
x = drw_text(drw, x, y, w, th, lrpad / 2, m->ltsymbol, 0); | |||||
if ((w = mw - sw - stw - x) > th) { | |||||
drw_setscheme(drw, scheme[SchemeNorm]); | |||||
drw_rect(drw, x, y, w, th, 1, 1); | |||||
} | } | ||||
drw_map(drw, m->barwin, 0, 0, m->ww, bh); | drw_map(drw, m->barwin, 0, 0, m->ww, bh); | ||||
} | } | ||||
@@ -1543,8 +1642,6 @@ propertynotify(XEvent *e) | |||||
} | } | ||||
if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { | if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { | ||||
updatetitle(c); | updatetitle(c); | ||||
if (c == c->mon->sel) | |||||
drawbar(c->mon); | |||||
drawtab(c->mon); | drawtab(c->mon); | ||||
} | } | ||||
if (ev->atom == netatom[NetWMWindowType]) | if (ev->atom == netatom[NetWMWindowType]) | ||||
@@ -1887,7 +1984,7 @@ setup(void) | |||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) | if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) | ||||
die("no fonts could be loaded."); | die("no fonts could be loaded."); | ||||
lrpad = drw->fonts->h; | lrpad = drw->fonts->h; | ||||
bh = drw->fonts->h + 2; | |||||
bh = user_bh ? user_bh : drw->fonts->h + 2 + vertpadbar + borderpx * 2; | |||||
th = bh; | th = bh; | ||||
updategeom(); | updategeom(); | ||||
/* init atoms */ | /* init atoms */ | ||||
@@ -1910,9 +2007,16 @@ setup(void) | |||||
cursor[CurResize] = drw_cur_create(drw, XC_sizing); | cursor[CurResize] = drw_cur_create(drw, XC_sizing); | ||||
cursor[CurMove] = drw_cur_create(drw, XC_fleur); | cursor[CurMove] = drw_cur_create(drw, XC_fleur); | ||||
/* init appearance */ | /* init appearance */ | ||||
scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); | |||||
if (LENGTH(tags) > LENGTH(tagsel)) | |||||
die("too few color schemes for the tags"); | |||||
scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); | |||||
scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); | |||||
for (i = 0; i < LENGTH(colors); i++) | for (i = 0; i < LENGTH(colors); i++) | ||||
scheme[i] = drw_scm_create(drw, colors[i], 3); | scheme[i] = drw_scm_create(drw, colors[i], 3); | ||||
drw_clr_create(drw, &clrborder, col_borderbar); | |||||
tagscheme = ecalloc(LENGTH(tagsel), sizeof(Clr *)); | |||||
for (i = 0; i < LENGTH(tagsel); i++) | |||||
tagscheme[i] = drw_scm_create(drw, tagsel[i], 2); | |||||
/* init bars */ | /* init bars */ | ||||
updatebars(); | updatebars(); | ||||
updatestatus(); | updatestatus(); | ||||
@@ -1,10 +1,51 @@ | |||||
--- dwm.c | |||||
+++ dwm.c | |||||
@@ -163,6 +163,7 @@ static void detach(Client *c); | |||||
static Monitor *dirtomon(int dir); | |||||
static void drawbar(Monitor *m); | |||||
static void drawbars(void); | |||||
+static int drawstatusbar(Monitor *m, int bh, char* text); | |||||
static void enternotify(XEvent *e); | |||||
static void expose(XEvent *e); | |||||
static void focus(Client *c); | |||||
--- dwm.c 2019-12-10 17:24:37.945708263 +1300 | |||||
+++ dwm.c 2019-12-10 17:41:46.192676099 +1300 | |||||
@@ -569,7 +571,7 @@ configurenotify(XEvent *e) | |||||
for (c = m->clients; c; c = c->next) | |||||
if (c->isfullscreen) | |||||
resizeclient(c, m->mx, m->my, m->mw, m->mh); | |||||
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); | |||||
+ XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh); | |||||
} | |||||
focus(NULL); | |||||
arrange(NULL); | |||||
@@ -707,7 +709,7 @@ drawbar(Monitor *m) | |||||
if (m == selmon) { /* status is only drawn on selected monitor */ | |||||
drw_setscheme(drw, scheme[SchemeNorm]); | |||||
sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ | |||||
- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); | |||||
+ drw_text(drw, m->ww - sw - 2 * sp, 0, sw, bh, 0, stext, 0); | |||||
} | |||||
for (c = m->clients; c; c = c->next) { | |||||
@@ -733,12 +735,12 @@ drawbar(Monitor *m) | |||||
if ((w = m->ww - sw - x) > bh) { | |||||
if (m->sel) { | |||||
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); | |||||
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); | |||||
+ drw_text(drw, x, 0, w - 2 * sp, bh, lrpad / 2, m->sel->name, 0); | |||||
if (m->sel->isfloating) | |||||
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); | |||||
} else { | |||||
drw_setscheme(drw, scheme[SchemeNorm]); | |||||
- drw_rect(drw, x, 0, w, bh, 1, 1); | |||||
+ drw_rect(drw, x, 0, w - 2 * sp, bh, 1, 1); | |||||
} | |||||
} | |||||
drw_map(drw, m->barwin, 0, 0, m->ww, bh); | |||||
@@ -1832,11 +1838,11 @@ updatebarpos(Monitor *m) | |||||
m->wy = m->my; | |||||
m->wh = m->mh; | |||||
if (m->showbar) { | |||||
- m->wh -= bh; | |||||
- m->by = m->topbar ? m->wy : m->wy + m->wh; | |||||
- m->wy = m->topbar ? m->wy + bh : m->wy; | |||||
+ m->wh = m->wh - vertpad - bh; | |||||
+ m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad; | |||||
+ m->wy = m->topbar ? m->wy + bh + vp : m->wy; | |||||
} else | |||||
- m->by = -bh; | |||||
+ m->by = -bh - vp; | |||||
} | |||||
void |
@@ -5,3 +5,9 @@ center | |||||
centeredmaster | centeredmaster | ||||
fullgaps | fullgaps | ||||
swallow | swallow | ||||
notitle | |||||
rainbowtags | |||||
statuspadding | |||||
underlinetags | |||||
pertag | |||||
barpadding |