How do I configure multiple monitors to work with dwm's tag rules?
The default dwm behaviour is to open applications, with a rule or not, on the monitor/screen that has focus.
To open Surf on the third tag of the currently focussed monitor, the rule would be:
{ "Surf", NULL, NULL, 1 << 2, True, -1 },
To open VLC on the second tag of the primary monitor, irrespective of where the focus is, the rule would be:
{ "VLC", NULL, NULL, 1 << 1, True, 1 },
If your rules are not conforming to this behaviour, then there is likely something else wrong with the way you have configured dwm. Pasting your entire config.h
might help.
Related videos on Youtube
Michael A
Updated on September 18, 2022Comments
-
Michael A over 1 year
I have a laptop with an external monitor and I want to use the external monitor as the primary one. I'm also running Debian with dwm.
xrandr -q
gives me this:Screen 0: minimum 320 x 200, current 3286 x 1080, maximum 8192 x 8192 LVDS1 connected 1366x768+1920+0 (normal left inverted right x axis y axis) 345mm x 194mm 1366x768 60.0*+ 50.0 VGA1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 509mm x 286mm 1920x1080 60.0*+
(I omitted some of the other resolutions for brevity). My dwm config.h file has several tag rules like this:
static const Rule rules[] = { /* xprop(1): * WM_CLASS(STRING) = instance, class * WM_NAME(STRING) = title */ /* class instance title tags mask isfloating monitor */ { "Chromium", NULL, NULL, 1, False, -1 }, { "xxxterm", NULL, NULL, 1, False, -1 }, { "Surf", NULL, NULL, 1, False, -1 }, { "Iceweasel", NULL, NULL, 1 << 1, False, -1 }, { "Vlc", NULL, NULL, 1 << 3, False, -1 }, };
and I have this xrandr command in my ~/.xinitrc file that configures the monitors properly when I run
startx
:xrandr --output VGA1 --auto --output LVDS1 --auto --right-of VGA1
I want my tag rules to apply whenever I open a program, and for that program to be automatically assigned to whichever monitor has focus. I found a reddit post that said that -1 would do this, but for any program that has a tag rule, they always open on my laptop (LVDS1), not the external monitor (VGA1).
For programs that don't have a tag rule, e.g. st, they will open on whichever monitor/tag has focus. I tried changing the monitor value to 0 or 1, rebuilding dwm and restarting X, and the result is the same.
How do I configure dwm so that programs with tag rules open in their respective tag on whichever monitor has focus?
My full
config.h
:/* appearance */ static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; static const char normbordercolor[] = "#333333"; static const char normbgcolor[] = "#101010"; static const char normfgcolor[] = "#999999"; static const char selbordercolor[] = "#224488"; static const char selbgcolor[] = "#224488"; static const char selfgcolor[] = "#ffffff"; static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ static const unsigned int minwsz = 20; /* Minimal heigt of a client */ static const Bool showbar = True; /* False means no bar */ static const Bool topbar = True; /* False means bottom bar */ static const Bool viewontag = False; /* Switch view on tag switch */ static const Bool extrabar = True; /* False means no extra bar */ /* 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 */ { "Chromium", NULL, NULL, 1, False, -1 }, { "xxxterm", NULL, NULL, 1, False, -1 }, { "Surf", NULL, NULL, 1, False, -1 }, { "Iceweasel", NULL, NULL, 1 << 1, False, -1 }, { "Vlc", NULL, NULL, 1 << 3, False, -1 }, { NULL, NULL, "IPython", 1 << 4, False, -1 }, { "Eclipse", NULL, NULL, 1 << 4, False, -1 }, { "Quodlibet", NULL, NULL, 1 << 5, False, -1 }, { "Icedove", NULL, NULL, 1 << 6, False, -1 }, { "libreoffice", NULL, NULL, 1 << 7, False, -1 }, { "Gnumeric", NULL, NULL, 1 << 7, False, -1 }, { "Abiword", NULL, NULL, 1 << 7, False, -1 }, { "Keepassx", NULL, NULL, 1 << 8, False, -1 }, }; /* layout(s) */ static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ static const float smfact = 0.00; /* factor of tiled clients [0.00..0.95] */ static const int nmaster = 1; /* number of clients in master area */ static const Bool resizehints = False; /* True means respect size hints in tiled resizals */ #include "patchlibs/bstack.c" #include "patchlibs/bstackhoriz.c" #include "patchlibs/fibonacci.c" #include "patchlibs/gaplessgrid.c" #include "patchlibs/tcl.c" static const Layout layouts[] = { /* symbol arrange function */ { "T", tile }, /* first entry is default */ { "F", NULL }, /* no layout function means floating behavior */ { "B", bstack }, { "G", gaplessgrid }, { "M", monocle }, { "H", bstackhoriz }, { "C", tcl }, { "S", spiral }, { "D", dwindle }, }; /* key definitions */ #define MODKEY Mod1Mask #define WINKEY 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 } } /* commands */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; static const char *termcmd[] = { "st", NULL }; static const char *chromiumcmd[] = {"chromium-incognito", NULL}; static const char *icedovecmd[] = {"icedove", NULL}; static const char *xxxtermcmd[] = {"xxxterm", NULL}; static const char *musiccmd[] = {"quodlibet", NULL}; static const char *ipythoncmd[] = {"ipython3qt", NULL}; static const char *iceweaselcmd[] = {"iceweasel", NULL}; static const char *texteditcmd[] = {"scite", NULL}; static const char *lockcmd[] = {"lock", NULL}; static const char *videocmd[] = {"vlc", NULL}; static const char *screenshotcmd[] = {"screenshot", NULL}; #include "patchlibs/movestack.c" static Key keys[] = { /* modifier key function argument */ { WINKEY, XK_t, spawn, {.v = termcmd } }, { WINKEY, XK_c, spawn, {.v = chromiumcmd } }, { WINKEY, XK_d, spawn, {.v = icedovecmd } }, { WINKEY, XK_x, spawn, {.v = xxxtermcmd } }, { WINKEY, XK_i, spawn, {.v = iceweaselcmd } }, { WINKEY, XK_m, spawn, {.v = musiccmd } }, { WINKEY, XK_e, spawn, {.v = texteditcmd } }, { WINKEY, XK_p, spawn, {.v = ipythoncmd } }, { WINKEY, XK_l, spawn, {.v = lockcmd } }, { WINKEY, XK_v, spawn, {.v = videocmd } }, { WINKEY, XK_s, spawn, {.v = screenshotcmd } }, { MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY, XK_b, togglebar, {0} }, { MODKEY, XK_b, toggleextrabar, {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_u, setsmfact, {.f = -0.05} }, { MODKEY, XK_m, setsmfact, {.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} }, { ControlMask|ShiftMask, XK_t, setlayout, {.v = &layouts[0]} }, { ControlMask|ShiftMask, XK_f, setlayout, {.v = &layouts[1]} }, { ControlMask|ShiftMask, XK_b, setlayout, {.v = &layouts[2]} }, { ControlMask|ShiftMask, XK_g, setlayout, {.v = &layouts[3]} }, { ControlMask|ShiftMask, XK_m, setlayout, {.v = &layouts[4]} }, { ControlMask|ShiftMask, XK_h, setlayout, {.v = &layouts[5]} }, { ControlMask|ShiftMask, XK_c, setlayout, {.v = &layouts[6]} }, { ControlMask|ShiftMask, XK_s, setlayout, {.v = &layouts[7]} }, { ControlMask|ShiftMask, XK_d, setlayout, {.v = &layouts[8]} }, { ControlMask, XK_space, setlayout, {0} }, { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, { MODKEY, XK_comma, focusmon, {.i = -1 } }, { MODKEY, XK_period, focusmon, {.i = +1 } }, { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, { MODKEY|ShiftMask, XK_k, movestack, {.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 ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static Button buttons[] = { /* click event mask button function argument */ { ClkLtSymbol, 0, Button1, setlayout, {0} }, { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[3]} }, { 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} }, };
-
Admin about 10 yearsI don't see anything obvious, but that is a lot of patches you have applied: you could remove them and test and then add them back one by one to see if one of them is breaking the default beahviour.
-
-
Michael A about 10 yearsUpdated the question with my full config.h file. Thanks!