Move command spawning to separate module

This commit is contained in:
Alex Kotov 2021-11-15 01:12:55 +05:00
parent b5ab26c8b6
commit 2849c3ae37
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
5 changed files with 144 additions and 22 deletions

View file

@ -3,7 +3,7 @@
include config.mk
SRC = atoms.c drw.c dwm.c settings.c tags.c util.c
SRC = atoms.c drw.c dwm.c settings.c spawn.c tags.c util.c
OBJ = ${SRC:.c=.o}
all: options polytreewm
@ -17,7 +17,7 @@ options:
%.o: %.c
${CC} -c $< -o $@ ${CFLAGS}
${OBJ}: atoms.h drw.h config.def.h config.mk settings.h tags.h util.h
${OBJ}: atoms.h drw.h config.def.h config.mk settings.h spawn.h tags.h util.h
polytreewm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}

View file

@ -51,18 +51,12 @@ static const Layout layouts[] = {
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
/* 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_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "st", NULL };
static const char *firefoxcmd[] = { "firefox", NULL };
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_n, nametag, {0} },
{ MODKEY, XK_slash, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY|ShiftMask, XK_f, spawn, {.v = firefoxcmd } },
{ MODKEY, XK_slash, spawn, {.v = "menu" } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = "term" } },
{ MODKEY|ShiftMask, XK_f, spawn, {.v = "firefox" } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },

23
dwm.c
View file

@ -28,7 +28,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
@ -44,6 +43,7 @@
#include "atoms.h"
#include "drw.h"
#include "settings.h"
#include "spawn.h"
#include "tags.h"
#include "util.h"
@ -235,6 +235,7 @@ static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
static void spawn(const Arg *arg);
static void spawn_callback();
static Monitor *systraytomon(Monitor *m);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
@ -2074,16 +2075,16 @@ sigchld(int unused)
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, "polytreewm: execvp %s", ((char **)arg->v)[0]);
perror(" failed");
exit(EXIT_SUCCESS);
const char *const command_name = arg->v;
spawn_command(command_name, spawn_callback, selmon->num);
}
void
spawn_callback()
{
if (dpy) {
close(ConnectionNumber(dpy));
}
}

121
spawn.c Normal file
View file

@ -0,0 +1,121 @@
#include "spawn.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_ARGS_COUNT 20
#define ARGS_SIZE (MAX_ARGS_COUNT + 1)
#define MON_ARG_SIZE 2
struct Command {
const char *name;
size_t monitor_arg_index;
const char *args[ARGS_SIZE];
};
static struct Command commands[] = {
{
.name = "menu",
.monitor_arg_index = 2,
.args = {
"dmenu_run",
// monitor
"-m",
"0",
// font
"-fn",
"monospace:size=10",
// color: gray 1
"-nb",
"#222222",
// color: gray 3
"-nf",
"#bbbbbb",
// color: cyan
"-sb",
"#005577",
// color: gray 4
"-sf",
"#eeeeee",
NULL,
},
},
{
.name = "term",
.monitor_arg_index = -1,
.args = { "st", NULL },
},
{
.name = "firefox",
.monitor_arg_index = -1,
.args = { "firefox", NULL },
},
};
void spawn_command(
const char *const name,
void (*const callback)(),
const int monitor
) {
if (name == NULL || monitor < 0 || monitor > 9) return;
for (
size_t command_index = 0;
command_index < sizeof(commands) / sizeof(struct Command);
++command_index
) {
const struct Command *const command = &commands[command_index];
if (strcmp(name, command->name) != 0) continue;
// We discard const modifier
// because we will only change newly allocated version.
char **args = (char**)command->args;
if (command->monitor_arg_index != -1) {
args = malloc(sizeof(char*) * ARGS_SIZE);
if (args == NULL) break;
for (size_t arg_index = 0;; ++arg_index) {
// We discard const modifier
// because we will only change newly allocated version.
args[arg_index] = (char*)command->args[arg_index];
if (args[arg_index] == NULL) break;
}
args[command->monitor_arg_index] =
malloc(sizeof(char) * MON_ARG_SIZE);
if (args[command->monitor_arg_index] == NULL) {
free(args);
break;
}
args[command->monitor_arg_index][0] = '0' + monitor;
args[command->monitor_arg_index][1] = '\0';
}
if (fork() == 0) {
// TODO: DRY (see the same code below)
if (command->monitor_arg_index != -1) {
free(args[command->monitor_arg_index]);
free(args);
}
callback();
setsid();
execvp(args[0], args);
fprintf(stderr, "polytreewm: execvp %s", args[0]);
perror(" failed");
exit(EXIT_SUCCESS);
}
if (command->monitor_arg_index != -1) {
free(args[command->monitor_arg_index]);
free(args);
}
break;
}
}

6
spawn.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef _SPAWN_H
#define _SPAWN_H
void spawn_command(const char *name, void (*callback)(), int monitor);
#endif // _SPAWN_H