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).
This commit is contained in:
Christian Neukirchen 2016-12-16 13:42:52 +01:00
commit 775ba78311
10 changed files with 685 additions and 706 deletions

View File

@ -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 *);

View File

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

794
conf.c
View File

@ -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,55 +611,17 @@ 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)
{
unsigned int i;
for (i = 0; i < nitems(cursor_binds); i++)
c->cursor[i] = XCreateFontCursor(X_Dpy, cursor_binds[i]);
}
static unsigned int ign_mods[] = { 0, LockMask, Mod2Mask, Mod2Mask | LockMask };
void
conf_grab_mouse(Window win)
{
struct bind_ctx *mb;
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++) {
XGrabButton(X_Dpy, mb->press.button,
(mb->modmask | ign_mods[i]), win, False,
BUTTONMASK, GrabModeAsync, GrabModeSync,
None, None);
}
}
}
void
conf_grab_kbd(Window win)
{
@ -679,12 +637,32 @@ conf_grab_kbd(Window win)
(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,
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;
XUngrabButton(X_Dpy, AnyButton, AnyModifier, win);
TAILQ_FOREACH(mb, &Conf.mousebindq, entry) {
if (mb->context != CWM_CONTEXT_CC)
continue;
for (i = 0; i < nitems(ignore_mods); i++) {
XGrabButton(X_Dpy, mb->press.button,
(mb->modmask | ignore_mods[i]), win, False,
BUTTONMASK, GrabModeAsync, GrabModeSync,
None, None);
}
}
}
static char *cwmhints[] = {
"WM_STATE",
"WM_DELETE_WINDOW",

9
cwm.1
View File

@ -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.

447
cwmrc.5
View File

@ -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
Move window
.Ar moveamount
pixels up.
.It movedown
Move window
.Ar moveamount
pixels down.
.It moveright
Move window
.Ar moveamount
pixels right.
.It moveleft
Move window
.Ar moveamount
pixels left.
.It bigmoveup
Move window 10 times
.Ar moveamount
pixels up.
.It bigmovedown
Move window 10 times
.Ar moveamount
pixels down.
.It bigmoveright
Move window 10 times
.Ar moveamount
pixels right.
.It bigmoveleft
Move window 10 times
.Ar moveamount
pixels left.
.It resizeup
Resize window
.Ar moveamount
pixels up.
.It resizedown
Resize window
.Ar moveamount
pixels down.
.It resizeright
Resize window
.Ar moveamount
pixels right.
.It resizeleft
Resize window
.Ar moveamount
pixels left.
.It bigresizeup
Resize window 10 times
.Ar moveamount
pixels up.
.It bigresizedown
Resize window 10 times
.Ar moveamount
pixels down.
.It bigresizeright
Resize window 10 times
.Ar moveamount
pixels right.
.It bigresizeleft
Resize window 10 times
.Ar moveamount
pixels left.
.It ptrmoveup
Move pointer
.Ar moveamount
pixels up.
.It ptrmovedown
Move pointer
.Ar moveamount
pixels down.
.It ptrmoveright
Move pointer
.Ar moveamount
pixels right.
.It ptrmoveleft
Move pointer
.Ar moveamount
pixels left.
.It bigptrmoveup
Move pointer 10 times
.Ar moveamount
pixels up.
.It bigptrmovedown
Move pointer 10 times
.Ar moveamount
pixels down.
.It bigptrmoveright
Move pointer 10 times
.Ar moveamount
pixels right.
.It bigptrmoveleft
Move pointer 10 times
.Ar moveamount
pixels left.
.It htile
.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 vtile
.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.
.El
.Sh MOUSEBIND COMMAND LIST
.Bl -tag -width 18n -compact
.It window_move
.It window-move
Move current window.
.It window_resize
.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.
.It window-move-up
Move window
.Ar moveamount
pixels up.
.It window-move-down
Move window
.Ar moveamount
pixels down.
.It window-move-right
Move window
.Ar moveamount
pixels right.
.It window-move-left
Move window
.Ar moveamount
pixels left.
.It window-move-up-big
Move window 10 times
.Ar moveamount
pixels up.
.It window-move-down-big
Move window 10 times
.Ar moveamount
pixels down.
.It window-move-right-big
Move window 10 times
.Ar moveamount
pixels right.
.It window-move-left-big
Move window 10 times
.Ar moveamount
pixels left.
.It window-resize-up
Resize window
.Ar moveamount
pixels up.
.It window-resize-down
Resize window
.Ar moveamount
pixels down.
.It window-resize-right
Resize window
.Ar moveamount
pixels right.
.It window-resize-left
Resize window
.Ar moveamount
pixels left.
.It window-resize-up-big
Resize window 10 times
.Ar moveamount
pixels up.
.It window-resize-down-big
Resize window 10 times
.Ar moveamount
pixels down.
.It window-resize-right-big
Resize window 10 times
.Ar moveamount
pixels right.
.It window-resize-left-big
Resize window 10 times
.Ar moveamount
pixels left.
.It pointer-move-up
Move pointer
.Ar moveamount
pixels up.
.It pointer-move-down
Move pointer
.Ar moveamount
pixels down.
.It pointer-move-right
Move pointer
.Ar moveamount
pixels right.
.It pointer-move-left
Move pointer
.Ar moveamount
pixels left.
.It pointer-move-up-big
Move pointer 10 times
.Ar moveamount
pixels up.
.It pointer-move-down-big
Move pointer 10 times
.Ar moveamount
pixels down.
.It pointer-move-right-big
Move pointer 10 times
.Ar moveamount
pixels right.
.It pointer-move-left-big
Move pointer 10 times
.Ar moveamount
pixels left.
.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

View File

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

10
menu.c
View File

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

View File

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

53
parse.y
View File

@ -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,9 @@ main : FONTNAME STRING {
conf->gap.left = $4;
conf->gap.right = $5;
}
| MOUSEBIND STRING string {
if (!conf_bind_mouse(conf, $2, $3)) {
yyerror("invalid mousebind: %s %s", $2, $3);
| BINDKEY STRING string {
if (!conf_bind_key(conf, $2, $3)) {
yyerror("invalid bind-key: %s %s", $2, $3);
free($2);
free($3);
YYERROR;
@ -204,6 +195,32 @@ main : FONTNAME STRING {
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 bind-mouse: %s %s", $2, $3);
free($2);
free($3);
YYERROR;
}
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}

View File

@ -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