I am trying to teach dwm to open appropriate application in each tag (www, files, music...). In dwm.c there is a function called view
that is responsible for tag switching.
void
view(const Arg *arg)
{
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
return;
/* toggle sel tagset */
selmon->seltags ^= 1;
if (arg->ui & TAGMASK)
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
// user specific edit
prepareTag(arg->ui);
focus(NULL);
arrange(selmon);
}
I have added a line where prepareTag
is called. This function has simple logic and do nothing else than a few verifications (is application already open?; what tag is it?) and the application spawn itself.
void
spawn(const Arg *arg)
{
if (arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
perror(" failed");
exit(EXIT_SUCCESS);
}
}
It works but the code goes asynchronously. The tag is changed and I see my wallpaper, than after ~20-50ms the application is started. It causes notable flicker. The problem is I have never worked with C and do not know the reason why the code work asynchronously. I have tried system
function instead of built-in spawn
but dwm do not catch applications open this way. I could probably use key binder and some BASHing but the way is quite dirty. Not to mention, I would like to have an ability to use mouse buttons to change tag.
In case someone need code base.
git clone https://git.suckless.org/dwm
If you read the manual for
fork()
, you will realize the it creates a copy of the running process.After the fork both the processes are independent of each other and may get scheduled in any order. This is the asynchronous behaviour you are seeing.
To get a synchronous behavior your parent process needs to wait till the forked process has completed (exits). This has be achieved using the
wait()
system call.You can modify your
spawn
function as -