Browse Source

status bar improvements

master
RinRi 2 years ago
parent
commit
25fa2df0c5
14 changed files with 475 additions and 1262 deletions
  1. +36
    -0
      .Xresources
  2. +30
    -8
      config.def.h
  3. +126
    -81
      config.def.h.orig
  4. +5
    -27
      config.def.h.rej
  5. +30
    -8
      config.h
  6. BIN
      dwm
  7. +0
    -59
      dwm-rainbowtags-6.2.diff
  8. +0
    -808
      dwm-tab-v2b-pertab-56a31dc.diff
  9. +0
    -176
      dwm.1.orig
  10. +49
    -47
      dwm.c
  11. +142
    -38
      dwm.c.orig
  12. +51
    -10
      dwm.c.rej
  13. BIN
      dwm.o
  14. +6
    -0
      patches.txt

+ 36
- 0
.Xresources View File

@@ -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

+ 30
- 8
config.def.h View File

@@ -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 showbar = 1; /* 0 means no 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 */
/* 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 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_gray2[] = "#444444";
static const char col_gray2[] = "#666666";
static const char col_gray3[] = "#bbbbbb";
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] = {
/* 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[] = {
@@ -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 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[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
@@ -90,7 +113,7 @@ static const Layout layouts[] = {

/* commands */
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 };

#include <X11/XF86keysym.h>
@@ -171,7 +194,6 @@ static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },


+ 126
- 81
config.def.h.orig View File

@@ -2,47 +2,86 @@

/* appearance */
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 int swallowfloating = 0; /* 1 means swallow floating windows by default */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const 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 dmenufont[] = "monospace:size=13";
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_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] = {
/* 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[] = {
"sh", "-c", "sh ~/scripts/xinit.sh", NULL,
"dunst", NULL,
"slstatus", NULL,
NULL /* terminate */
};

/* 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[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* 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) */
@@ -72,73 +111,79 @@ static const Layout layouts[] = {

/* commands */
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 };

#include <X11/XF86keysym.h>

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 */
@@ -147,7 +192,6 @@ static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
@@ -156,5 +200,6 @@ static Button buttons[] = {
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
{ ClkTabBar, 0, Button1, focuswin, {0} },
};


+ 5
- 27
config.def.h.rej View File

@@ -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 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 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 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

+ 30
- 8
config.h View File

@@ -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 showbar = 1; /* 0 means no 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 */
/* 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 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_gray2[] = "#444444";
static const char col_gray2[] = "#666666";
static const char col_gray3[] = "#bbbbbb";
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] = {
/* 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[] = {
@@ -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 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[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
@@ -90,7 +113,7 @@ static const Layout layouts[] = {

/* commands */
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 };

#include <X11/XF86keysym.h>
@@ -171,7 +194,6 @@ static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },


BIN
dwm View File


+ 0
- 59
dwm-rainbowtags-6.2.diff View File

@@ -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();

+ 0
- 808
dwm-tab-v2b-pertab-56a31dc.diff View File

@@ -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;

+ 0
- 176
dwm.1.orig View File

@@ -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.

+ 49
- 47
dwm.c View File

@@ -65,12 +65,12 @@

/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { SchemeNorm, SchemeSel }; /* color schemes */
enum { SchemeNorm, SchemeSel, SchemeDis}; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */

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 th = 0; /* tab bar geometry */
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 unsigned int numlockmask = 0;
static void (*handler[LASTEvent]) (XEvent *) = {
@@ -301,7 +303,8 @@ static void (*handler[LASTEvent]) (XEvent *) = {
static Atom wmatom[WMLast], netatom[NetLast];
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
static Clr **scheme, clrborder;
static Clr **tagscheme;
static Display *dpy;
static Drw *drw;
static Monitor *mons, *selmon;
@@ -571,10 +574,8 @@ buttonpress(XEvent *e)
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
else if (ev->x > selmon->ww - TEXTW(stext))
click = ClkStatusText;
else
click = ClkWinTitle;
click = ClkStatusText;
}
if(ev->window == selmon->tabwin) {
i = 0; x = 0;
@@ -719,7 +720,7 @@ configurenotify(XEvent *e)
//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);
XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh);
}
focus(NULL);
arrange(NULL);
@@ -911,14 +912,14 @@ drawstatusbar(Monitor *m, int bh, char* stext) {
isCode = 0;
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->scheme[ColFg] = scheme[SchemeNorm][ColFg];
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 */
i = -1;
@@ -928,7 +929,7 @@ drawstatusbar(Monitor *m, int bh, char* stext) {

text[i] = '\0';
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;

@@ -958,7 +959,7 @@ drawstatusbar(Monitor *m, int bh, char* stext) {
while (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') {
x += atoi(text + ++i);
}
@@ -972,7 +973,7 @@ drawstatusbar(Monitor *m, int bh, char* stext) {

if (!isCode) {
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]);
@@ -984,15 +985,20 @@ drawstatusbar(Monitor *m, int bh, char* stext) {
void
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 boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
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 */
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) {
@@ -1000,34 +1006,22 @@ drawbar(Monitor *m)
if (c->isurgent)
urg |= c->tags;
}
x = 0;
x = borderpx;
for (i = 0; i < LENGTH(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;
}
w = blw = TEXTW(m->ltsymbol);
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);
}
@@ -1650,8 +1644,6 @@ propertynotify(XEvent *e)
}
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])
@@ -1994,9 +1986,12 @@ setup(void)
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
bh = drw->fonts->h + 2;
bh = user_bh ? user_bh : drw->fonts->h + 2 + vertpadbar + borderpx * 2;
th = bh;
updategeom();
sp = sidepad;
vp = (topbar == 1) ? vertpad : - vertpad;

/* init atoms */
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
@@ -2017,13 +2012,20 @@ setup(void)
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
/* init appearance */
if (LENGTH(tags) > LENGTH(tagsel))
die("too few color schemes for the tags");
scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *));
scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3);
for (i = 0; i < LENGTH(colors); i++)
scheme[i] = drw_scm_create(drw, colors[i], 3);
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 */
updatebars();
updatestatus();
updatebarpos(selmon);
/* supporting window for NetWMCheck */
wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
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;
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);
}

@@ -2352,7 +2354,7 @@ updatebars(void)
for (m = mons; m; m = m->next) {
if (m->barwin)
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),
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
@@ -2375,12 +2377,12 @@ 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->wh = m->wh - vertpad - bh;
m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad;
if ( m->topbar )
m->wy += bh;
m->wy += bh + vp;
} else {
m->by = -bh;
m->by = -bh - vp;
}

for(c = m->clients; c; c = c->next){


+ 142
- 38
dwm.c.orig View File

@@ -65,12 +65,12 @@

/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { SchemeNorm, SchemeSel }; /* color schemes */
enum { SchemeNorm, SchemeSel, SchemeDis}; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */

typedef union {
@@ -185,6 +185,7 @@ static void detachstack(Client *c);
static Monitor *dirtomon(int dir);
static void drawbar(Monitor *m);
static void drawbars(void);
static int drawstatusbar(Monitor *m, int bh, char* text);
static void drawtab(Monitor *m);
static void drawtabs(void);
static void enternotify(XEvent *e);
@@ -273,7 +274,7 @@ static pid_t winpid(Window w);

/* variables */
static const char broken[] = "broken";
static char stext[256];
static char stext[1024];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@@ -300,7 +301,8 @@ static void (*handler[LASTEvent]) (XEvent *) = {
static Atom wmatom[WMLast], netatom[NetLast];
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
static Clr **scheme, clrborder;
static Clr **tagscheme;
static Display *dpy;
static Drw *drw;
static Monitor *mons, *selmon;
@@ -570,10 +572,8 @@ buttonpress(XEvent *e)
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
else if (ev->x > selmon->ww - TEXTW(stext))
click = ClkStatusText;
else
click = ClkWinTitle;
click = ClkStatusText;
}
if(ev->window == selmon->tabwin) {
i = 0; x = 0;
@@ -634,7 +634,7 @@ cleanup(void)
cleanupmon(mons);
for (i = 0; i < CurLast; i++)
drw_cur_free(drw, cursor[i]);
for (i = 0; i < LENGTH(colors); i++)
for (i = 0; i < LENGTH(colors) + 1; i++)
free(scheme[i]);
XDestroyWindow(dpy, wmcheckwin);
drw_free(drw);
@@ -872,20 +872,131 @@ dirtomon(int dir)
return m;
}

int
drawstatusbar(Monitor *m, int bh, char* stext) {
int ret, i, w, x, len;
short isCode = 0;
char *text;
char *p;

len = strlen(stext) + 1 ;
if (!(text = (char*) malloc(sizeof(char)*len)))
die("malloc");
p = text;
memcpy(text, stext, len);

/* compute width of the status text */
w = 0;
i = -1;
while (text[++i]) {
if (text[i] == '^') {
if (!isCode) {
isCode = 1;
text[i] = '\0';
w += TEXTW(text) - lrpad;
text[i] = '^';
if (text[++i] == 'f')
w += atoi(text + ++i);
} else {
isCode = 0;
text = text + i + 1;
i = -1;
}
}
}
if (!isCode)
w += TEXTW(text) - lrpad;
else
isCode = 0;
text = p;

w += 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
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 boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
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 */
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) {
@@ -893,34 +1004,22 @@ drawbar(Monitor *m)
if (c->isurgent)
urg |= c->tags;
}
x = 0;
x = borderpx;
for (i = 0; i < LENGTH(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;
}
w = blw = TEXTW(m->ltsymbol);
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);
}
@@ -1543,8 +1642,6 @@ propertynotify(XEvent *e)
}
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])
@@ -1887,7 +1984,7 @@ setup(void)
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
bh = drw->fonts->h + 2;
bh = user_bh ? user_bh : drw->fonts->h + 2 + vertpadbar + borderpx * 2;
th = bh;
updategeom();
/* init atoms */
@@ -1910,9 +2007,16 @@ setup(void)
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
/* init appearance */
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
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++)
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 */
updatebars();
updatestatus();


+ 51
- 10
dwm.c.rej View File

@@ -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

BIN
dwm.o View File


+ 6
- 0
patches.txt View File

@@ -5,3 +5,9 @@ center
centeredmaster
fullgaps
swallow
notitle
rainbowtags
statuspadding
underlinetags
pertag
barpadding

Loading…
Cancel
Save