Hi cwm users, I am not sure how many cwm users actually use the 'wm' (exec window manager) menu, but I'd like to somewhat change it.
Right now it works just like the 'exec' menu where it populates any executable in the path, then replaces the existing window manager with that. For cwm development (or any wm development this feature is for), this is essentially useless because one does't actually install the various test binaries into the path (even if one did, the menu doesn't display the path of each, just the first match, etc, etc). One has to always hand type the full path of whatever replacement window manager into the 'wm' menu - it's painful and slow. I don't know many other people actively working on cwm so I'm not sure of the opinions and impact here. What I'd prefer is somewhat what other window managers have - a list, via config, for a selection of available window managers. A default list as just 'wm cwm cwm' (wm <name> <path_and_args>). Most folks might have just used this 'wm' feature to restart cwm as opposed to the 'restart' command from the old days (which is why this menu originated long time ago I believe) - leaving support for that and not changing the function name is fine. I doubt people are installing window managers and switching back and forth in such a manner that annotating them via config is a burden. Below is a rough draft of the above - it needs manpage changes, clean-up of the old way, etc, but it's the minimal diff for the general idea. Bonus side-effect: This also limits the shell-like goop to just the 'exec' menu. Thanks, Okan Index: calmwm.h =================================================================== RCS file: /home/open/cvs/xenocara/app/cwm/calmwm.h,v retrieving revision 1.347 diff -u -p -r1.347 calmwm.h --- calmwm.h 19 Dec 2017 14:30:53 -0000 1.347 +++ calmwm.h 27 Dec 2017 19:21:24 -0000 @@ -255,6 +255,7 @@ struct cmd_ctx { char path[PATH_MAX]; }; TAILQ_HEAD(cmd_q, cmd_ctx); +TAILQ_HEAD(wm_q, cmd_ctx); enum menu_exec { CWM_MENU_EXEC_EXEC, @@ -284,6 +285,7 @@ struct conf { struct autogroup_q autogroupq; struct ignore_q ignoreq; struct cmd_q cmdq; + struct wm_q wmq; int ngroups; int stickygroups; int nameqlen; @@ -457,10 +459,13 @@ void search_match_cmd(struct menu_q * char *); void search_match_group(struct menu_q *, struct menu_q *, char *); +void search_match_wm(struct menu_q *, struct menu_q *, + char *); void search_print_client(struct menu *, int); void search_print_cmd(struct menu *, int); void search_print_group(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 geom screen_apply_gap(struct screen_ctx *, struct geom); @@ -500,6 +505,7 @@ void kbfunc_group_alltoggle(void *, s void kbfunc_menu_client(void *, struct cargs *); void kbfunc_menu_cmd(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_ssh(void *, struct cargs *); void kbfunc_client_menu_label(void *, struct cargs *); @@ -528,6 +534,8 @@ int conf_bind_mouse(struct conf *, co void conf_clear(struct conf *); void conf_client(struct client_ctx *); int conf_cmd_add(struct conf *, const char *, + const char *); +int conf_wm_add(struct conf *, const char *, const char *); void conf_cursor(struct conf *); void conf_grab_kbd(Window); Index: conf.c =================================================================== RCS file: /home/open/cvs/xenocara/app/cwm/conf.c,v retrieving revision 1.236 diff -u -p -r1.236 conf.c --- conf.c 19 Dec 2017 14:30:53 -0000 1.236 +++ conf.c 27 Dec 2017 19:25:07 -0000 @@ -195,8 +195,7 @@ static const struct { CWM_MENU_WINDOW_HIDDEN }, { "menu-exec", kbfunc_menu_exec, CWM_CONTEXT_SC, CWM_MENU_EXEC_EXEC }, - { "menu-exec-wm", kbfunc_menu_exec, CWM_CONTEXT_SC, - CWM_MENU_EXEC_WM }, + { "menu-exec-wm", kbfunc_menu_wm, CWM_CONTEXT_SC, 0 }, { "terminal", kbfunc_exec_term, CWM_CONTEXT_SC, 0 }, { "lock", kbfunc_exec_lock, CWM_CONTEXT_SC, 0 }, @@ -298,6 +297,7 @@ conf_init(struct conf *c) TAILQ_INIT(&c->ignoreq); TAILQ_INIT(&c->cmdq); + TAILQ_INIT(&c->wmq); TAILQ_INIT(&c->keybindq); TAILQ_INIT(&c->autogroupq); TAILQ_INIT(&c->mousebindq); @@ -314,6 +314,8 @@ conf_init(struct conf *c) conf_cmd_add(c, "lock", "xlock"); conf_cmd_add(c, "term", "xterm"); + conf_wm_add(c, "cwm", "cwm"); + (void)snprintf(c->known_hosts, sizeof(c->known_hosts), "%s/%s", c->homedir, ".ssh/known_hosts"); @@ -327,7 +329,7 @@ conf_clear(struct conf *c) struct autogroup *ag; struct bind_ctx *kb, *mb; struct winname *wn; - struct cmd_ctx *cmd; + struct cmd_ctx *cmd, *wm; int i; while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) { @@ -335,6 +337,11 @@ conf_clear(struct conf *c) free(cmd->name); 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) { TAILQ_REMOVE(&c->keybindq, kb, entry); free(kb); @@ -391,6 +398,23 @@ conf_cmd_remove(struct conf *c, const ch free(cmd); } } +} + +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 Index: kbfunc.c =================================================================== RCS file: /home/open/cvs/xenocara/app/cwm/kbfunc.c,v retrieving revision 1.155 diff -u -p -r1.155 kbfunc.c --- kbfunc.c 19 Dec 2017 19:38:43 -0000 1.155 +++ kbfunc.c 27 Dec 2017 20:35:38 -0000 @@ -542,6 +542,33 @@ kbfunc_menu_group(void *ctx, struct carg } 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 kbfunc_menu_exec(void *ctx, struct cargs *cargs) { #define NPATHS 256 Index: parse.y =================================================================== RCS file: /home/open/cvs/xenocara/app/cwm/parse.y,v retrieving revision 1.68 diff -u -p -r1.68 parse.y --- parse.y 26 Apr 2017 21:10:54 -0000 1.68 +++ parse.y 27 Dec 2017 20:55:49 -0000 @@ -70,7 +70,7 @@ typedef struct { %token BINDKEY UNBINDKEY BINDMOUSE UNBINDMOUSE %token FONTNAME STICKY GAP -%token AUTOGROUP COMMAND IGNORE +%token AUTOGROUP COMMAND IGNORE WM %token YES NO BORDERWIDTH MOVEAMOUNT %token COLOR SNAPDIST %token ACTIVEBORDER INACTIVEBORDER URGENCYBORDER @@ -146,6 +146,16 @@ main : FONTNAME STRING { free($2); 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 { if ($2 < 0 || $2 > 9) { yyerror("invalid autogroup"); @@ -317,6 +327,7 @@ lookup(char *s) { "unbind-mouse", UNBINDMOUSE}, { "ungroupborder", UNGROUPBORDER}, { "urgencyborder", URGENCYBORDER}, + { "wm", WM}, { "yes", YES} }; const struct keywords *p; Index: search.c =================================================================== RCS file: /home/open/cvs/xenocara/app/cwm/search.c,v retrieving revision 1.66 diff -u -p -r1.66 search.c --- search.c 13 Dec 2017 15:10:17 -0000 1.66 +++ search.c 27 Dec 2017 21:20:52 -0000 @@ -228,6 +228,21 @@ search_match_text(struct menu_q *menuq, } 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 search_print_client(struct menu *mi, int listing) { struct client_ctx *cc = (struct client_ctx *)mi->ctx; @@ -265,4 +280,13 @@ void search_print_text(struct menu *mi, int listing) { (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); }