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);
 }

Reply via email to