Add ewmhtags,holdbar,dwmc,killunsel,switchtags patches

This commit is contained in:
mintycube 2024-05-13 21:35:17 +05:00
parent ebbbe877c9
commit 2562c98132
31 changed files with 907 additions and 340 deletions

View File

@ -48,6 +48,7 @@ install: all
ifdef YAJLLIBS
cp -f dwm-msg ${DESTDIR}${PREFIX}/bin
endif
cp -f patch/dwmc ${DESTDIR}${PREFIX}/bin
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
ifdef YAJLLIBS
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm-msg
@ -55,13 +56,9 @@ endif
mkdir -p ${DESTDIR}${MANPREFIX}/man1
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
mkdir -p ${DESTDIR}${PREFIX}/share/xsessions
test -f ${DESTDIR}${PREFIX}/share/xsessions/dwm.desktop || cp -n dwm.desktop ${DESTDIR}${PREFIX}/share/xsessions
chmod 644 ${DESTDIR}${PREFIX}/share/xsessions/dwm.desktop
uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
${DESTDIR}${MANPREFIX}/man1/dwm.1\
${DESTDIR}${PREFIX}/share/xsessions/dwm.desktop
${DESTDIR}${MANPREFIX}/man1/dwm.1
.PHONY: all clean dist install uninstall

View File

@ -6,36 +6,46 @@ This build of dwm was generated using [dwm-flexipatch](https://github.com/bakkeb
The patches used are listed below:
- bar_dwmblocks
- bar_ltsymbol
- bar_status
- bar_statusbutton
- bar_statuscmd
- bar_status2d
- bar_status2d_xrdb_termcolors
- bar_tags
- bar_hidevacanttags
- center
- cool_autostart
- fakefullscreen_client
- focusdir
- focusfollowmouse
- monoclesymbol
- noborder
- nodmenu
- no_transparent_borders
- on_empty_keys
- pertag
- restartsig
- rotatestack
- scratchpads
- scratchpads_keep_position_and_size
- seamless_restart
- shiftboth
- shiftview_clients
- tapresize
- toggletag
- transfer
- xrdb
- tile_layout
- monocle_layout
- BAR_DWMBLOCKS_PATCH
- BAR_LTSYMBOL_PATCH
- BAR_STATUS_PATCH
- BAR_STATUSBUTTON_PATCH
- BAR_STATUSCMD_PATCH
- BAR_STATUS2D_PATCH
- BAR_STATUS2D_XRDB_TERMCOLORS_PATCH
- BAR_TAGS_PATCH
- BAR_BORDER_PATCH
- BAR_CENTEREDWINDOWNAME_PATCH
- BAR_EWMHTAGS_PATCH
- BAR_HEIGHT_PATCH
- BAR_HIDEVACANTTAGS_PATCH
- BAR_HOLDBAR_PATCH
- BAR_STATUSPADDING_PATCH
- CENTER_PATCH
- COOL_AUTOSTART_PATCH
- DWMC_PATCH
- FAKEFULLSCREEN_CLIENT_PATCH
- FOCUSDIR_PATCH
- FOCUSONCLICK_PATCH
- KILLUNSEL_PATCH
- MONOCLESYMBOL_PATCH
- NOBORDER_PATCH
- NODMENU_PATCH
- NO_TRANSPARENT_BORDERS_PATCH
- ON_EMPTY_KEYS_PATCH
- PERTAG_PATCH
- RESTARTSIG_PATCH
- ROTATESTACK_PATCH
- SAVEFLOATS_PATCH
- SCRATCHPADS_PATCH
- SCRATCHPADS_KEEP_POSITION_AND_SIZE_PATCH
- SEAMLESS_RESTART_PATCH
- SHIFTBOTH_PATCH
- SHIFTVIEW_CLIENTS_PATCH
- SWITCHTAG_PATCH
- TAPRESIZE_PATCH
- TOGGLETAG_PATCH
- TRANSFER_PATCH
- XRDB_PATCH
- TILE_LAYOUT
- MONOCLE_LAYOUT

View File

@ -1,11 +1,21 @@
/* See LICENSE file for copyright and license details. */
#include <X11/XF86keysym.h>
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
/* This allows the bar border size to be explicitly set separately from borderpx.
* If left as 0 then it will default to the borderpx value of the monitor and will
* automatically update with setborderpx. */
static const unsigned int barborderpx = 0; /* border pixel of bar */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int showbar = 0; /* 0 means no bar */
static const int topbar = 0; /* 0 means bottom bar */
static const int bar_height = 0; /* 0 means derive from font, >= 1 explicit height */
static const int focusonwheel = 0;
/* Status is to be shown on: -1 (all monitors), 0 (a specific monitor by index), 'A' (active monitor) */
static const int statusmon = 'A';
static const int horizpadbar = 2; /* horizontal padding for statusbar */
static const int vertpadbar = 0; /* vertical padding for statusbar */
static const char buttonbar[] = "";
/* Indicators: see patch/bar_indicators.h for options */
@ -14,8 +24,8 @@ static int tiledindicatortype = INDICATOR_NONE;
static int floatindicatortype = INDICATOR_TOP_LEFT_SQUARE;
static int fakefsindicatortype = INDICATOR_PLUS;
static int floatfakefsindicatortype = INDICATOR_PLUS_AND_LARGER_SQUARE;
// static const char *fonts[] = { "JetBrainsMono NF DWM:size=9" };
static const char *fonts[] = { "CaskaydiaCove NF :pixelsize=12" };
static const char dmenufont[] = "monospace:size=10";
static char c000000[] = "#000000"; // placeholder value
@ -25,9 +35,9 @@ static char normbordercolor[] = "#444444";
static char normfloatcolor[] = "#db8fd9";
static char selfgcolor[] = "#eeeeee";
static char selbgcolor[] = "#88c096";
static char selbordercolor[] = "#88c096";
static char selfloatcolor[] = "#88c096";
static char selbgcolor[] = "#005577";
static char selbordercolor[] = "#005577";
static char selfloatcolor[] = "#005577";
static char titlenormfgcolor[] = "#bbbbbb";
static char titlenormbgcolor[] = "#222222";
@ -35,9 +45,9 @@ static char titlenormbordercolor[] = "#444444";
static char titlenormfloatcolor[] = "#db8fd9";
static char titleselfgcolor[] = "#eeeeee";
static char titleselbgcolor[] = "#88c096";
static char titleselbordercolor[] = "#88c096";
static char titleselfloatcolor[] = "#88c096";
static char titleselbgcolor[] = "#005577";
static char titleselbordercolor[] = "#005577";
static char titleselfloatcolor[] = "#005577";
static char tagsnormfgcolor[] = "#bbbbbb";
static char tagsnormbgcolor[] = "#222222";
@ -45,11 +55,11 @@ static char tagsnormbordercolor[] = "#444444";
static char tagsnormfloatcolor[] = "#db8fd9";
static char tagsselfgcolor[] = "#eeeeee";
static char tagsselbgcolor[] = "#88c096";
static char tagsselbordercolor[] = "#88c096";
static char tagsselfloatcolor[] = "#88c096";
static char tagsselbgcolor[] = "#005577";
static char tagsselbordercolor[] = "#005577";
static char tagsselfloatcolor[] = "#005577";
static char hidnormfgcolor[] = "#88c096";
static char hidnormfgcolor[] = "#005577";
static char hidselfgcolor[] = "#227799";
static char hidnormbgcolor[] = "#222222";
static char hidselbgcolor[] = "#222222";
@ -75,7 +85,7 @@ static char *colors[][ColCount] = {
static const char *const autostart[] = {
// "st", NULL,
"dwmblocks", NULL,
NULL
NULL /* terminate */
};
const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x28", NULL };
@ -92,6 +102,33 @@ static Sp scratchpads[] = {
{"spnotes", spcmd5},
};
/* Tags
* In a traditional dwm the number of tags in use can be changed simply by changing the number
* of strings in the tags array. This build does things a bit different which has some added
* benefits. If you need to change the number of tags here then change the NUMTAGS macro in dwm.c.
*
* Examples:
*
* 1) static char *tagicons[][NUMTAGS*2] = {
* [DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I" },
* }
*
* 2) static char *tagicons[][1] = {
* [DEFAULT_TAGS] = { "" },
* }
*
* The first example would result in the tags on the first monitor to be 1 through 9, while the
* tags for the second monitor would be named A through I. A third monitor would start again at
* 1 through 9 while the tags on a fourth monitor would also be named A through I. Note the tags
* count of NUMTAGS*2 in the array initialiser which defines how many tag text / icon exists in
* the array. This can be changed to *3 to add separate icons for a third monitor.
*
* For the second example each tag would be represented as a bullet point. Both cases work the
* same from a technical standpoint - the icon index is derived from the tag index and the monitor
* index. If the icon index is is greater than the number of tag icons then it will wrap around
* until it an icon matches. Similarly if there are two tag icons then it would alternate between
* them. This works seamlessly with alternative tags and alttagsdecoration patches.
*/
static char *tagicons[][NUMTAGS] =
{
[DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" },
@ -99,13 +136,43 @@ static char *tagicons[][NUMTAGS] =
[ALT_TAGS_DECORATION] = { "<1>", "<2>", "<3>", "<4>", "<5>", "<6>", "<7>", "<8>", "<9>" },
};
/* There are two options when it comes to per-client rules:
* - a typical struct table or
* - using the RULE macro
*
* A traditional struct table looks like this:
* // class instance title wintype tags mask isfloating monitor
* { "Gimp", NULL, NULL, NULL, 1 << 4, 0, -1 },
* { "Firefox", NULL, NULL, NULL, 1 << 7, 0, -1 },
*
* The RULE macro has the default values set for each field allowing you to only
* specify the values that are relevant for your rule, e.g.
*
* RULE(.class = "Gimp", .tags = 1 << 4)
* RULE(.class = "Firefox", .tags = 1 << 7)
*
* Refer to the Rule struct definition for the list of available fields depending on
* the patches you enable.
*/
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
* WM_WINDOW_ROLE(STRING) = role
* _NET_WM_WINDOW_TYPE(ATOM) = wintype
*/
RULE(.wintype = WTYPE "DIALOG", .isfloating = 1)
RULE(.wintype = WTYPE "UTILITY", .isfloating = 1)
RULE(.wintype = WTYPE "TOOLBAR", .isfloating = 1)
RULE(.wintype = WTYPE "SPLASH", .isfloating = 1)
// RULE(.class = "Gimp", .tags = 1 << 4)
// RULE(.class = "Firefox", .tags = 1 << 7)
RULE(.instance = "st",.class = "St", .title = "~", .tags = 1, .switchtag = 3)
RULE(.class = "firefox", .tags = 1 << 1, .switchtag = 3)
RULE(.title = "nvim", .tags = 1 << 2, .switchtag = 3)
RULE(.title = "lf", .tags = 1 << 3, .switchtag = 3)
RULE(.class = "mpv", .tags = 1 << 4, .switchtag = 3)
RULE(.title = "newsboat", .tags = 1 << 5, .switchtag = 3)
RULE(.class = "Gimp", .tags = 1 << 8, .switchtag = 3)
RULE(.instance = "spterm", .tags = SPTAG(0), .isfloating = 1)
RULE(.instance = "spcalc", .tags = SPTAG(1), .isfloating = 1)
RULE(.class = "Qalculate-gtk", .tags = SPTAG(2), .isfloating = 1)
@ -113,8 +180,21 @@ static const Rule rules[] = {
RULE(.instance = "spnotes", .tags = SPTAG(4), .isfloating = 1)
RULE(.instance = "dictionary", .isfloating = 1)
RULE(.class = "volume-ui", .isfloating = 1)
RULE(.instance = "spterm", .tags = SPTAG(0), .isfloating = 1)
};
/* Bar rules allow you to configure what is shown where on the bar, as well as
* introducing your own bar modules.
*
* monitor:
* -1 show on all monitors
* 0 show on monitor 0
* 'A' show on active monitor (i.e. focused / selected) (or just -1 for active?)
* bar - bar index, 0 is default, 1 is extrabar
* alignment - how the module is aligned compared to other modules
* widthfunc, drawfunc, clickfunc - providing bar module width, draw and click functions
* name - does nothing, intended for visual clue and for logging / debugging
*/
static const BarRule barrules[] = {
/* monitor bar alignment widthfunc drawfunc clickfunc hoverfunc name */
{ -1, 0, BAR_ALIGN_LEFT, width_stbutton, draw_stbutton, click_stbutton, NULL, "statusbutton" },
@ -124,13 +204,14 @@ static const BarRule barrules[] = {
};
/* layout(s) */
static const float mfact = 0.50;
static const int nmaster = 1;
static const int resizehints = 0;
static const int lockfullscreen = 1;
static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
/* mouse scroll resize */
static const int scrollsensetivity = 15;
static const int scrollsensetivity = 30; /* 1 means resize window by 1 pixel for each scroll event */
/* resizemousescroll direction argument list */
static const int scrollargs[][2] = {
/* width change height change */
{ +scrollsensetivity, 0 },
@ -140,8 +221,9 @@ static const int scrollargs[][2] = {
};
static const Layout layouts[] = {
/* symbol arrange function */
{ "󰙀", tile }, /* first entry is default */
{ "󰖲", NULL },
{ "󰖲", NULL }, /* no layout function means floating behavior */
{ "󰖯", monocle },
};
@ -154,14 +236,20 @@ static const Layout layouts[] = {
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
#define HOLDKEY 0xffeb // replace 0 with the keysym to activate holdbar
/* 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 const char *termcmd[] = { "st", NULL };
static const char* dmenu_run_cmd[] = { "dmenu_run", "-bw", "2", "-i", "-W", "390", "-X", "961", "-Y", "15", "-l", "15", "-g", "3", NULL };
static const char* clipmenu_cmd[] = { "clipmenu", "-bw", "2", "-i", "-W", "290", "-X", "1061", "-Y", "15", "-l", "15", NULL };
static const char* volume_ui_cmd[] = { "st", "-c", "volume-ui", "-g=80x15+353+20", "-e", "pulsemixer", NULL } ;
/* This defines the name of the executable that handles the bar (used for signalling purposes) */
#define STATUSBAR "dwmblocks"
static const Key on_empty_keys[] = {
/* modifier key function argument */
{0, XK_w, spawn, {.v = (const char *[]){"firefox", NULL}}},
@ -184,6 +272,7 @@ static const Key keys[] = {
{ 0,XF86XK_AudioNext, spawn, {.v = (const char*[]){ "mpc", "next", NULL } } },
{ 0,XF86XK_AudioPause, spawn, {.v = (const char*[]){ "mpc", "pause", NULL } } },
{ 0,XF86XK_AudioPlay, spawn, {.v = (const char*[]){ "mpc", "play", NULL } } },
{ MODKEY|ShiftMask, XK_F5, xrdb, {.v = NULL } },
{ 0,XK_F7, spawn, {.v = clipmenu_cmd } },
{ 0,XF86XK_MonBrightnessUp, spawn, {.v = (const char*[]){ "xbacklight", "-inc", "15", NULL } } },
{ 0,XF86XK_MonBrightnessDown, spawn, {.v = (const char*[]){ "xbacklight", "-dec", "15", NULL } } },
@ -191,6 +280,7 @@ static const Key keys[] = {
{ MODKEY, XK_Print, spawn, {.v = (const char*[]){ "dmenurecord", NULL } } },
{ MODKEY|ShiftMask, XK_Delete, quit, {0} },
{ MODKEY, XK_Delete, quit, {1} },
{ MODKEY, XK_grave, togglescratch, {.ui = 0 } },
{ MODKEY|ControlMask, XK_grave, setscratch, {.ui = 0 } },
{ MODKEY|ShiftMask, XK_grave, removescratch, {.ui = 0 } },
{ MODKEY, XK_0, view, {.ui = ~SPTAGMASK } },
@ -204,49 +294,61 @@ static const Key keys[] = {
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY, XK_equal, spawn, {.v = volume_ui_cmd } },
{ MODKEY, XK_minus, spawn, {.v = volume_ui_cmd } },
{ MODKEY, XK_BackSpace, spawn, {.v = (const char*[]){ "sysact", NULL } } },
{ MODKEY|ShiftMask, XK_BackSpace, spawn, {.v = (const char*[]){ "sysact", NULL } } },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY, XK_q, killclient, {0} },
{ MODKEY|ShiftMask, XK_q, killunsel, {0} },
{ MODKEY, XK_w, spawn, {.v = (const char*[]){ "firefox", NULL } } },
{ MODKEY, XK_e, spawn, {.v = (const char*[]){ "networkmanager_dmenu", NULL } } },
{ MODKEY, XK_r, spawn, {.v = (const char*[]){ "st", "-e", "lf", NULL } } },
{ MODKEY|ShiftMask, XK_r, spawn, {.v = (const char*[]){ "thunar", NULL } } },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, // tiled
{ MODKEY, XK_y, setlayout, {.v = &layouts[1]} }, // monocle
{ MODKEY, XK_u, setlayout, {.v = &layouts[2]} }, // none
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_u, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_y, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_i, setlayout, {0} },
{ MODKEY, XK_o, incnmaster, {.i = +1 } },
{ MODKEY|ShiftMask, XK_o, incnmaster, {.i = -1 } },
{ MODKEY, XK_a, spawn, {.v = (const char*[]){ "dmenu_hub", NULL } } },
{ MODKEY, XK_d, spawn, {.v = dmenu_run_cmd } },
{ MODKEY, XK_f, togglefakefullscreen, {0} },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ ALTKEY, XK_h, spawn, {.v = (const char*[]){ "dmenuhandler", NULL } } },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ ALTKEY, XK_l, spawn, {.v = (const char*[]){"dictionary", NULL } } },
{ MODKEY|ShiftMask, XK_apostrophe, togglescratch, {.ui = 2 } },
{ MODKEY, XK_apostrophe, togglescratch, {.ui = 1 } },
{ MODKEY, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_Return, spawn, {.v = (const char *[]){"st", NULL}}},
{ ALTKEY, XK_Return, spawn, {.v = (const char *[]){"st", "-c", "st", NULL}}},
{ MODKEY|ShiftMask, XK_Return, togglescratch, {.ui = 0 } },
{ MODKEY, XK_m, togglescratch, {.ui = 3 } },
{ MODKEY, XK_comma, togglescratch, {.ui = 4 } },
{ MODKEY, XK_x, transfer, {0} },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY|ShiftMask, XK_b, spawn, {.v = (const char*[]){ "dmenu_web", "--add" , NULL } } },
{ MODKEY, XK_n, spawn, {.v = (const char*[]){ "st", "-e", "nvim", NULL } } },
{ MODKEY|ShiftMask, XK_n, spawn, {.v = (const char*[]){ "st", "-e", "newsboat", NULL } } },
// { MODKEY, XK_m, spawn, {.v = (const char*[]){ "st", "-e", "ncmpcpp", NULL } } },
{ MODKEY, XK_m, togglescratch, {.ui = 3 } },
{ MODKEY, XK_comma, togglescratch, {.ui = 4 } },
// { MODKEY, XK_comma, focusmon, {.i = -1 } },
// { MODKEY, XK_period, focusmon, {.i = +1 } },
// { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
// { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
{ MODKEY, XK_slash, zoom, {0} },
{ 0, HOLDKEY, holdbar, {0} },
{ MODKEY, XK_space, spawn, {.v = (const char*[]){ "dmenu_web", NULL } } },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_Left, focusdir, {.i = 0 } },
{ MODKEY, XK_Right, focusdir, {.i = 1 } },
{ MODKEY, XK_Up, focusdir, {.i = 2 } },
{ MODKEY, XK_Down, focusdir, {.i = 3 } },
{ MODKEY, XK_Left, focusdir, {.i = 0 } }, // left
{ MODKEY, XK_Right, focusdir, {.i = 1 } }, // right
{ MODKEY, XK_Up, focusdir, {.i = 2 } }, // up
{ MODKEY, XK_Down, focusdir, {.i = 3 } }, // down
{ MODKEY|ControlMask, XK_Up, rotatestack, {.i = +1 } },
{ MODKEY|ControlMask, XK_Down, rotatestack, {.i = -1 } },
{ MODKEY|Mod1Mask, XK_Left, shiftboth, { .i = -1 } },
{ MODKEY|Mod1Mask, XK_Right, shiftboth, { .i = +1 } },
{ MODKEY|ControlMask, XK_Left, shiftviewclients, { .i = -1 } },
{ MODKEY|ControlMask, XK_Right, shiftviewclients, { .i = +1 } },
};
/* button definitions */
@ -259,6 +361,7 @@ static const Button buttons[] = {
{ ClkButton, 0, Button3, spawn, {.v = (const char*[]){ "dmenu_hub", NULL } } },
{ 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 } },
@ -278,3 +381,39 @@ static const Button buttons[] = {
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
/* signal definitions */
/* signum must be greater than 0 */
/* trigger signals using `xsetroot -name "fsignal:<signame> [<type> <value>]"` */
static const Signal signals[] = {
/* signum function */
{ "focusstack", focusstack },
{ "setmfact", setmfact },
{ "togglebar", togglebar },
{ "incnmaster", incnmaster },
{ "togglefloating", togglefloating },
{ "focusmon", focusmon },
{ "rotatestack", rotatestack },
{ "transfer", transfer },
{ "tagmon", tagmon },
{ "zoom", zoom },
{ "view", view },
{ "viewall", viewallex },
{ "viewex", viewex },
{ "toggleview", toggleview },
{ "shiftboth", shiftboth },
{ "shiftviewclients", shiftviewclients },
{ "toggleviewex", toggleviewex },
{ "tag", tag },
{ "tagall", tagallex },
{ "tagex", tagex },
{ "toggletag", toggletag },
{ "toggletagex", toggletagex },
{ "togglefakefullscreen", togglefakefullscreen },
{ "togglescratch", togglescratch },
{ "killclient", killclient },
{ "xrdb", xrdb },
{ "quit", quit },
{ "setlayout", setlayout },
{ "setlayoutex", setlayoutex },
};

View File

@ -1,5 +1,5 @@
# dwm version
VERSION = 6.4
VERSION = 6.5
# Customize below to fit your system
@ -15,8 +15,8 @@ X11LIB = /usr/X11R6/lib
#X11LIB = /usr/local/lib
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA
# XINERAMALIBS = -lXinerama
# XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lfontconfig -lXft
@ -29,7 +29,7 @@ FREETYPEINC = /usr/include/freetype2
#KVMLIB = -lkvm
# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH)
XRENDER = -lXrender
#XRENDER = -lXrender
# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH
#MPDCLIENT = -lmpdclient

View File

@ -8,7 +8,6 @@
#include "drw.h"
#include "util.h"
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
@ -17,7 +16,6 @@ static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
static long
utf8decodebyte(const char c, size_t *i)
{
@ -136,7 +134,6 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
die("no font specified.");
}
font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont;
font->pattern = pattern;
@ -235,7 +232,6 @@ drw_setscheme(Drw *drw, Clr *scm)
drw->scheme = scm;
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
@ -378,8 +374,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
return x + (render ? w : 0);
}
void
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
{

View File

@ -1,6 +1,5 @@
/* See LICENSE file for copyright and license details. */
typedef struct {
Cursor cursor;
} Cur;

View File

@ -44,12 +44,8 @@
#include "drw.h"
#include "util.h"
#include <poll.h>
/* macros */
#define Button6 6
#define Button7 7
@ -99,6 +95,7 @@ enum {
enum {
NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop,
NetClientList,
NetLast
}; /* EWMH atoms */
@ -142,7 +139,6 @@ enum {
BAR_ALIGN_LAST
}; /* bar alignment */
typedef union {
int i;
unsigned int ui;
@ -194,17 +190,18 @@ typedef struct {
const Arg arg;
} Button;
typedef struct Client Client;
struct Client {
char name[256];
float mina, maxa;
int x, y, w, h;
int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */
unsigned int idx;
int oldx, oldy, oldw, oldh;
int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
int bw, oldbw;
unsigned int tags;
unsigned int switchtag;
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
int fakefullscreen;
int iscentered;
@ -221,13 +218,11 @@ typedef struct {
const Arg arg;
} Key;
typedef struct {
const char *symbol;
void (*arrange)(Monitor *);
} Layout;
typedef struct Pertag Pertag;
struct Monitor {
char ltsymbol[16];
@ -255,6 +250,7 @@ typedef struct {
const char *title;
const char *wintype;
unsigned int tags;
int switchtag;
int iscentered;
int isfloating;
int monitor;
@ -269,8 +265,7 @@ typedef struct {
#define FAKEFULLSCREEN
#define NOSWALLOW
#define TERMINAL
#define SWITCHTAG
#define SWITCHTAG , .switchtag = 1
/* function declarations */
static void applyrules(Client *c);
@ -295,7 +290,6 @@ static Monitor *dirtomon(int dir);
static void drawbar(Monitor *m);
static void drawbars(void);
static void drawbarwin(Bar *bar);
static void enternotify(XEvent *e);
static void expose(XEvent *e);
static void focus(Client *c);
static void focusin(XEvent *e);
@ -316,6 +310,7 @@ static void maprequest(XEvent *e);
static void motionnotify(XEvent *e);
static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c);
static int noborder(Client *c);
static void pop(Client *c);
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
@ -386,14 +381,15 @@ static int (*xerrorxlib)(Display *, XErrorEvent *);
static unsigned int numlockmask = 0;
static void (*handler[LASTEvent]) (XEvent *) = {
[ButtonPress] = buttonpress,
[ButtonRelease] = keyrelease,
[ClientMessage] = clientmessage,
[ConfigureRequest] = configurerequest,
[ConfigureNotify] = configurenotify,
[DestroyNotify] = destroynotify,
[EnterNotify] = enternotify,
[Expose] = expose,
[FocusIn] = focusin,
[KeyPress] = keypress,
[KeyRelease] = keyrelease,
[MappingNotify] = mappingnotify,
[MapRequest] = maprequest,
[MotionNotify] = motionnotify,
@ -426,6 +422,7 @@ applyrules(Client *c)
const char *class, *instance;
Atom wintype;
unsigned int i;
unsigned int newtagset;
const Rule *r;
Monitor *m;
XClassHint ch = { NULL, NULL };
@ -438,7 +435,6 @@ applyrules(Client *c)
instance = ch.res_name ? ch.res_name : broken;
wintype = getatomprop(c, netatom[NetWMWindowType], XA_ATOM);
for (i = 0; i < LENGTH(rules); i++) {
r = &rules[i];
if ((!r->title || strstr(c->name, r->title))
@ -457,6 +453,27 @@ applyrules(Client *c)
if (m)
c->mon = m;
if (r->switchtag)
{
unfocus(selmon->sel, 1, NULL);
selmon = c->mon;
if (r->switchtag == 2 || r->switchtag == 4)
newtagset = c->mon->tagset[c->mon->seltags] ^ c->tags;
else
newtagset = c->tags;
/* Switch to the client's tag, but only if that tag is not already shown */
if (newtagset && !(c->tags & c->mon->tagset[c->mon->seltags])) {
if (r->switchtag == 3 || r->switchtag == 4)
c->switchtag = c->mon->tagset[c->mon->seltags];
if (r->switchtag == 1 || r->switchtag == 3) {
view(&((Arg) { .ui = newtagset }));
} else {
c->mon->tagset[c->mon->seltags] = newtagset;
arrange(c->mon);
}
}
}
}
}
if (ch.res_class)
@ -583,9 +600,9 @@ buttonpress(XEvent *e)
BarArg carg = { 0, 0, 0, 0 };
click = ClkRootWin;
/* focus monitor if necessary */
if ((m = wintomon(ev->window)) && m != selmon
&& (focusonwheel || (ev->button != Button4 && ev->button != Button5))
) {
unfocus(selmon->sel, 1, NULL);
selmon = m;
@ -615,10 +632,9 @@ buttonpress(XEvent *e)
}
}
if (click == ClkRootWin && (c = wintoclient(ev->window))) {
if (focusonwheel || (ev->button != Button4 && ev->button != Button5))
focus(c);
restack(selmon);
XAllowEvents(dpy, ReplayPointer, CurrentTime);
click = ClkClientWin;
}
@ -653,7 +669,6 @@ cleanup(void)
Layout foo = { "", NULL };
size_t i;
for (m = mons; m; m = m->next)
persistmonitorstate(m);
@ -715,7 +730,6 @@ clientmessage(XEvent *e)
XClientMessageEvent *cme = &e->xclient;
Client *c = wintoclient(cme->window);
if (!c)
return;
if (cme->message_type == netatom[NetWMState]) {
@ -748,6 +762,13 @@ configure(Client *c)
ce.width = c->w;
ce.height = c->h;
ce.border_width = c->bw;
if (noborder(c)) {
ce.width += c->bw * 2;
ce.height += c->bw * 2;
ce.border_width = 0;
}
ce.above = None;
ce.override_redirect = False;
XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
@ -875,12 +896,11 @@ createmon(void)
istopbar = !istopbar;
bar->showbar = 1;
bar->external = 0;
bar->borderpx = 0;
bar->borderpx = (barborderpx ? barborderpx : borderpx);
bar->bh = bh + bar->borderpx * 2;
bar->borderscheme = SchemeNorm;
}
if (!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag))))
die("fatal: could not malloc() %u bytes\n", sizeof(Pertag));
m->pertag->curtag = 1;
@ -892,8 +912,6 @@ createmon(void)
/* init mfacts */
m->pertag->mfacts[i] = m->mfact;
/* init layouts */
m->pertag->ltidxs[i][0] = m->lt[0];
m->pertag->ltidxs[i][1] = m->lt[1];
@ -1096,25 +1114,6 @@ drawbarwin(Bar *bar)
drw_map(drw, bar->win, 0, 0, bar->bw, bar->bh);
}
void
enternotify(XEvent *e)
{
Client *c;
Monitor *m;
XCrossingEvent *ev = &e->xcrossing;
if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
return;
c = wintoclient(ev->window);
m = c ? c->mon : wintomon(ev->window);
if (m != selmon) {
unfocus(selmon->sel, 1, c);
selmon = m;
} else if (!c || c == selmon->sel)
return;
focus(c);
}
void
expose(XEvent *e)
{
@ -1129,8 +1128,6 @@ expose(XEvent *e)
void
focus(Client *c)
{
if (!c || !ISVISIBLE(c))
c = getpointerclient();
if (!c || !ISVISIBLE(c))
for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
if (selmon->sel && selmon->sel != c)
@ -1219,7 +1216,6 @@ getatomprop(Client *c, Atom prop, Atom req)
unsigned char *p = NULL;
Atom da, atom = None;
/* FIXME getatomprop should return the number of items and a pointer to
* the stored data instead of this workaround */
if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
@ -1412,6 +1408,7 @@ manage(Window w, XWindowAttributes *wa)
c = ecalloc(1, sizeof(Client));
c->win = w;
/* geometry */
c->sfx = c->sfy = c->sfw = c->sfh = -9999;
c->x = c->oldx = wa->x;
c->y = c->oldy = wa->y;
c->w = c->oldw = wa->width;
@ -1420,7 +1417,6 @@ manage(Window w, XWindowAttributes *wa)
settings_restored = restoreclientstate(c);
updatetitle(c);
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
c->mon = t->mon;
c->tags = t->tags;
@ -1428,8 +1424,10 @@ manage(Window w, XWindowAttributes *wa)
if (c->x == c->mon->wx && c->y == c->mon->wy)
c->iscentered = 1;
} else {
if (!settings_restored)
if (!settings_restored || c->mon == NULL) {
c->mon = selmon;
settings_restored = 0;
}
if (c->x == c->mon->wx && c->y == c->mon->wy)
c->iscentered = 1;
c->bw = borderpx;
@ -1437,7 +1435,6 @@ manage(Window w, XWindowAttributes *wa)
applyrules(c);
}
if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
c->x = c->mon->wx + c->mon->ww - WIDTH(c);
if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh)
@ -1456,8 +1453,12 @@ manage(Window w, XWindowAttributes *wa)
updatewmhints(c);
if (c->iscentered) {
c->x = c->mon->wx + (c->mon->ww - WIDTH(c)) / 2;
c->y = c->mon->wy + (c->mon->wh - HEIGHT(c)) / 2;
c->sfx = c->x = c->mon->wx + (c->mon->ww - WIDTH(c)) / 2;
c->sfy = c->y = c->mon->wy + (c->mon->wh - HEIGHT(c)) / 2;
}
if (c->sfw == -9999) {
c->sfw = c->w;
c->sfh = c->h;
}
if (getatomprop(c, netatom[NetWMState], XA_ATOM) == netatom[NetWMFullscreen])
@ -1486,6 +1487,7 @@ manage(Window w, XWindowAttributes *wa)
XMapWindow(dpy, c->win);
focus(NULL);
setfloatinghint(c);
}
void
@ -1504,7 +1506,6 @@ maprequest(XEvent *e)
static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest;
if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect)
return;
if (!wintoclient(ev->window))
@ -1514,8 +1515,6 @@ maprequest(XEvent *e)
void
motionnotify(XEvent *e)
{
static Monitor *mon = NULL;
Monitor *m;
Bar *bar;
XMotionEvent *ev = &e->xmotion;
@ -1524,15 +1523,6 @@ motionnotify(XEvent *e)
return;
}
if (ev->window != root)
return;
if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
unfocus(selmon->sel, 1, NULL);
selmon = m;
focus(NULL);
}
mon = m;
}
void
@ -1582,6 +1572,7 @@ movemouse(const Arg *arg)
ny = selmon->wy + selmon->wh - HEIGHT(c);
if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
&& (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) {
c->sfx = -9999; // disable savefloats when using movemouse
togglefloating(NULL);
}
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
@ -1601,6 +1592,11 @@ movemouse(const Arg *arg)
selmon = m;
focus(NULL);
}
/* save last known float coordinates */
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
c->sfx = nx;
c->sfy = ny;
}
ignoreconfigurerequests = 0;
}
@ -1611,6 +1607,29 @@ nexttiled(Client *c)
return c;
}
int
noborder(Client *c)
{
int monocle_layout = 0;
if (&monocle == c->mon->lt[c->mon->sellt]->arrange)
monocle_layout = 1;
if (!monocle_layout && (nexttiled(c->mon->clients) != c || nexttiled(c->next)))
return 0;
if (c->isfloating)
return 0;
if (!c->mon->lt[c->mon->sellt]->arrange)
return 0;
if (c->fakefullscreen != 1 && c->isfullscreen)
return 0;
return 1;
}
void
pop(Client *c)
{
@ -1627,8 +1646,8 @@ propertynotify(XEvent *e)
Window trans;
XPropertyEvent *ev = &e->xproperty;
if ((ev->window == root) && (ev->atom == XA_WM_NAME)) {
if (!fake_signal())
updatestatus();
} else if (ev->state == PropertyDelete) {
return; /* ignore */
@ -1695,14 +1714,9 @@ resizeclient(Client *c, int x, int y, int w, int h)
c->oldw = c->w; c->w = wc.width = w;
c->oldh = c->h; c->h = wc.height = h;
wc.border_width = c->bw;
if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next))
|| &monocle == c->mon->lt[c->mon->sellt]->arrange
)
&& (c->fakefullscreen == 1 || !c->isfullscreen)
&& !c->isfloating
&& c->mon->lt[c->mon->sellt]->arrange) {
c->w = wc.width += c->bw * 2;
c->h = wc.height += c->bw * 2;
if (noborder(c)) {
wc.width += c->bw * 2;
wc.height += c->bw * 2;
wc.border_width = 0;
}
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
@ -1753,6 +1767,7 @@ resizemouse(const Arg *arg)
{
if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
&& (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) {
c->sfx = -9999; // disable savefloats when using resizemouse
togglefloating(NULL);
}
}
@ -1775,6 +1790,13 @@ resizemouse(const Arg *arg)
selmon = m;
focus(NULL);
}
/* save last known float dimensions */
if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) {
c->sfx = nx;
c->sfy = ny;
c->sfw = nw;
c->sfh = nh;
}
ignoreconfigurerequests = 0;
}
@ -1874,6 +1896,8 @@ sendmon(Client *c, Monitor *m)
attachstack(c);
arrange(NULL);
focus(NULL);
if (c->switchtag)
c->switchtag = 0;
}
void
@ -2049,8 +2073,8 @@ setup(void)
drw = drw_create(dpy, screen, root, sw, sh);
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
bh = drw->fonts->h + 2;
lrpad = drw->fonts->h + horizpadbar;
bh = drw->fonts->h + vertpadbar;
updategeom();
/* init atoms */
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
@ -2062,6 +2086,10 @@ setup(void)
clientatom[ClientTags] = XInternAtom(dpy, "_DWM_CLIENT_TAGS", False);
netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
netatom[NetDesktopViewport] = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False);
netatom[NetNumberOfDesktops] = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
@ -2092,6 +2120,10 @@ setup(void)
/* EWMH support per view */
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
PropModeReplace, (unsigned char *) netatom, NetLast);
setnumdesktops();
setcurrentdesktop();
setdesktopnames();
setviewport();
XDeleteProperty(dpy, root, netatom[NetClientList]);
/* select events */
wa.cursor = cursor[CurNormal]->cursor;
@ -2101,12 +2133,10 @@ setup(void)
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
XSelectInput(dpy, root, wa.event_mask);
grabkeys();
focus(NULL);
}
void
seturgent(Client *c, int urg)
{
@ -2140,6 +2170,12 @@ showhide(Client *c)
c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
}
/* show clients top down */
if (!c->mon->lt[c->mon->sellt]->arrange && c->sfx != -9999 && !c->isfullscreen) {
XMoveResizeWindow(dpy, c->win, c->sfx, c->sfy, c->sfw, c->sfh);
resize(c, c->sfx, c->sfy, c->sfw, c->sfh, 0);
showhide(c->snext);
return;
}
XMoveWindow(dpy, c->win, c->x, c->y);
if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating)
&& !c->isfullscreen
@ -2182,7 +2218,6 @@ spawn(const Arg *arg)
{
struct sigaction sa;
if (fork() == 0)
{
if (dpy)
@ -2206,6 +2241,8 @@ tag(const Arg *arg)
if (selmon->sel && arg->ui & TAGMASK) {
selmon->sel->tags = arg->ui & TAGMASK;
if (selmon->sel->switchtag)
selmon->sel->switchtag = 0;
arrange(selmon);
focus(NULL);
}
@ -2216,9 +2253,16 @@ tagmon(const Arg *arg)
{
Client *c = selmon->sel;
Monitor *dest;
int restored;
if (!c || !mons->next)
return;
dest = dirtomon(arg->i);
savewindowfloatposition(c, c->mon);
restored = restorewindowfloatposition(c, dest);
if (restored && (!dest->lt[dest->sellt]->arrange || c->isfloating)) {
XMoveResizeWindow(dpy, c->win, c->sfx, c->sfy, c->sfw, c->sfh);
resize(c, c->sfx, c->sfy, c->sfw, c->sfh, 1);
}
sendmon(c, dest);
}
@ -2226,7 +2270,7 @@ void
togglebar(const Arg *arg)
{
Bar *bar;
selmon->showbar = !selmon->showbar;
selmon->showbar = (selmon->showbar == 2 ? 1 : !selmon->showbar);
updatebarpos(selmon);
for (bar = selmon->bar; bar; bar = bar->next)
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
@ -2249,10 +2293,21 @@ togglefloating(const Arg *arg)
else
XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
if (c->isfloating) {
if (c->sfx != -9999) {
/* restore last known float dimensions */
resize(c, c->sfx, c->sfy, c->sfw, c->sfh, 0);
} else
resize(c, c->x, c->y, c->w, c->h, 0);
} else {
/* save last known float dimensions */
c->sfx = c->x;
c->sfy = c->y;
c->sfw = c->w;
c->sfh = c->h;
}
arrange(c->mon);
setfloatinghint(c);
}
void
@ -2268,6 +2323,7 @@ toggletag(const Arg *arg)
arrange(selmon);
focus(NULL);
}
updatecurrentdesktop();
}
void
@ -2276,7 +2332,6 @@ toggleview(const Arg *arg)
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);;
int i;
if (newtagset) {
selmon->tagset[selmon->seltags] = newtagset;
@ -2299,6 +2354,7 @@ toggleview(const Arg *arg)
arrange(selmon);
focus(NULL);
}
updatecurrentdesktop();
}
void
@ -2321,11 +2377,11 @@ void
unmanage(Client *c, int destroyed)
{
Monitor *m;
unsigned int switchtag = c->switchtag;
XWindowChanges wc;
m = c->mon;
detach(c);
detachstack(c);
if (!destroyed) {
@ -2341,11 +2397,12 @@ unmanage(Client *c, int destroyed)
XUngrabServer(dpy);
}
free(c);
arrange(m);
focus(NULL);
updateclientlist();
if (switchtag && ((switchtag & TAGMASK) != selmon->tagset[selmon->seltags]))
view(&((Arg) { .ui = switchtag }));
}
void
@ -2401,7 +2458,6 @@ updatebarpos(Monitor *m)
int y_pad = 0;
int x_pad = 0;
for (bar = m->bar; bar; bar = bar->next) {
bar->bx = m->wx + x_pad;
bar->bw = m->ww - 2 * x_pad;
@ -2411,7 +2467,6 @@ updatebarpos(Monitor *m)
if (!m->showbar || !bar->showbar)
bar->by = -bar->bh - y_pad;
if (!m->showbar)
return;
for (bar = m->bar; bar; bar = bar->next) {
@ -2638,6 +2693,7 @@ view(const Arg *arg)
pertagview(arg);
arrange(selmon);
focus(NULL);
updatecurrentdesktop();
}
Client *
@ -2717,8 +2773,6 @@ zoom(const Arg *arg)
if (!c)
return;
if (!c->mon->lt[c->mon->sellt]->arrange || !c || c->isfloating)
return;

View File

@ -1,7 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
Name=Dwm
Comment=Dynamic window manager
Exec=dwm
Icon=dwm
Type=XSession

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 B

View File

@ -0,0 +1,52 @@
void
setcurrentdesktop(void)
{
long data[] = { 0 };
XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
}
void
setdesktopnames(void)
{
int i;
XTextProperty text;
char *tags[NUMTAGS];
for (i = 0; i < NUMTAGS; i++)
tags[i] = tagicon(selmon, i);
Xutf8TextListToTextProperty(dpy, tags, NUMTAGS, XUTF8StringStyle, &text);
XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]);
}
void
setfloatinghint(Client *c)
{
Atom target = XInternAtom(dpy, "_IS_FLOATING", 0);
unsigned int floating[1] = {c->isfloating};
XChangeProperty(dpy, c->win, target, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)floating, 1);
}
void
setnumdesktops(void)
{
long data[] = { NUMTAGS };
XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
}
void
setviewport(void)
{
long data[] = { 0, 0 };
XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2);
}
void
updatecurrentdesktop(void)
{
long rawdata[] = { selmon->tagset[selmon->seltags] };
int i = 0;
while (*rawdata >> (i + 1)) {
i++;
}
long data[] = { i };
XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
}

View File

@ -0,0 +1,7 @@
static void setcurrentdesktop(void);
static void setdesktopnames(void);
static void setfloatinghint(Client *c);
static void setnumdesktops(void);
static void setviewport(void);
static void updatecurrentdesktop(void);

View File

@ -0,0 +1,36 @@
void
holdbar(const Arg *arg)
{
if (selmon->showbar)
return;
Bar *bar;
selmon->showbar = 2;
updatebarpos(selmon);
for (bar = selmon->bar; bar; bar = bar->next)
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
drawbar(selmon);
}
void
keyrelease(XEvent *e)
{
Bar *bar;
if (XEventsQueued(dpy, QueuedAfterReading)) {
XEvent ne;
XPeekEvent(dpy, &ne);
if (ne.type == KeyPress && ne.xkey.time == e->xkey.time &&
ne.xkey.keycode == e->xkey.keycode) {
XNextEvent(dpy, &ne);
return;
}
}
if (e->xkey.keycode == XKeysymToKeycode(dpy, HOLDKEY) && selmon->showbar == 2) {
selmon->showbar = 0;
updatebarpos(selmon);
for (bar = selmon->bar; bar; bar = bar->next)
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
arrange(selmon);
}
}

View File

@ -0,0 +1,3 @@
static void keyrelease(XEvent *e);
static void holdbar(const Arg *arg);

View File

@ -4,14 +4,12 @@ width_status(Bar *bar, BarArg *a)
return TEXTWM(stext);
}
int
draw_status(Bar *bar, BarArg *a)
{
return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, stext, 0, True);
}
int
click_status(Bar *bar, Arg *arg, BarArg *a)
{

View File

@ -27,15 +27,12 @@ width_status2d(Bar *bar, BarArg *a)
return width ? width + lrpad : 0;
}
int
draw_status2d(Bar *bar, BarArg *a)
{
return drawstatusbar(a, rawstext);
}
int
drawstatusbar(BarArg *a, char* stext)
{

View File

@ -1,11 +1,9 @@
int
click_statuscmd(Bar *bar, Arg *arg, BarArg *a)
{
return click_statuscmd_text(arg, a->x, rawstext);
}
int
click_statuscmd_text(Arg *arg, int rel_x, char *text)
{

136
.config/suckless/dwm/patch/dwmc Executable file
View File

@ -0,0 +1,136 @@
#!/usr/bin/env bash
signal() {
xsetroot -name "fsignal:$*"
}
case $# in
1)
case $1 in
focusurgent) ;&
mirrorlayout) ;&
mpdcontrol) ;&
nametag) ;&
pushdown) ;&
pushup) ;&
self_restart) ;&
setlayout) ;&
setcfact) ;&
showhideclient) ;&
switchcol) ;&
view) ;&
viewall) ;&
viewtoleft) ;&
viewtoright) ;&
tagtoleft) ;&
tagtoright) ;&
tagandviewtoleft) ;&
tagandviewtoright) ;&
transfer) ;&
transferall) ;&
togglealttag) ;&
togglebar) ;&
toggletopbar) ;&
togglefloating) ;&
togglefullscreen) ;&
fullscreen) ;&
togglefakefullscreen) ;&
togglesticky) ;&
togglehorizontalmax) ;&
toggleverticalmax) ;&
togglemax) ;&
togglegaps) ;&
defaultgaps) ;&
unfloatvisible) ;&
winview) ;&
xrdb) ;&
zoom) ;&
killclient) ;&
quit)
signal $1
;;
*)
echo "Unknown command ($1) or missing one argument."
exit 1
;;
esac
;;
2)
case $1 in
cyclelayout) ;&
explace) ;&
moveplace) ;&
mpdchange) ;&
setkeymode) ;&
switchtag) ;&
togglescratch) ;&
view)
signal $1 ui $2
;;
viewex) ;&
toggleviewex) ;&
tagallmon) ;&
tagswapmon) ;&
tagex) ;&
toggletagex) ;&
setborderpx) ;&
setgaps) ;&
setlayoutex) ;&
setlayoutaxisex) ;&
swapfocus) ;&
focusstack) ;&
pushstack) ;&
inplacerotate) ;&
rotatestack) ;&
rotatelayoutaxis) ;&
incnmaster) ;&
incnstack) ;&
incrgaps) ;&
incrigaps) ;&
incrogaps) ;&
incrihgaps) ;&
incrivgaps) ;&
incrohgaps) ;&
incrovgaps) ;&
movestack) ;&
shiftview) ;&
shiftviewclients) ;&
focusmon) ;&
tagmon)
signal $1 i $2
;;
setcfact) ;&
setmfact)
signal $1 f $2
;;
floatpos)
signal $1 v $2
;;
*)
echo "Unknown command ($1) or too many arguments"
exit 1
;;
esac
;;
5)
case $1 in
setgaps)
# Expects "setgaps oh ov ih iv" where -1 means to keep existing values
[ $2 = -1 ] && oh=128 || oh=$2
[ $3 = -1 ] && ov=128 || ov=$3
[ $4 = -1 ] && ih=128 || ih=$4
[ $5 = -1 ] && iv=128 || iv=$5
signal $1 i $(((oh << 24) + (ov << 16) + (ih << 8) + iv))
;;
*)
echo "Unknown command ($1) or too many arguments"
exit 1
;;
esac
;;
*)
echo "Unknown command ($1) or too many arguments"
exit 1
;;
esac

View File

@ -0,0 +1,87 @@
void
setlayoutex(const Arg *arg)
{
setlayout(&((Arg) { .v = &layouts[arg->i] }));
}
void
viewex(const Arg *arg)
{
view(&((Arg) { .ui = 1 << arg->ui }));
}
void
viewallex(const Arg *arg)
{
view(&((Arg){.ui = ~SPTAGMASK}));
}
void
toggleviewex(const Arg *arg)
{
toggleview(&((Arg) { .ui = 1 << arg->ui }));
}
void
tagex(const Arg *arg)
{
tag(&((Arg) { .ui = 1 << arg->ui }));
}
void
toggletagex(const Arg *arg)
{
toggletag(&((Arg) { .ui = 1 << arg->ui }));
}
void
tagallex(const Arg *arg)
{
tag(&((Arg){.ui = ~SPTAGMASK}));
}
int
fake_signal(void)
{
char fsignal[256];
char indicator[9] = "fsignal:";
char str_sig[50];
char param[16];
int i, len_str_sig, n, paramn;
size_t len_fsignal, len_indicator = strlen(indicator);
Arg arg;
// Get root name property
if (gettextprop(root, XA_WM_NAME, fsignal, sizeof(fsignal))) {
len_fsignal = strlen(fsignal);
// Check if this is indeed a fake signal
if (len_indicator > len_fsignal ? 0 : strncmp(indicator, fsignal, len_indicator) == 0) {
paramn = sscanf(fsignal+len_indicator, "%s%n%s%n", str_sig, &len_str_sig, param, &n);
if (paramn == 1) arg = (Arg) {0};
else if (paramn > 2) return 1;
else if (strncmp(param, "i", n - len_str_sig) == 0)
sscanf(fsignal + len_indicator + n, "%i", &(arg.i));
else if (strncmp(param, "ui", n - len_str_sig) == 0)
sscanf(fsignal + len_indicator + n, "%u", &(arg.ui));
else if (strncmp(param, "f", n - len_str_sig) == 0)
sscanf(fsignal + len_indicator + n, "%f", &(arg.f));
else if (strncmp(param, "v", n - len_str_sig) == 0)
arg.v = &(fsignal[len_indicator + n + 1]);
else return 1;
// Check if a signal was found, and if so handle it
for (i = 0; i < LENGTH(signals); i++)
if (strncmp(str_sig, signals[i].sig, len_str_sig) == 0 && signals[i].func)
signals[i].func(&(arg));
// A fake signal was sent
return 1;
}
}
// No fake signal was sent, so proceed with update
return 0;
}

View File

@ -0,0 +1,14 @@
typedef struct {
const char * sig;
void (*func)(const Arg *);
} Signal;
static void setlayoutex(const Arg *arg);
static void viewex(const Arg *arg);
static void viewallex(const Arg *arg);
static void toggleviewex(const Arg *arg);
static void tagex(const Arg *arg);
static void toggletagex(const Arg *arg);
static void tagallex(const Arg *arg);
static int fake_signal(void);

View File

@ -1,9 +0,0 @@
Client *
getpointerclient(void)
{
Window dummy, win;
int di;
unsigned int dui;
XQueryPointer(dpy, root, &dummy, &win, &di, &di, &di, &di, &dui);
return wintoclient(win);
}

View File

@ -1 +0,0 @@
static Client *getpointerclient(void);

View File

@ -4,19 +4,22 @@
#include "bar.c"
#include "bar_dwmblocks.c"
#include "bar_ewmhtags.c"
#include "bar_ltsymbol.c"
#include "bar_status.c"
#include "bar_status2d.c"
#include "bar_statusbutton.c"
#include "bar_statuscmd.c"
#include "bar_tags.c"
#include "bar_holdbar.c"
/* Other patches */
#include "attachx.c"
#include "cool_autostart.c"
#include "dwmc.c"
#include "fakefullscreenclient.c"
#include "focusdir.c"
#include "focusfollowmouse.c"
#include "killunsel.c"
#include "pertag.c"
#include "restartsig.c"
#include "rotatestack.c"

View File

@ -4,6 +4,8 @@
#include "bar.h"
#include "bar_dwmblocks.h"
#include "bar_ewmhtags.h"
#include "bar_holdbar.h"
#include "bar_ltsymbol.h"
#include "bar_status.h"
#include "bar_status2d.h"
@ -14,9 +16,10 @@
/* Other patches */
#include "attachx.h"
#include "cool_autostart.h"
#include "dwmc.h"
#include "fakefullscreenclient.h"
#include "focusdir.h"
#include "focusfollowmouse.h"
#include "killunsel.h"
#include "pertag.h"
#include "restartsig.h"
#include "rotatestack.h"

View File

@ -0,0 +1,24 @@
void
killunsel(const Arg *arg)
{
Client *i = NULL;
if (!selmon->sel)
return;
for (i = selmon->clients; i; i = i->next) {
if (ISVISIBLE(i) && i != selmon->sel) {
if (!sendevent(i, wmatom[WMDelete]))
{
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll);
XKillClient(dpy, i->win);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
}
}
}
}

View File

@ -0,0 +1,2 @@
static void killunsel(const Arg *arg);

View File

@ -8,7 +8,6 @@ tile(Monitor *m)
int mrest, srest;
Client *c;
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
if (n == 0)

View File

@ -24,6 +24,5 @@ pertagview(const Arg *arg)
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];
}

View File

@ -25,14 +25,16 @@ persistclientstate(Client *c)
{
setclienttags(c);
setclientfields(c);
savewindowfloatposition(c, c->mon);
}
int
restoreclientstate(Client *c)
{
return getclienttags(c)
| getclientfields(c)
;
int restored = getclientfields(c);
getclienttags(c);
restorewindowfloatposition(c, c->mon ? c->mon : selmon);
return restored;
}
void setmonitorfields(Monitor *m)
@ -237,3 +239,76 @@ getclienttags(Client *c)
return 1;
}
void
savewindowfloatposition(Client *c, Monitor *m)
{
char atom[22] = {0};
if (c->sfx == -9999)
return;
sprintf(atom, "_DWM_FLOATPOS_%u", m->num);
uint32_t pos[] = { (MAX(c->sfx - m->mx, 0) & 0xffff) | ((MAX(c->sfy - m->my, 0) & 0xffff) << 16) };
XChangeProperty(dpy, c->win, XInternAtom(dpy, atom, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)pos, 1);
sprintf(atom, "_DWM_FLOATSIZE_%u", m->num);
uint32_t size[] = { (c->sfw & 0xffff) | ((c->sfh & 0xffff) << 16) };
XChangeProperty(dpy, c->win, XInternAtom(dpy, atom, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)size, 1);
XSync(dpy, False);
}
int
restorewindowfloatposition(Client *c, Monitor *m)
{
char atom[22] = {0};
Atom key, value;
int x, y, w, h;
if (m == NULL)
return 0;
sprintf(atom, "_DWM_FLOATPOS_%u", m->num);
key = XInternAtom(dpy, atom, False);
if (!key)
return 0;
value = getatomprop(c, key, AnyPropertyType);
if (!value)
return 0;
x = value & 0xffff;
y = value >> 16;
sprintf(atom, "_DWM_FLOATSIZE_%u", m->num);
key = XInternAtom(dpy, atom, False);
if (!key)
return 0;
value = getatomprop(c, key, AnyPropertyType);
if (!value)
return 0;
w = value & 0xffff;
h = value >> 16;
if (w <= 0 || h <= 0) {
fprintf(stderr, "restorewindowfloatposition: bad float values x = %d, y = %d, w = %d, h = %d for client = %s\n", x, y, w, h, c->name);
return 0;
}
c->sfx = m->mx + x;
c->sfy = m->my + y;
c->sfw = w;
c->sfh = h;
if (c->isfloating) {
c->x = c->sfx;
c->y = c->sfy;
c->w = c->sfw;
c->h = c->sfh;
}
return 1;
}

View File

@ -13,3 +13,5 @@ static int getclientfields(Client *c);
static void setclienttags(Client *c);
static int getclienttags(Client *c);
static int getlayoutindex(const Layout *layout);
static void savewindowfloatposition(Client *c, Monitor *m);
static int restorewindowfloatposition(Client *c, Monitor *m);

View File

@ -19,4 +19,3 @@
static void loadxrdb(void);
static void xrdb(const Arg *arg);

View File

@ -1,43 +0,0 @@
/* cc transient.c -o transient -lX11 */
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main(void) {
Display *d;
Window r, f, t = None;
XSizeHints h;
XEvent e;
d = XOpenDisplay(NULL);
if (!d)
exit(1);
r = DefaultRootWindow(d);
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
h.min_width = h.max_width = h.min_height = h.max_height = 400;
h.flags = PMinSize | PMaxSize;
XSetWMNormalHints(d, f, &h);
XStoreName(d, f, "floating");
XMapWindow(d, f);
XSelectInput(d, f, ExposureMask);
while (1) {
XNextEvent(d, &e);
if (t == None) {
sleep(5);
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
XSetTransientForHint(d, t, f);
XStoreName(d, t, "transient");
XMapWindow(d, t);
XSelectInput(d, t, ExposureMask);
}
}
XCloseDisplay(d);
exit(0);
}