We've been handling grabbing wrong all this time (noticed at c2k8).

add conf_grab() and conf_ungrab, and use them in the keybinding manipulation
functions to {,un}grab the binding for all screens we have defined.

the lovely little ordering problem comes in here, since when we parse
the config initially Screenq is empty, so regrab after we fill the
queue, hopefully later reordering will remove this little need and there
will be much rejoicing.

ok okan.
This commit is contained in:
oga 2008-07-22 20:51:54 +00:00
parent 436a9e5c54
commit 0df9e0673c
3 changed files with 48 additions and 5 deletions

View File

@ -127,6 +127,7 @@ void
x_setup(void)
{
struct screen_ctx *sc;
struct keybinding *kb;
int i;
Nscreens = ScreenCount(X_Dpy);
@ -136,6 +137,14 @@ x_setup(void)
TAILQ_INSERT_TAIL(&Screenq, sc, entry);
}
/*
* XXX key grabs weren't done before, since Screenq was empty,
* do them here for now (this needs changing).
*/
TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
conf_grab(&Conf, kb);
Cursor_move = XCreateFontCursor(X_Dpy, XC_fleur);
Cursor_resize = XCreateFontCursor(X_Dpy, XC_bottom_right_corner);
Cursor_select = XCreateFontCursor(X_Dpy, XC_hand1);
@ -151,7 +160,6 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
Window *wins, w0, w1;
XWindowAttributes winattr;
XSetWindowAttributes rootattr;
struct keybinding *kb;
u_int nwins, i;
Curscreen = sc;
@ -178,9 +186,6 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
"black", &sc->blackcolor, &tmp);
TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
xu_key_grab(sc->rootwin, kb->modmask, kb->keysym);
sc->blackpixl = BlackPixel(X_Dpy, sc->which);
sc->whitepixl = WhitePixel(X_Dpy, sc->which);
sc->bluepixl = sc->fccolor.pixel;

View File

@ -419,6 +419,8 @@ void screen_updatestackingorder(void);
void conf_setup(struct conf *, const char *);
void conf_client(struct client_ctx *);
void conf_grab(struct conf *, struct keybinding *);
void conf_ungrab(struct conf *, struct keybinding *);
void conf_bindname(struct conf *, char *, char *);
void conf_unbind(struct conf *, struct keybinding *);
void conf_mousebind(struct conf *, char *, char *);

38
conf.c
View File

@ -290,6 +290,38 @@ struct {
{ NULL, NULL, 0, 0},
};
/*
* The following two functions are used when grabbing and ungrabbing keys for
* bindings
*/
/*
* Grab key combination on all screens and add to the global queue
*/
void
conf_grab(struct conf *c, struct keybinding *kb)
{
extern struct screen_ctx_q Screenq;
struct screen_ctx *sc;
TAILQ_FOREACH(sc, &Screenq, entry)
xu_key_grab(sc->rootwin, kb->modmask, kb->keysym);
}
/*
* Ungrab key combination from all screens and remove from global queue
*/
void
conf_ungrab(struct conf *c, struct keybinding *kb)
{
extern struct screen_ctx_q Screenq;
struct screen_ctx *sc;
TAILQ_FOREACH(sc, &Screenq, entry)
xu_key_ungrab(sc->rootwin, kb->modmask, kb->keysym);
}
void
conf_bindname(struct conf *c, char *name, char *binding)
{
@ -349,6 +381,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
current_binding->callback = name_to_kbfunc[iter].handler;
current_binding->flags = name_to_kbfunc[iter].flags;
current_binding->argument = name_to_kbfunc[iter].argument;
conf_grab(c, current_binding);
TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
return;
}
@ -356,11 +389,13 @@ conf_bindname(struct conf *c, char *name, char *binding)
current_binding->callback = kbfunc_cmdexec;
current_binding->argument = xstrdup(binding);
current_binding->flags = 0;
conf_grab(c, current_binding);
TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
return;
}
void conf_unbind(struct conf *c, struct keybinding *unbind)
void
conf_unbind(struct conf *c, struct keybinding *unbind)
{
struct keybinding *key = NULL, *keynxt;
@ -374,6 +409,7 @@ void conf_unbind(struct conf *c, struct keybinding *unbind)
if ((key->keycode != 0 && key->keysym == NoSymbol &&
key->keycode == unbind->keycode) ||
key->keysym == unbind->keysym) {
conf_ungrab(c, key);
TAILQ_REMOVE(&c->keybindingq, key, entry);
xfree(key);
}