mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
Convert menu-exec-wm from an abritrary exec menu, into a config-based menu from
which one may configure (wm <name> <path_and_args>) (and choose) specific window managers to replace the running one. 'wm cwm cwm' is included by default. No objections and seems sensible to sthen.
This commit is contained in:
parent
43db5b55ea
commit
6e7dbf5bb7
12
calmwm.h
12
calmwm.h
@ -255,11 +255,8 @@ struct cmd_ctx {
|
|||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
};
|
};
|
||||||
TAILQ_HEAD(cmd_q, cmd_ctx);
|
TAILQ_HEAD(cmd_q, cmd_ctx);
|
||||||
|
TAILQ_HEAD(wm_q, cmd_ctx);
|
||||||
|
|
||||||
enum menu_exec {
|
|
||||||
CWM_MENU_EXEC_EXEC,
|
|
||||||
CWM_MENU_EXEC_WM
|
|
||||||
};
|
|
||||||
#define CWM_MENU_DUMMY 0x0001
|
#define CWM_MENU_DUMMY 0x0001
|
||||||
#define CWM_MENU_FILE 0x0002
|
#define CWM_MENU_FILE 0x0002
|
||||||
#define CWM_MENU_LIST 0x0004
|
#define CWM_MENU_LIST 0x0004
|
||||||
@ -284,6 +281,7 @@ struct conf {
|
|||||||
struct autogroup_q autogroupq;
|
struct autogroup_q autogroupq;
|
||||||
struct ignore_q ignoreq;
|
struct ignore_q ignoreq;
|
||||||
struct cmd_q cmdq;
|
struct cmd_q cmdq;
|
||||||
|
struct wm_q wmq;
|
||||||
int ngroups;
|
int ngroups;
|
||||||
int stickygroups;
|
int stickygroups;
|
||||||
int nameqlen;
|
int nameqlen;
|
||||||
@ -457,10 +455,13 @@ void search_match_cmd(struct menu_q *, struct menu_q *,
|
|||||||
char *);
|
char *);
|
||||||
void search_match_group(struct menu_q *, struct menu_q *,
|
void search_match_group(struct menu_q *, struct menu_q *,
|
||||||
char *);
|
char *);
|
||||||
|
void search_match_wm(struct menu_q *, struct menu_q *,
|
||||||
|
char *);
|
||||||
void search_print_client(struct menu *, int);
|
void search_print_client(struct menu *, int);
|
||||||
void search_print_cmd(struct menu *, int);
|
void search_print_cmd(struct menu *, int);
|
||||||
void search_print_group(struct menu *, int);
|
void search_print_group(struct menu *, int);
|
||||||
void search_print_text(struct menu *, int);
|
void search_print_text(struct menu *, int);
|
||||||
|
void search_print_wm(struct menu *, int);
|
||||||
|
|
||||||
struct region_ctx *region_find(struct screen_ctx *, int, int);
|
struct region_ctx *region_find(struct screen_ctx *, int, int);
|
||||||
struct geom screen_apply_gap(struct screen_ctx *, struct geom);
|
struct geom screen_apply_gap(struct screen_ctx *, struct geom);
|
||||||
@ -500,6 +501,7 @@ void kbfunc_group_alltoggle(void *, struct cargs *);
|
|||||||
void kbfunc_menu_client(void *, struct cargs *);
|
void kbfunc_menu_client(void *, struct cargs *);
|
||||||
void kbfunc_menu_cmd(void *, struct cargs *);
|
void kbfunc_menu_cmd(void *, struct cargs *);
|
||||||
void kbfunc_menu_group(void *, struct cargs *);
|
void kbfunc_menu_group(void *, struct cargs *);
|
||||||
|
void kbfunc_menu_wm(void *, struct cargs *);
|
||||||
void kbfunc_menu_exec(void *, struct cargs *);
|
void kbfunc_menu_exec(void *, struct cargs *);
|
||||||
void kbfunc_menu_ssh(void *, struct cargs *);
|
void kbfunc_menu_ssh(void *, struct cargs *);
|
||||||
void kbfunc_client_menu_label(void *, struct cargs *);
|
void kbfunc_client_menu_label(void *, struct cargs *);
|
||||||
@ -529,6 +531,8 @@ void conf_clear(struct conf *);
|
|||||||
void conf_client(struct client_ctx *);
|
void conf_client(struct client_ctx *);
|
||||||
int conf_cmd_add(struct conf *, const char *,
|
int conf_cmd_add(struct conf *, const char *,
|
||||||
const char *);
|
const char *);
|
||||||
|
int conf_wm_add(struct conf *, const char *,
|
||||||
|
const char *);
|
||||||
void conf_cursor(struct conf *);
|
void conf_cursor(struct conf *);
|
||||||
void conf_grab_kbd(Window);
|
void conf_grab_kbd(Window);
|
||||||
void conf_grab_mouse(Window);
|
void conf_grab_mouse(Window);
|
||||||
|
33
conf.c
33
conf.c
@ -193,10 +193,8 @@ static const struct {
|
|||||||
CWM_MENU_WINDOW_ALL },
|
CWM_MENU_WINDOW_ALL },
|
||||||
{ "menu-window-hidden", kbfunc_menu_client, CWM_CONTEXT_SC,
|
{ "menu-window-hidden", kbfunc_menu_client, CWM_CONTEXT_SC,
|
||||||
CWM_MENU_WINDOW_HIDDEN },
|
CWM_MENU_WINDOW_HIDDEN },
|
||||||
{ "menu-exec", kbfunc_menu_exec, CWM_CONTEXT_SC,
|
{ "menu-exec", kbfunc_menu_exec, CWM_CONTEXT_SC, 0 },
|
||||||
CWM_MENU_EXEC_EXEC },
|
{ "menu-exec-wm", kbfunc_menu_wm, CWM_CONTEXT_SC, 0 },
|
||||||
{ "menu-exec-wm", kbfunc_menu_exec, CWM_CONTEXT_SC,
|
|
||||||
CWM_MENU_EXEC_WM },
|
|
||||||
|
|
||||||
{ "terminal", kbfunc_exec_term, CWM_CONTEXT_SC, 0 },
|
{ "terminal", kbfunc_exec_term, CWM_CONTEXT_SC, 0 },
|
||||||
{ "lock", kbfunc_exec_lock, CWM_CONTEXT_SC, 0 },
|
{ "lock", kbfunc_exec_lock, CWM_CONTEXT_SC, 0 },
|
||||||
@ -298,6 +296,7 @@ conf_init(struct conf *c)
|
|||||||
|
|
||||||
TAILQ_INIT(&c->ignoreq);
|
TAILQ_INIT(&c->ignoreq);
|
||||||
TAILQ_INIT(&c->cmdq);
|
TAILQ_INIT(&c->cmdq);
|
||||||
|
TAILQ_INIT(&c->wmq);
|
||||||
TAILQ_INIT(&c->keybindq);
|
TAILQ_INIT(&c->keybindq);
|
||||||
TAILQ_INIT(&c->autogroupq);
|
TAILQ_INIT(&c->autogroupq);
|
||||||
TAILQ_INIT(&c->mousebindq);
|
TAILQ_INIT(&c->mousebindq);
|
||||||
@ -314,6 +313,8 @@ conf_init(struct conf *c)
|
|||||||
conf_cmd_add(c, "lock", "xlock");
|
conf_cmd_add(c, "lock", "xlock");
|
||||||
conf_cmd_add(c, "term", "xterm");
|
conf_cmd_add(c, "term", "xterm");
|
||||||
|
|
||||||
|
conf_wm_add(c, "cwm", "cwm");
|
||||||
|
|
||||||
(void)snprintf(c->known_hosts, sizeof(c->known_hosts), "%s/%s",
|
(void)snprintf(c->known_hosts, sizeof(c->known_hosts), "%s/%s",
|
||||||
c->homedir, ".ssh/known_hosts");
|
c->homedir, ".ssh/known_hosts");
|
||||||
|
|
||||||
@ -327,7 +328,7 @@ conf_clear(struct conf *c)
|
|||||||
struct autogroup *ag;
|
struct autogroup *ag;
|
||||||
struct bind_ctx *kb, *mb;
|
struct bind_ctx *kb, *mb;
|
||||||
struct winname *wn;
|
struct winname *wn;
|
||||||
struct cmd_ctx *cmd;
|
struct cmd_ctx *cmd, *wm;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) {
|
while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) {
|
||||||
@ -335,6 +336,11 @@ conf_clear(struct conf *c)
|
|||||||
free(cmd->name);
|
free(cmd->name);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
|
while ((wm = TAILQ_FIRST(&c->wmq)) != NULL) {
|
||||||
|
TAILQ_REMOVE(&c->wmq, wm, entry);
|
||||||
|
free(wm->name);
|
||||||
|
free(wm);
|
||||||
|
}
|
||||||
while ((kb = TAILQ_FIRST(&c->keybindq)) != NULL) {
|
while ((kb = TAILQ_FIRST(&c->keybindq)) != NULL) {
|
||||||
TAILQ_REMOVE(&c->keybindq, kb, entry);
|
TAILQ_REMOVE(&c->keybindq, kb, entry);
|
||||||
free(kb);
|
free(kb);
|
||||||
@ -393,6 +399,23 @@ conf_cmd_remove(struct conf *c, const char *name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
conf_wm_add(struct conf *c, const char *name, const char *path)
|
||||||
|
{
|
||||||
|
struct cmd_ctx *wm;
|
||||||
|
|
||||||
|
wm = xmalloc(sizeof(*wm));
|
||||||
|
wm->name = xstrdup(name);
|
||||||
|
if (strlcpy(wm->path, path, sizeof(wm->path)) >= sizeof(wm->path)) {
|
||||||
|
free(wm->name);
|
||||||
|
free(wm);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&c->wmq, wm, entry);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
conf_autogroup(struct conf *c, int num, const char *name, const char *class)
|
conf_autogroup(struct conf *c, int num, const char *name, const char *class)
|
||||||
{
|
{
|
||||||
|
2
cwm.1
2
cwm.1
@ -143,7 +143,7 @@ will be executed via the configured terminal emulator.
|
|||||||
.It Ic CM-w
|
.It Ic CM-w
|
||||||
Spawn
|
Spawn
|
||||||
.Dq exec WindowManager
|
.Dq exec WindowManager
|
||||||
dialog, allowing a switch to another window manager.
|
menu, allowing a switch to another window manager.
|
||||||
.It Ic CMS-r
|
.It Ic CMS-r
|
||||||
Restart.
|
Restart.
|
||||||
.It Ic CMS-q
|
.It Ic CMS-q
|
||||||
|
6
cwmrc.5
6
cwmrc.5
@ -245,6 +245,12 @@ A special
|
|||||||
keyword
|
keyword
|
||||||
.Dq all
|
.Dq all
|
||||||
can be used to unbind all buttons.
|
can be used to unbind all buttons.
|
||||||
|
.It Ic wm Ar name path
|
||||||
|
Every
|
||||||
|
.Ar name
|
||||||
|
entry is shown in the wm menu.
|
||||||
|
When selected, the window manager is replaced by
|
||||||
|
.Ar path .
|
||||||
.El
|
.El
|
||||||
.Sh BIND FUNCTION LIST
|
.Sh BIND FUNCTION LIST
|
||||||
.Bl -tag -width 23n -compact
|
.Bl -tag -width 23n -compact
|
||||||
|
58
kbfunc.c
58
kbfunc.c
@ -545,6 +545,33 @@ kbfunc_menu_group(void *ctx, struct cargs *cargs)
|
|||||||
menuq_clear(&menuq);
|
menuq_clear(&menuq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kbfunc_menu_wm(void *ctx, struct cargs *cargs)
|
||||||
|
{
|
||||||
|
struct screen_ctx *sc = ctx;
|
||||||
|
struct cmd_ctx *wm;
|
||||||
|
struct menu *mi;
|
||||||
|
struct menu_q menuq;
|
||||||
|
int mflags = 0;
|
||||||
|
|
||||||
|
if (cargs->xev == CWM_XEV_BTN)
|
||||||
|
mflags |= CWM_MENU_LIST;
|
||||||
|
|
||||||
|
TAILQ_INIT(&menuq);
|
||||||
|
TAILQ_FOREACH(wm, &Conf.wmq, entry)
|
||||||
|
menuq_add(&menuq, wm, NULL);
|
||||||
|
|
||||||
|
if ((mi = menu_filter(sc, &menuq, "wm", NULL, mflags,
|
||||||
|
search_match_wm, search_print_wm)) != NULL) {
|
||||||
|
wm = (struct cmd_ctx *)mi->ctx;
|
||||||
|
free(Conf.wm_argv);
|
||||||
|
Conf.wm_argv = xstrdup(wm->path);
|
||||||
|
cwm_status = CWM_EXEC_WM;
|
||||||
|
}
|
||||||
|
|
||||||
|
menuq_clear(&menuq);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
kbfunc_menu_exec(void *ctx, struct cargs *cargs)
|
kbfunc_menu_exec(void *ctx, struct cargs *cargs)
|
||||||
{
|
{
|
||||||
@ -553,26 +580,13 @@ kbfunc_menu_exec(void *ctx, struct cargs *cargs)
|
|||||||
char **ap, *paths[NPATHS], *path, *pathcpy;
|
char **ap, *paths[NPATHS], *path, *pathcpy;
|
||||||
char tpath[PATH_MAX];
|
char tpath[PATH_MAX];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
const char *label;
|
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
struct menu *mi;
|
struct menu *mi;
|
||||||
struct menu_q menuq;
|
struct menu_q menuq;
|
||||||
int l, i, cmd = cargs->flag;
|
int l, i;
|
||||||
int mflags = (CWM_MENU_DUMMY | CWM_MENU_FILE);
|
int mflags = (CWM_MENU_DUMMY | CWM_MENU_FILE);
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case CWM_MENU_EXEC_EXEC:
|
|
||||||
label = "exec";
|
|
||||||
break;
|
|
||||||
case CWM_MENU_EXEC_WM:
|
|
||||||
label = "wm";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errx(1, "%s: invalid cmd %d", __func__, cmd);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
TAILQ_INIT(&menuq);
|
TAILQ_INIT(&menuq);
|
||||||
|
|
||||||
if ((path = getenv("PATH")) == NULL)
|
if ((path = getenv("PATH")) == NULL)
|
||||||
@ -611,23 +625,11 @@ kbfunc_menu_exec(void *ctx, struct cargs *cargs)
|
|||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
if ((mi = menu_filter(sc, &menuq, label, NULL, mflags,
|
if ((mi = menu_filter(sc, &menuq, "exec", NULL, mflags,
|
||||||
search_match_exec, search_print_text)) != NULL) {
|
search_match_exec, search_print_text)) != NULL) {
|
||||||
if (mi->text[0] == '\0')
|
if (mi->text[0] == '\0')
|
||||||
goto out;
|
goto out;
|
||||||
switch (cmd) {
|
u_spawn(mi->text);
|
||||||
case CWM_MENU_EXEC_EXEC:
|
|
||||||
u_spawn(mi->text);
|
|
||||||
break;
|
|
||||||
case CWM_MENU_EXEC_WM:
|
|
||||||
cwm_status = CWM_EXEC_WM;
|
|
||||||
free(Conf.wm_argv);
|
|
||||||
Conf.wm_argv = xstrdup(mi->text);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errx(1, "%s: egad, cmd changed value!", __func__);
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (mi != NULL && mi->dummy)
|
if (mi != NULL && mi->dummy)
|
||||||
|
13
parse.y
13
parse.y
@ -70,7 +70,7 @@ typedef struct {
|
|||||||
|
|
||||||
%token BINDKEY UNBINDKEY BINDMOUSE UNBINDMOUSE
|
%token BINDKEY UNBINDKEY BINDMOUSE UNBINDMOUSE
|
||||||
%token FONTNAME STICKY GAP
|
%token FONTNAME STICKY GAP
|
||||||
%token AUTOGROUP COMMAND IGNORE
|
%token AUTOGROUP COMMAND IGNORE WM
|
||||||
%token YES NO BORDERWIDTH MOVEAMOUNT
|
%token YES NO BORDERWIDTH MOVEAMOUNT
|
||||||
%token COLOR SNAPDIST
|
%token COLOR SNAPDIST
|
||||||
%token ACTIVEBORDER INACTIVEBORDER URGENCYBORDER
|
%token ACTIVEBORDER INACTIVEBORDER URGENCYBORDER
|
||||||
@ -146,6 +146,16 @@ main : FONTNAME STRING {
|
|||||||
free($2);
|
free($2);
|
||||||
free($3);
|
free($3);
|
||||||
}
|
}
|
||||||
|
| WM STRING string {
|
||||||
|
if (!conf_wm_add(conf, $2, $3)) {
|
||||||
|
yyerror("wm name/path too long");
|
||||||
|
free($2);
|
||||||
|
free($3);
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
free($2);
|
||||||
|
free($3);
|
||||||
|
}
|
||||||
| AUTOGROUP NUMBER STRING {
|
| AUTOGROUP NUMBER STRING {
|
||||||
if ($2 < 0 || $2 > 9) {
|
if ($2 < 0 || $2 > 9) {
|
||||||
yyerror("invalid autogroup");
|
yyerror("invalid autogroup");
|
||||||
@ -317,6 +327,7 @@ lookup(char *s)
|
|||||||
{ "unbind-mouse", UNBINDMOUSE},
|
{ "unbind-mouse", UNBINDMOUSE},
|
||||||
{ "ungroupborder", UNGROUPBORDER},
|
{ "ungroupborder", UNGROUPBORDER},
|
||||||
{ "urgencyborder", URGENCYBORDER},
|
{ "urgencyborder", URGENCYBORDER},
|
||||||
|
{ "wm", WM},
|
||||||
{ "yes", YES}
|
{ "yes", YES}
|
||||||
};
|
};
|
||||||
const struct keywords *p;
|
const struct keywords *p;
|
||||||
|
24
search.c
24
search.c
@ -227,6 +227,21 @@ search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
search_match_wm(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||||
|
{
|
||||||
|
struct menu *mi;
|
||||||
|
struct cmd_ctx *wm;
|
||||||
|
|
||||||
|
TAILQ_INIT(resultq);
|
||||||
|
TAILQ_FOREACH(mi, menuq, entry) {
|
||||||
|
wm = (struct cmd_ctx *)mi->ctx;
|
||||||
|
if ((match_substr(search, wm->name, 0)) ||
|
||||||
|
(match_substr(search, wm->path, 0)))
|
||||||
|
TAILQ_INSERT_TAIL(resultq, mi, resultentry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
search_print_client(struct menu *mi, int listing)
|
search_print_client(struct menu *mi, int listing)
|
||||||
{
|
{
|
||||||
@ -266,3 +281,12 @@ search_print_text(struct menu *mi, int listing)
|
|||||||
{
|
{
|
||||||
(void)snprintf(mi->print, sizeof(mi->print), "%s", mi->text);
|
(void)snprintf(mi->print, sizeof(mi->print), "%s", mi->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
search_print_wm(struct menu *mi, int listing)
|
||||||
|
{
|
||||||
|
struct cmd_ctx *wm = (struct cmd_ctx *)mi->ctx;
|
||||||
|
|
||||||
|
(void)snprintf(mi->print, sizeof(mi->print), "%s [%s]",
|
||||||
|
wm->name, wm->path);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user