Dwm - place different tags on different monitors

I’m pretty sure I have seen this done, but I can’t locate a config.h or patch to add this functionality.

In bspwmrc I can add:

bspc monitor HDMI1 -d 1 2 3 4 5
bspc monitor VGA1 -d 6 7 8 9 10

So that workspaces 1-5 are on one monitor and 6-10 are on the other monitor of a dual monitor setup.

What would be the dwm equivalent to add to the config.h, or the patch to provide the same functionality to dwm?

1 Like

Thx for sharing, might help other members here .

I’ll post my relevant part of my config.def.h (just a reminder this may have some values due to patching you may not show at your end)

static const Rule rules[] = {
	/* xprop(1):
	 *	WM_CLASS(STRING) = instance, class
	 *	WM_NAME(STRING) = title
	 *  WM_WINDOW_ROLE(STRING) = role
	 */
	/* class            role                          instance     title   tags mask  switchtag  iscentered   isfloating   monitor */
	{ "qutebrowser",    NULL,                         NULL,        NULL,   1,	      1,         0,           0,            0 },
	{ "Brave-browser",  NULL,                         NULL,        NULL,   1,	      1,         0,           0,            0 },
	{ "firefox",        NULL,                         NULL,        NULL,   1,	      1,         0,           0,            0 },
	{ "Nightly",        NULL,                         NULL,        NULL,   1,	      1,         0,           0,            0 },
	{ "Google-chrome",  NULL,                         NULL,        NULL,   1,	      1,         0,           0,            0 },
	{ "Vivaldi-stable", NULL,                         NULL,        NULL,   1,	      1,         0,           0,            0 },
	{ "Surf",           NULL,                         NULL,        NULL,   1,	      1,         0,           0,            0 },
	{ "ncmpcpp",   		NULL,  				  		  NULL,   	   NULL,   1 << 3,    1,         0,			  0,		    1 },
	{ "St",	            NULL,                         NULL,        NULL,   1 << 1,    1,         0,           0,            0 },
	{ "Transmission-gtk",NULL,                        NULL,        NULL,   1 << 2,    1,         0,           0,            0 },
	{ "SoulseekQt",		NULL,                         NULL,        NULL,   1 << 2,    1,         0,           0,            0 },
	{ "Thunar",		    NULL,                         NULL,        NULL,   1 << 4,    1,         0,           0,            0 },
	{ "File-roller",    NULL,                         NULL,        NULL,   1 << 4,    1,         1,           1,            0 },
	{ "mpv",          	NULL,                         NULL,        NULL,   1 << 4,    1,         0,           1,            0 },
	{ "Subl3",		    NULL,                         NULL,        NULL,   1 << 6,    1,         0,           0,            0 },
	{ "Code",		    NULL,                         NULL,        NULL,   1 << 6,    1,         0,           0,            0 },
	{ "Steam",          NULL,                         NULL,        NULL,   1 << 7,    1,         0,           0,            0 },
	{ "Slack",          NULL,                         NULL,        NULL,   1 << 7,    1,         0,           0,            0 },
	{ "Easytag",	    NULL,                         NULL,        NULL,   1 << 8,    1,         1,           0,            0 },
	{ "Xfce4-taskmanager",NULL,                       NULL,        NULL,   1 << 9,    1,         1,           0,            0 },
	{ "Nitrogen",		NULL,                         NULL,        NULL,   1 << 9,    1,         1,           1,            1 },
	{ "Xfce4-appearance-settings", NULL, 			  NULL, 	   NULL,   1 << 9,    1,         1,    		  1,            0 },
	{ "Xfce4-mouse-settings", NULL, 			  	  NULL, 	   NULL,   1 << 9,    1,         1,    		  1,            0 },
    { "Lxappearance",   NULL, 			  			  NULL, 	   NULL,   1 << 9,    1,         1,    		  1,            1 },
    { "Blueman-manager", NULL, 			  			  NULL, 	   NULL,   1 << 9,    1,         1,    		  1,            1 },
    { "Gimp", 			NULL, 			  			  NULL, 	   NULL,   1 << 9,    1,         1,    		  1,            0 },
    { "firefox",		"GtkFileChooserDialog",       "Save File", NULL,   0,         0,         1,           1,            0 },

For me, the end column is where I control what is shown on what monitor, a ‘0’ means the main monitor ‘1’ is my second monitor.

A vanilla config.def.h for comparison

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 },
};

Hope this assists.

I do notice that the vanilla config has a ‘-1’, changing it to ‘0’ has had no negative effect. Also, if you run a triple head setup, ‘2’ would indicate a third monitor.

P.S. I’ll move this thread into the Suckless section.

That will open an application on a specific tag - which is handy.

What I am looking to do is have the tags on separate monitors like I do in bspwm -

so this line from the dwm config.h

/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };

needs to change to something like:

/* tagging */
static const char *tags0[] = { "1", "2", "3", "4", "5" };
static const char *tags1[] = { "6", "7", "8", "9" };

so that the tags0 and tags1 functions place tags on separate monitors.

i3 and spectrwm already assign a different workspace to each monitor by default, and i3 can be set up so workspaces can be assigned to different monitors. Same functionality has to be possible for dwm.

I understand now, I already searched this up and I couldn’t quite find a solution. What I posted above was pretty much my bandaid. Though how I use dual monitors now, compared to how I was when using i3 has changed completely so my “bandaid” actually works perfectly.

There must be a patch somewhere that will achieve what you want.

@PackRat check this Reddit post

I had come across this but I never tried it due to the already heavy patched nature of my install. Might be worth trying.

There is also a link to another patch in the comments that may work too.

1 Like

Actually, looks more like the sane way to accomplish the task.
I will mark that as the solution since I know those patches work and one does not need super ninja coding skills to make it happen.

1 Like

It’s actually one of the reasons I went to back to barless. There was just too much effort involved to get the bars working how I wanted them to so I just did away with the bars. A simple alt+b makes them show anyway.

It’s what I have wanted out of dwm since I moved over from i3. It’s nice to finally get it working as intended.

There is the single_tagset patch but it breaks most other patches and it’s not small. dwm really relies on each monitor having it’s own tags for a lot of the code, it really feels like trying to force a different multihead paradigm and it stops being dwm. I’m sure there’s other wm that incorporate this into the design, dk’s static_ws setting comes to mind which is much like i3 but while still using list tiling, both bsp and i3 use trees so it won’t have the same tiling style.

2 Likes

I read somewhere xmonad does what @PackRat wants. Not sure, never looked into it or even used xmonad.

2 Likes

Xmonad does.

dwm and awesome don’t have this functionality as default. I suspect a lua function could be written for awesome.

1 Like