aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorokan2008-06-14 21:48:54 +0000
committerokan2008-06-14 21:48:54 +0000
commitc13dbbd835133e5160bdeefa8251adef63c56a9e (patch)
tree7839e98d228f6339db838ea006fa49f539d18763
parentb41388716ed8af14f5165df937627ad66200a0b5 (diff)
downloadcwm-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--Makefile4
-rw-r--r--calmwm.h26
-rw-r--r--conf.c90
-rw-r--r--cwmrc.563
-rw-r--r--mousefunc.c126
-rw-r--r--parse.y22
-rw-r--r--xevents.c111
7 files changed, 335 insertions, 107 deletions
diff --git a/Makefile b/Makefile
index 2fb5f2e..ba7ef30 100644
--- a/Makefile
+++ b/Makefile
@@ -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}
diff --git a/calmwm.h b/calmwm.h
index 00f6149..88f44a7 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -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);
diff --git a/conf.c b/conf.c
index 96dd723..be87f6e 100644
--- a/conf.c
+++ b/conf.c
@@ -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);
+ }
+ }
+}
+
diff --git a/cwmrc.5 b/cwmrc.5
index 07cc104..d8f87d7 100644
--- a/cwmrc.5
+++ b/cwmrc.5
@@ -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);
+ }
+}
diff --git a/parse.y b/parse.y
index 6219960..dd2a45b 100644
--- a/parse.y
+++ b/parse.y
@@ -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,
diff --git a/xevents.c b/xevents.c
index 926cdc3..5ab7d70 100644
--- a/xevents.c
+++ b/xevents.c
@@ -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: