diff options
author | okan | 2008-06-14 21:48:54 +0000 |
---|---|---|
committer | okan | 2008-06-14 21:48:54 +0000 |
commit | c13dbbd835133e5160bdeefa8251adef63c56a9e (patch) | |
tree | 7839e98d228f6339db838ea006fa49f539d18763 | |
parent | b41388716ed8af14f5165df937627ad66200a0b5 (diff) | |
download | cwm-c13dbbd835133e5160bdeefa8251adef63c56a9e.tar.gz |
confable menu and window mouse bindings from rivo nurges (thanks!) with
some minor fixups, man page bits and knf.
ok oga@
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | calmwm.h | 26 | ||||
-rw-r--r-- | conf.c | 90 | ||||
-rw-r--r-- | cwmrc.5 | 63 | ||||
-rw-r--r-- | mousefunc.c | 126 | ||||
-rw-r--r-- | parse.y | 22 | ||||
-rw-r--r-- | xevents.c | 111 |
7 files changed, 335 insertions, 107 deletions
@@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.7 2008/05/20 14:50:51 oga Exp $ +# $OpenBSD: Makefile,v 1.8 2008/06/14 21:48:54 okan Exp $ .include <bsd.xconf.mk> @@ -6,7 +6,7 @@ PROG= cwm SRCS= calmwm.c screen.c xmalloc.c client.c grab.c menu.c \ search.c util.c xutil.c conf.c input.c xevents.c group.c \ - kbfunc.c font.c parse.y + kbfunc.c mousefunc.c font.c parse.y CPPFLAGS+= -I${X11BASE}/include -I${X11BASE}/include/freetype2 -I${.CURDIR} @@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: calmwm.h,v 1.51 2008/06/12 19:10:56 okan Exp $ + * $Id: calmwm.h,v 1.52 2008/06/14 21:48:54 okan Exp $ */ #ifndef _CALMWM_H_ @@ -249,8 +249,20 @@ struct cmd { /* (argv) */ }; +struct mousebinding { + int modmask; + int button; + int context; + void (*callback)(struct client_ctx *, void *); + TAILQ_ENTRY(mousebinding) entry; +}; + +#define MOUSEBIND_CTX_ROOT 1 +#define MOUSEBIND_CTX_WIN 2 + TAILQ_HEAD(keybinding_q, keybinding); TAILQ_HEAD(cmd_q, cmd); +TAILQ_HEAD(mousebinding_q, mousebinding); /* Global configuration */ struct conf { @@ -259,6 +271,7 @@ struct conf { struct winmatch_q ignoreq; char conf_path[MAXPATHLEN]; struct cmd_q cmdq; + struct mousebinding_q mousebindingq; #define CONF_STICKY_GROUPS 0x0001 int flags; @@ -424,6 +437,8 @@ void conf_setup(struct conf *, const char *); void conf_client(struct client_ctx *); void conf_bindname(struct conf *, char *, char *); void conf_unbind(struct conf *, struct keybinding *); +void conf_mousebind(struct conf *, char *, char *); +void conf_mouseunbind(struct conf *, struct mousebinding *); int conf_changed(char *); void conf_reload(struct conf *); @@ -450,6 +465,15 @@ void kbfunc_ssh(struct client_ctx *, void *); void kbfunc_term(struct client_ctx *, void *); void kbfunc_lock(struct client_ctx *, void *); +void mousefunc_window_resize(struct client_ctx *, void *); +void mousefunc_window_move(struct client_ctx *, void *); +void mousefunc_window_grouptoggle(struct client_ctx *, + void *); +void mousefunc_window_lower(struct client_ctx *, void *); +void mousefunc_menu_group(struct client_ctx *, void *); +void mousefunc_menu_unhide(struct client_ctx *, void *); +void mousefunc_menu_cmd(struct client_ctx *, void *); + void search_match_client(struct menu_q *, struct menu_q *, char *); void search_print_client(struct menu *, int); @@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: conf.c,v 1.36 2008/06/05 00:07:05 okan Exp $ + * $Id: conf.c,v 1.37 2008/06/14 21:48:54 okan Exp $ */ #include "headers.h" @@ -90,6 +90,7 @@ conf_init(struct conf *c) TAILQ_INIT(&c->cmdq); TAILQ_INIT(&c->keybindingq); TAILQ_INIT(&c->autogroupq); + TAILQ_INIT(&c->mousebindingq); conf_bindname(c, "CM-Return", "terminal"); conf_bindname(c, "CM-Delete", "lock"); @@ -149,6 +150,14 @@ conf_init(struct conf *c) conf_bindname(c, "CS-Up", "bigptrmoveup"); conf_bindname(c, "CS-Right", "bigptrmoveright"); + conf_mousebind(c, "1", "menu_unhide"); + conf_mousebind(c, "2", "menu_group"); + conf_mousebind(c, "3", "menu_cmd"); + conf_mousebind(c, "M-1", "window_move"); + conf_mousebind(c, "CM-1", "window_grouptoggle"); + conf_mousebind(c, "M-2", "window_resize"); + conf_mousebind(c, "M-3", "window_lower"); + /* Default term/lock */ strlcpy(c->termpath, "xterm", sizeof(c->termpath)); strlcpy(c->lockpath, "xlock", sizeof(c->lockpath)); @@ -379,3 +388,82 @@ void conf_unbind(struct conf *c, struct keybinding *unbind) } } } + +struct { + char *tag; + void (*handler)(struct client_ctx *, void *); + int context; +} name_to_mousefunc[] = { + { "window_move", mousefunc_window_move, MOUSEBIND_CTX_WIN }, + { "window_resize", mousefunc_window_resize, MOUSEBIND_CTX_WIN }, + { "window_grouptoggle", mousefunc_window_grouptoggle, + MOUSEBIND_CTX_WIN }, + { "window_lower", mousefunc_window_lower, MOUSEBIND_CTX_WIN }, + { "menu_group", mousefunc_menu_group, MOUSEBIND_CTX_ROOT }, + { "menu_unhide", mousefunc_menu_unhide, MOUSEBIND_CTX_ROOT }, + { "menu_cmd", mousefunc_menu_cmd, MOUSEBIND_CTX_ROOT }, + { NULL, NULL, 0 }, +}; + +void +conf_mousebind(struct conf *c, char *name, char *binding) +{ + int iter; + struct mousebinding *current_binding; + char *substring; + const char *errstr; + + XCALLOC(current_binding, struct mousebinding); + + if (strchr(name, 'C') != NULL && + strchr(name, 'C') < strchr(name, '-')) + current_binding->modmask |= ControlMask; + + if (strchr(name, 'M') != NULL && + strchr(name, 'M') < strchr(name, '-')) + current_binding->modmask |= Mod1Mask; + + substring = strchr(name, '-') + 1; + + if (strchr(name, '-') == NULL) + substring = name; + + current_binding->button = strtonum(substring); + if (errstr) + warnx("number of buttons is %s: %s", errstr, substring); + + conf_mouseunbind(c, current_binding); + + if (strcmp("unmap", binding) == 0) + return; + + for (iter = 0; name_to_mousefunc[iter].tag != NULL; iter++) { + if (strcmp(name_to_mousefunc[iter].tag, binding) != 0) + continue; + + current_binding->context = name_to_mousefunc[iter].context; + current_binding->callback = name_to_mousefunc[iter].handler; + TAILQ_INSERT_TAIL(&c->mousebindingq, current_binding, entry); + return; + } +} + +void +conf_mouseunbind(struct conf *c, struct mousebinding *unbind) +{ + struct mousebinding *mb = NULL, *mbnxt; + + for (mb = TAILQ_FIRST(&c->mousebindingq); + mb != TAILQ_END(&c->mousebindingq); mb = mbnxt) { + mbnxt = TAILQ_NEXT(mb, entry); + + if (mb->modmask != unbind->modmask) + continue; + + if (mb->button == unbind->button) { + TAILQ_REMOVE(&c->mousebindingq, mb, entry); + xfree(mb); + } + } +} + @@ -1,4 +1,4 @@ -.\" $OpenBSD: cwmrc.5,v 1.8 2008/06/13 21:22:34 okan Exp $ +.\" $OpenBSD: cwmrc.5,v 1.9 2008/06/14 21:48:54 okan Exp $ .\" .\" Copyright (c) 2004,2005 Marius Aamodt Eriksen <marius@monkey.org> .\" @@ -15,7 +15,7 @@ .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .\" The following requests are required for all man pages. -.Dd $Mdocdate: June 13 2008 $ +.Dd $Mdocdate: June 14 2008 $ .Dt CWMRC 5 .Os .Sh NAME @@ -130,6 +130,41 @@ where the user may wish to remain visible. Ignore drawing borders around a window with the name .Ar windowname . .Pp +.It Ic mousebind Ar buttons Ar command +Cause the creation of a mouse binding, or replacement of a default +mouse binding. +The modifier keys come first, followed by a +.Sq - . +.Pb +The following modifiers are recognised: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It C +The Control key. +.It M +The Meta key. +.El +.Pp +The +.Sq - +should be followed by number: +.Pb +.Bl -tag -width Ds -offset indent -compact +.Pp +.It 1 +Left mouse button. +.It 2 +Right mouse button. +.It 3 +Middle mouse button. +.El +.Pp +The +.Ar command +may be taken from the +.Sx MOUSEBIND COMMAND LIST +(see below). +.Pp .It Ic sticky Ic yes Ns \&| Ns Ic no Toggle sticky group mode. The default behavior for new windows is to not assign any group. @@ -161,9 +196,13 @@ ignore xapm ignore xclock # Keybindings -bind CM-r "label" +bind CM-r label bind CS-Return "xterm -e top" -bind 4-o "unmap" +bind 4-o unmap + +# Mousebindings +mousebind M-2 window_lower +mousebind M-3 window_resize .Ed .Sh BIND COMMAND LIST .Bl -tag -width 18n -compact @@ -267,6 +306,22 @@ move pointer 10 pixels right .It bigptrmoveleft move pointer 10 pixels left .El +.Sh MOUSEBIND COMMAND LIST +.Bl -tag -width 18n -compact +.It window_move +move a window +.It window_resize +resize a window +.It window_lower +lower a window +.It window_grouptoggle +.It menu_group +launch group list +.It menu_unhide +launch group list +.It menu_cmd +launch command list +.El .Sh FILES .Bl -tag -width "~/.cwmrcXXX" -compact .It Pa ~/.cwmrc diff --git a/mousefunc.c b/mousefunc.c new file mode 100644 index 0000000..d8619ac --- /dev/null +++ b/mousefunc.c @@ -0,0 +1,126 @@ +/* + * calmwm - the calm window manager + * + * Copyright (c) 2008 rivo nurges <rix@estpak.ee> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: mousefunc.c,v 1.1 2008/06/14 21:48:54 okan Exp $ + */ + +#include "headers.h" +#include "calmwm.h" + +void +mousefunc_window_resize(struct client_ctx *cc, void *arg) +{ + grab_sweep(cc); + client_resize(cc); +} + +void +mousefunc_window_move(struct client_ctx *cc, void *arg) +{ + grab_drag(cc); + client_move(cc); +} + +void +mousefunc_window_grouptoggle(struct client_ctx *cc, void *arg) +{ + group_sticky_toggle_enter(cc); +} + +void +mousefunc_window_lower(struct client_ctx *cc, void *arg) +{ + client_ptrsave(cc); + client_lower(cc); +} + +void +mousefunc_menu_group(struct client_ctx *cc, void *arg) +{ + group_menu(arg); +} + +void +mousefunc_menu_unhide(struct client_ctx *cc, void *arg) +{ + struct menu *mi; + struct menu_q menuq; + char *wname; + struct client_ctx *old_cc = client_current(); + + TAILQ_INIT(&menuq); + TAILQ_FOREACH(cc, &Clientq, entry) + if (cc->flags & CLIENT_HIDDEN) { + if (cc->label != NULL) + wname = cc->label; + else + wname = cc->name; + + if (wname == NULL) + continue; + + XCALLOC(mi, struct menu); + strlcpy(mi->text, wname, sizeof(mi->text)); + mi->ctx = cc; + TAILQ_INSERT_TAIL(&menuq, mi, entry); + } + + if (TAILQ_EMPTY(&menuq)) + return; + + mi = menu_filter(&menuq, NULL, NULL, 0, NULL, NULL); + if (mi != NULL) { + cc = (struct client_ctx *)mi->ctx; + client_unhide(cc); + + if (old_cc != NULL) + client_ptrsave(old_cc); + client_ptrwarp(cc); + } else + while ((mi = TAILQ_FIRST(&menuq)) != NULL) { + TAILQ_REMOVE(&menuq, mi, entry); + xfree(mi); + } +} + +void +mousefunc_menu_cmd(struct client_ctx *cc, void *arg) +{ + struct menu *mi; + struct menu_q menuq; + struct cmd *cmd; + conf_reload(&Conf); + + TAILQ_INIT(&menuq); + TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { + XCALLOC(mi, struct menu); + strlcpy(mi->text, cmd->label, sizeof(mi->text)); + mi->ctx = cmd; + TAILQ_INSERT_TAIL(&menuq, mi, entry); + } + if (TAILQ_EMPTY(&menuq)) + return; + + mi = menu_filter(&menuq, NULL, NULL, 0, NULL, NULL); + if (mi != NULL) + u_spawn(((struct cmd *)mi->ctx)->image); + else + while ((mi = TAILQ_FIRST(&menuq)) != NULL) { + TAILQ_REMOVE(&menuq, mi, entry); + xfree(mi); + } +} @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.9 2008/05/19 17:13:55 oga Exp $ */ +/* $OpenBSD: parse.y,v 1.10 2008/06/14 21:48:54 okan Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -66,7 +66,7 @@ typedef struct { %} -%token FONTNAME STICKY GAP +%token FONTNAME STICKY GAP MOUSEBIND %token AUTOGROUP BIND COMMAND IGNORE %token YES NO %token ERROR @@ -167,6 +167,11 @@ main : FONTNAME STRING { conf->gap_left = $4; conf->gap_right = $5; } + | MOUSEBIND STRING string { + conf_mousebind(conf, $2, $3); + free($2); + free($3); + } ; %% @@ -206,6 +211,7 @@ lookup(char *s) { "fontname", FONTNAME}, { "gap", GAP}, { "ignore", IGNORE}, + { "mousebind", MOUSEBIND}, { "no", NO}, { "sticky", STICKY}, { "yes", YES} @@ -469,6 +475,7 @@ conf_clear(struct conf *c) struct keybinding *kb; struct winmatch *wm; struct cmd *cmd; + struct mousebinding *mb; while (cmd = TAILQ_FIRST(&c->cmdq)) { TAILQ_REMOVE(&c->cmdq, cmd, entry); @@ -494,6 +501,11 @@ conf_clear(struct conf *c) free(wm); } + while (mb = TAILQ_FIRST(&c->mousebindingq)) { + TAILQ_REMOVE(&c->mousebindingq, mb, entry); + free(mb); + } + if (c->DefaultFontName != NULL && c->DefaultFontName != DEFAULTFONTNAME) free(c->DefaultFontName); @@ -529,6 +541,7 @@ parse_config(const char *filename, struct conf *xconf) struct keybinding *kb; struct winmatch *wm; struct cmd *cmd; + struct mousebinding *mb; conf_clear(xconf); @@ -554,6 +567,11 @@ parse_config(const char *filename, struct conf *xconf) TAILQ_INSERT_TAIL(&xconf->ignoreq, wm, entry); } + while (mb = TAILQ_FIRST(&conf->mousebindingq)) { + TAILQ_REMOVE(&conf->mousebindingq, mb, entry); + TAILQ_INSERT_TAIL(&xconf->mousebindingq, mb, entry); + } + strlcpy(xconf->termpath, conf->termpath, sizeof(xconf->termpath)); strlcpy(xconf->lockpath, conf->lockpath, @@ -15,7 +15,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: xevents.c,v 1.18 2008/06/13 03:41:58 oga Exp $ + * $Id: xevents.c,v 1.19 2008/06/14 21:48:54 okan Exp $ */ /* @@ -221,113 +221,30 @@ void xev_handle_buttonpress(struct xevent *xev, XEvent *ee) { XButtonEvent *e = &ee->xbutton; - struct client_ctx *cc, *old_cc = client_current(); + struct client_ctx *cc; struct screen_ctx *sc = screen_fromroot(e->root); char *wname; - int altcontrol = e->state == (ControlMask|Mod1Mask); + struct mousebinding *mb; cc = client_find(e->window); - if (sc->rootwin == e->window && !altcontrol) { - struct menu_q menuq; - struct menu *mi; - - /* XXXSIGH!!!! */ - if (e->button == Button2) { - group_menu(e); - goto out; - } - - TAILQ_INIT(&menuq); - - switch (e->button) { - case Button1: - TAILQ_FOREACH(cc, &Clientq, entry) { - if (cc->flags & CLIENT_HIDDEN) { - if (cc->label != NULL) - wname = cc->label; - else - wname = cc->name; - - if (wname == NULL) - continue; - - XCALLOC(mi, struct menu); - strlcpy(mi->text, - wname, sizeof(mi->text)); - mi->ctx = cc; - TAILQ_INSERT_TAIL(&menuq, mi, entry); - } - } - break; - case Button3: { - struct cmd *cmd; - conf_reload(&Conf); - TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { - XCALLOC(mi, struct menu); - strlcpy(mi->text, cmd->label, sizeof(mi->text)); - mi->ctx = cmd; - TAILQ_INSERT_TAIL(&menuq, mi, entry); - } - break; - } - default: - break; - } - - if (TAILQ_EMPTY(&menuq)) - goto out; - - mi = menu_filter(&menuq, NULL, NULL, 0, NULL, NULL); - if (mi == NULL) - goto cleanup; - - switch (e->button) { - case Button1: - cc = (struct client_ctx *)mi->ctx; - client_unhide(cc); - - if (old_cc != NULL) - client_ptrsave(old_cc); - client_ptrwarp(cc); - break; - case Button3: - u_spawn(((struct cmd *)mi->ctx)->image); - break; - default: - break; - } - - cleanup: - while ((mi = TAILQ_FIRST(&menuq)) != NULL) { - TAILQ_REMOVE(&menuq, mi, entry); - xfree(mi); + if (sc->rootwin == e->window) + TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) { + if(e->button!=mb->button || e->state!=mb->modmask || + mb->context!=MOUSEBIND_CTX_ROOT) + continue; + (*mb->callback)(cc, e); } - goto out; - } - if (cc == NULL || e->state == 0) goto out; - sc = CCTOSC(cc); + TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) { + if(e->button!=mb->button || e->state!=mb->modmask || + mb->context!=MOUSEBIND_CTX_WIN) + continue; - switch (e->button) { - case Button1: - if (altcontrol) - group_sticky_toggle_enter(cc); - else { - grab_drag(cc); - client_move(cc); - } - break; - case Button2: - grab_sweep(cc); - client_resize(cc); - break; - case Button3: - client_ptrsave(cc); - client_lower(cc); + (*mb->callback)(cc, NULL); break; } out: |