Manage focus/client buttons grabbing

This commit is contained in:
Martin Duquesnoy 2011-09-02 18:46:27 +02:00
parent c1727da152
commit 350c789482
7 changed files with 117 additions and 23 deletions

View File

@ -6,6 +6,8 @@
#include "client.h" #include "client.h"
#include "util.h" #include "util.h"
#define CLIENT_MOUSE_MOD Mod1Mask
/** Send a ConfigureRequest event to the Client /** Send a ConfigureRequest event to the Client
* \param c Client pointer * \param c Client pointer
*/ */
@ -58,25 +60,59 @@ client_unmap(Client *c)
XUnmapWindow(W->dpy, c->win); XUnmapWindow(W->dpy, c->win);
} }
static void
client_grabbuttons(Client *c, bool focused)
{
int i, but[] = {Button1, Button2, Button3, Button4, Button5};
/* wmfs_numlockmask();*/
XUngrabButton(W->dpy, AnyButton, AnyModifier, c->win);
if(focused)
{
for(i = 0; i < LEN(but); ++i)
{
XGrabButton(W->dpy, but[i], CLIENT_MOUSE_MOD, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(W->dpy, but[i], CLIENT_MOUSE_MOD | LockMask, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(W->dpy, but[i], CLIENT_MOUSE_MOD | W->numlockmask, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(W->dpy, but[i], CLIENT_MOUSE_MOD | LockMask | W->numlockmask, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
}
return;
}
XGrabButton(W->dpy, AnyButton, AnyModifier, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
}
void void
client_focus(Client *c) client_focus(Client *c)
{ {
/* Unfocus selected */ /* Unfocus selected */
if(c->tag->sel && c->tag->sel != c) if(W->client && W->client != c)
{ {
XSetWindowBorder(W->dpy, c->win, 0xf0f0f0); XSetWindowBorder(W->dpy, W->client->win, 0xfF0000);
client_grabbuttons(W->client, false);
} }
/* Focus c */ /* Focus c */
if((c->tag->sel = c)) if((W->client = c))
{ {
c->tag->sel = c;
XSetWindowBorder(W->dpy, c->win, 0xffffff); XSetWindowBorder(W->dpy, c->win, 0xffffff);
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime); client_grabbuttons(c, true);
XRaiseWindow(W->dpy, c->win); XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
} }
/* Else, set input focus to root window */
else else
XSetInputFocus(W->dpy, W->root, RevertToPointerRoot, CurrentTime); XSetInputFocus(W->dpy, W->root, RevertToPointerRoot, CurrentTime);
@ -152,9 +188,11 @@ client_new(Window w, XWindowAttributes *wa)
/* C attributes */ /* C attributes */
c->win = w; c->win = w;
c->screen = W->screen; c->screen = W->screen;
c->tag = W->screen->seltag;
c->flags = 0; c->flags = 0;
/* Set tag */
tag_client(W->screen->seltag, c);
/* Geometry */ /* Geometry */
c->geo.x = wa->x; c->geo.x = wa->x;
c->geo.y = wa->y; c->geo.y = wa->y;
@ -166,16 +204,22 @@ client_new(Window w, XWindowAttributes *wa)
XSetWindowBorder(W->dpy, w, 0xffffff); XSetWindowBorder(W->dpy, w, 0xffffff);
XSetWindowBorderWidth(W->dpy, w, 1); XSetWindowBorderWidth(W->dpy, w, 1);
client_grabbuttons(c, false);
/* Attach */ /* Attach */
SLIST_INSERT_HEAD(&W->h.client, c, next); SLIST_INSERT_HEAD(&W->h.client, c, next);
XMoveResizeWindow(W->dpy, w,
c->screen->ugeo.x,
c->screen->ugeo.y,
c->screen->ugeo.w,
c->screen->ugeo.h);
client_map(c); client_map(c);
XMoveResizeWindow(W->dpy, w, c->geo.x, c->geo.y, c->geo.w, c->geo.h);
XRaiseWindow(W->dpy, w); XRaiseWindow(W->dpy, w);
client_focus(c);
client_configure(c); client_configure(c);
return c; return c;
@ -184,11 +228,22 @@ client_new(Window w, XWindowAttributes *wa)
void void
client_remove(Client *c) client_remove(Client *c)
{ {
Client *cc;
XGrabServer(W->dpy); XGrabServer(W->dpy);
XSetErrorHandler(wmfs_error_handler_dummy); XSetErrorHandler(wmfs_error_handler_dummy);
if(W->client == c)
client_focus(NULL);
SLIST_REMOVE(&W->h.client, c, Client, next); SLIST_REMOVE(&W->h.client, c, Client, next);
if(c->tag->sel == c)
c->tag->sel = SLIST_FIRST(&c->tag->clients);
tag_client(NULL, c);
XSync(W->dpy, False);
XUngrabServer(W->dpy); XUngrabServer(W->dpy);
XSetErrorHandler(wmfs_error_handler); XSetErrorHandler(wmfs_error_handler);

View File

@ -106,8 +106,8 @@ event_focusin(XEvent *e)
{ {
Client *c; Client *c;
if((c = W->screen->seltag->sel) && e->xfocus.window != c->win) if(W->client && e->xfocus.window != W->client->win)
client_focus(c); client_focus(W->client);
} }
static void static void

View File

@ -36,7 +36,6 @@ infobar_placement(Infobar *i, Barpos p)
i->geo = i->screen->ugeo; i->geo = i->screen->ugeo;
i->geo.h = i->theme->bars_width; i->geo.h = i->theme->bars_width;
/* Top */
switch(p) switch(p)
{ {
case BarTop: case BarTop:

View File

@ -6,6 +6,7 @@
#include "tag.h" #include "tag.h"
#include "util.h" #include "util.h"
#include "infobar.h" #include "infobar.h"
#include "client.h"
Tag* Tag*
tag_new(Scr33n *s, char *name) tag_new(Scr33n *s, char *name)
@ -29,9 +30,31 @@ tag_screen(Scr33n *s, Tag *t)
{ {
s->seltag = t; s->seltag = t;
client_focus(t->sel);
infobar_elem_screen_update(s, ElemTag); infobar_elem_screen_update(s, ElemTag);
} }
void
tag_client(Tag *t, Client *c)
{
/* Remove client from its previous tag */
if(c->tag)
{
SLIST_REMOVE(&c->tag->clients, c, Client, tnext);
if(c->tag->sel == c)
c->tag->sel = NULL;
}
/* Case of client remove, t = NULL */
if(!(c->tag = t))
return;
/* Insert in new tag list */
SLIST_INSERT_HEAD(&t->clients, c, tnext);
}
void void
uicb_tag_set(Uicb cmd) uicb_tag_set(Uicb cmd)

View File

@ -10,6 +10,7 @@
Tag *tag_new(Scr33n *s, char *name); Tag *tag_new(Scr33n *s, char *name);
void tag_screen(Scr33n *s, Tag *t); void tag_screen(Scr33n *s, Tag *t);
void tag_client(Tag *t, Client *c);
void tag_free(Scr33n *s); void tag_free(Scr33n *s);
void uicb_tag_set(Uicb cmd); void uicb_tag_set(Uicb cmd);
void uicb_tag_set_with_name(Uicb cmd); void uicb_tag_set_with_name(Uicb cmd);

View File

@ -57,6 +57,21 @@ wmfs_error_handler_dummy(Display *d, XErrorEvent *event)
return 0; return 0;
} }
void
wmfs_numlockmask(void)
{
int i, j;
XModifierKeymap *mm = XGetModifierMapping(W->dpy);
for(i = 0; i < 8; i++)
for(j = 0; j < mm->max_keypermod; ++j)
if(mm->modifiermap[i * mm->max_keypermod + j]
== XKeysymToKeycode(W->dpy, XK_Num_Lock))
W->numlockmask = (1 << i);
XFreeModifiermap(mm);
}
void void
wmfs_init_font(char *font, Theme *t) wmfs_init_font(char *font, Theme *t)
{ {
@ -121,14 +136,7 @@ wmfs_xinit(void)
/* /*
* Keys * Keys
*/ */
mm = XGetModifierMapping(W->dpy); wmfs_numlockmask();
for(i = 0; i < 8; i++)
for(j = 0; j < mm->max_keypermod; ++j)
if(mm->modifiermap[i * mm->max_keypermod + j]
== XKeysymToKeycode(W->dpy, XK_Num_Lock))
W->numlockmask = (1 << i);
XFreeModifiermap(mm);
/* /*
* Barwin linked list * Barwin linked list
@ -144,6 +152,8 @@ wmfs_grab_keys(void)
KeyCode c; KeyCode c;
Keybind *k; Keybind *k;
wmfs_numlockmask();
XUngrabKey(W->dpy, AnyKey, AnyModifier, W->root); XUngrabKey(W->dpy, AnyKey, AnyModifier, W->root);
SLIST_FOREACH(k, &W->h.keybind, next) SLIST_FOREACH(k, &W->h.keybind, next)
@ -166,6 +176,8 @@ wmfs_scan(void)
XWindowAttributes wa; XWindowAttributes wa;
Window usl, usl2, *w = NULL; Window usl, usl2, *w = NULL;
SLIST_INIT(&W->h.client);
/* /*
Atom rt; Atom rt;
int s, rf, tag = -1, screen = -1, flags = -1, i; int s, rf, tag = -1, screen = -1, flags = -1, i;

View File

@ -110,6 +110,7 @@ struct Tag
Scr33n *screen; Scr33n *screen;
Flags flags; Flags flags;
Client *sel; Client *sel;
SLIST_HEAD(, Client) clients;
TAILQ_ENTRY(Tag) next; TAILQ_ENTRY(Tag) next;
}; };
@ -122,7 +123,8 @@ struct Client
Flags flags; Flags flags;
char *title; char *title;
Window win; Window win;
SLIST_ENTRY(Client) next; SLIST_ENTRY(Client) next; /* Global list */
SLIST_ENTRY(Client) tnext; /* Tag list */
}; };
/* Config */ /* Config */
@ -197,15 +199,17 @@ struct Wmfs
} h; } h;
/* /*
* Selected screen, from what you go everywhere; selected tag, * Selected screen, client
* and then selected client.
*/ */
Scr33n *screen; Scr33n *screen;
Client *client;
}; };
int wmfs_error_handler(Display *d, XErrorEvent *event); int wmfs_error_handler(Display *d, XErrorEvent *event);
int wmfs_error_handler_dummy(Display *d, XErrorEvent *event); int wmfs_error_handler_dummy(Display *d, XErrorEvent *event);
void wmfs_grab_keys(void); void wmfs_grab_keys(void);
void wmfs_numlockmask(void);
void wmfs_init_font(char *font, Theme *t); void wmfs_init_font(char *font, Theme *t);
void wmfs_quit(void); void wmfs_quit(void);
void uicb_reload(Uicb cmd); void uicb_reload(Uicb cmd);