diff options
author | Christian Neukirchen <chneukirchen@gmail.com> | 2016-12-16 13:42:52 +0100 |
---|---|---|
committer | Christian Neukirchen <chneukirchen@gmail.com> | 2016-12-16 13:48:38 +0100 |
commit | 775ba78311768b7a944db95273822c0a567dc171 (patch) | |
tree | 13ea9cb9db8e9121cc80e9cce4186a925fb889e2 | |
parent | dcb741d2b1378432e226bbeea274c2e5e2508c2d (diff) | |
parent | 8b4666cb926121481905b68bf93d6e81c307e9e3 (diff) | |
download | cwm-775ba78311768b7a944db95273822c0a567dc171.tar.gz cwm-775ba78311768b7a944db95273822c0a567dc171.tar.xz cwm-775ba78311768b7a944db95273822c0a567dc171.zip |
cvsimport
* refs/heads/master: stray newlines Add search_print_text(), a default callback for mi->print in menu_filter(). While here, normalize the remaining search_print_* argument paramters. Consistent use of menuq_add for ssh menu. Now that dim.{x,y} are available early, use them before requiring a MotionNotify event. Set dim.{x,y} during client_init and update on resize, instead of (re)calculating only when applying hints. 'window-search' is spelled 'menu-window'; the former snuck in during the conversion('menu-window' already existed and was properlly documented); found the hard way by sthen@ while trying to convert. Fold unbinding functions into one for each, key and mouse; plugs a leak when unbinding a mouse button bound to a command. use the correct type Tame the number of 'exec' and 'path' search_match wrappers. No functional change now, though more can likely go later, losing the (paritally complete or incomplete/broken) argument completion bits. Switch ssh menu to search_match_text; like group/window/cmd menus, use only a substring match. The previous matching is only intended for the exec menus. Change 'menu-window' to display all windows; then add 'menu-window-hidden' for the previous behaviour of 'menu-window'. 'menu-window' becomes the default binding; use 'bind-mouse "1" menu-window-hidden' to restore old behaviour for those who prefer. Normalize bind function names, based on a few categories: window, group, menu and pointer. Use an additional check with lstat(2) when d_type is unknown. revert previous; upcoming changes will hopefully deal with these more naturally. Add a wrapper based upon xevent handlers around client move/resize for key and mouse bindings. Define callbacks, then default bindings. Reorganize for upcoming changes. Remove the (8) default bindings for pointer move since they conflict with default bindings for emacs, which wins; the feature remains and can be bound to whatever users wish with cwmrc(5).
-rw-r--r-- | calmwm.h | 9 | ||||
-rw-r--r-- | client.c | 8 | ||||
-rw-r--r-- | conf.c | 786 | ||||
-rw-r--r-- | cwm.1 | 9 | ||||
-rw-r--r-- | cwmrc.5 | 315 | ||||
-rw-r--r-- | kbfunc.c | 21 | ||||
-rw-r--r-- | menu.c | 10 | ||||
-rw-r--r-- | mousefunc.c | 4 | ||||
-rw-r--r-- | parse.y | 51 | ||||
-rw-r--r-- | search.c | 36 |
10 files changed, 614 insertions, 635 deletions
diff --git a/calmwm.h b/calmwm.h index faac8bb..eb64dd7 100644 --- a/calmwm.h +++ b/calmwm.h @@ -282,6 +282,8 @@ enum menu_exec { #define CWM_MENU_DUMMY 0x0001 #define CWM_MENU_FILE 0x0002 #define CWM_MENU_LIST 0x0004 +#define CWM_MENU_WINDOW_ALL 0x0008 +#define CWM_MENU_WINDOW_HIDDEN 0x0010 struct menu { TAILQ_ENTRY(menu) entry; @@ -461,15 +463,14 @@ void search_match_client(struct menu_q *, struct menu_q *, char *); void search_match_exec(struct menu_q *, struct menu_q *, char *); -void search_match_exec_path(struct menu_q *, - struct menu_q *, char *); -void search_match_path_any(struct menu_q *, struct menu_q *, +void search_match_path(struct menu_q *, struct menu_q *, char *); void search_match_text(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); struct region_ctx *region_find(struct screen_ctx *, int, int); struct geom screen_apply_gap(struct screen_ctx *, struct geom); @@ -539,7 +540,7 @@ int parse_config(const char *, struct conf *); void conf_atoms(void); void conf_autogroup(struct conf *, int, const char *, const char *); -int conf_bind_kbd(struct conf *, const char *, +int conf_bind_key(struct conf *, const char *, const char *); int conf_bind_mouse(struct conf *, const char *, const char *); diff --git a/client.c b/client.c index 7975bb9..377abdb 100644 --- a/client.c +++ b/client.c @@ -91,6 +91,8 @@ client_init(Window win, struct screen_ctx *sc, int active) cc->geom.y = wattr.y; cc->geom.w = wattr.width; cc->geom.h = wattr.height; + cc->dim.w = (cc->geom.w - cc->hint.basew) / cc->hint.incw; + cc->dim.h = (cc->geom.h - cc->hint.baseh) / cc->hint.inch; cc->ptr.x = cc->geom.w / 2; cc->ptr.y = cc->geom.h / 2; @@ -424,6 +426,8 @@ client_resize(struct client_ctx *cc, int reset) XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x, cc->geom.y, cc->geom.w, cc->geom.h); + cc->dim.w = (cc->geom.w - cc->hint.basew) / cc->hint.incw; + cc->dim.h = (cc->geom.h - cc->hint.baseh) / cc->hint.inch; client_config(cc); } @@ -877,9 +881,6 @@ client_applysizehints(struct client_ctx *cc) cc->geom.w = MIN(cc->geom.w, cc->hint.maxw); if (cc->hint.maxh) cc->geom.h = MIN(cc->geom.h, cc->hint.maxh); - - cc->dim.w = (cc->geom.w - cc->hint.basew) / cc->hint.incw; - cc->dim.h = (cc->geom.h - cc->hint.baseh) / cc->hint.inch; } static void @@ -1085,4 +1086,3 @@ client_set_wm_state(struct client_ctx *cc, long state) XChangeProperty(X_Dpy, cc->win, cwmh[WM_STATE], cwmh[WM_STATE], 32, PropModeReplace, (unsigned char *)data, 2); } - diff --git a/conf.c b/conf.c index cebfc07..15d3217 100644 --- a/conf.c +++ b/conf.c @@ -34,27 +34,330 @@ static const char *conf_bind_getmask(const char *, unsigned int *); static void conf_cmd_remove(struct conf *, const char *); -static void conf_unbind_kbd(struct conf *, struct bind_ctx *); +static void conf_unbind_key(struct conf *, struct bind_ctx *); static void conf_unbind_mouse(struct conf *, struct bind_ctx *); +static int cursor_binds[] = { + XC_left_ptr, /* CF_NORMAL */ + XC_fleur, /* CF_MOVE */ + XC_bottom_right_corner, /* CF_RESIZE */ + XC_question_arrow, /* CF_QUESTION */ +}; +static const char *color_binds[] = { + "#CCCCCC", /* CWM_COLOR_BORDER_ACTIVE */ + "#666666", /* CWM_COLOR_BORDER_INACTIVE */ + "#FC8814", /* CWM_COLOR_BORDER_URGENCY */ + "blue", /* CWM_COLOR_BORDER_GROUP */ + "red", /* CWM_COLOR_BORDER_UNGROUP */ + "black", /* CWM_COLOR_MENU_FG */ + "white", /* CWM_COLOR_MENU_BG */ + "black", /* CWM_COLOR_MENU_FONT */ + "", /* CWM_COLOR_MENU_FONT_SEL */ +}; +static const struct { + const char *tag; + void (*handler)(void *, union arg *, enum xev); + enum context context; + union arg argument; +} name_to_func[] = { + { "window-menu-label", kbfunc_menu_client_label, CWM_CONTEXT_CC, {0} }, + { "window-lower", kbfunc_client_lower, CWM_CONTEXT_CC, {0} }, + { "window-raise", kbfunc_client_raise, CWM_CONTEXT_CC, {0} }, + { "window-hide", kbfunc_client_hide, CWM_CONTEXT_CC, {0} }, + { "window-delete", kbfunc_client_delete, CWM_CONTEXT_CC, {0} }, + { "window-htile", kbfunc_client_htile, CWM_CONTEXT_CC, {0} }, + { "window-vtile", kbfunc_client_vtile, CWM_CONTEXT_CC, {0} }, + { "window-stick", kbfunc_client_toggle_sticky, CWM_CONTEXT_CC, {0} }, + { "window-fullscreen", kbfunc_client_toggle_fullscreen, CWM_CONTEXT_CC, {0} }, + { "window-maximize", kbfunc_client_toggle_maximize, CWM_CONTEXT_CC, {0} }, + { "window-vmaximize", kbfunc_client_toggle_vmaximize, CWM_CONTEXT_CC, {0} }, + { "window-hmaximize", kbfunc_client_toggle_hmaximize, CWM_CONTEXT_CC, {0} }, + { "window-freeze", kbfunc_client_toggle_freeze, CWM_CONTEXT_CC, {0} }, + { "window-cycle", kbfunc_client_cycle, CWM_CONTEXT_SC, + {.i = (CWM_CYCLE_FORWARD)} }, + { "window-rcycle", kbfunc_client_cycle, CWM_CONTEXT_SC, + {.i = (CWM_CYCLE_REVERSE)} }, + { "window-cycle-ingroup", kbfunc_client_cycle, CWM_CONTEXT_SC, + {.i = (CWM_CYCLE_FORWARD | CWM_CYCLE_INGROUP)} }, + { "window-rcycle-ingroup", kbfunc_client_cycle, CWM_CONTEXT_SC, + {.i = (CWM_CYCLE_REVERSE | CWM_CYCLE_INGROUP)} }, + { "window-group", kbfunc_client_toggle_group, CWM_CONTEXT_CC, {0} }, + { "window-movetogroup-1", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 1} }, + { "window-movetogroup-2", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 2} }, + { "window-movetogroup-3", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 3} }, + { "window-movetogroup-4", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 4} }, + { "window-movetogroup-5", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 5} }, + { "window-movetogroup-6", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 6} }, + { "window-movetogroup-7", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 7} }, + { "window-movetogroup-8", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 8} }, + { "window-movetogroup-9", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 9} }, + + { "window-move", mousefunc_client_move, CWM_CONTEXT_CC, {0} }, + { "window-move-up", kbfunc_client_move, CWM_CONTEXT_CC, + {.i = (CWM_UP)} }, + { "window-move-down", kbfunc_client_move, CWM_CONTEXT_CC, + {.i = (CWM_DOWN)} }, + { "window-move-right", kbfunc_client_move, CWM_CONTEXT_CC, + {.i = (CWM_RIGHT)} }, + { "window-move-left", kbfunc_client_move, CWM_CONTEXT_CC, + {.i = (CWM_LEFT)} }, + { "window-move-up-big", kbfunc_client_move, CWM_CONTEXT_CC, + {.i = (CWM_UP | CWM_BIGAMOUNT)} }, + { "window-move-down-big", kbfunc_client_move, CWM_CONTEXT_CC, + {.i = (CWM_DOWN | CWM_BIGAMOUNT)} }, + { "window-move-right-big", kbfunc_client_move, CWM_CONTEXT_CC, + {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} }, + { "window-move-left-big", kbfunc_client_move, CWM_CONTEXT_CC, + {.i = (CWM_LEFT | CWM_BIGAMOUNT)} }, + { "window-resize", mousefunc_client_resize, CWM_CONTEXT_CC, {0} }, + { "window-resize-up", kbfunc_client_resize, CWM_CONTEXT_CC, + {.i = (CWM_UP)} }, + { "window-resize-down", kbfunc_client_resize, CWM_CONTEXT_CC, + {.i = (CWM_DOWN)} }, + { "window-resize-right", kbfunc_client_resize, CWM_CONTEXT_CC, + {.i = (CWM_RIGHT)} }, + { "window-resize-left", kbfunc_client_resize, CWM_CONTEXT_CC, + {.i = (CWM_LEFT)} }, + { "window-resize-up-big", kbfunc_client_resize, CWM_CONTEXT_CC, + {.i = (CWM_UP | CWM_BIGAMOUNT)} }, + { "window-resize-down-big", kbfunc_client_resize, CWM_CONTEXT_CC, + {.i = (CWM_DOWN | CWM_BIGAMOUNT)} }, + { "window-resize-right-big", kbfunc_client_resize, CWM_CONTEXT_CC, + {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} }, + { "window-resize-left-big", kbfunc_client_resize, CWM_CONTEXT_CC, + {.i = (CWM_LEFT | CWM_BIGAMOUNT)} }, + + { "group-cycle", kbfunc_group_cycle, CWM_CONTEXT_SC, + {.i = (CWM_CYCLE_FORWARD)} }, + { "group-rcycle", kbfunc_group_cycle, CWM_CONTEXT_SC, + {.i = (CWM_CYCLE_REVERSE)} }, + { "group-toggle-all", kbfunc_group_alltoggle, CWM_CONTEXT_SC, {0} }, + { "group-toggle-1", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 1} }, + { "group-toggle-2", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 2} }, + { "group-toggle-3", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 3} }, + { "group-toggle-4", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 4} }, + { "group-toggle-5", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 5} }, + { "group-toggle-6", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 6} }, + { "group-toggle-7", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 7} }, + { "group-toggle-8", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 8} }, + { "group-toggle-9", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 9} }, + { "group-only-1", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 1} }, + { "group-only-2", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 2} }, + { "group-only-3", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 3} }, + { "group-only-4", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 4} }, + { "group-only-5", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 5} }, + { "group-only-6", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 6} }, + { "group-only-7", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 7} }, + { "group-only-8", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 8} }, + { "group-only-9", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 9} }, + + { "pointer-move-up", kbfunc_ptrmove, CWM_CONTEXT_SC, + {.i = (CWM_UP)} }, + { "pointer-move-down", kbfunc_ptrmove, CWM_CONTEXT_SC, + {.i = (CWM_DOWN)} }, + { "pointer-move-left", kbfunc_ptrmove, CWM_CONTEXT_SC, + {.i = (CWM_LEFT)} }, + { "pointer-move-right", kbfunc_ptrmove, CWM_CONTEXT_SC, + {.i = (CWM_RIGHT)} }, + { "pointer-move-up-big", kbfunc_ptrmove, CWM_CONTEXT_SC, + {.i = (CWM_UP | CWM_BIGAMOUNT)} }, + { "pointer-move-down-big", kbfunc_ptrmove, CWM_CONTEXT_SC, + {.i = (CWM_DOWN | CWM_BIGAMOUNT)} }, + { "pointer-move-left-big", kbfunc_ptrmove, CWM_CONTEXT_SC, + {.i = (CWM_LEFT | CWM_BIGAMOUNT)} }, + { "pointer-move-right-big", kbfunc_ptrmove, CWM_CONTEXT_SC, + {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} }, + + { "menu-cmd", kbfunc_menu_cmd, CWM_CONTEXT_SC, {0} }, + { "menu-group", kbfunc_menu_group, CWM_CONTEXT_SC, {0} }, + { "menu-ssh", kbfunc_menu_ssh, CWM_CONTEXT_SC, {0} }, + { "menu-window", kbfunc_menu_client, CWM_CONTEXT_SC, + {.i = CWM_MENU_WINDOW_ALL} }, + { "menu-window-hidden", kbfunc_menu_client, CWM_CONTEXT_SC, + {.i = CWM_MENU_WINDOW_HIDDEN} }, + { "menu-exec", kbfunc_menu_exec, CWM_CONTEXT_SC, + {.i = CWM_MENU_EXEC_EXEC} }, + { "menu-exec-wm", kbfunc_menu_exec, CWM_CONTEXT_SC, + {.i = CWM_MENU_EXEC_WM} }, + + { "terminal", kbfunc_exec_term, CWM_CONTEXT_SC, {0} }, + { "lock", kbfunc_exec_lock, CWM_CONTEXT_SC, {0} }, + { "restart", kbfunc_cwm_status, CWM_CONTEXT_SC, {.i = CWM_EXEC_WM} }, + { "quit", kbfunc_cwm_status, CWM_CONTEXT_SC, {.i = CWM_QUIT} }, + +}; +static unsigned int ignore_mods[] = { + 0, LockMask, Mod2Mask, Mod2Mask | LockMask +}; +static const struct { + const char ch; + int mask; +} bind_mods[] = { + { 'C', ControlMask }, + { 'M', Mod1Mask }, + { '4', Mod4Mask }, + { 'S', ShiftMask }, +}; +static const struct { + const char *key; + const char *func; +} key_binds[] = { + { "CM-Return", "terminal" }, + { "CM-Delete", "lock" }, + { "M-question", "menu-exec" }, + { "CM-w", "menu-exec-wm" }, + { "M-period", "menu-ssh" }, + { "M-Return", "window-hide" }, + { "M-Down", "window-lower" }, + { "M-Up", "window-raise" }, + { "M-slash", "menu-window" }, + { "C-slash", "menu-cmd" }, + { "M-Tab", "window-cycle" }, + { "MS-Tab", "window-rcycle" }, + { "CM-n", "window-menu-label" }, + { "CM-x", "window-delete" }, + { "CM-a", "group-toggle-all" }, + { "CM-0", "group-toggle-all" }, + { "CM-1", "group-toggle-1" }, + { "CM-2", "group-toggle-2" }, + { "CM-3", "group-toggle-3" }, + { "CM-4", "group-toggle-4" }, + { "CM-5", "group-toggle-5" }, + { "CM-6", "group-toggle-6" }, + { "CM-7", "group-toggle-7" }, + { "CM-8", "group-toggle-8" }, + { "CM-9", "group-toggle-9" }, + { "M-Right", "group-cycle" }, + { "M-Left", "group-rcycle" }, + { "CM-g", "window-group" }, + { "CM-f", "window-fullscreen" }, + { "CM-m", "window-maximize" }, + { "CM-s", "window-stick" }, + { "CM-equal", "window-vmaximize" }, + { "CMS-equal", "window-hmaximize" }, + { "CMS-f", "window-freeze" }, + { "CMS-r", "restart" }, + { "CMS-q", "quit" }, + { "M-h", "window-move-left" }, + { "M-j", "window-move-down" }, + { "M-k", "window-move-up" }, + { "M-l", "window-move-right" }, + { "MS-h", "window-move-left-big" }, + { "MS-j", "window-move-down-big" }, + { "MS-k", "window-move-up-big" }, + { "MS-l", "window-move-right-big" }, + { "CM-h", "window-resize-left" }, + { "CM-j", "window-resize-down" }, + { "CM-k", "window-resize-up" }, + { "CM-l", "window-resize-right" }, + { "CMS-h", "window-resize-left-big" }, + { "CMS-j", "window-resize-down-big" }, + { "CMS-k", "window-resize-up-big" }, + { "CMS-l", "window-resize-right-big" }, +}, +mouse_binds[] = { + { "1", "menu-window" }, + { "2", "menu-group" }, + { "3", "menu-cmd" }, + { "M-1", "window-move" }, + { "CM-1", "window-group" }, + { "M-2", "window-resize" }, + { "M-3", "window-lower" }, + { "CMS-3", "window-hide" }, +}; + +void +conf_init(struct conf *c) +{ + unsigned int i; + + c->stickygroups = 0; + c->bwidth = 1; + c->mamount = 1; + c->snapdist = 0; + c->ngroups = 10; + c->nameqlen = 5; + + TAILQ_INIT(&c->ignoreq); + TAILQ_INIT(&c->cmdq); + TAILQ_INIT(&c->keybindq); + TAILQ_INIT(&c->autogroupq); + TAILQ_INIT(&c->mousebindq); + + for (i = 0; i < nitems(key_binds); i++) + conf_bind_key(c, key_binds[i].key, key_binds[i].func); + + for (i = 0; i < nitems(mouse_binds); i++) + conf_bind_mouse(c, mouse_binds[i].key, mouse_binds[i].func); + + for (i = 0; i < nitems(color_binds); i++) + c->color[i] = xstrdup(color_binds[i]); + + conf_cmd_add(c, "lock", "xlock"); + conf_cmd_add(c, "term", "xterm"); + + (void)snprintf(c->known_hosts, sizeof(c->known_hosts), "%s/%s", + homedir, ".ssh/known_hosts"); + + c->font = xstrdup("sans-serif:pixelsize=14:bold"); + c->wmname = xstrdup("CWM"); +} + +void +conf_clear(struct conf *c) +{ + struct autogroup *ag; + struct bind_ctx *kb, *mb; + struct winname *wn; + struct cmd_ctx *cmd; + int i; + + while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) { + TAILQ_REMOVE(&c->cmdq, cmd, entry); + free(cmd->name); + free(cmd); + } + while ((kb = TAILQ_FIRST(&c->keybindq)) != NULL) { + TAILQ_REMOVE(&c->keybindq, kb, entry); + free(kb); + } + while ((ag = TAILQ_FIRST(&c->autogroupq)) != NULL) { + TAILQ_REMOVE(&c->autogroupq, ag, entry); + free(ag->class); + free(ag->name); + free(ag); + } + while ((wn = TAILQ_FIRST(&c->ignoreq)) != NULL) { + TAILQ_REMOVE(&c->ignoreq, wn, entry); + free(wn->name); + free(wn); + } + while ((mb = TAILQ_FIRST(&c->mousebindq)) != NULL) { + TAILQ_REMOVE(&c->mousebindq, mb, entry); + free(mb); + } + for (i = 0; i < CWM_COLOR_NITEMS; i++) + free(c->color[i]); + + free(c->font); + free(c->wmname); +} + int conf_cmd_add(struct conf *c, const char *name, const char *path) { struct cmd_ctx *cmd; cmd = xmalloc(sizeof(*cmd)); - cmd->name = xstrdup(name); if (strlcpy(cmd->path, path, sizeof(cmd->path)) >= sizeof(cmd->path)) { free(cmd->name); free(cmd); return(0); } - conf_cmd_remove(c, name); TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry); - return(1); } @@ -71,6 +374,7 @@ conf_cmd_remove(struct conf *c, const char *name) } } } + void conf_autogroup(struct conf *c, int num, const char *name, const char *class) { @@ -78,7 +382,6 @@ conf_autogroup(struct conf *c, int num, const char *name, const char *class) char *p; ag = xmalloc(sizeof(*ag)); - if ((p = strchr(class, ',')) == NULL) { if (name == NULL) ag->name = NULL; @@ -88,7 +391,6 @@ conf_autogroup(struct conf *c, int num, const char *name, const char *class) ag->class = xstrdup(class); } else { *(p++) = '\0'; - if (name == NULL) ag->name = xstrdup(class); else @@ -97,7 +399,6 @@ conf_autogroup(struct conf *c, int num, const char *name, const char *class) ag->class = xstrdup(p); } ag->num = num; - TAILQ_INSERT_TAIL(&c->autogroupq, ag, entry); } @@ -111,17 +412,30 @@ conf_ignore(struct conf *c, const char *name) TAILQ_INSERT_TAIL(&c->ignoreq, wn, entry); } -static const char *color_binds[] = { - "#CCCCCC", /* CWM_COLOR_BORDER_ACTIVE */ - "#666666", /* CWM_COLOR_BORDER_INACTIVE */ - "#FC8814", /* CWM_COLOR_BORDER_URGENCY */ - "blue", /* CWM_COLOR_BORDER_GROUP */ - "red", /* CWM_COLOR_BORDER_UNGROUP */ - "black", /* CWM_COLOR_MENU_FG */ - "white", /* CWM_COLOR_MENU_BG */ - "black", /* CWM_COLOR_MENU_FONT */ - "", /* CWM_COLOR_MENU_FONT_SEL */ -}; +void +conf_cursor(struct conf *c) +{ + unsigned int i; + + for (i = 0; i < nitems(cursor_binds); i++) + c->cursor[i] = XCreateFontCursor(X_Dpy, cursor_binds[i]); +} + +void +conf_client(struct client_ctx *cc) +{ + struct winname *wn; + int ignore = 0; + + TAILQ_FOREACH(wn, &Conf.ignoreq, entry) { + if (strncasecmp(wn->name, cc->name, strlen(wn->name)) == 0) { + ignore = 1; + break; + } + } + cc->bwidth = (ignore) ? 0 : Conf.bwidth; + cc->flags |= (ignore) ? CLIENT_IGNORE : 0; +} void conf_screen(struct screen_ctx *sc) @@ -174,322 +488,6 @@ conf_screen(struct screen_ctx *sc) conf_grab_kbd(sc->rootwin); } -static const struct { - const char *key; - const char *func; -} kbd_binds[] = { - { "CM-Return", "terminal" }, - { "CM-Delete", "lock" }, - { "M-question", "exec" }, - { "CM-w", "exec_wm" }, - { "M-period", "ssh" }, - { "M-Return", "hide" }, - { "M-Down", "lower" }, - { "M-Up", "raise" }, - { "M-slash", "search" }, - { "C-slash", "menusearch" }, - { "M-Tab", "cycle" }, - { "MS-Tab", "rcycle" }, - { "CM-n", "label" }, - { "CM-x", "delete" }, - { "CM-a", "nogroup" }, - { "CM-0", "nogroup" }, - { "CM-1", "group1" }, - { "CM-2", "group2" }, - { "CM-3", "group3" }, - { "CM-4", "group4" }, - { "CM-5", "group5" }, - { "CM-6", "group6" }, - { "CM-7", "group7" }, - { "CM-8", "group8" }, - { "CM-9", "group9" }, - { "M-Right", "cyclegroup" }, - { "M-Left", "rcyclegroup" }, - { "CM-g", "grouptoggle" }, - { "CM-f", "fullscreen" }, - { "CM-m", "maximize" }, - { "CM-s", "stick" }, - { "CM-equal", "vmaximize" }, - { "CMS-equal", "hmaximize" }, - { "CMS-f", "freeze" }, - { "CMS-r", "restart" }, - { "CMS-q", "quit" }, - { "M-h", "moveleft" }, - { "M-j", "movedown" }, - { "M-k", "moveup" }, - { "M-l", "moveright" }, - { "MS-h", "bigmoveleft" }, - { "MS-j", "bigmovedown" }, - { "MS-k", "bigmoveup" }, - { "MS-l", "bigmoveright" }, - { "CM-h", "resizeleft" }, - { "CM-j", "resizedown" }, - { "CM-k", "resizeup" }, - { "CM-l", "resizeright" }, - { "CMS-h", "bigresizeleft" }, - { "CMS-j", "bigresizedown" }, - { "CMS-k", "bigresizeup" }, - { "CMS-l", "bigresizeright" }, - { "C-Left", "ptrmoveleft" }, - { "C-Down", "ptrmovedown" }, - { "C-Up", "ptrmoveup" }, - { "C-Right", "ptrmoveright" }, - { "CS-Left", "bigptrmoveleft" }, - { "CS-Down", "bigptrmovedown" }, - { "CS-Up", "bigptrmoveup" }, - { "CS-Right", "bigptrmoveright" }, -}, -mouse_binds[] = { - { "1", "menu_unhide" }, - { "2", "menu_group" }, - { "3", "menu_cmd" }, - { "M-1", "window_move" }, - { "CM-1", "window_grouptoggle" }, - { "M-2", "window_resize" }, - { "M-3", "window_lower" }, - { "CMS-3", "window_hide" }, -}; - -void -conf_init(struct conf *c) -{ - unsigned int i; - - c->stickygroups = 0; - c->bwidth = 1; - c->mamount = 1; - c->snapdist = 0; - c->ngroups = 10; - c->nameqlen = 5; - - TAILQ_INIT(&c->ignoreq); - TAILQ_INIT(&c->cmdq); - TAILQ_INIT(&c->keybindq); - TAILQ_INIT(&c->autogroupq); - TAILQ_INIT(&c->mousebindq); - - for (i = 0; i < nitems(kbd_binds); i++) - conf_bind_kbd(c, kbd_binds[i].key, kbd_binds[i].func); - - for (i = 0; i < nitems(mouse_binds); i++) - conf_bind_mouse(c, mouse_binds[i].key, mouse_binds[i].func); - - for (i = 0; i < nitems(color_binds); i++) - c->color[i] = xstrdup(color_binds[i]); - - conf_cmd_add(c, "lock", "xlock"); - conf_cmd_add(c, "term", "xterm"); - - (void)snprintf(c->known_hosts, sizeof(c->known_hosts), "%s/%s", - homedir, ".ssh/known_hosts"); - - c->font = xstrdup("sans-serif:pixelsize=14:bold"); - c->wmname = xstrdup("CWM"); -} - -void -conf_clear(struct conf *c) -{ - struct autogroup *ag; - struct bind_ctx *kb, *mb; - struct winname *wn; - struct cmd_ctx *cmd; - int i; - - while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) { - TAILQ_REMOVE(&c->cmdq, cmd, entry); - free(cmd->name); - free(cmd); - } - - while ((kb = TAILQ_FIRST(&c->keybindq)) != NULL) { - TAILQ_REMOVE(&c->keybindq, kb, entry); - free(kb); - } - - while ((ag = TAILQ_FIRST(&c->autogroupq)) != NULL) { - TAILQ_REMOVE(&c->autogroupq, ag, entry); - free(ag->class); - free(ag->name); - free(ag); - } - - while ((wn = TAILQ_FIRST(&c->ignoreq)) != NULL) { - TAILQ_REMOVE(&c->ignoreq, wn, entry); - free(wn->name); - free(wn); - } - - while ((mb = TAILQ_FIRST(&c->mousebindq)) != NULL) { - TAILQ_REMOVE(&c->mousebindq, mb, entry); - free(mb); - } - - for (i = 0; i < CWM_COLOR_NITEMS; i++) - free(c->color[i]); - - free(c->font); - free(c->wmname); -} - -void -conf_client(struct client_ctx *cc) -{ - struct winname *wn; - int ignore = 0; - - TAILQ_FOREACH(wn, &Conf.ignoreq, entry) { - if (strncasecmp(wn->name, cc->name, strlen(wn->name)) == 0) { - ignore = 1; - break; - } - } - - cc->bwidth = (ignore) ? 0 : Conf.bwidth; - cc->flags |= (ignore) ? CLIENT_IGNORE : 0; -} - -static const struct { - const char *tag; - void (*handler)(void *, union arg *, enum xev); - int context; - union arg argument; -} name_to_func[] = { - { "lower", kbfunc_client_lower, CWM_CONTEXT_CC, {0} }, - { "raise", kbfunc_client_raise, CWM_CONTEXT_CC, {0} }, - { "search", kbfunc_menu_client, CWM_CONTEXT_SC, {0} }, - { "menusearch", kbfunc_menu_cmd, CWM_CONTEXT_SC, {0} }, - { "groupsearch", kbfunc_menu_group, CWM_CONTEXT_SC, {0} }, - { "hide", kbfunc_client_hide, CWM_CONTEXT_CC, {0} }, - { "cycle", kbfunc_client_cycle, CWM_CONTEXT_SC, - {.i = (CWM_CYCLE_FORWARD)} }, - { "rcycle", kbfunc_client_cycle, CWM_CONTEXT_SC, - {.i = (CWM_CYCLE_REVERSE)} }, - { "label", kbfunc_menu_client_label, CWM_CONTEXT_CC, {0} }, - { "delete", kbfunc_client_delete, CWM_CONTEXT_CC, {0} }, - { "group1", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 1} }, - { "group2", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 2} }, - { "group3", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 3} }, - { "group4", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 4} }, - { "group5", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 5} }, - { "group6", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 6} }, - { "group7", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 7} }, - { "group8", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 8} }, - { "group9", kbfunc_group_toggle, CWM_CONTEXT_SC, {.i = 9} }, - { "grouponly1", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 1} }, - { "grouponly2", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 2} }, - { "grouponly3", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 3} }, - { "grouponly4", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 4} }, - { "grouponly5", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 5} }, - { "grouponly6", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 6} }, - { "grouponly7", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 7} }, - { "grouponly8", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 8} }, - { "grouponly9", kbfunc_group_only, CWM_CONTEXT_SC, {.i = 9} }, - { "movetogroup1", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 1} }, - { "movetogroup2", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 2} }, - { "movetogroup3", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 3} }, - { "movetogroup4", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 4} }, - { "movetogroup5", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 5} }, - { "movetogroup6", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 6} }, - { "movetogroup7", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 7} }, - { "movetogroup8", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 8} }, - { "movetogroup9", kbfunc_client_movetogroup, CWM_CONTEXT_CC, {.i = 9} }, - { "nogroup", kbfunc_group_alltoggle, CWM_CONTEXT_SC, {0} }, - { "cyclegroup", kbfunc_group_cycle, CWM_CONTEXT_SC, - {.i = (CWM_CYCLE_FORWARD)} }, - { "rcyclegroup", kbfunc_group_cycle, CWM_CONTEXT_SC, - {.i = (CWM_CYCLE_REVERSE)} }, - { "cycleingroup", kbfunc_client_cycle, CWM_CONTEXT_SC, - {.i = (CWM_CYCLE_FORWARD | CWM_CYCLE_INGROUP)} }, - { "rcycleingroup", kbfunc_client_cycle, CWM_CONTEXT_SC, - {.i = (CWM_CYCLE_REVERSE | CWM_CYCLE_INGROUP)} }, - { "grouptoggle", kbfunc_client_toggle_group, CWM_CONTEXT_CC, {0} }, - { "stick", kbfunc_client_toggle_sticky, CWM_CONTEXT_CC, {0} }, - { "fullscreen", kbfunc_client_toggle_fullscreen, CWM_CONTEXT_CC, {0} }, - { "maximize", kbfunc_client_toggle_maximize, CWM_CONTEXT_CC, {0} }, - { "vmaximize", kbfunc_client_toggle_vmaximize, CWM_CONTEXT_CC, {0} }, - { "hmaximize", kbfunc_client_toggle_hmaximize, CWM_CONTEXT_CC, {0} }, - { "freeze", kbfunc_client_toggle_freeze, CWM_CONTEXT_CC, {0} }, - { "restart", kbfunc_cwm_status, CWM_CONTEXT_SC, {.i = CWM_EXEC_WM} }, - { "quit", kbfunc_cwm_status, CWM_CONTEXT_SC, {.i = CWM_QUIT} }, - { "exec", kbfunc_menu_exec, CWM_CONTEXT_SC, - {.i = CWM_MENU_EXEC_EXEC} }, - { "exec_wm", kbfunc_menu_exec, CWM_CONTEXT_SC, - {.i = CWM_MENU_EXEC_WM} }, - { "ssh", kbfunc_menu_ssh, CWM_CONTEXT_SC, {0} }, - { "terminal", kbfunc_exec_term, CWM_CONTEXT_SC, {0} }, - { "lock", kbfunc_exec_lock, CWM_CONTEXT_SC, {0} }, - { "moveup", kbfunc_client_move, CWM_CONTEXT_CC, - {.i = (CWM_UP)} }, - { "movedown", kbfunc_client_move, CWM_CONTEXT_CC, - {.i = (CWM_DOWN)} }, - { "moveright", kbfunc_client_move, CWM_CONTEXT_CC, - {.i = (CWM_RIGHT)} }, - { "moveleft", kbfunc_client_move, CWM_CONTEXT_CC, - {.i = (CWM_LEFT)} }, - { "bigmoveup", kbfunc_client_move, CWM_CONTEXT_CC, - {.i = (CWM_UP | CWM_BIGAMOUNT)} }, - { "bigmovedown", kbfunc_client_move, CWM_CONTEXT_CC, - {.i = (CWM_DOWN | CWM_BIGAMOUNT)} }, - { "bigmoveright", kbfunc_client_move, CWM_CONTEXT_CC, - {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} }, - { "bigmoveleft", kbfunc_client_move, CWM_CONTEXT_CC, - {.i = (CWM_LEFT | CWM_BIGAMOUNT)} }, - { "resizeup", kbfunc_client_resize, CWM_CONTEXT_CC, - {.i = (CWM_UP)} }, - { "resizedown", kbfunc_client_resize, CWM_CONTEXT_CC, - {.i = (CWM_DOWN)} }, - { "resizeright", kbfunc_client_resize, CWM_CONTEXT_CC, - {.i = (CWM_RIGHT)} }, - { "resizeleft", kbfunc_client_resize, CWM_CONTEXT_CC, - {.i = (CWM_LEFT)} }, - { "bigresizeup", kbfunc_client_resize, CWM_CONTEXT_CC, - {.i = (CWM_UP | CWM_BIGAMOUNT)} }, - { "bigresizedown", kbfunc_client_resize, CWM_CONTEXT_CC, - {.i = (CWM_DOWN | CWM_BIGAMOUNT)} }, - { "bigresizeright", kbfunc_client_resize, CWM_CONTEXT_CC, - {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} }, - { "bigresizeleft", kbfunc_client_resize, CWM_CONTEXT_CC, - {.i = (CWM_LEFT | CWM_BIGAMOUNT)} }, - { "ptrmoveup", kbfunc_ptrmove, CWM_CONTEXT_SC, - {.i = (CWM_UP)} }, - { "ptrmovedown", kbfunc_ptrmove, CWM_CONTEXT_SC, - {.i = (CWM_DOWN)} }, - { "ptrmoveleft", kbfunc_ptrmove, CWM_CONTEXT_SC, - {.i = (CWM_LEFT)} }, - { "ptrmoveright", kbfunc_ptrmove, CWM_CONTEXT_SC, - {.i = (CWM_RIGHT)} }, - { "bigptrmoveup", kbfunc_ptrmove, CWM_CONTEXT_SC, - {.i = (CWM_UP | CWM_BIGAMOUNT)} }, - { "bigptrmovedown", kbfunc_ptrmove, CWM_CONTEXT_SC, - {.i = (CWM_DOWN | CWM_BIGAMOUNT)} }, - { "bigptrmoveleft", kbfunc_ptrmove, CWM_CONTEXT_SC, - {.i = (CWM_LEFT | CWM_BIGAMOUNT)} }, - { "bigptrmoveright", kbfunc_ptrmove, CWM_CONTEXT_SC, - {.i = (CWM_RIGHT | CWM_BIGAMOUNT)} }, - { "htile", kbfunc_client_htile, CWM_CONTEXT_CC, {0} }, - { "vtile", kbfunc_client_vtile, CWM_CONTEXT_CC, {0} }, - { "window_lower", kbfunc_client_lower, CWM_CONTEXT_CC, {0} }, - { "window_raise", kbfunc_client_raise, CWM_CONTEXT_CC, {0} }, - { "window_hide", kbfunc_client_hide, CWM_CONTEXT_CC, {0} }, - { "window_move", mousefunc_client_move, CWM_CONTEXT_CC, {0} }, - { "window_resize", mousefunc_client_resize, CWM_CONTEXT_CC, {0} }, - { "window_grouptoggle", kbfunc_client_toggle_group, CWM_CONTEXT_CC, {0} }, - { "menu_group", kbfunc_menu_group, CWM_CONTEXT_SC, {0} }, - { "menu_unhide", kbfunc_menu_client, CWM_CONTEXT_SC, {0} }, - { "menu_cmd", kbfunc_menu_cmd, CWM_CONTEXT_SC, {0} }, -}; - -static const struct { - const char ch; - int mask; -} bind_mods[] = { - { 'C', ControlMask }, - { 'M', Mod1Mask }, - { '4', Mod4Mask }, - { 'S', ShiftMask }, -}; - static const char * conf_bind_getmask(const char *name, unsigned int *mask) { @@ -504,64 +502,60 @@ conf_bind_getmask(const char *name, unsigned int *mask) if ((ch = strchr(name, bind_mods[i].ch)) != NULL && ch < dash) *mask |= bind_mods[i].mask; } - /* Skip past modifiers. */ return(dash + 1); } int -conf_bind_kbd(struct conf *c, const char *bind, const char *cmd) +conf_bind_key(struct conf *c, const char *bind, const char *cmd) { struct bind_ctx *kb; const char *key; unsigned int i; + if ((strcmp(bind, "all") == 0) && (cmd == NULL)) { + conf_unbind_key(c, NULL); + goto out; + } kb = xmalloc(sizeof(*kb)); key = conf_bind_getmask(bind, &kb->modmask); - kb->press.keysym = XStringToKeysym(key); if (kb->press.keysym == NoSymbol) { warnx("unknown symbol: %s", key); free(kb); return(0); } - - /* We now have the correct binding, remove duplicates. */ - conf_unbind_kbd(c, kb); - - if (strcmp("unmap", cmd) == 0) { + conf_unbind_key(c, kb); + if (cmd == NULL) { free(kb); - return(1); + goto out; } - for (i = 0; i < nitems(name_to_func); i++) { if (strcmp(name_to_func[i].tag, cmd) != 0) continue; - kb->callback = name_to_func[i].handler; kb->context = name_to_func[i].context; kb->argument = name_to_func[i].argument; TAILQ_INSERT_TAIL(&c->keybindq, kb, entry); - return(1); + goto out; } - kb->callback = kbfunc_exec_cmd; kb->context = CWM_CONTEXT_NONE; kb->argument.c = xstrdup(cmd); TAILQ_INSERT_TAIL(&c->keybindq, kb, entry); +out: return(1); } static void -conf_unbind_kbd(struct conf *c, struct bind_ctx *unbind) +conf_unbind_key(struct conf *c, struct bind_ctx *unbind) { struct bind_ctx *key = NULL, *keynxt; TAILQ_FOREACH_SAFE(key, &c->keybindq, entry, keynxt) { - if (key->modmask != unbind->modmask) - continue; - - if (key->press.keysym == unbind->press.keysym) { + if ((unbind == NULL) || + ((key->modmask == unbind->modmask) && + (key->press.keysym == unbind->press.keysym))) { TAILQ_REMOVE(&c->keybindq, key, entry); if (key->context == CWM_CONTEXT_NONE) free(key->argument.c); @@ -577,36 +571,38 @@ conf_bind_mouse(struct conf *c, const char *bind, const char *cmd) const char *button, *errstr; unsigned int i; + if ((strcmp(bind, "all") == 0) && (cmd == NULL)) { + conf_unbind_mouse(c, NULL); + goto out; + } mb = xmalloc(sizeof(*mb)); button = conf_bind_getmask(bind, &mb->modmask); - mb->press.button = strtonum(button, Button1, Button5, &errstr); if (errstr) { warnx("button number is %s: %s", errstr, button); free(mb); return(0); } - - /* We now have the correct binding, remove duplicates. */ conf_unbind_mouse(c, mb); - - if (strcmp("unmap", cmd) == 0) { + if (cmd == NULL) { free(mb); - return(1); + goto out; } - for (i = 0; i < nitems(name_to_func); i++) { if (strcmp(name_to_func[i].tag, cmd) != 0) continue; - mb->callback = name_to_func[i].handler; mb->context = name_to_func[i].context; mb->argument = name_to_func[i].argument; TAILQ_INSERT_TAIL(&c->mousebindq, mb, entry); - return(1); + goto out; } - - return(0); + mb->callback = kbfunc_exec_cmd; + mb->context = CWM_CONTEXT_NONE; + mb->argument.c = xstrdup(cmd); + TAILQ_INSERT_TAIL(&c->mousebindq, mb, entry); +out: + return(1); } static void @@ -615,74 +611,56 @@ conf_unbind_mouse(struct conf *c, struct bind_ctx *unbind) struct bind_ctx *mb = NULL, *mbnxt; TAILQ_FOREACH_SAFE(mb, &c->mousebindq, entry, mbnxt) { - if (mb->modmask != unbind->modmask) - continue; - - if (mb->press.button == unbind->press.button) { + if ((unbind == NULL) || + ((mb->modmask == unbind->modmask) && + (mb->press.button == unbind->press.button))) { TAILQ_REMOVE(&c->mousebindq, mb, entry); + if (mb->context == CWM_CONTEXT_NONE) + free(mb->argument.c); free(mb); } } } -static int cursor_binds[] = { - XC_left_ptr, /* CF_NORMAL */ - XC_fleur, /* CF_MOVE */ - XC_bottom_right_corner, /* CF_RESIZE */ - XC_question_arrow, /* CF_QUESTION */ -}; - void -conf_cursor(struct conf *c) +conf_grab_kbd(Window win) { + struct bind_ctx *kb; + KeyCode kc; unsigned int i; - for (i = 0; i < nitems(cursor_binds); i++) - c->cursor[i] = XCreateFontCursor(X_Dpy, cursor_binds[i]); -} + XUngrabKey(X_Dpy, AnyKey, AnyModifier, win); -static unsigned int ign_mods[] = { 0, LockMask, Mod2Mask, Mod2Mask | LockMask }; + TAILQ_FOREACH(kb, &Conf.keybindq, entry) { + kc = XKeysymToKeycode(X_Dpy, kb->press.keysym); + if ((XkbKeycodeToKeysym(X_Dpy, kc, 0, 0) != kb->press.keysym) && + (XkbKeycodeToKeysym(X_Dpy, kc, 0, 1) == kb->press.keysym)) + kb->modmask |= ShiftMask; + + for (i = 0; i < nitems(ignore_mods); i++) + XGrabKey(X_Dpy, kc, (kb->modmask | ignore_mods[i]), win, + True, GrabModeAsync, GrabModeAsync); + } +} void conf_grab_mouse(Window win) { struct bind_ctx *mb; - unsigned int i; + unsigned int i; XUngrabButton(X_Dpy, AnyButton, AnyModifier, win); TAILQ_FOREACH(mb, &Conf.mousebindq, entry) { if (mb->context != CWM_CONTEXT_CC) continue; - for (i = 0; i < nitems(ign_mods); i++) { + for (i = 0; i < nitems(ignore_mods); i++) { XGrabButton(X_Dpy, mb->press.button, - (mb->modmask | ign_mods[i]), win, False, + (mb->modmask | ignore_mods[i]), win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); } } - -} - -void -conf_grab_kbd(Window win) -{ - struct bind_ctx *kb; - KeyCode kc; - unsigned int i; - - XUngrabKey(X_Dpy, AnyKey, AnyModifier, win); - - TAILQ_FOREACH(kb, &Conf.keybindq, entry) { - kc = XKeysymToKeycode(X_Dpy, kb->press.keysym); - if ((XkbKeycodeToKeysym(X_Dpy, kc, 0, 0) != kb->press.keysym) && - (XkbKeycodeToKeysym(X_Dpy, kc, 0, 1) == kb->press.keysym)) - kb->modmask |= ShiftMask; - - for (i = 0; i < nitems(ign_mods); i++) - XGrabKey(X_Dpy, kc, (kb->modmask | ign_mods[i]), win, - True, GrabModeAsync, GrabModeAsync); - } } static char *cwmhints[] = { diff --git a/cwm.1 b/cwm.1 index 68434c3..2898a52 100644 --- a/cwm.1 +++ b/cwm.1 @@ -117,11 +117,6 @@ Toggle maximization of current window. Toggle vertical maximization of current window. .It Ic CMS-= Toggle horizontal maximization of current window. -.It Ic C-[Up | Down | Left | Right] -Move pointer by a small amount. -.It Ic CS-[Up | Down | Left | Right] -Move pointer by a large amount; see -.Xr cwmrc 5 . .It Ic M-[hjkl] Move window by a small amount. .It Ic MS-[hjkl] @@ -224,8 +219,8 @@ Menus are recalled by clicking the mouse on the root window: .Pp .Bl -tag -width Ds -offset indent -compact .It Ic M1 -Show list of currently hidden windows. -Selecting an item will unhide that window. +Show list of currently defined windows. +Selecting an item will warp to that window, unhiding it if necessary. .It Ic M2 Show list of currently defined groups. Selecting an item will hide/unhide that group. diff --git a/cwmrc.5 b/cwmrc.5 index 93f7273..6419abd 100644 --- a/cwmrc.5 +++ b/cwmrc.5 @@ -63,11 +63,15 @@ The name and class values, respectively, for existing windows are both set in the WM_CLASS property and may be obtained using .Xr xprop 1 . .Pp -.It Ic bind Ar keys command -Cause the creation of a key binding, or replacement of a default -key binding. +.It Ic bind-key Ar key function +Bind or rebind key +.Ar key +to +.Ar function . The modifier keys come first, followed by a -.Sq - . +.Sq - , +then a keysym name, taken from +.Pa /usr/X11R6/include/X11/keysymdef.h . .Pp The following modifiers are recognised: .Pp @@ -83,22 +87,53 @@ Mod4 (windows) key. .El .Pp The -.Sq - -should be followed by a keysym name, taken from -.Pa /usr/X11R6/include/X11/keysymdef.h . -The -.Ar command +.Ar function may either be one from the -.Sx BIND COMMAND LIST +.Sx BIND FUNCTION LIST (see below) or the command line that is to be executed. .Pp -A special -.Ar command -keyword -.Dq unmap -can be used to remove the named key binding. -This can be used to remove a binding which conflicts with an -application. +.It Ic bind-mouse Ar button function +Bind or rebind button +.Ar button +to +.Ar function . +The modifier keys come first, followed by a +.Sq - , +then the button number. +.Pp +The following modifiers are recognised: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It Ic C +Control key. +.It Ic M +Meta key. +.It Ic S +Shift key. +.It Ic 4 +Mod4 (windows) key. +.El +.Pp +The following buttons are recognised: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It Ic 1 +Left mouse button. +.It Ic 2 +Middle mouse button. +.It Ic 3 +Right mouse button. +.It Ic 4 +Scroll up mouse button. +.It Ic 5 +Scroll down mouse button. +.El +.Pp +The +.Ar function +may be taken from the +.Sx BIND FUNCTION LIST +(see below) or the command line that is to be executed. .Pp .It Ic borderwidth Ar pixels Set the window border width to @@ -177,48 +212,6 @@ Ignore, and do not warp to, windows with the name .Ar windowname when drawing borders and cycling through windows. .Pp -.It Ic mousebind Ar buttons command -Cause the creation of a mouse binding, or replacement of a default -mouse binding. -The modifier keys come first, followed by a -.Sq - . -.Pp -The following modifiers are recognised: -.Pp -.Bl -tag -width Ds -offset indent -compact -.It Ic C -Control key. -.It Ic M -Meta key. -.It Ic S -Shift key. -.It Ic 4 -Mod4 (windows) key. -.El -.Pp -The -.Sq - -should be followed by number: -.Pp -.Bl -tag -width Ds -offset indent -compact -.It Ic 1 -Left mouse button. -.It Ic 2 -Middle mouse button. -.It Ic 3 -Right mouse button. -.It Ic 4 -Scroll up mouse button. -.It Ic 5 -Scroll down mouse button. -.El -.Pp -The -.Ar command -may be taken from the -.Sx MOUSEBIND COMMAND LIST -(see below). -.Pp .It Ic moveamount Ar pixels Set a default size for the keyboard movement bindings, in pixels. @@ -234,9 +227,28 @@ The default behavior for new windows is to not assign any group. By enabling sticky group mode, .Xr cwm 1 will assign new windows to the currently selected group. +.Pp +.It Ic unbind-key Ar key +Unbind function bound to +.Ar key . +A special +.Ar key +keyword +.Dq all +can be used to unbind all keys. +.Pp +.It Ic unbind-mouse Ar button +Unbind function bound to +.Ar button . +A special +.Ar button +keyword +.Dq all +can be used to unbind all buttons. +.Pp .El -.Sh BIND COMMAND LIST -.Bl -tag -width 18n -compact +.Sh BIND FUNCTION LIST +.Bl -tag -width 23n -compact .It restart Restart the running .Xr cwm 1 . @@ -247,197 +259,176 @@ Quit Spawn a new terminal. .It lock Lock the screen. -.It search +.It menu-window Launch window search menu. -.It menusearch +.It menu-window-hidden +Launch hidden window search menu. +.It menu-cmd Launch application search menu. -.It groupsearch +.It menu-group Launch group search menu. -.It exec +.It menu-exec Launch .Dq exec program menu. -.It exec_wm +.It menu-exec-wm Launch .Dq exec WindowManager menu. -.It ssh +.It menu-ssh Launch .Dq ssh menu. -.It group[n] +.It group-toggle-[n] Toggle visibility of group n, where n is 1-9. -.It grouponly[n] -Like -.Ar group[n] -but also hides the other groups. -.It nogroup +.It group-only-[n] +Show only group n, where n is 1-9, hiding other groups. +.It window-toggle-all Toggle visibility of all groups. -.It grouptoggle +.It window-group Toggle group membership of current window. -.It movetogroup[n] +.It window-movetogroup-[n] Hide current window from display and move to group n, where n is 1-9. -.It cyclegroup +.It group-cycle Forward cycle through groups. -.It rcyclegroup +.It group-rcycle Reverse cycle through groups. -.It cycle +.It window-cycle Forward cycle through windows. -.It rcycle +.It window-rcycle Reverse cycle through windows. -.It cycleingroup +.It window-cycle-ingroup Forward cycle through windows in current group. -.It rcycleingroup +.It window-rcycle-ingroup Reverse cycle through windows in current group. -.It delete +.It window-delete Delete current window. -.It hide +.It window-hide Hide current window. -.It lower +.It window-lower Lower current window. -.It raise +.It window-raise Raise current window. -.It label +.It window-menu-label Label current window. -.It freeze +.It window-freeze Freeze current window geometry. -.It stick +.It window-stick Stick current window to all groups (same as assigning to nogroup). -.It fullscreen +.It window-fullscreen Full-screen current window (gap + border removed). -.It maximize +.It window-maximize Maximize current window (gap + border honored). -.It vmaximize +.It window-vmaximize Vertically maximize current window (gap + border honored). -.It hmaximize +.It window-hmaximize Horizontally maximize current window (gap + border honored). -.It moveup +.It window-htile +Current window is placed at the top of the screen and maximized +horizontally, other windows in its group share remaining screen space. +.It window-vtile +Current window is placed on the left of the screen and maximized +vertically, other windows in its group share remaining screen space. +.It window-move +Move current window. +.It window-resize +Resize current window. +.It window-move-up Move window .Ar moveamount pixels up. -.It movedown +.It window-move-down Move window .Ar moveamount pixels down. -.It moveright +.It window-move-right Move window .Ar moveamount pixels right. -.It moveleft +.It window-move-left Move window .Ar moveamount pixels left. -.It bigmoveup +.It window-move-up-big Move window 10 times .Ar moveamount pixels up. -.It bigmovedown +.It window-move-down-big Move window 10 times .Ar moveamount pixels down. -.It bigmoveright +.It window-move-right-big Move window 10 times .Ar moveamount pixels right. -.It bigmoveleft +.It window-move-left-big Move window 10 times .Ar moveamount pixels left. -.It resizeup +.It window-resize-up Resize window .Ar moveamount pixels up. -.It resizedown +.It window-resize-down Resize window .Ar moveamount pixels down. -.It resizeright +.It window-resize-right Resize window .Ar moveamount pixels right. -.It resizeleft +.It window-resize-left Resize window .Ar moveamount pixels left. -.It bigresizeup +.It window-resize-up-big Resize window 10 times .Ar moveamount pixels up. -.It bigresizedown +.It window-resize-down-big Resize window 10 times .Ar moveamount pixels down. -.It bigresizeright +.It window-resize-right-big Resize window 10 times .Ar moveamount pixels right. -.It bigresizeleft +.It window-resize-left-big Resize window 10 times .Ar moveamount pixels left. -.It ptrmoveup +.It pointer-move-up Move pointer .Ar moveamount pixels up. -.It ptrmovedown +.It pointer-move-down Move pointer .Ar moveamount pixels down. -.It ptrmoveright +.It pointer-move-right Move pointer .Ar moveamount pixels right. -.It ptrmoveleft +.It pointer-move-left Move pointer .Ar moveamount pixels left. -.It bigptrmoveup +.It pointer-move-up-big Move pointer 10 times .Ar moveamount pixels up. -.It bigptrmovedown +.It pointer-move-down-big Move pointer 10 times .Ar moveamount pixels down. -.It bigptrmoveright +.It pointer-move-right-big Move pointer 10 times .Ar moveamount pixels right. -.It bigptrmoveleft +.It pointer-move-left-big Move pointer 10 times .Ar moveamount pixels left. -.It htile -Current window is placed at the top of the screen and maximized -horizontally, other windows in its group share remaining screen space. -.It vtile -Current window is placed on the left of the screen and maximized -vertically, other windows in its group share remaining screen space. -.El -.Sh MOUSEBIND COMMAND LIST -.Bl -tag -width 18n -compact -.It window_move -Move current window. -.It window_resize -Resize current window. -.It window_lower -Lower current window. -.It window_raise -Raise current window. -.It window_hide -Hide current window. -.It window_grouptoggle -Toggle group membership of current window. -.It cyclegroup -Forward cycle through groups. -.It rcyclegroup -Reverse cycle through groups. -.It menu_group -Launch group list. -.It menu_unhide -Launch hidden window list. -.It menu_cmd -Launch command list. .El .Sh FILES .Bl -tag -width "~/.cwmrcXXX" -compact @@ -470,23 +461,23 @@ ignore xapm ignore xclock # Key bindings -bind CM-r label -bind CS-Return "xterm -e top" -bind 4-o unmap -bind CM-equal unmap -bind CMS-equal unmap -bind C4-equal vmaximize -bind C4S-equal hmaximize -bind M-1 grouponly1 -bind M-2 grouponly2 -bind M-3 grouponly3 -bind MS-1 movetogroup1 -bind MS-2 movetogroup2 -bind MS-3 movetogroup3 +bind-key CM-r window-menu-label +bind-key CS-Return "xterm -e top" +bind-key C4-equal window-vmaximize +bind-key C4S-equal window-hmaximize +bind-key M-1 group-only-1 +bind-key M-2 group-only-2 +bind-key M-3 group-only-3 +bind-key MS-1 window-movetogroup-1 +bind-key MS-2 window-movetogroup-2 +bind-key MS-3 window-movetogroup-3 +unbind-key 4-o +unbind-key CM-equal +unbind-key CMS-equal # Mouse bindings -mousebind M-2 window_lower -mousebind M-3 window_resize +bind-mouse M-2 window-lower +bind-mouse M-3 window-resize .Ed .Sh SEE ALSO .Xr cwm 1 diff --git a/kbfunc.c b/kbfunc.c index 5f5a163..5edb59d 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -298,12 +298,13 @@ kbfunc_menu_client(void *ctx, union arg *arg, enum xev xev) struct menu *mi; struct menu_q menuq; int m = (xev == CWM_XEV_BTN); + int all = (arg->i & CWM_MENU_WINDOW_ALL); old_cc = client_current(); TAILQ_INIT(&menuq); TAILQ_FOREACH(cc, &sc->clientq, entry) { - if (m) { + if (!all) { if (cc->flags & CLIENT_HIDDEN) menuq_add(&menuq, cc, NULL); } else @@ -390,6 +391,7 @@ kbfunc_menu_exec(void *ctx, union arg *arg, enum xev xev) struct screen_ctx *sc = ctx; char **ap, *paths[NPATHS], *path, *pathcpy; char tpath[PATH_MAX]; + struct stat sb; const char *label; DIR *dirp; struct dirent *dp; @@ -432,12 +434,13 @@ kbfunc_menu_exec(void *ctx, union arg *arg, enum xev xev) dp->d_name); if (l == -1 || l >= sizeof(tpath)) continue; - /* skip everything but regular files and symlinks */ + /* Skip everything but regular files and symlinks. */ if (dp->d_type != DT_REG && dp->d_type != DT_LNK) { - /* use an additional stat-based check in case d_type isn't supported */ - if (lstat(tpath, &sb) < 0) + /* lstat(2) in case d_type isn't supported. */ + if (lstat(tpath, &sb) == -1) continue; - if (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode)) + if (!S_ISREG(sb.st_mode) && + !S_ISLNK(sb.st_mode)) continue; } if (access(tpath, X_OK) == 0) @@ -449,7 +452,7 @@ kbfunc_menu_exec(void *ctx, union arg *arg, enum xev xev) if ((mi = menu_filter(sc, &menuq, label, NULL, (CWM_MENU_DUMMY | CWM_MENU_FILE), - search_match_exec_path, NULL)) != NULL) { + search_match_exec, search_print_text)) != NULL) { if (mi->text[0] == '\0') goto out; switch (cmd) { @@ -518,13 +521,13 @@ kbfunc_menu_ssh(void *ctx, union arg *arg, enum xev xev) if (p - buf + 1 > sizeof(hostbuf)) continue; (void)strlcpy(hostbuf, buf, p - buf + 1); - menuq_add(&menuq, NULL, hostbuf); + menuq_add(&menuq, NULL, "%s", hostbuf); } free(lbuf); (void)fclose(fp); menu: if ((mi = menu_filter(sc, &menuq, "ssh", NULL, (CWM_MENU_DUMMY), - search_match_exec, NULL)) != NULL) { + search_match_text, search_print_text)) != NULL) { if (mi->text[0] == '\0') goto out; l = snprintf(path, sizeof(path), "%s -T '[ssh] %s' -e ssh %s", @@ -550,7 +553,7 @@ kbfunc_menu_client_label(void *ctx, union arg *arg, enum xev xev) /* dummy is set, so this will always return */ mi = menu_filter(cc->sc, &menuq, "label", cc->label, (CWM_MENU_DUMMY), - search_match_text, NULL); + search_match_text, search_print_text); if (!mi->abort) { free(cc->label); diff --git a/menu.c b/menu.c index 44f76da..af13cbf 100644 --- a/menu.c +++ b/menu.c @@ -126,7 +126,6 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt, CurrentTime) != GrabSuccess) { XUnmapWindow(X_Dpy, sc->menu.win); return(NULL); - } XGetInputFocus(X_Dpy, &focuswin, &focusrevert); @@ -196,7 +195,7 @@ menu_complete_path(struct menu_ctx *mc) TAILQ_INIT(&menuq); if ((mi = menu_filter(sc, &menuq, mc->searchstr, NULL, - (CWM_MENU_DUMMY), search_match_path_any, NULL)) != NULL) { + (CWM_MENU_DUMMY), search_match_path, search_print_text)) != NULL) { mr->abort = mi->abort; mr->dummy = mi->dummy; if (mi->text[0] != '\0') @@ -366,11 +365,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq) } TAILQ_FOREACH(mi, resultq, resultentry) { - if (mc->print != NULL) - (*mc->print)(mi, mc->listing); - else - (void)snprintf(mi->print, sizeof(mi->print), - "%s", mi->text); + (*mc->print)(mi, mc->listing); XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)mi->print, @@ -671,4 +666,3 @@ menu_windraw(struct screen_ctx *sc, Window win, const char *fmt, ...) free(text); } - diff --git a/mousefunc.c b/mousefunc.c index dbec420..0926506 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -53,6 +53,8 @@ mousefunc_client_resize(void *ctx, union arg *arg, enum xev xev) CurrentTime) != GrabSuccess) return; + menu_windraw(sc, cc->win, "%4d x %-4d", cc->dim.w, cc->dim.h); + for (;;) { XWindowEvent(X_Dpy, cc->win, MOUSEMASK, &ev); @@ -120,6 +122,8 @@ mousefunc_client_move(void *ctx, union arg *arg, enum xev xev) CurrentTime) != GrabSuccess) return; + menu_windraw(sc, cc->win, "%4d, %-4d", cc->geom.x, cc->geom.y); + for (;;) { XWindowEvent(X_Dpy, cc->win, MOUSEMASK, &ev); diff --git a/parse.y b/parse.y index abd3224..c8942d9 100644 --- a/parse.y +++ b/parse.y @@ -70,8 +70,9 @@ typedef struct { %} -%token FONTNAME STICKY GAP MOUSEBIND -%token AUTOGROUP BIND COMMAND IGNORE +%token BINDKEY UNBINDKEY BINDMOUSE UNBINDMOUSE +%token FONTNAME STICKY GAP +%token AUTOGROUP COMMAND IGNORE %token YES NO BORDERWIDTH MOVEAMOUNT %token COLOR SNAPDIST %token ACTIVEBORDER INACTIVEBORDER URGENCYBORDER @@ -171,16 +172,6 @@ main : FONTNAME STRING { conf_ignore(conf, $2); free($2); } - | BIND STRING string { - if (!conf_bind_kbd(conf, $2, $3)) { - yyerror("invalid bind: %s %s", $2, $3); - free($2); - free($3); - YYERROR; - } - free($2); - free($3); - } | GAP NUMBER NUMBER NUMBER NUMBER { if ($2 < 0 || $2 > INT_MAX || $3 < 0 || $3 > INT_MAX || @@ -194,9 +185,27 @@ main : FONTNAME STRING { conf->gap.left = $4; conf->gap.right = $5; } - | MOUSEBIND STRING string { + | BINDKEY STRING string { + if (!conf_bind_key(conf, $2, $3)) { + yyerror("invalid bind-key: %s %s", $2, $3); + free($2); + free($3); + YYERROR; + } + free($2); + free($3); + } + | UNBINDKEY STRING { + if (!conf_bind_key(conf, $2, NULL)) { + yyerror("invalid unbind-key: %s", $2); + free($2); + YYERROR; + } + free($2); + } + | BINDMOUSE STRING string { if (!conf_bind_mouse(conf, $2, $3)) { - yyerror("invalid mousebind: %s %s", $2, $3); + yyerror("invalid bind-mouse: %s %s", $2, $3); free($2); free($3); YYERROR; @@ -204,6 +213,14 @@ main : FONTNAME STRING { free($2); free($3); } + | UNBINDMOUSE STRING { + if (!conf_bind_mouse(conf, $2, NULL)) { + yyerror("invalid unbind-mouse: %s", $2); + free($2); + YYERROR; + } + free($2); + } ; color : COLOR colors @@ -280,7 +297,8 @@ lookup(char *s) static const struct keywords keywords[] = { { "activeborder", ACTIVEBORDER}, { "autogroup", AUTOGROUP}, - { "bind", BIND}, + { "bind-key", BINDKEY}, + { "bind-mouse", BINDMOUSE}, { "borderwidth", BORDERWIDTH}, { "color", COLOR}, { "command", COMMAND}, @@ -292,12 +310,13 @@ lookup(char *s) { "inactiveborder", INACTIVEBORDER}, { "menubg", MENUBG}, { "menufg", MENUFG}, - { "mousebind", MOUSEBIND}, { "moveamount", MOVEAMOUNT}, { "no", NO}, { "selfont", FONTSELCOLOR}, { "snapdist", SNAPDIST}, { "sticky", STICKY}, + { "unbind-key", UNBINDKEY}, + { "unbind-mouse", UNBINDMOUSE}, { "ungroupborder", UNGROUPBORDER}, { "urgencyborder", URGENCYBORDER}, { "yes", YES} diff --git a/search.c b/search.c index c1b3e3d..e50884a 100644 --- a/search.c +++ b/search.c @@ -36,10 +36,8 @@ #define PATH_ANY 0x0001 #define PATH_EXEC 0x0002 -static void search_match_path(struct menu_q *, struct menu_q *, +static void search_match_path_type(struct menu_q *, struct menu_q *, char *, int); -static void search_match_path_exec(struct menu_q *, struct menu_q *, - char *); static int strsubmatch(char *, char *, int); void @@ -107,7 +105,13 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search) } void -search_print_cmd(struct menu *mi, int i) +search_print_text(struct menu *mi, int listing) +{ + (void)snprintf(mi->print, sizeof(mi->print), "%s", mi->text); +} + +void +search_print_cmd(struct menu *mi, int listing) { struct cmd_ctx *cmd = (struct cmd_ctx *)mi->ctx; @@ -115,7 +119,7 @@ search_print_cmd(struct menu *mi, int i) } void -search_print_group(struct menu *mi, int i) +search_print_group(struct menu *mi, int listing) { struct group_ctx *gc = (struct group_ctx *)mi->ctx; @@ -125,7 +129,7 @@ search_print_group(struct menu *mi, int i) } void -search_print_client(struct menu *mi, int list) +search_print_client(struct menu *mi, int listing) { struct client_ctx *cc = (struct client_ctx *)mi->ctx; char flag = ' '; @@ -141,7 +145,8 @@ search_print_client(struct menu *mi, int list) } static void -search_match_path(struct menu_q *menuq, struct menu_q *resultq, char *search, int flag) +search_match_path_type(struct menu_q *menuq, struct menu_q *resultq, + char *search, int flag) { char pattern[PATH_MAX]; glob_t g; @@ -162,16 +167,10 @@ search_match_path(struct menu_q *menuq, struct menu_q *resultq, char *search, in globfree(&g); } -static void -search_match_path_exec(struct menu_q *menuq, struct menu_q *resultq, char *search) -{ - return(search_match_path(menuq, resultq, search, PATH_EXEC)); -} - void -search_match_path_any(struct menu_q *menuq, struct menu_q *resultq, char *search) +search_match_path(struct menu_q *menuq, struct menu_q *resultq, char *search) { - return(search_match_path(menuq, resultq, search, PATH_ANY)); + return(search_match_path_type(menuq, resultq, search, PATH_ANY)); } void @@ -208,14 +207,9 @@ search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search) if (mj == NULL) TAILQ_INSERT_TAIL(resultq, mi, resultentry); } -} -void -search_match_exec_path(struct menu_q *menuq, struct menu_q *resultq, char *search) -{ - search_match_exec(menuq, resultq, search); if (TAILQ_EMPTY(resultq)) - search_match_path_exec(menuq, resultq, search); + search_match_path_type(menuq, resultq, search, PATH_EXEC); } static int |