Compare commits
	
		
			8 Commits
		
	
	
		
			f7fdd0bdc3
			...
			master
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 196da2f243 | ||
|   | df372959b0 | ||
|   | d3d34aaa84 | ||
|   | afa4d7420c | ||
|   | 021f3bae93 | ||
|   | d74d889cca | ||
|   | d8676b687e | ||
|   | f80338211b | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | dwm | ||||||
|  | *.o | ||||||
							
								
								
									
										1
									
								
								.pc/.quilt_patches
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.pc/.quilt_patches
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | patches | ||||||
							
								
								
									
										1
									
								
								.pc/.quilt_series
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.pc/.quilt_series
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | series | ||||||
							
								
								
									
										1
									
								
								.pc/.version
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.pc/.version
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | 2 | ||||||
							
								
								
									
										4
									
								
								.pc/applied-patches
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.pc/applied-patches
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | dwm-swallow-6.3.diff | ||||||
|  | dwm-hide_vacant_tags-6.4.diff | ||||||
|  | dwm-pertag-20200914-61bb8b2.diff | ||||||
|  | dwm-statuscmd-20241009-8933ebc.diff | ||||||
							
								
								
									
										0
									
								
								.pc/dwm-hide_vacant_tags-6.4.diff/.timestamp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								.pc/dwm-hide_vacant_tags-6.4.diff/.timestamp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										2387
									
								
								.pc/dwm-hide_vacant_tags-6.4.diff/dwm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2387
									
								
								.pc/dwm-hide_vacant_tags-6.4.diff/dwm.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										0
									
								
								.pc/dwm-pertag-20200914-61bb8b2.diff/.timestamp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								.pc/dwm-pertag-20200914-61bb8b2.diff/.timestamp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										2392
									
								
								.pc/dwm-pertag-20200914-61bb8b2.diff/dwm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2392
									
								
								.pc/dwm-pertag-20200914-61bb8b2.diff/dwm.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										0
									
								
								.pc/dwm-statuscmd-20241009-8933ebc.diff/.timestamp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								.pc/dwm-statuscmd-20241009-8933ebc.diff/.timestamp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										120
									
								
								.pc/dwm-statuscmd-20241009-8933ebc.diff/config.def.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								.pc/dwm-statuscmd-20241009-8933ebc.diff/config.def.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | |||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  |  | ||||||
|  | /* appearance */ | ||||||
|  | static const unsigned int borderpx  = 1;        /* border pixel of windows */ | ||||||
|  | static const unsigned int snap      = 32;       /* snap pixel */ | ||||||
|  | static const int swallowfloating    = 0;        /* 1 means swallow floating windows by default */ | ||||||
|  | static const int showbar            = 1;        /* 0 means no bar */ | ||||||
|  | static const int topbar             = 1;        /* 0 means bottom bar */ | ||||||
|  | static const char *fonts[]          = { "monospace:size=10" }; | ||||||
|  | static const char dmenufont[]       = "monospace:size=10"; | ||||||
|  | static const char col_gray1[]       = "#222222"; | ||||||
|  | static const char col_gray2[]       = "#444444"; | ||||||
|  | static const char col_gray3[]       = "#bbbbbb"; | ||||||
|  | static const char col_gray4[]       = "#eeeeee"; | ||||||
|  | static const char col_cyan[]        = "#005577"; | ||||||
|  | static const char *colors[][3]      = { | ||||||
|  | 	/*               fg         bg         border   */ | ||||||
|  | 	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | ||||||
|  | 	[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* tagging */ | ||||||
|  | static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; | ||||||
|  |  | ||||||
|  | static const Rule rules[] = { | ||||||
|  | 	/* xprop(1): | ||||||
|  | 	 *	WM_CLASS(STRING) = instance, class | ||||||
|  | 	 *	WM_NAME(STRING) = title | ||||||
|  | 	 */ | ||||||
|  | 	/* class     instance  title           tags mask  isfloating  isterminal  noswallow  monitor */ | ||||||
|  | 	{ "Gimp",    NULL,     NULL,           0,         1,          0,           0,        -1 }, | ||||||
|  | 	{ "Firefox", NULL,     NULL,           1 << 8,    0,          0,          -1,        -1 }, | ||||||
|  | 	{ "St",      NULL,     NULL,           0,         0,          1,           0,        -1 }, | ||||||
|  | 	{ NULL,      NULL,     "Event Tester", 0,         0,          0,           1,        -1 }, /* xev */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* layout(s) */ | ||||||
|  | static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */ | ||||||
|  | static const int nmaster     = 1;    /* number of clients in master area */ | ||||||
|  | static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */ | ||||||
|  | static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ | ||||||
|  | static const int refreshrate = 120;  /* refresh rate (per second) for client move/resize */ | ||||||
|  |  | ||||||
|  | static const Layout layouts[] = { | ||||||
|  | 	/* symbol     arrange function */ | ||||||
|  | 	{ "[]=",      tile },    /* first entry is default */ | ||||||
|  | 	{ "><>",      NULL },    /* no layout function means floating behavior */ | ||||||
|  | 	{ "[M]",      monocle }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* key definitions */ | ||||||
|  | #define MODKEY Mod1Mask | ||||||
|  | #define TAGKEYS(KEY,TAG) \ | ||||||
|  | 	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} }, | ||||||
|  |  | ||||||
|  | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ | ||||||
|  | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } | ||||||
|  |  | ||||||
|  | /* 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 *termcmd[]  = { "st", NULL }; | ||||||
|  |  | ||||||
|  | static const Key keys[] = { | ||||||
|  | 	/* modifier                     key        function        argument */ | ||||||
|  | 	{ 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_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 } }, | ||||||
|  | 	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 */ | ||||||
|  | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ | ||||||
|  | static const 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} }, | ||||||
|  | 	{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} }, | ||||||
|  | 	{ ClkTagBar,            0,              Button1,        view,           {0} }, | ||||||
|  | 	{ ClkTagBar,            0,              Button3,        toggleview,     {0} }, | ||||||
|  | 	{ ClkTagBar,            MODKEY,         Button1,        tag,            {0} }, | ||||||
|  | 	{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} }, | ||||||
|  | }; | ||||||
|  |  | ||||||
							
								
								
									
										2468
									
								
								.pc/dwm-statuscmd-20241009-8933ebc.diff/dwm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2468
									
								
								.pc/dwm-statuscmd-20241009-8933ebc.diff/dwm.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										0
									
								
								.pc/dwm-swallow-6.3.diff/.timestamp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								.pc/dwm-swallow-6.3.diff/.timestamp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										117
									
								
								.pc/dwm-swallow-6.3.diff/config.def.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								.pc/dwm-swallow-6.3.diff/config.def.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | |||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  |  | ||||||
|  | /* appearance */ | ||||||
|  | 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 */ | ||||||
|  | static const char *fonts[]          = { "monospace:size=10" }; | ||||||
|  | static const char dmenufont[]       = "monospace:size=10"; | ||||||
|  | static const char col_gray1[]       = "#222222"; | ||||||
|  | static const char col_gray2[]       = "#444444"; | ||||||
|  | static const char col_gray3[]       = "#bbbbbb"; | ||||||
|  | static const char col_gray4[]       = "#eeeeee"; | ||||||
|  | static const char col_cyan[]        = "#005577"; | ||||||
|  | static const char *colors[][3]      = { | ||||||
|  | 	/*               fg         bg         border   */ | ||||||
|  | 	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | ||||||
|  | 	[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* tagging */ | ||||||
|  | static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; | ||||||
|  |  | ||||||
|  | static const Rule rules[] = { | ||||||
|  | 	/* xprop(1): | ||||||
|  | 	 *	WM_CLASS(STRING) = instance, class | ||||||
|  | 	 *	WM_NAME(STRING) = title | ||||||
|  | 	 */ | ||||||
|  | 	/* class      instance    title       tags mask     isfloating   monitor */ | ||||||
|  | 	{ "Gimp",     NULL,       NULL,       0,            1,           -1 }, | ||||||
|  | 	{ "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* layout(s) */ | ||||||
|  | static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */ | ||||||
|  | static const int nmaster     = 1;    /* number of clients in master area */ | ||||||
|  | static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */ | ||||||
|  | static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ | ||||||
|  | static const int refreshrate = 120;  /* refresh rate (per second) for client move/resize */ | ||||||
|  |  | ||||||
|  | static const Layout layouts[] = { | ||||||
|  | 	/* symbol     arrange function */ | ||||||
|  | 	{ "[]=",      tile },    /* first entry is default */ | ||||||
|  | 	{ "><>",      NULL },    /* no layout function means floating behavior */ | ||||||
|  | 	{ "[M]",      monocle }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* key definitions */ | ||||||
|  | #define MODKEY Mod1Mask | ||||||
|  | #define TAGKEYS(KEY,TAG) \ | ||||||
|  | 	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} }, | ||||||
|  |  | ||||||
|  | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ | ||||||
|  | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } | ||||||
|  |  | ||||||
|  | /* 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 *termcmd[]  = { "st", NULL }; | ||||||
|  |  | ||||||
|  | static const Key keys[] = { | ||||||
|  | 	/* modifier                     key        function        argument */ | ||||||
|  | 	{ 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_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 } }, | ||||||
|  | 	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 */ | ||||||
|  | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ | ||||||
|  | static const 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} }, | ||||||
|  | 	{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} }, | ||||||
|  | 	{ ClkTagBar,            0,              Button1,        view,           {0} }, | ||||||
|  | 	{ ClkTagBar,            0,              Button3,        toggleview,     {0} }, | ||||||
|  | 	{ ClkTagBar,            MODKEY,         Button1,        tag,            {0} }, | ||||||
|  | 	{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} }, | ||||||
|  | }; | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								.pc/dwm-swallow-6.3.diff/config.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								.pc/dwm-swallow-6.3.diff/config.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | # dwm version | ||||||
|  | VERSION = 6.6 | ||||||
|  |  | ||||||
|  | # Customize below to fit your system | ||||||
|  |  | ||||||
|  | # paths | ||||||
|  | PREFIX = /usr/local | ||||||
|  | MANPREFIX = ${PREFIX}/share/man | ||||||
|  |  | ||||||
|  | X11INC = /usr/X11R6/include | ||||||
|  | X11LIB = /usr/X11R6/lib | ||||||
|  |  | ||||||
|  | # Xinerama, comment if you don't want it | ||||||
|  | XINERAMALIBS  = -lXinerama | ||||||
|  | XINERAMAFLAGS = -DXINERAMA | ||||||
|  |  | ||||||
|  | # freetype | ||||||
|  | FREETYPELIBS = -lfontconfig -lXft | ||||||
|  | FREETYPEINC = /usr/include/freetype2 | ||||||
|  | # OpenBSD (uncomment) | ||||||
|  | #FREETYPEINC = ${X11INC}/freetype2 | ||||||
|  | #MANPREFIX = ${PREFIX}/man | ||||||
|  |  | ||||||
|  | # includes and libs | ||||||
|  | INCS = -I${X11INC} -I${FREETYPEINC} | ||||||
|  | LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} | ||||||
|  |  | ||||||
|  | # flags | ||||||
|  | CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} | ||||||
|  | #CFLAGS   = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} | ||||||
|  | CFLAGS   = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} | ||||||
|  | LDFLAGS  = ${LIBS} | ||||||
|  |  | ||||||
|  | # Solaris | ||||||
|  | #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" | ||||||
|  | #LDFLAGS = ${LIBS} | ||||||
|  |  | ||||||
|  | # compiler and linker | ||||||
|  | CC = cc | ||||||
							
								
								
									
										2164
									
								
								.pc/dwm-swallow-6.3.diff/dwm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2164
									
								
								.pc/dwm-swallow-6.3.diff/dwm.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										48
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								README
									
									
									
									
									
								
							| @@ -1,48 +0,0 @@ | |||||||
| dwm - dynamic window manager |  | ||||||
| ============================ |  | ||||||
| dwm is an extremely fast, small, and dynamic window manager for X. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Requirements |  | ||||||
| ------------ |  | ||||||
| In order to build dwm you need the Xlib header files. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Installation |  | ||||||
| ------------ |  | ||||||
| Edit config.mk to match your local setup (dwm is installed into |  | ||||||
| the /usr/local namespace by default). |  | ||||||
|  |  | ||||||
| Afterwards enter the following command to build and install dwm (if |  | ||||||
| necessary as root): |  | ||||||
|  |  | ||||||
|     make clean install |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Running dwm |  | ||||||
| ----------- |  | ||||||
| Add the following line to your .xinitrc to start dwm using startx: |  | ||||||
|  |  | ||||||
|     exec dwm |  | ||||||
|  |  | ||||||
| In order to connect dwm to a specific display, make sure that |  | ||||||
| the DISPLAY environment variable is set correctly, e.g.: |  | ||||||
|  |  | ||||||
|     DISPLAY=foo.bar:1 exec dwm |  | ||||||
|  |  | ||||||
| (This will start dwm on display :1 of the host foo.bar.) |  | ||||||
|  |  | ||||||
| In order to display status info in the bar, you can do something |  | ||||||
| like this in your .xinitrc: |  | ||||||
|  |  | ||||||
|     while xsetroot -name "`date` `uptime | sed 's/.*,//'`" |  | ||||||
|     do |  | ||||||
|     	sleep 1 |  | ||||||
|     done & |  | ||||||
|     exec dwm |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Configuration |  | ||||||
| ------------- |  | ||||||
| The configuration of dwm is done by creating a custom config.h |  | ||||||
| and (re)compiling the source code. |  | ||||||
							
								
								
									
										20
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | # dwm - dynamic window manager - Mike's build | ||||||
|  |  | ||||||
|  | ## Patches Applied | ||||||
|  |  | ||||||
|  | * [Swallow](https://dwm.suckless.org/patches/swallow/) *Note: I had to change "St" in my config.h to "st" for this to work with st* | ||||||
|  | * [Hide Vacant Tags](https://dwm.suckless.org/patches/hide_vacant_tags/) | ||||||
|  | * [Pertag](https://dwm.suckless.org/patches/pertag/) | ||||||
|  | * [statuscmd](https://dwm.suckless.org/patches/statuscmd/) *Note: intended to be used with [dwmblocks](https://git.mjwilson.org/mike/dwmblocks-async)* | ||||||
|  |  | ||||||
|  | ### Patch Management | ||||||
|  |  | ||||||
|  | Patches are applied using [Quilt](https://savannah.nongnu.org/projects/quilt/quilt/), which is a patch manager that allows you to easily apply multiple patches, revert specific patches, etc. It makes customizing suckless projects much easier since most changes are done via patches. | ||||||
|  |  | ||||||
|  | ## Installation | ||||||
|  |  | ||||||
|  | ```sh | ||||||
|  | git clone https://git.mjwilson.org/mike/dwm.git | ||||||
|  | cd dwm | ||||||
|  | sudo make clean install | ||||||
|  | ``` | ||||||
							
								
								
									
										15
									
								
								config.def.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								config.def.h
									
									
									
									
									
								
							| @@ -3,6 +3,7 @@ | |||||||
| /* appearance */ | /* appearance */ | ||||||
| static const unsigned int borderpx  = 1;        /* border pixel of windows */ | static const unsigned int borderpx  = 1;        /* border pixel of windows */ | ||||||
| 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 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 char *fonts[]          = { "monospace:size=10" }; | static const char *fonts[]          = { "monospace:size=10" }; | ||||||
| @@ -26,9 +27,11 @@ static const Rule rules[] = { | |||||||
| 	 *	WM_CLASS(STRING) = instance, class | 	 *	WM_CLASS(STRING) = instance, class | ||||||
| 	 *	WM_NAME(STRING) = title | 	 *	WM_NAME(STRING) = title | ||||||
| 	 */ | 	 */ | ||||||
| 	/* class      instance    title       tags mask     isfloating   monitor */ | 	/* class     instance  title           tags mask  isfloating  isterminal  noswallow  monitor */ | ||||||
| 	{ "Gimp",     NULL,       NULL,       0,            1,           -1 }, | 	{ "Gimp",    NULL,     NULL,           0,         1,          0,           0,        -1 }, | ||||||
| 	{ "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 }, | 	{ "Firefox", NULL,     NULL,           1 << 8,    0,          0,          -1,        -1 }, | ||||||
|  | 	{ "St",      NULL,     NULL,           0,         0,          1,           0,        -1 }, | ||||||
|  | 	{ NULL,      NULL,     "Event Tester", 0,         0,          0,           1,        -1 }, /* xev */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* layout(s) */ | /* layout(s) */ | ||||||
| @@ -56,6 +59,8 @@ static const Layout layouts[] = { | |||||||
| /* helper for spawning shell commands in the pre dwm-5.0 fashion */ | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ | ||||||
| #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } | ||||||
|  |  | ||||||
|  | #define STATUSBAR "dwmblocks" | ||||||
|  |  | ||||||
| /* 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, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; | ||||||
| @@ -105,7 +110,9 @@ static const Button buttons[] = { | |||||||
| 	{ 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} }, | 	{ ClkWinTitle,          0,              Button2,        zoom,           {0} }, | ||||||
| 	{ ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } }, | 	{ ClkStatusText,        0,              Button1,        sigstatusbar,   {.i = 1} }, | ||||||
|  | 	{ ClkStatusText,        0,              Button2,        sigstatusbar,   {.i = 2} }, | ||||||
|  | 	{ ClkStatusText,        0,              Button3,        sigstatusbar,   {.i = 3} }, | ||||||
| 	{ ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} }, | 	{ ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} }, | ||||||
| 	{ ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} }, | 	{ ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} }, | ||||||
| 	{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} }, | 	{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} }, | ||||||
|   | |||||||
							
								
								
									
										124
									
								
								config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | |||||||
|  | /* See LICENSE file for copyright and license details. */ | ||||||
|  |  | ||||||
|  | /* appearance */ | ||||||
|  | static const unsigned int borderpx  = 1;        /* border pixel of windows */ | ||||||
|  | static const unsigned int snap      = 32;       /* snap pixel */ | ||||||
|  | static const int swallowfloating    = 0;        /* 1 means swallow floating windows by default */ | ||||||
|  | static const int showbar            = 1;        /* 0 means no bar */ | ||||||
|  | static const int topbar             = 1;        /* 0 means bottom bar */ | ||||||
|  | static const char *fonts[]          = { "monospace:size=10" }; | ||||||
|  | static const char dmenufont[]       = "monospace:size=10"; | ||||||
|  | static const char col_gray1[]       = "#222222"; | ||||||
|  | static const char col_gray2[]       = "#444444"; | ||||||
|  | static const char col_gray3[]       = "#bbbbbb"; | ||||||
|  | static const char col_gray4[]       = "#eeeeee"; | ||||||
|  | static const char col_cyan[]        = "#005577"; | ||||||
|  | static const char *colors[][3]      = { | ||||||
|  | 	/*               fg         bg         border   */ | ||||||
|  | 	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, | ||||||
|  | 	[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* tagging */ | ||||||
|  | static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; | ||||||
|  |  | ||||||
|  | static const Rule rules[] = { | ||||||
|  | 	/* xprop(1): | ||||||
|  | 	 *	WM_CLASS(STRING) = instance, class | ||||||
|  | 	 *	WM_NAME(STRING) = title | ||||||
|  | 	 */ | ||||||
|  | 	/* class     instance  title           tags mask  isfloating  isterminal  noswallow  monitor */ | ||||||
|  | 	{ "Gimp",    NULL,     NULL,           0,         1,          0,           0,        -1 }, | ||||||
|  | 	{ "Firefox", NULL,     NULL,           1 << 8,    0,          0,          -1,        -1 }, | ||||||
|  | 	{ "st",      NULL,     NULL,           0,         0,          1,           0,        -1 }, | ||||||
|  | 	{ NULL,      NULL,     "Event Tester", 0,         0,          0,           1,        -1 }, /* xev */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* layout(s) */ | ||||||
|  | static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */ | ||||||
|  | static const int nmaster     = 1;    /* number of clients in master area */ | ||||||
|  | static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */ | ||||||
|  | static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ | ||||||
|  | static const int refreshrate = 120;  /* refresh rate (per second) for client move/resize */ | ||||||
|  |  | ||||||
|  | static const Layout layouts[] = { | ||||||
|  | 	/* symbol     arrange function */ | ||||||
|  | 	{ "[]=",      tile },    /* first entry is default */ | ||||||
|  | 	{ "><>",      NULL },    /* no layout function means floating behavior */ | ||||||
|  | 	{ "[M]",      monocle }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* key definitions */ | ||||||
|  | #define MODKEY Mod4Mask | ||||||
|  | #define TAGKEYS(KEY,TAG) \ | ||||||
|  | 	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \ | ||||||
|  | 	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} }, | ||||||
|  |  | ||||||
|  | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ | ||||||
|  | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } | ||||||
|  |  | ||||||
|  | #define STATUSBAR "dwmblocks" | ||||||
|  |  | ||||||
|  | /* 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 *termcmd[]  = { "st", NULL }; | ||||||
|  |  | ||||||
|  | static const Key keys[] = { | ||||||
|  | 	/* modifier                     key        function        argument */ | ||||||
|  | 	{ 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_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 } }, | ||||||
|  | 	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 */ | ||||||
|  | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ | ||||||
|  | static const 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,              Button1,        sigstatusbar,   {.i = 1} }, | ||||||
|  | 	{ ClkStatusText,        0,              Button2,        sigstatusbar,   {.i = 2} }, | ||||||
|  | 	{ ClkStatusText,        0,              Button3,        sigstatusbar,   {.i = 3} }, | ||||||
|  | 	{ ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} }, | ||||||
|  | 	{ ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} }, | ||||||
|  | 	{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} }, | ||||||
|  | 	{ ClkTagBar,            0,              Button1,        view,           {0} }, | ||||||
|  | 	{ ClkTagBar,            0,              Button3,        toggleview,     {0} }, | ||||||
|  | 	{ ClkTagBar,            MODKEY,         Button1,        tag,            {0} }, | ||||||
|  | 	{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} }, | ||||||
|  | }; | ||||||
|  |  | ||||||
| @@ -20,10 +20,11 @@ FREETYPEINC = /usr/include/freetype2 | |||||||
| # OpenBSD (uncomment) | # OpenBSD (uncomment) | ||||||
| #FREETYPEINC = ${X11INC}/freetype2 | #FREETYPEINC = ${X11INC}/freetype2 | ||||||
| #MANPREFIX = ${PREFIX}/man | #MANPREFIX = ${PREFIX}/man | ||||||
|  | #KVMLIB = -lkvm | ||||||
|  |  | ||||||
| # includes and libs | # includes and libs | ||||||
| INCS = -I${X11INC} -I${FREETYPEINC} | INCS = -I${X11INC} -I${FREETYPEINC} | ||||||
| LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} | LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB} | ||||||
|  |  | ||||||
| # flags | # flags | ||||||
| CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} | CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} | ||||||
|   | |||||||
							
								
								
									
										446
									
								
								dwm.c
									
									
									
									
									
								
							
							
						
						
									
										446
									
								
								dwm.c
									
									
									
									
									
								
							| @@ -40,6 +40,12 @@ | |||||||
| #include <X11/extensions/Xinerama.h> | #include <X11/extensions/Xinerama.h> | ||||||
| #endif /* XINERAMA */ | #endif /* XINERAMA */ | ||||||
| #include <X11/Xft/Xft.h> | #include <X11/Xft/Xft.h> | ||||||
|  | #include <X11/Xlib-xcb.h> | ||||||
|  | #include <xcb/res.h> | ||||||
|  | #ifdef __OpenBSD__ | ||||||
|  | #include <sys/sysctl.h> | ||||||
|  | #include <kvm.h> | ||||||
|  | #endif /* __OpenBSD */ | ||||||
|  |  | ||||||
| #include "drw.h" | #include "drw.h" | ||||||
| #include "util.h" | #include "util.h" | ||||||
| @@ -91,9 +97,11 @@ struct Client { | |||||||
| 	int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; | 	int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; | ||||||
| 	int bw, oldbw; | 	int bw, oldbw; | ||||||
| 	unsigned int tags; | 	unsigned int tags; | ||||||
| 	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; | 	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow; | ||||||
|  | 	pid_t pid; | ||||||
| 	Client *next; | 	Client *next; | ||||||
| 	Client *snext; | 	Client *snext; | ||||||
|  | 	Client *swallowing; | ||||||
| 	Monitor *mon; | 	Monitor *mon; | ||||||
| 	Window win; | 	Window win; | ||||||
| }; | }; | ||||||
| @@ -110,6 +118,7 @@ typedef struct { | |||||||
| 	void (*arrange)(Monitor *); | 	void (*arrange)(Monitor *); | ||||||
| } Layout; | } Layout; | ||||||
|  |  | ||||||
|  | typedef struct Pertag Pertag; | ||||||
| struct Monitor { | struct Monitor { | ||||||
| 	char ltsymbol[16]; | 	char ltsymbol[16]; | ||||||
| 	float mfact; | 	float mfact; | ||||||
| @@ -129,6 +138,7 @@ struct Monitor { | |||||||
| 	Monitor *next; | 	Monitor *next; | ||||||
| 	Window barwin; | 	Window barwin; | ||||||
| 	const Layout *lt[2]; | 	const Layout *lt[2]; | ||||||
|  | 	Pertag *pertag; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
| @@ -137,6 +147,8 @@ typedef struct { | |||||||
| 	const char *title; | 	const char *title; | ||||||
| 	unsigned int tags; | 	unsigned int tags; | ||||||
| 	int isfloating; | 	int isfloating; | ||||||
|  | 	int isterminal; | ||||||
|  | 	int noswallow; | ||||||
| 	int monitor; | 	int monitor; | ||||||
| } Rule; | } Rule; | ||||||
|  |  | ||||||
| @@ -171,6 +183,7 @@ static void focusstack(const Arg *arg); | |||||||
| static Atom getatomprop(Client *c, Atom prop); | static Atom getatomprop(Client *c, Atom prop); | ||||||
| static int getrootptr(int *x, int *y); | static int getrootptr(int *x, int *y); | ||||||
| static long getstate(Window w); | static long getstate(Window w); | ||||||
|  | static pid_t getstatusbarpid(); | ||||||
| static int gettextprop(Window w, Atom atom, char *text, unsigned int size); | static int gettextprop(Window w, Atom atom, char *text, unsigned int size); | ||||||
| static void grabbuttons(Client *c, int focused); | static void grabbuttons(Client *c, int focused); | ||||||
| static void grabkeys(void); | static void grabkeys(void); | ||||||
| @@ -204,6 +217,7 @@ static void setmfact(const Arg *arg); | |||||||
| static void setup(void); | static void setup(void); | ||||||
| static void seturgent(Client *c, int urg); | static void seturgent(Client *c, int urg); | ||||||
| static void showhide(Client *c); | static void showhide(Client *c); | ||||||
|  | static void sigstatusbar(const Arg *arg); | ||||||
| static void spawn(const Arg *arg); | static void spawn(const Arg *arg); | ||||||
| static void tag(const Arg *arg); | static void tag(const Arg *arg); | ||||||
| static void tagmon(const Arg *arg); | static void tagmon(const Arg *arg); | ||||||
| @@ -233,9 +247,18 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee); | |||||||
| static int xerrorstart(Display *dpy, XErrorEvent *ee); | static int xerrorstart(Display *dpy, XErrorEvent *ee); | ||||||
| static void zoom(const Arg *arg); | static void zoom(const Arg *arg); | ||||||
|  |  | ||||||
|  | static pid_t getparentprocess(pid_t p); | ||||||
|  | static int isdescprocess(pid_t p, pid_t c); | ||||||
|  | static Client *swallowingclient(Window w); | ||||||
|  | static Client *termforwin(const Client *c); | ||||||
|  | static pid_t winpid(Window w); | ||||||
|  |  | ||||||
| /* variables */ | /* variables */ | ||||||
| static const char broken[] = "broken"; | static const char broken[] = "broken"; | ||||||
| static char stext[256]; | static char stext[256]; | ||||||
|  | static int statusw; | ||||||
|  | static int statussig; | ||||||
|  | static pid_t statuspid = -1; | ||||||
| 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;               /* bar height */ | static int bh;               /* bar height */ | ||||||
| @@ -267,9 +290,20 @@ static Drw *drw; | |||||||
| static Monitor *mons, *selmon; | static Monitor *mons, *selmon; | ||||||
| static Window root, wmcheckwin; | static Window root, wmcheckwin; | ||||||
|  |  | ||||||
|  | static xcb_connection_t *xcon; | ||||||
|  |  | ||||||
| /* configuration, allows nested code to access above variables */ | /* configuration, allows nested code to access above variables */ | ||||||
| #include "config.h" | #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  */ | ||||||
|  | 	int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* compile-time check if all tags fit into an unsigned int bit array. */ | /* compile-time check if all tags fit into an unsigned int bit array. */ | ||||||
| struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; | struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; | ||||||
|  |  | ||||||
| @@ -296,6 +330,8 @@ applyrules(Client *c) | |||||||
| 		&& (!r->class || strstr(class, r->class)) | 		&& (!r->class || strstr(class, r->class)) | ||||||
| 		&& (!r->instance || strstr(instance, r->instance))) | 		&& (!r->instance || strstr(instance, r->instance))) | ||||||
| 		{ | 		{ | ||||||
|  | 			c->isterminal = r->isterminal; | ||||||
|  | 			c->noswallow  = r->noswallow; | ||||||
| 			c->isfloating = r->isfloating; | 			c->isfloating = r->isfloating; | ||||||
| 			c->tags |= r->tags; | 			c->tags |= r->tags; | ||||||
| 			for (m = mons; m && m->num != r->monitor; m = m->next); | 			for (m = mons; m && m->num != r->monitor; m = m->next); | ||||||
| @@ -414,6 +450,53 @@ attachstack(Client *c) | |||||||
| 	c->mon->stack = c; | 	c->mon->stack = c; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | swallow(Client *p, Client *c) | ||||||
|  | { | ||||||
|  |  | ||||||
|  | 	if (c->noswallow || c->isterminal) | ||||||
|  | 		return; | ||||||
|  | 	if (c->noswallow && !swallowfloating && c->isfloating) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	detach(c); | ||||||
|  | 	detachstack(c); | ||||||
|  |  | ||||||
|  | 	setclientstate(c, WithdrawnState); | ||||||
|  | 	XUnmapWindow(dpy, p->win); | ||||||
|  |  | ||||||
|  | 	p->swallowing = c; | ||||||
|  | 	c->mon = p->mon; | ||||||
|  |  | ||||||
|  | 	Window w = p->win; | ||||||
|  | 	p->win = c->win; | ||||||
|  | 	c->win = w; | ||||||
|  | 	updatetitle(p); | ||||||
|  | 	XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); | ||||||
|  | 	arrange(p->mon); | ||||||
|  | 	configure(p); | ||||||
|  | 	updateclientlist(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | unswallow(Client *c) | ||||||
|  | { | ||||||
|  | 	c->win = c->swallowing->win; | ||||||
|  |  | ||||||
|  | 	free(c->swallowing); | ||||||
|  | 	c->swallowing = NULL; | ||||||
|  |  | ||||||
|  | 	/* unfullscreen the client */ | ||||||
|  | 	setfullscreen(c, 0); | ||||||
|  | 	updatetitle(c); | ||||||
|  | 	arrange(c->mon); | ||||||
|  | 	XMapWindow(dpy, c->win); | ||||||
|  | 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); | ||||||
|  | 	setclientstate(c, NormalState); | ||||||
|  | 	focus(NULL); | ||||||
|  | 	arrange(c->mon); | ||||||
|  | } | ||||||
|  |  | ||||||
| void | void | ||||||
| buttonpress(XEvent *e) | buttonpress(XEvent *e) | ||||||
| { | { | ||||||
| @@ -422,6 +505,7 @@ buttonpress(XEvent *e) | |||||||
| 	Client *c; | 	Client *c; | ||||||
| 	Monitor *m; | 	Monitor *m; | ||||||
| 	XButtonPressedEvent *ev = &e->xbutton; | 	XButtonPressedEvent *ev = &e->xbutton; | ||||||
|  | 	char *text, *s, ch; | ||||||
|  |  | ||||||
| 	click = ClkRootWin; | 	click = ClkRootWin; | ||||||
| 	/* focus monitor if necessary */ | 	/* focus monitor if necessary */ | ||||||
| @@ -432,17 +516,41 @@ buttonpress(XEvent *e) | |||||||
| 	} | 	} | ||||||
| 	if (ev->window == selmon->barwin) { | 	if (ev->window == selmon->barwin) { | ||||||
| 		i = x = 0; | 		i = x = 0; | ||||||
| 		do | 		unsigned int occ = 0; | ||||||
|  | 		for(c = m->clients; c; c=c->next) | ||||||
|  | 			occ |= c->tags == TAGMASK ? 0 : c->tags; | ||||||
|  | 		do { | ||||||
|  | 			/* Do not reserve space for vacant tags */ | ||||||
|  | 			if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) | ||||||
|  | 				continue; | ||||||
| 			x += TEXTW(tags[i]); | 			x += TEXTW(tags[i]); | ||||||
| 		while (ev->x >= x && ++i < LENGTH(tags)); | 		} while (ev->x >= x && ++i < LENGTH(tags)); | ||||||
| 		if (i < LENGTH(tags)) { | 		if (i < LENGTH(tags)) { | ||||||
| 			click = ClkTagBar; | 			click = ClkTagBar; | ||||||
| 			arg.ui = 1 << i; | 			arg.ui = 1 << i; | ||||||
| 		} else if (ev->x < x + TEXTW(selmon->ltsymbol)) | 		} else if (ev->x < x + TEXTW(selmon->ltsymbol)) | ||||||
| 			click = ClkLtSymbol; | 			click = ClkLtSymbol; | ||||||
| 		else if (ev->x > selmon->ww - (int)TEXTW(stext)) | 		else if (ev->x > selmon->ww - statusw) { | ||||||
|  | 			x = selmon->ww - statusw; | ||||||
| 			click = ClkStatusText; | 			click = ClkStatusText; | ||||||
| 		else | 			statussig = 0; | ||||||
|  | 			for (text = s = stext; *s && x <= ev->x; s++) { | ||||||
|  | 				if ((unsigned char)(*s) < ' ') { | ||||||
|  | 					ch = *s; | ||||||
|  | 					*s = '\0'; | ||||||
|  | 					x += TEXTW(text) - lrpad; | ||||||
|  | 					*s = ch; | ||||||
|  | 					text = s + 1; | ||||||
|  | 					if (x >= ev->x) | ||||||
|  | 						break; | ||||||
|  | 					/* reset on matching signal raw byte */ | ||||||
|  | 					if (ch == statussig) | ||||||
|  | 						statussig = 0; | ||||||
|  | 					else | ||||||
|  | 						statussig = ch; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} else | ||||||
| 			click = ClkWinTitle; | 			click = ClkWinTitle; | ||||||
| 	} else if ((c = wintoclient(ev->window))) { | 	} else if ((c = wintoclient(ev->window))) { | ||||||
| 		focus(c); | 		focus(c); | ||||||
| @@ -633,6 +741,7 @@ Monitor * | |||||||
| createmon(void) | createmon(void) | ||||||
| { | { | ||||||
| 	Monitor *m; | 	Monitor *m; | ||||||
|  | 	unsigned int i; | ||||||
|  |  | ||||||
| 	m = ecalloc(1, sizeof(Monitor)); | 	m = ecalloc(1, sizeof(Monitor)); | ||||||
| 	m->tagset[0] = m->tagset[1] = 1; | 	m->tagset[0] = m->tagset[1] = 1; | ||||||
| @@ -643,6 +752,20 @@ createmon(void) | |||||||
| 	m->lt[0] = &layouts[0]; | 	m->lt[0] = &layouts[0]; | ||||||
| 	m->lt[1] = &layouts[1 % LENGTH(layouts)]; | 	m->lt[1] = &layouts[1 % LENGTH(layouts)]; | ||||||
| 	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); | 	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); | ||||||
|  | 	m->pertag = ecalloc(1, sizeof(Pertag)); | ||||||
|  | 	m->pertag->curtag = m->pertag->prevtag = 1; | ||||||
|  |  | ||||||
|  | 	for (i = 0; i <= LENGTH(tags); i++) { | ||||||
|  | 		m->pertag->nmasters[i] = m->nmaster; | ||||||
|  | 		m->pertag->mfacts[i] = m->mfact; | ||||||
|  |  | ||||||
|  | 		m->pertag->ltidxs[i][0] = m->lt[0]; | ||||||
|  | 		m->pertag->ltidxs[i][1] = m->lt[1]; | ||||||
|  | 		m->pertag->sellts[i] = m->sellt; | ||||||
|  |  | ||||||
|  | 		m->pertag->showbars[i] = m->showbar; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return m; | 	return m; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -654,6 +777,9 @@ destroynotify(XEvent *e) | |||||||
|  |  | ||||||
| 	if ((c = wintoclient(ev->window))) | 	if ((c = wintoclient(ev->window))) | ||||||
| 		unmanage(c, 1); | 		unmanage(c, 1); | ||||||
|  |  | ||||||
|  | 	else if ((c = swallowingclient(ev->window))) | ||||||
|  | 		unmanage(c->swallowing, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -708,25 +834,39 @@ drawbar(Monitor *m) | |||||||
|  |  | ||||||
| 	/* 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 */ | ||||||
|  | 		char *text, *s, ch; | ||||||
| 		drw_setscheme(drw, scheme[SchemeNorm]); | 		drw_setscheme(drw, scheme[SchemeNorm]); | ||||||
| 		tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ |  | ||||||
| 		drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); | 		x = 0; | ||||||
|  | 		for (text = s = stext; *s; s++) { | ||||||
|  | 			if ((unsigned char)(*s) < ' ') { | ||||||
|  | 				ch = *s; | ||||||
|  | 				*s = '\0'; | ||||||
|  | 				tw = TEXTW(text) - lrpad; | ||||||
|  | 				drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0); | ||||||
|  | 				x += tw; | ||||||
|  | 				*s = ch; | ||||||
|  | 				text = s + 1; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		tw = TEXTW(text) - lrpad + 2; | ||||||
|  | 		drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0); | ||||||
|  | 		tw = statusw; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for (c = m->clients; c; c = c->next) { | 	for (c = m->clients; c; c = c->next) { | ||||||
| 		occ |= c->tags; | 		occ |= c->tags == TAGMASK ? 0 : c->tags; | ||||||
| 		if (c->isurgent) | 		if (c->isurgent) | ||||||
| 			urg |= c->tags; | 			urg |= c->tags; | ||||||
| 	} | 	} | ||||||
| 	x = 0; | 	x = 0; | ||||||
| 	for (i = 0; i < LENGTH(tags); i++) { | 	for (i = 0; i < LENGTH(tags); i++) { | ||||||
|  | 		/* Do not draw vacant tags */ | ||||||
|  | 		if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) | ||||||
|  | 			continue; | ||||||
| 		w = TEXTW(tags[i]); | 		w = TEXTW(tags[i]); | ||||||
| 		drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); | 		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); | 		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); |  | ||||||
| 		x += w; | 		x += w; | ||||||
| 	} | 	} | ||||||
| 	w = TEXTW(m->ltsymbol); | 	w = TEXTW(m->ltsymbol); | ||||||
| @@ -876,6 +1016,30 @@ getatomprop(Client *c, Atom prop) | |||||||
| 	return atom; | 	return atom; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | pid_t | ||||||
|  | getstatusbarpid() | ||||||
|  | { | ||||||
|  | 	char buf[32], *str = buf, *c; | ||||||
|  | 	FILE *fp; | ||||||
|  |  | ||||||
|  | 	if (statuspid > 0) { | ||||||
|  | 		snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspid); | ||||||
|  | 		if ((fp = fopen(buf, "r"))) { | ||||||
|  | 			fgets(buf, sizeof(buf), fp); | ||||||
|  | 			while ((c = strchr(str, '/'))) | ||||||
|  | 				str = c + 1; | ||||||
|  | 			fclose(fp); | ||||||
|  | 			if (!strcmp(str, STATUSBAR)) | ||||||
|  | 				return statuspid; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if (!(fp = popen("pidof -s "STATUSBAR, "r"))) | ||||||
|  | 		return -1; | ||||||
|  | 	fgets(buf, sizeof(buf), fp); | ||||||
|  | 	pclose(fp); | ||||||
|  | 	return strtol(buf, NULL, 10); | ||||||
|  | } | ||||||
|  |  | ||||||
| int | int | ||||||
| getrootptr(int *x, int *y) | getrootptr(int *x, int *y) | ||||||
| { | { | ||||||
| @@ -979,7 +1143,7 @@ grabkeys(void) | |||||||
| void | void | ||||||
| incnmaster(const Arg *arg) | 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); | 	arrange(selmon); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1030,12 +1194,13 @@ killclient(const Arg *arg) | |||||||
| void | void | ||||||
| manage(Window w, XWindowAttributes *wa) | manage(Window w, XWindowAttributes *wa) | ||||||
| { | { | ||||||
| 	Client *c, *t = NULL; | 	Client *c, *t = NULL, *term = NULL; | ||||||
| 	Window trans = None; | 	Window trans = None; | ||||||
| 	XWindowChanges wc; | 	XWindowChanges wc; | ||||||
|  |  | ||||||
| 	c = ecalloc(1, sizeof(Client)); | 	c = ecalloc(1, sizeof(Client)); | ||||||
| 	c->win = w; | 	c->win = w; | ||||||
|  | 	c->pid = winpid(w); | ||||||
| 	/* geometry */ | 	/* geometry */ | ||||||
| 	c->x = c->oldx = wa->x; | 	c->x = c->oldx = wa->x; | ||||||
| 	c->y = c->oldy = wa->y; | 	c->y = c->oldy = wa->y; | ||||||
| @@ -1050,6 +1215,7 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 	} else { | 	} else { | ||||||
| 		c->mon = selmon; | 		c->mon = selmon; | ||||||
| 		applyrules(c); | 		applyrules(c); | ||||||
|  | 		term = termforwin(c); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) | 	if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) | ||||||
| @@ -1084,6 +1250,8 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 	c->mon->sel = c; | 	c->mon->sel = c; | ||||||
| 	arrange(c->mon); | 	arrange(c->mon); | ||||||
| 	XMapWindow(dpy, c->win); | 	XMapWindow(dpy, c->win); | ||||||
|  | 	if (term) | ||||||
|  | 		swallow(term, c); | ||||||
| 	focus(NULL); | 	focus(NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1510,9 +1678,9 @@ void | |||||||
| setlayout(const Arg *arg) | setlayout(const Arg *arg) | ||||||
| { | { | ||||||
| 	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) | 	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) | ||||||
| 		selmon->sellt ^= 1; | 		selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; | ||||||
| 	if (arg && arg->v) | 	if (arg && arg->v) | ||||||
| 		selmon->lt[selmon->sellt] = (Layout *)arg->v; | 		selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; | ||||||
| 	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); | 	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); | ||||||
| 	if (selmon->sel) | 	if (selmon->sel) | ||||||
| 		arrange(selmon); | 		arrange(selmon); | ||||||
| @@ -1531,7 +1699,7 @@ setmfact(const Arg *arg) | |||||||
| 	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; | 	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; | ||||||
| 	if (f < 0.05 || f > 0.95) | 	if (f < 0.05 || f > 0.95) | ||||||
| 		return; | 		return; | ||||||
| 	selmon->mfact = f; | 	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; | ||||||
| 	arrange(selmon); | 	arrange(selmon); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1643,6 +1811,20 @@ showhide(Client *c) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | sigstatusbar(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	union sigval sv; | ||||||
|  |  | ||||||
|  | 	if (!statussig) | ||||||
|  | 		return; | ||||||
|  | 	sv.sival_int = arg->i; | ||||||
|  | 	if ((statuspid = getstatusbarpid()) <= 0) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	sigqueue(statuspid, SIGRTMIN+statussig, sv); | ||||||
|  | } | ||||||
|  |  | ||||||
| void | void | ||||||
| spawn(const Arg *arg) | spawn(const Arg *arg) | ||||||
| { | { | ||||||
| @@ -1714,7 +1896,7 @@ tile(Monitor *m) | |||||||
| void | void | ||||||
| togglebar(const Arg *arg) | togglebar(const Arg *arg) | ||||||
| { | { | ||||||
| 	selmon->showbar = !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, selmon->by, selmon->ww, bh); | ||||||
| 	arrange(selmon); | 	arrange(selmon); | ||||||
| @@ -1753,9 +1935,33 @@ void | |||||||
| toggleview(const Arg *arg) | toggleview(const Arg *arg) | ||||||
| { | { | ||||||
| 	unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); | 	unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
| 	if (newtagset) { | 	if (newtagset) { | ||||||
| 		selmon->tagset[selmon->seltags] = newtagset; | 		selmon->tagset[selmon->seltags] = 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; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		/* 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); | 		focus(NULL); | ||||||
| 		arrange(selmon); | 		arrange(selmon); | ||||||
| 	} | 	} | ||||||
| @@ -1780,6 +1986,20 @@ unmanage(Client *c, int destroyed) | |||||||
| 	Monitor *m = c->mon; | 	Monitor *m = c->mon; | ||||||
| 	XWindowChanges wc; | 	XWindowChanges wc; | ||||||
|  |  | ||||||
|  | 	if (c->swallowing) { | ||||||
|  | 		unswallow(c); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Client *s = swallowingclient(c->win); | ||||||
|  | 	if (s) { | ||||||
|  | 		free(s->swallowing); | ||||||
|  | 		s->swallowing = NULL; | ||||||
|  | 		arrange(m); | ||||||
|  | 		focus(NULL); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	detach(c); | 	detach(c); | ||||||
| 	detachstack(c); | 	detachstack(c); | ||||||
| 	if (!destroyed) { | 	if (!destroyed) { | ||||||
| @@ -1795,9 +2015,12 @@ unmanage(Client *c, int destroyed) | |||||||
| 		XUngrabServer(dpy); | 		XUngrabServer(dpy); | ||||||
| 	} | 	} | ||||||
| 	free(c); | 	free(c); | ||||||
| 	focus(NULL); |  | ||||||
| 	updateclientlist(); | 	if (!s) { | ||||||
| 	arrange(m); | 		arrange(m); | ||||||
|  | 		focus(NULL); | ||||||
|  | 		updateclientlist(); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -2004,8 +2227,25 @@ updatesizehints(Client *c) | |||||||
| void | void | ||||||
| updatestatus(void) | updatestatus(void) | ||||||
| { | { | ||||||
| 	if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) | 	if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) { | ||||||
| 		strcpy(stext, "dwm-"VERSION); | 		strcpy(stext, "dwm-"VERSION); | ||||||
|  | 		statusw = TEXTW(stext) - lrpad + 2; | ||||||
|  | 	} else { | ||||||
|  | 		char *text, *s, ch; | ||||||
|  |  | ||||||
|  | 		statusw  = 0; | ||||||
|  | 		for (text = s = stext; *s; s++) { | ||||||
|  | 			if ((unsigned char)(*s) < ' ') { | ||||||
|  | 				ch = *s; | ||||||
|  | 				*s = '\0'; | ||||||
|  | 				statusw += TEXTW(text) - lrpad; | ||||||
|  | 				*s = ch; | ||||||
|  | 				text = s + 1; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		statusw += TEXTW(text) - lrpad + 2; | ||||||
|  |  | ||||||
|  | 	} | ||||||
| 	drawbar(selmon); | 	drawbar(selmon); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -2052,15 +2292,171 @@ updatewmhints(Client *c) | |||||||
| void | void | ||||||
| view(const Arg *arg) | view(const Arg *arg) | ||||||
| { | { | ||||||
|  | 	int i; | ||||||
|  | 	unsigned int tmptag; | ||||||
|  |  | ||||||
| 	if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) | 	if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) | ||||||
| 		return; | 		return; | ||||||
| 	selmon->seltags ^= 1; /* toggle sel tagset */ | 	selmon->seltags ^= 1; /* toggle sel tagset */ | ||||||
| 	if (arg->ui & TAGMASK) | 	if (arg->ui & TAGMASK) { | ||||||
| 		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; | 		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; | ||||||
|  | 		selmon->pertag->prevtag = selmon->pertag->curtag; | ||||||
|  |  | ||||||
|  | 		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); | 	focus(NULL); | ||||||
| 	arrange(selmon); | 	arrange(selmon); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | pid_t | ||||||
|  | winpid(Window w) | ||||||
|  | { | ||||||
|  |  | ||||||
|  | 	pid_t result = 0; | ||||||
|  |  | ||||||
|  | #ifdef __linux__ | ||||||
|  | 	xcb_res_client_id_spec_t spec = {0}; | ||||||
|  | 	spec.client = w; | ||||||
|  | 	spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; | ||||||
|  |  | ||||||
|  | 	xcb_generic_error_t *e = NULL; | ||||||
|  | 	xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); | ||||||
|  | 	xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); | ||||||
|  |  | ||||||
|  | 	if (!r) | ||||||
|  | 		return (pid_t)0; | ||||||
|  |  | ||||||
|  | 	xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); | ||||||
|  | 	for (; i.rem; xcb_res_client_id_value_next(&i)) { | ||||||
|  | 		spec = i.data->spec; | ||||||
|  | 		if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { | ||||||
|  | 			uint32_t *t = xcb_res_client_id_value_value(i.data); | ||||||
|  | 			result = *t; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	free(r); | ||||||
|  |  | ||||||
|  | 	if (result == (pid_t)-1) | ||||||
|  | 		result = 0; | ||||||
|  |  | ||||||
|  | #endif /* __linux__ */ | ||||||
|  |  | ||||||
|  | #ifdef __OpenBSD__ | ||||||
|  |         Atom type; | ||||||
|  |         int format; | ||||||
|  |         unsigned long len, bytes; | ||||||
|  |         unsigned char *prop; | ||||||
|  |         pid_t ret; | ||||||
|  |  | ||||||
|  |         if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 0), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop) | ||||||
|  |                return 0; | ||||||
|  |  | ||||||
|  |         ret = *(pid_t*)prop; | ||||||
|  |         XFree(prop); | ||||||
|  |         result = ret; | ||||||
|  |  | ||||||
|  | #endif /* __OpenBSD__ */ | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pid_t | ||||||
|  | getparentprocess(pid_t p) | ||||||
|  | { | ||||||
|  | 	unsigned int v = 0; | ||||||
|  |  | ||||||
|  | #ifdef __linux__ | ||||||
|  | 	FILE *f; | ||||||
|  | 	char buf[256]; | ||||||
|  | 	snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); | ||||||
|  |  | ||||||
|  | 	if (!(f = fopen(buf, "r"))) | ||||||
|  | 		return 0; | ||||||
|  |  | ||||||
|  | 	fscanf(f, "%*u %*s %*c %u", &v); | ||||||
|  | 	fclose(f); | ||||||
|  | #endif /* __linux__*/ | ||||||
|  |  | ||||||
|  | #ifdef __OpenBSD__ | ||||||
|  | 	int n; | ||||||
|  | 	kvm_t *kd; | ||||||
|  | 	struct kinfo_proc *kp; | ||||||
|  |  | ||||||
|  | 	kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL); | ||||||
|  | 	if (!kd) | ||||||
|  | 		return 0; | ||||||
|  |  | ||||||
|  | 	kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n); | ||||||
|  | 	v = kp->p_ppid; | ||||||
|  | #endif /* __OpenBSD__ */ | ||||||
|  |  | ||||||
|  | 	return (pid_t)v; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | isdescprocess(pid_t p, pid_t c) | ||||||
|  | { | ||||||
|  | 	while (p != c && c != 0) | ||||||
|  | 		c = getparentprocess(c); | ||||||
|  |  | ||||||
|  | 	return (int)c; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Client * | ||||||
|  | termforwin(const Client *w) | ||||||
|  | { | ||||||
|  | 	Client *c; | ||||||
|  | 	Monitor *m; | ||||||
|  |  | ||||||
|  | 	if (!w->pid || w->isterminal) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	for (m = mons; m; m = m->next) { | ||||||
|  | 		for (c = m->clients; c; c = c->next) { | ||||||
|  | 			if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) | ||||||
|  | 				return c; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Client * | ||||||
|  | swallowingclient(Window w) | ||||||
|  | { | ||||||
|  | 	Client *c; | ||||||
|  | 	Monitor *m; | ||||||
|  |  | ||||||
|  | 	for (m = mons; m; m = m->next) { | ||||||
|  | 		for (c = m->clients; c; c = c->next) { | ||||||
|  | 			if (c->swallowing && c->swallowing->win == w) | ||||||
|  | 				return c; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
| Client * | Client * | ||||||
| wintoclient(Window w) | wintoclient(Window w) | ||||||
| { | { | ||||||
| @@ -2150,10 +2546,12 @@ main(int argc, char *argv[]) | |||||||
| 		fputs("warning: no locale support\n", stderr); | 		fputs("warning: no locale support\n", stderr); | ||||||
| 	if (!(dpy = XOpenDisplay(NULL))) | 	if (!(dpy = XOpenDisplay(NULL))) | ||||||
| 		die("dwm: cannot open display"); | 		die("dwm: cannot open display"); | ||||||
|  | 	if (!(xcon = XGetXCBConnection(dpy))) | ||||||
|  | 		die("dwm: cannot get xcb connection\n"); | ||||||
| 	checkotherwm(); | 	checkotherwm(); | ||||||
| 	setup(); | 	setup(); | ||||||
| #ifdef __OpenBSD__ | #ifdef __OpenBSD__ | ||||||
| 	if (pledge("stdio rpath proc exec", NULL) == -1) | 	if (pledge("stdio rpath proc exec ps", NULL) == -1) | ||||||
| 		die("pledge"); | 		die("pledge"); | ||||||
| #endif /* __OpenBSD__ */ | #endif /* __OpenBSD__ */ | ||||||
| 	scan(); | 	scan(); | ||||||
|   | |||||||
							
								
								
									
										48
									
								
								patches/dwm-hide_vacant_tags-6.4.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								patches/dwm-hide_vacant_tags-6.4.diff
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | :100644 100644 f1d86b2 0000000 M	dwm.c | ||||||
|  |  | ||||||
|  | diff --git a/dwm.c b/dwm.c | ||||||
|  | index f1d86b2..d41cc14 100644 | ||||||
|  | --- a/dwm.c | ||||||
|  | +++ b/dwm.c | ||||||
|  | @@ -433,9 +433,15 @@ buttonpress(XEvent *e) | ||||||
|  |  	} | ||||||
|  |  	if (ev->window == selmon->barwin) { | ||||||
|  |  		i = x = 0; | ||||||
|  | -		do | ||||||
|  | +		unsigned int occ = 0; | ||||||
|  | +		for(c = m->clients; c; c=c->next) | ||||||
|  | +			occ |= c->tags == TAGMASK ? 0 : c->tags; | ||||||
|  | +		do { | ||||||
|  | +			/* Do not reserve space for vacant tags */ | ||||||
|  | +			if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) | ||||||
|  | +				continue; | ||||||
|  |  			x += TEXTW(tags[i]); | ||||||
|  | -		while (ev->x >= x && ++i < LENGTH(tags)); | ||||||
|  | +		} while (ev->x >= x && ++i < LENGTH(tags)); | ||||||
|  |  		if (i < LENGTH(tags)) { | ||||||
|  |  			click = ClkTagBar; | ||||||
|  |  			arg.ui = 1 << i; | ||||||
|  | @@ -715,19 +721,18 @@ drawbar(Monitor *m) | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	for (c = m->clients; c; c = c->next) { | ||||||
|  | -		occ |= c->tags; | ||||||
|  | +		occ |= c->tags == TAGMASK ? 0 : c->tags; | ||||||
|  |  		if (c->isurgent) | ||||||
|  |  			urg |= c->tags; | ||||||
|  |  	} | ||||||
|  |  	x = 0; | ||||||
|  |  	for (i = 0; i < LENGTH(tags); i++) { | ||||||
|  | +		/* Do not draw vacant tags */ | ||||||
|  | +		if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) | ||||||
|  | +			continue; | ||||||
|  |  		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); | ||||||
|  |  		x += w; | ||||||
|  |  	} | ||||||
|  |  	w = TEXTW(m->ltsymbol); | ||||||
							
								
								
									
										177
									
								
								patches/dwm-pertag-20200914-61bb8b2.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								patches/dwm-pertag-20200914-61bb8b2.diff
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | |||||||
|  | diff --git a/dwm.c b/dwm.c | ||||||
|  | index 664c527..ac8e4ec 100644 | ||||||
|  | --- a/dwm.c | ||||||
|  | +++ b/dwm.c | ||||||
|  | @@ -111,6 +111,7 @@ typedef struct { | ||||||
|  |  	void (*arrange)(Monitor *); | ||||||
|  |  } Layout; | ||||||
|  |   | ||||||
|  | +typedef struct Pertag Pertag; | ||||||
|  |  struct Monitor { | ||||||
|  |  	char ltsymbol[16]; | ||||||
|  |  	float mfact; | ||||||
|  | @@ -130,6 +131,7 @@ struct Monitor { | ||||||
|  |  	Monitor *next; | ||||||
|  |  	Window barwin; | ||||||
|  |  	const Layout *lt[2]; | ||||||
|  | +	Pertag *pertag; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  typedef struct { | ||||||
|  | @@ -272,6 +274,15 @@ static Window root, wmcheckwin; | ||||||
|  |  /* 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  */ | ||||||
|  | +	int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  /* compile-time check if all tags fit into an unsigned int bit array. */ | ||||||
|  |  struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; | ||||||
|  |   | ||||||
|  | @@ -632,6 +643,7 @@ Monitor * | ||||||
|  |  createmon(void) | ||||||
|  |  { | ||||||
|  |  	Monitor *m; | ||||||
|  | +	unsigned int i; | ||||||
|  |   | ||||||
|  |  	m = ecalloc(1, sizeof(Monitor)); | ||||||
|  |  	m->tagset[0] = m->tagset[1] = 1; | ||||||
|  | @@ -642,6 +654,20 @@ createmon(void) | ||||||
|  |  	m->lt[0] = &layouts[0]; | ||||||
|  |  	m->lt[1] = &layouts[1 % LENGTH(layouts)]; | ||||||
|  |  	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); | ||||||
|  | +	m->pertag = ecalloc(1, sizeof(Pertag)); | ||||||
|  | +	m->pertag->curtag = m->pertag->prevtag = 1; | ||||||
|  | + | ||||||
|  | +	for (i = 0; i <= LENGTH(tags); i++) { | ||||||
|  | +		m->pertag->nmasters[i] = m->nmaster; | ||||||
|  | +		m->pertag->mfacts[i] = m->mfact; | ||||||
|  | + | ||||||
|  | +		m->pertag->ltidxs[i][0] = m->lt[0]; | ||||||
|  | +		m->pertag->ltidxs[i][1] = m->lt[1]; | ||||||
|  | +		m->pertag->sellts[i] = m->sellt; | ||||||
|  | + | ||||||
|  | +		m->pertag->showbars[i] = m->showbar; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	return m; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -967,7 +993,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); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -1502,9 +1528,9 @@ void | ||||||
|  |  setlayout(const Arg *arg) | ||||||
|  |  { | ||||||
|  |  	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) | ||||||
|  | -		selmon->sellt ^= 1; | ||||||
|  | +		selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; | ||||||
|  |  	if (arg && arg->v) | ||||||
|  | -		selmon->lt[selmon->sellt] = (Layout *)arg->v; | ||||||
|  | +		selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; | ||||||
|  |  	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); | ||||||
|  |  	if (selmon->sel) | ||||||
|  |  		arrange(selmon); | ||||||
|  | @@ -1523,7 +1549,7 @@ setmfact(const Arg *arg) | ||||||
|  |  	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; | ||||||
|  |  	if (f < 0.05 || f > 0.95) | ||||||
|  |  		return; | ||||||
|  | -	selmon->mfact = f; | ||||||
|  | +	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; | ||||||
|  |  	arrange(selmon); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -1702,7 +1728,7 @@ 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); | ||||||
|  | @@ -1741,9 +1767,33 @@ void | ||||||
|  |  toggleview(const Arg *arg) | ||||||
|  |  { | ||||||
|  |  	unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); | ||||||
|  | +	int i; | ||||||
|  |   | ||||||
|  |  	if (newtagset) { | ||||||
|  |  		selmon->tagset[selmon->seltags] = 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; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		/* 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); | ||||||
|  |  	} | ||||||
|  | @@ -2038,11 +2088,37 @@ updatewmhints(Client *c) | ||||||
|  |  void | ||||||
|  |  view(const Arg *arg) | ||||||
|  |  { | ||||||
|  | +	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->tagset[selmon->seltags] = arg->ui & TAGMASK; | ||||||
|  | +		selmon->pertag->prevtag = selmon->pertag->curtag; | ||||||
|  | + | ||||||
|  | +		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); | ||||||
|  |  } | ||||||
							
								
								
									
										220
									
								
								patches/dwm-statuscmd-20241009-8933ebc.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								patches/dwm-statuscmd-20241009-8933ebc.diff
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,220 @@ | |||||||
|  | From ca2a2e6386a746ebfc3480787e5d99da11e7abee Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Justinas Grigas <dev@jstnas.com> | ||||||
|  | Date: Wed, 9 Oct 2024 01:00:20 +0100 | ||||||
|  | Subject: [PATCH] [dwm][statuscmd] better click regions | ||||||
|  |  | ||||||
|  | The main improvement of this patch over the previous version 20210405 is that | ||||||
|  | the click region now ends on a matching signal raw byte. | ||||||
|  |  | ||||||
|  | The matching byte is optional, and without it dwm will behave as before. | ||||||
|  |  | ||||||
|  | To take advantage of this feature, scripts need to be modified to print the raw | ||||||
|  | byte at the end as well. | ||||||
|  |  | ||||||
|  | In addition, this patch cleanly applies onto master branch. | ||||||
|  | --- | ||||||
|  |  config.def.h |   6 ++- | ||||||
|  |  dwm.c        | 104 ++++++++++++++++++++++++++++++++++++++++++++++++--- | ||||||
|  |  2 files changed, 104 insertions(+), 6 deletions(-) | ||||||
|  |  | ||||||
|  | diff --git a/config.def.h b/config.def.h | ||||||
|  | index 9efa774..d008275 100644 | ||||||
|  | --- a/config.def.h | ||||||
|  | +++ b/config.def.h | ||||||
|  | @@ -55,6 +55,8 @@ static const Layout layouts[] = { | ||||||
|  |  /* helper for spawning shell commands in the pre dwm-5.0 fashion */ | ||||||
|  |  #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } | ||||||
|  |   | ||||||
|  | +#define STATUSBAR "dwmblocks" | ||||||
|  | + | ||||||
|  |  /* 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 }; | ||||||
|  | @@ -104,7 +106,9 @@ static const Button buttons[] = { | ||||||
|  |  	{ ClkLtSymbol,          0,              Button1,        setlayout,      {0} }, | ||||||
|  |  	{ ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} }, | ||||||
|  |  	{ ClkWinTitle,          0,              Button2,        zoom,           {0} }, | ||||||
|  | -	{ ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } }, | ||||||
|  | +	{ ClkStatusText,        0,              Button1,        sigstatusbar,   {.i = 1} }, | ||||||
|  | +	{ ClkStatusText,        0,              Button2,        sigstatusbar,   {.i = 2} }, | ||||||
|  | +	{ ClkStatusText,        0,              Button3,        sigstatusbar,   {.i = 3} }, | ||||||
|  |  	{ ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} }, | ||||||
|  |  	{ ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} }, | ||||||
|  |  	{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} }, | ||||||
|  | diff --git a/dwm.c b/dwm.c | ||||||
|  | index 1443802..94ee0c7 100644 | ||||||
|  | --- a/dwm.c | ||||||
|  | +++ b/dwm.c | ||||||
|  | @@ -171,6 +171,7 @@ static void focusstack(const Arg *arg); | ||||||
|  |  static Atom getatomprop(Client *c, Atom prop); | ||||||
|  |  static int getrootptr(int *x, int *y); | ||||||
|  |  static long getstate(Window w); | ||||||
|  | +static pid_t getstatusbarpid(); | ||||||
|  |  static int gettextprop(Window w, Atom atom, char *text, unsigned int size); | ||||||
|  |  static void grabbuttons(Client *c, int focused); | ||||||
|  |  static void grabkeys(void); | ||||||
|  | @@ -204,6 +205,7 @@ static void setmfact(const Arg *arg); | ||||||
|  |  static void setup(void); | ||||||
|  |  static void seturgent(Client *c, int urg); | ||||||
|  |  static void showhide(Client *c); | ||||||
|  | +static void sigstatusbar(const Arg *arg); | ||||||
|  |  static void spawn(const Arg *arg); | ||||||
|  |  static void tag(const Arg *arg); | ||||||
|  |  static void tagmon(const Arg *arg); | ||||||
|  | @@ -236,6 +238,9 @@ static void zoom(const Arg *arg); | ||||||
|  |  /* variables */ | ||||||
|  |  static const char broken[] = "broken"; | ||||||
|  |  static char stext[256]; | ||||||
|  | +static int statusw; | ||||||
|  | +static int statussig; | ||||||
|  | +static pid_t statuspid = -1; | ||||||
|  |  static int screen; | ||||||
|  |  static int sw, sh;           /* X display screen geometry width, height */ | ||||||
|  |  static int bh;               /* bar height */ | ||||||
|  | @@ -422,6 +427,7 @@ buttonpress(XEvent *e) | ||||||
|  |  	Client *c; | ||||||
|  |  	Monitor *m; | ||||||
|  |  	XButtonPressedEvent *ev = &e->xbutton; | ||||||
|  | +	char *text, *s, ch; | ||||||
|  |   | ||||||
|  |  	click = ClkRootWin; | ||||||
|  |  	/* focus monitor if necessary */ | ||||||
|  | @@ -440,9 +446,27 @@ buttonpress(XEvent *e) | ||||||
|  |  			arg.ui = 1 << i; | ||||||
|  |  		} else if (ev->x < x + TEXTW(selmon->ltsymbol)) | ||||||
|  |  			click = ClkLtSymbol; | ||||||
|  | -		else if (ev->x > selmon->ww - (int)TEXTW(stext)) | ||||||
|  | +		else if (ev->x > selmon->ww - statusw) { | ||||||
|  | +			x = selmon->ww - statusw; | ||||||
|  |  			click = ClkStatusText; | ||||||
|  | -		else | ||||||
|  | +			statussig = 0; | ||||||
|  | +			for (text = s = stext; *s && x <= ev->x; s++) { | ||||||
|  | +				if ((unsigned char)(*s) < ' ') { | ||||||
|  | +					ch = *s; | ||||||
|  | +					*s = '\0'; | ||||||
|  | +					x += TEXTW(text) - lrpad; | ||||||
|  | +					*s = ch; | ||||||
|  | +					text = s + 1; | ||||||
|  | +					if (x >= ev->x) | ||||||
|  | +						break; | ||||||
|  | +					/* reset on matching signal raw byte */ | ||||||
|  | +					if (ch == statussig) | ||||||
|  | +						statussig = 0; | ||||||
|  | +					else | ||||||
|  | +						statussig = ch; | ||||||
|  | +				} | ||||||
|  | +			} | ||||||
|  | +		} else | ||||||
|  |  			click = ClkWinTitle; | ||||||
|  |  	} else if ((c = wintoclient(ev->window))) { | ||||||
|  |  		focus(c); | ||||||
|  | @@ -708,9 +732,24 @@ drawbar(Monitor *m) | ||||||
|  |   | ||||||
|  |  	/* draw status first so it can be overdrawn by tags later */ | ||||||
|  |  	if (m == selmon) { /* status is only drawn on selected monitor */ | ||||||
|  | +		char *text, *s, ch; | ||||||
|  |  		drw_setscheme(drw, scheme[SchemeNorm]); | ||||||
|  | -		tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ | ||||||
|  | -		drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); | ||||||
|  | + | ||||||
|  | +		x = 0; | ||||||
|  | +		for (text = s = stext; *s; s++) { | ||||||
|  | +			if ((unsigned char)(*s) < ' ') { | ||||||
|  | +				ch = *s; | ||||||
|  | +				*s = '\0'; | ||||||
|  | +				tw = TEXTW(text) - lrpad; | ||||||
|  | +				drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0); | ||||||
|  | +				x += tw; | ||||||
|  | +				*s = ch; | ||||||
|  | +				text = s + 1; | ||||||
|  | +			} | ||||||
|  | +		} | ||||||
|  | +		tw = TEXTW(text) - lrpad + 2; | ||||||
|  | +		drw_text(drw, m->ww - statusw + x, 0, tw, bh, 0, text, 0); | ||||||
|  | +		tw = statusw; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	for (c = m->clients; c; c = c->next) { | ||||||
|  | @@ -876,6 +915,30 @@ getatomprop(Client *c, Atom prop) | ||||||
|  |  	return atom; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +pid_t | ||||||
|  | +getstatusbarpid() | ||||||
|  | +{ | ||||||
|  | +	char buf[32], *str = buf, *c; | ||||||
|  | +	FILE *fp; | ||||||
|  | + | ||||||
|  | +	if (statuspid > 0) { | ||||||
|  | +		snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspid); | ||||||
|  | +		if ((fp = fopen(buf, "r"))) { | ||||||
|  | +			fgets(buf, sizeof(buf), fp); | ||||||
|  | +			while ((c = strchr(str, '/'))) | ||||||
|  | +				str = c + 1; | ||||||
|  | +			fclose(fp); | ||||||
|  | +			if (!strcmp(str, STATUSBAR)) | ||||||
|  | +				return statuspid; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | +	if (!(fp = popen("pidof -s "STATUSBAR, "r"))) | ||||||
|  | +		return -1; | ||||||
|  | +	fgets(buf, sizeof(buf), fp); | ||||||
|  | +	pclose(fp); | ||||||
|  | +	return strtol(buf, NULL, 10); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  int | ||||||
|  |  getrootptr(int *x, int *y) | ||||||
|  |  { | ||||||
|  | @@ -1643,6 +1706,20 @@ showhide(Client *c) | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void | ||||||
|  | +sigstatusbar(const Arg *arg) | ||||||
|  | +{ | ||||||
|  | +	union sigval sv; | ||||||
|  | + | ||||||
|  | +	if (!statussig) | ||||||
|  | +		return; | ||||||
|  | +	sv.sival_int = arg->i; | ||||||
|  | +	if ((statuspid = getstatusbarpid()) <= 0) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	sigqueue(statuspid, SIGRTMIN+statussig, sv); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  void | ||||||
|  |  spawn(const Arg *arg) | ||||||
|  |  { | ||||||
|  | @@ -2004,8 +2081,25 @@ updatesizehints(Client *c) | ||||||
|  |  void | ||||||
|  |  updatestatus(void) | ||||||
|  |  { | ||||||
|  | -	if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) | ||||||
|  | +	if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) { | ||||||
|  |  		strcpy(stext, "dwm-"VERSION); | ||||||
|  | +		statusw = TEXTW(stext) - lrpad + 2; | ||||||
|  | +	} else { | ||||||
|  | +		char *text, *s, ch; | ||||||
|  | + | ||||||
|  | +		statusw  = 0; | ||||||
|  | +		for (text = s = stext; *s; s++) { | ||||||
|  | +			if ((unsigned char)(*s) < ' ') { | ||||||
|  | +				ch = *s; | ||||||
|  | +				*s = '\0'; | ||||||
|  | +				statusw += TEXTW(text) - lrpad; | ||||||
|  | +				*s = ch; | ||||||
|  | +				text = s + 1; | ||||||
|  | +			} | ||||||
|  | +		} | ||||||
|  | +		statusw += TEXTW(text) - lrpad + 2; | ||||||
|  | + | ||||||
|  | +	} | ||||||
|  |  	drawbar(selmon); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --  | ||||||
|  | 2.46.2 | ||||||
|  |  | ||||||
							
								
								
									
										412
									
								
								patches/dwm-swallow-6.3.diff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										412
									
								
								patches/dwm-swallow-6.3.diff
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,412 @@ | |||||||
|  | From 0cf9a007511f7dfd7dd94171b172562ebac9b6d5 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Tom Schwindl <schwindl@posteo.de> | ||||||
|  | Date: Sat, 10 Sep 2022 12:51:09 +0200 | ||||||
|  | Subject: [PATCH] 6.3 swallow patch | ||||||
|  |  | ||||||
|  | --- | ||||||
|  |  config.def.h |   9 +- | ||||||
|  |  config.mk    |   3 +- | ||||||
|  |  dwm.c        | 235 +++++++++++++++++++++++++++++++++++++++++++++++++-- | ||||||
|  |  3 files changed, 237 insertions(+), 10 deletions(-) | ||||||
|  |  | ||||||
|  | diff --git a/config.def.h b/config.def.h | ||||||
|  | index 061ad662f82a..0b2b8ffd30d5 100644 | ||||||
|  | --- a/config.def.h | ||||||
|  | +++ b/config.def.h | ||||||
|  | @@ -3,6 +3,7 @@ | ||||||
|  |  /* appearance */ | ||||||
|  |  static const unsigned int borderpx  = 1;        /* border pixel of windows */ | ||||||
|  |  static const unsigned int snap      = 32;       /* snap pixel */ | ||||||
|  | +static const int swallowfloating    = 0;        /* 1 means swallow floating windows by default */ | ||||||
|  |  static const int showbar            = 1;        /* 0 means no bar */ | ||||||
|  |  static const int topbar             = 1;        /* 0 means bottom bar */ | ||||||
|  |  static const char *fonts[]          = { "monospace:size=10" }; | ||||||
|  | @@ -26,9 +27,11 @@ static const Rule rules[] = { | ||||||
|  |  	 *	WM_CLASS(STRING) = instance, class | ||||||
|  |  	 *	WM_NAME(STRING) = title | ||||||
|  |  	 */ | ||||||
|  | -	/* class      instance    title       tags mask     isfloating   monitor */ | ||||||
|  | -	{ "Gimp",     NULL,       NULL,       0,            1,           -1 }, | ||||||
|  | -	{ "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 }, | ||||||
|  | +	/* class     instance  title           tags mask  isfloating  isterminal  noswallow  monitor */ | ||||||
|  | +	{ "Gimp",    NULL,     NULL,           0,         1,          0,           0,        -1 }, | ||||||
|  | +	{ "Firefox", NULL,     NULL,           1 << 8,    0,          0,          -1,        -1 }, | ||||||
|  | +	{ "St",      NULL,     NULL,           0,         0,          1,           0,        -1 }, | ||||||
|  | +	{ NULL,      NULL,     "Event Tester", 0,         0,          0,           1,        -1 }, /* xev */ | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* layout(s) */ | ||||||
|  | diff --git a/config.mk b/config.mk | ||||||
|  | index 81c493ef4aff..52d1ebf30bec 100644 | ||||||
|  | --- a/config.mk | ||||||
|  | +++ b/config.mk | ||||||
|  | @@ -20,10 +20,11 @@ FREETYPEINC = /usr/include/freetype2 | ||||||
|  |  # OpenBSD (uncomment) | ||||||
|  |  #FREETYPEINC = ${X11INC}/freetype2 | ||||||
|  |  #MANPREFIX = ${PREFIX}/man | ||||||
|  | +#KVMLIB = -lkvm | ||||||
|  |   | ||||||
|  |  # includes and libs | ||||||
|  |  INCS = -I${X11INC} -I${FREETYPEINC} | ||||||
|  | -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} | ||||||
|  | +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB} | ||||||
|  |   | ||||||
|  |  # flags | ||||||
|  |  CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} | ||||||
|  | diff --git a/dwm.c b/dwm.c | ||||||
|  | index e5efb6a22806..e68294b6b679 100644 | ||||||
|  | --- a/dwm.c | ||||||
|  | +++ b/dwm.c | ||||||
|  | @@ -40,6 +40,12 @@ | ||||||
|  |  #include <X11/extensions/Xinerama.h> | ||||||
|  |  #endif /* XINERAMA */ | ||||||
|  |  #include <X11/Xft/Xft.h> | ||||||
|  | +#include <X11/Xlib-xcb.h> | ||||||
|  | +#include <xcb/res.h> | ||||||
|  | +#ifdef __OpenBSD__ | ||||||
|  | +#include <sys/sysctl.h> | ||||||
|  | +#include <kvm.h> | ||||||
|  | +#endif /* __OpenBSD */ | ||||||
|  |   | ||||||
|  |  #include "drw.h" | ||||||
|  |  #include "util.h" | ||||||
|  | @@ -92,9 +98,11 @@ struct Client { | ||||||
|  |  	int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; | ||||||
|  |  	int bw, oldbw; | ||||||
|  |  	unsigned int tags; | ||||||
|  | -	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; | ||||||
|  | +	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow; | ||||||
|  | +	pid_t pid; | ||||||
|  |  	Client *next; | ||||||
|  |  	Client *snext; | ||||||
|  | +	Client *swallowing; | ||||||
|  |  	Monitor *mon; | ||||||
|  |  	Window win; | ||||||
|  |  }; | ||||||
|  | @@ -138,6 +146,8 @@ typedef struct { | ||||||
|  |  	const char *title; | ||||||
|  |  	unsigned int tags; | ||||||
|  |  	int isfloating; | ||||||
|  | +	int isterminal; | ||||||
|  | +	int noswallow; | ||||||
|  |  	int monitor; | ||||||
|  |  } Rule; | ||||||
|  |   | ||||||
|  | @@ -235,6 +245,12 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee); | ||||||
|  |  static int xerrorstart(Display *dpy, XErrorEvent *ee); | ||||||
|  |  static void zoom(const Arg *arg); | ||||||
|  |   | ||||||
|  | +static pid_t getparentprocess(pid_t p); | ||||||
|  | +static int isdescprocess(pid_t p, pid_t c); | ||||||
|  | +static Client *swallowingclient(Window w); | ||||||
|  | +static Client *termforwin(const Client *c); | ||||||
|  | +static pid_t winpid(Window w); | ||||||
|  | + | ||||||
|  |  /* variables */ | ||||||
|  |  static const char broken[] = "broken"; | ||||||
|  |  static char stext[256]; | ||||||
|  | @@ -269,6 +285,8 @@ static Drw *drw; | ||||||
|  |  static Monitor *mons, *selmon; | ||||||
|  |  static Window root, wmcheckwin; | ||||||
|  |   | ||||||
|  | +static xcb_connection_t *xcon; | ||||||
|  | + | ||||||
|  |  /* configuration, allows nested code to access above variables */ | ||||||
|  |  #include "config.h" | ||||||
|  |   | ||||||
|  | @@ -298,6 +316,8 @@ applyrules(Client *c) | ||||||
|  |  		&& (!r->class || strstr(class, r->class)) | ||||||
|  |  		&& (!r->instance || strstr(instance, r->instance))) | ||||||
|  |  		{ | ||||||
|  | +			c->isterminal = r->isterminal; | ||||||
|  | +			c->noswallow  = r->noswallow; | ||||||
|  |  			c->isfloating = r->isfloating; | ||||||
|  |  			c->tags |= r->tags; | ||||||
|  |  			for (m = mons; m && m->num != r->monitor; m = m->next); | ||||||
|  | @@ -416,6 +436,53 @@ attachstack(Client *c) | ||||||
|  |  	c->mon->stack = c; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void | ||||||
|  | +swallow(Client *p, Client *c) | ||||||
|  | +{ | ||||||
|  | + | ||||||
|  | +	if (c->noswallow || c->isterminal) | ||||||
|  | +		return; | ||||||
|  | +	if (c->noswallow && !swallowfloating && c->isfloating) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	detach(c); | ||||||
|  | +	detachstack(c); | ||||||
|  | + | ||||||
|  | +	setclientstate(c, WithdrawnState); | ||||||
|  | +	XUnmapWindow(dpy, p->win); | ||||||
|  | + | ||||||
|  | +	p->swallowing = c; | ||||||
|  | +	c->mon = p->mon; | ||||||
|  | + | ||||||
|  | +	Window w = p->win; | ||||||
|  | +	p->win = c->win; | ||||||
|  | +	c->win = w; | ||||||
|  | +	updatetitle(p); | ||||||
|  | +	XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); | ||||||
|  | +	arrange(p->mon); | ||||||
|  | +	configure(p); | ||||||
|  | +	updateclientlist(); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +void | ||||||
|  | +unswallow(Client *c) | ||||||
|  | +{ | ||||||
|  | +	c->win = c->swallowing->win; | ||||||
|  | + | ||||||
|  | +	free(c->swallowing); | ||||||
|  | +	c->swallowing = NULL; | ||||||
|  | + | ||||||
|  | +	/* unfullscreen the client */ | ||||||
|  | +	setfullscreen(c, 0); | ||||||
|  | +	updatetitle(c); | ||||||
|  | +	arrange(c->mon); | ||||||
|  | +	XMapWindow(dpy, c->win); | ||||||
|  | +	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); | ||||||
|  | +	setclientstate(c, NormalState); | ||||||
|  | +	focus(NULL); | ||||||
|  | +	arrange(c->mon); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  void | ||||||
|  |  buttonpress(XEvent *e) | ||||||
|  |  { | ||||||
|  | @@ -656,6 +723,9 @@ destroynotify(XEvent *e) | ||||||
|  |   | ||||||
|  |  	if ((c = wintoclient(ev->window))) | ||||||
|  |  		unmanage(c, 1); | ||||||
|  | + | ||||||
|  | +	else if ((c = swallowingclient(ev->window))) | ||||||
|  | +		unmanage(c->swallowing, 1); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void | ||||||
|  | @@ -1022,12 +1092,13 @@ killclient(const Arg *arg) | ||||||
|  |  void | ||||||
|  |  manage(Window w, XWindowAttributes *wa) | ||||||
|  |  { | ||||||
|  | -	Client *c, *t = NULL; | ||||||
|  | +	Client *c, *t = NULL, *term = NULL; | ||||||
|  |  	Window trans = None; | ||||||
|  |  	XWindowChanges wc; | ||||||
|  |   | ||||||
|  |  	c = ecalloc(1, sizeof(Client)); | ||||||
|  |  	c->win = w; | ||||||
|  | +	c->pid = winpid(w); | ||||||
|  |  	/* geometry */ | ||||||
|  |  	c->x = c->oldx = wa->x; | ||||||
|  |  	c->y = c->oldy = wa->y; | ||||||
|  | @@ -1042,6 +1113,7 @@ manage(Window w, XWindowAttributes *wa) | ||||||
|  |  	} else { | ||||||
|  |  		c->mon = selmon; | ||||||
|  |  		applyrules(c); | ||||||
|  | +		term = termforwin(c); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) | ||||||
|  | @@ -1076,6 +1148,8 @@ manage(Window w, XWindowAttributes *wa) | ||||||
|  |  	c->mon->sel = c; | ||||||
|  |  	arrange(c->mon); | ||||||
|  |  	XMapWindow(dpy, c->win); | ||||||
|  | +	if (term) | ||||||
|  | +		swallow(term, c); | ||||||
|  |  	focus(NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -1763,6 +1837,20 @@ unmanage(Client *c, int destroyed) | ||||||
|  |  	Monitor *m = c->mon; | ||||||
|  |  	XWindowChanges wc; | ||||||
|  |   | ||||||
|  | +	if (c->swallowing) { | ||||||
|  | +		unswallow(c); | ||||||
|  | +		return; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	Client *s = swallowingclient(c->win); | ||||||
|  | +	if (s) { | ||||||
|  | +		free(s->swallowing); | ||||||
|  | +		s->swallowing = NULL; | ||||||
|  | +		arrange(m); | ||||||
|  | +		focus(NULL); | ||||||
|  | +		return; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	detach(c); | ||||||
|  |  	detachstack(c); | ||||||
|  |  	if (!destroyed) { | ||||||
|  | @@ -1778,9 +1866,12 @@ unmanage(Client *c, int destroyed) | ||||||
|  |  		XUngrabServer(dpy); | ||||||
|  |  	} | ||||||
|  |  	free(c); | ||||||
|  | -	focus(NULL); | ||||||
|  | -	updateclientlist(); | ||||||
|  | -	arrange(m); | ||||||
|  | + | ||||||
|  | +	if (!s) { | ||||||
|  | +		arrange(m); | ||||||
|  | +		focus(NULL); | ||||||
|  | +		updateclientlist(); | ||||||
|  | +	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void | ||||||
|  | @@ -2044,6 +2135,136 @@ view(const Arg *arg) | ||||||
|  |  	arrange(selmon); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +pid_t | ||||||
|  | +winpid(Window w) | ||||||
|  | +{ | ||||||
|  | + | ||||||
|  | +	pid_t result = 0; | ||||||
|  | + | ||||||
|  | +#ifdef __linux__ | ||||||
|  | +	xcb_res_client_id_spec_t spec = {0}; | ||||||
|  | +	spec.client = w; | ||||||
|  | +	spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; | ||||||
|  | + | ||||||
|  | +	xcb_generic_error_t *e = NULL; | ||||||
|  | +	xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); | ||||||
|  | +	xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); | ||||||
|  | + | ||||||
|  | +	if (!r) | ||||||
|  | +		return (pid_t)0; | ||||||
|  | + | ||||||
|  | +	xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); | ||||||
|  | +	for (; i.rem; xcb_res_client_id_value_next(&i)) { | ||||||
|  | +		spec = i.data->spec; | ||||||
|  | +		if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { | ||||||
|  | +			uint32_t *t = xcb_res_client_id_value_value(i.data); | ||||||
|  | +			result = *t; | ||||||
|  | +			break; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	free(r); | ||||||
|  | + | ||||||
|  | +	if (result == (pid_t)-1) | ||||||
|  | +		result = 0; | ||||||
|  | + | ||||||
|  | +#endif /* __linux__ */ | ||||||
|  | + | ||||||
|  | +#ifdef __OpenBSD__ | ||||||
|  | +        Atom type; | ||||||
|  | +        int format; | ||||||
|  | +        unsigned long len, bytes; | ||||||
|  | +        unsigned char *prop; | ||||||
|  | +        pid_t ret; | ||||||
|  | + | ||||||
|  | +        if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 0), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop) | ||||||
|  | +               return 0; | ||||||
|  | + | ||||||
|  | +        ret = *(pid_t*)prop; | ||||||
|  | +        XFree(prop); | ||||||
|  | +        result = ret; | ||||||
|  | + | ||||||
|  | +#endif /* __OpenBSD__ */ | ||||||
|  | +	return result; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +pid_t | ||||||
|  | +getparentprocess(pid_t p) | ||||||
|  | +{ | ||||||
|  | +	unsigned int v = 0; | ||||||
|  | + | ||||||
|  | +#ifdef __linux__ | ||||||
|  | +	FILE *f; | ||||||
|  | +	char buf[256]; | ||||||
|  | +	snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); | ||||||
|  | + | ||||||
|  | +	if (!(f = fopen(buf, "r"))) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	fscanf(f, "%*u %*s %*c %u", &v); | ||||||
|  | +	fclose(f); | ||||||
|  | +#endif /* __linux__*/ | ||||||
|  | + | ||||||
|  | +#ifdef __OpenBSD__ | ||||||
|  | +	int n; | ||||||
|  | +	kvm_t *kd; | ||||||
|  | +	struct kinfo_proc *kp; | ||||||
|  | + | ||||||
|  | +	kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL); | ||||||
|  | +	if (!kd) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n); | ||||||
|  | +	v = kp->p_ppid; | ||||||
|  | +#endif /* __OpenBSD__ */ | ||||||
|  | + | ||||||
|  | +	return (pid_t)v; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +int | ||||||
|  | +isdescprocess(pid_t p, pid_t c) | ||||||
|  | +{ | ||||||
|  | +	while (p != c && c != 0) | ||||||
|  | +		c = getparentprocess(c); | ||||||
|  | + | ||||||
|  | +	return (int)c; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +Client * | ||||||
|  | +termforwin(const Client *w) | ||||||
|  | +{ | ||||||
|  | +	Client *c; | ||||||
|  | +	Monitor *m; | ||||||
|  | + | ||||||
|  | +	if (!w->pid || w->isterminal) | ||||||
|  | +		return NULL; | ||||||
|  | + | ||||||
|  | +	for (m = mons; m; m = m->next) { | ||||||
|  | +		for (c = m->clients; c; c = c->next) { | ||||||
|  | +			if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) | ||||||
|  | +				return c; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return NULL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +Client * | ||||||
|  | +swallowingclient(Window w) | ||||||
|  | +{ | ||||||
|  | +	Client *c; | ||||||
|  | +	Monitor *m; | ||||||
|  | + | ||||||
|  | +	for (m = mons; m; m = m->next) { | ||||||
|  | +		for (c = m->clients; c; c = c->next) { | ||||||
|  | +			if (c->swallowing && c->swallowing->win == w) | ||||||
|  | +				return c; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return NULL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  Client * | ||||||
|  |  wintoclient(Window w) | ||||||
|  |  { | ||||||
|  | @@ -2133,10 +2354,12 @@ main(int argc, char *argv[]) | ||||||
|  |  		fputs("warning: no locale support\n", stderr); | ||||||
|  |  	if (!(dpy = XOpenDisplay(NULL))) | ||||||
|  |  		die("dwm: cannot open display"); | ||||||
|  | +	if (!(xcon = XGetXCBConnection(dpy))) | ||||||
|  | +		die("dwm: cannot get xcb connection\n"); | ||||||
|  |  	checkotherwm(); | ||||||
|  |  	setup(); | ||||||
|  |  #ifdef __OpenBSD__ | ||||||
|  | -	if (pledge("stdio rpath proc exec", NULL) == -1) | ||||||
|  | +	if (pledge("stdio rpath proc exec ps", NULL) == -1) | ||||||
|  |  		die("pledge"); | ||||||
|  |  #endif /* __OpenBSD__ */ | ||||||
|  |  	scan(); | ||||||
|  | --  | ||||||
|  | 2.37.2 | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								patches/series
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								patches/series
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | dwm-swallow-6.3.diff | ||||||
|  | dwm-hide_vacant_tags-6.4.diff | ||||||
|  | dwm-pertag-20200914-61bb8b2.diff | ||||||
|  | dwm-statuscmd-20241009-8933ebc.diff | ||||||
		Reference in New Issue
	
	Block a user