Open apps on dedicated tags

Hello dwm guru-types…

I have an issue I remain unable to resolve. It’s not on the order of “whirled peas” or anything. But, does any one here have a method for setting select applications to ‘always’ open in focus on its pre-selected workspace?

I promise to try and break any offered solution, as I do with all of those offered so generously here. :wink:

EDIT: FWIW I found this eye-candy dwm site:
https://githubmemory.com/repo/abbsi/suckless

Firstly, I’ll open this in it’s own thread.

Secondly, take a look at the snippet from my config.def.h:


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,            1 },
	{ "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 },
};

The tags mask column is where you define the selected tag (or workspace, let’s use tag as thats the common name for it in Suckless).

Using my snippet a ‘1’ determines that Firefox will open on the first tag. ‘1 << 4’ determines Thunar to open on the 5th tag '1 << 8 ’ determines that Easytag will open on tag number 9 and so on.

To find the “class” of your desired app use xprop.

Does that make sense? Or is it as clear as mud? Explaining things isn’t my forte.

Check out the switchtotag and viewontag patches.

@manyroads - is that what you’re going for?

@Dobbie03 - your snippet is missing the column headers on my end.

Updated! Hopefully that’s a bit better.

1 Like

Gentlemen (@Dobbie03 and @Packrat, I use that term cautiously) That’s exactly what I was looking for. I have implemented two dwm patches. Everything works like greased lightning.

  1. focusonnetactive
  2. switchtotag

Here’s my config.h:

/* See LICENSE file for copyright and license details. */

/* appearance */
static const unsigned int borderpx  = 3;        /* border pixel of windows */
static const unsigned int snap      = 34;       /* snap pixel */
static const unsigned int systraypinning = 0;   /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
static const unsigned int systrayspacing = 2;   /* systray spacing */
static const int systraypinningfailfirst = 0;   /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
static const int showsystray        = 1;     	/* 0 means no systray */
static const int showbar            = 1;        /* 0 means no bar */
static const int topbar             = 1;        /* 0 means bottom bar */
/*static const char *fonts[]        = { "DejaVu Sans Mono:pixelsize=17:antialias=true:autohint=true" };*/
static const char *fonts[]          = { "Hack:pixelsize=17:antialias=true:autohint=true" };
/*static const char *fonts [] 		= { "Mono:pixelsize=17:antialias=true:autohint=true" };*/
static const char dmenufont[]       = "Hack:pixelsize=17";
static const char col_gray1[]       = "#222222";
static const char col_gray2[]       = "#444444";
static const char col_gray3[]       = "#bbbbbb";
static const char col_gray4[]       = "#303643";
static const char col_blue[]        = "#8FBCBB";/* 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_blue,  col_blue  },
};

/* tagging */
static const char *tags[] = {"","","","","","","","","" };
static const Rule rules[] = {
	/* xprop(1):
	 *	WM_CLASS(STRING) = instance, class
	 *	WM_NAME(STRING) = title
	 */
	/* class      				instance    title       tags mask  switchtotag   isfloating   monitor */

	{ "Pamac-manager", 			NULL,       NULL,       1,            1,			1,           -1 },
	{ "Yad",	     			NULL,     	NULL,       0,            0,			1,           -1 },
	{ "St",     				NULL,     	NULL,       0,            0,			1,           -1 },
	{ "Termite",     			NULL,     	NULL,       0,            0,			1,           -1 },
	{ "Filezilla", 				NULL,       NULL,       1,            1,			1,           -1 },
	{ "luckybackup", 			NULL,       NULL,       1,            1,			1,           -1 },
	{ "Grsync", 				NULL,       NULL,       1,            1,			1,           -1 },
	{ "Mintstick.py",	 		NULL,       NULL,       1,            1,			1,           -1 },
	{ "firefox",  				NULL,       NULL,       2,       	  1,			0,           -1 },
	{ "Vivaldi-stable",			NULL,       NULL,       2,       	  1,			0,           -1 },
	{ "Chromium",  				NULL,       NULL,       2,       	  1,			0,           -1 },
	{ "Thunar",     			NULL,       NULL,   	1 << 2,       1,			0,           -1 },
	{ "Nemo",   				NULL,       NULL,   	1 << 2,       1,			0,           -1 },	
	{ "calibre",     			NULL,    	NULL,       1 << 3,       1,			0,           -1 },
	{ "Xed",	     			NULL,    	NULL,       1 << 3,       0,			1,           -1 },
	{ "Leafpad",     			NULL,    	NULL,       1 << 3,       1,           	1,			 -1 },
	{ "VirtualBox Manager", 	NULL,   	NULL,       1 << 4,       0,			0,           -1 },
	{ "Gimp",     				NULL,       NULL,   	1 << 4,       1,			0,           -1 },
	{ "Skype",     				NULL,       NULL,   	1 << 5,       1,			1,           -1 },
	{ "zoom",     				NULL,       NULL,   	1 << 5,       1,			1,			 -1 },
	{ "Pavucontrol",    		NULL,       NULL,   	1 << 6,		  1,			1,           -1 },
	{ "Deadbeef",     			NULL,       NULL,   	1 << 6,       1,			1,           -1 },
	{ "Geany",     				NULL,       NULL,   	1 << 7,       1,			0,           -1 },
	{ "Thunderbird",    		NULL,       NULL,   	1 << 8,       1,			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 Layout layouts[] = {
	/* symbol     arrange function */
	{ "[]",     	NULL },    /* no layout function means floating behavior */
	{ "[] ",      	tile },    /* first entry is default */
	{ "[]",      	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 } }

/* 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_blue, "-sf", col_gray4, NULL };
static const char *termcmd[]  = { "st", NULL };

static Key keys[] = {
/*    modifier                      key        function        argument          */
	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
	{ MODKEY,			            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|ShiftMask,             XK_Return, zoom,           {0} },
	{ MODKEY,                       XK_Tab,    view,           {0} },
	{ MODKEY|ShiftMask,			    XK_q,      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, 			            XK_q,      	quit,         {0} },
};

/* button definitions */
/* click can be ClkTagBar, 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[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} },
};
1 Like

I would when it concerns me, I am no gentleman. @PackRat on the other hand is a true Linux Gentleman.

Glad you are sorted out.

1 Like