Move command spawning to separate module
This commit is contained in:
parent
b5ab26c8b6
commit
2849c3ae37
5 changed files with 144 additions and 22 deletions
4
Makefile
4
Makefile
|
@ -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}
|
||||
|
|
12
config.def.h
12
config.def.h
|
@ -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
23
dwm.c
|
@ -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
121
spawn.c
Normal 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
6
spawn.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _SPAWN_H
|
||||
#define _SPAWN_H
|
||||
|
||||
void spawn_command(const char *name, void (*callback)(), int monitor);
|
||||
|
||||
#endif // _SPAWN_H
|
Loading…
Reference in a new issue