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 "util.h"
#define CLIENT_MOUSE_MOD Mod1Mask
/** Send a ConfigureRequest event to the Client
* \param c Client pointer
*/
@ -58,25 +60,59 @@ client_unmap(Client *c)
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
client_focus(Client *c)
{
/* 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 */
if((c->tag->sel = c))
if((W->client = c))
{
c->tag->sel = c;
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
XSetInputFocus(W->dpy, W->root, RevertToPointerRoot, CurrentTime);
@ -152,9 +188,11 @@ client_new(Window w, XWindowAttributes *wa)
/* C attributes */
c->win = w;
c->screen = W->screen;
c->tag = W->screen->seltag;
c->flags = 0;
/* Set tag */
tag_client(W->screen->seltag, c);
/* Geometry */
c->geo.x = wa->x;
c->geo.y = wa->y;
@ -166,16 +204,22 @@ client_new(Window w, XWindowAttributes *wa)
XSetWindowBorder(W->dpy, w, 0xffffff);
XSetWindowBorderWidth(W->dpy, w, 1);
client_grabbuttons(c, false);
/* Attach */
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);
XMoveResizeWindow(W->dpy, w, c->geo.x, c->geo.y, c->geo.w, c->geo.h);
XRaiseWindow(W->dpy, w);
client_focus(c);
client_configure(c);
return c;
@ -184,11 +228,22 @@ client_new(Window w, XWindowAttributes *wa)
void
client_remove(Client *c)
{
Client *cc;
XGrabServer(W->dpy);
XSetErrorHandler(wmfs_error_handler_dummy);
if(W->client == c)
client_focus(NULL);
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);
XSetErrorHandler(wmfs_error_handler);

View File

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

View File

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

View File

@ -6,6 +6,7 @@
#include "tag.h"
#include "util.h"
#include "infobar.h"
#include "client.h"
Tag*
tag_new(Scr33n *s, char *name)
@ -29,9 +30,31 @@ tag_screen(Scr33n *s, Tag *t)
{
s->seltag = t;
client_focus(t->sel);
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
uicb_tag_set(Uicb cmd)

View File

@ -10,6 +10,7 @@
Tag *tag_new(Scr33n *s, char *name);
void tag_screen(Scr33n *s, Tag *t);
void tag_client(Tag *t, Client *c);
void tag_free(Scr33n *s);
void uicb_tag_set(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;
}
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
wmfs_init_font(char *font, Theme *t)
{
@ -121,14 +136,7 @@ wmfs_xinit(void)
/*
* Keys
*/
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);
wmfs_numlockmask();
/*
* Barwin linked list
@ -144,6 +152,8 @@ wmfs_grab_keys(void)
KeyCode c;
Keybind *k;
wmfs_numlockmask();
XUngrabKey(W->dpy, AnyKey, AnyModifier, W->root);
SLIST_FOREACH(k, &W->h.keybind, next)
@ -166,6 +176,8 @@ wmfs_scan(void)
XWindowAttributes wa;
Window usl, usl2, *w = NULL;
SLIST_INIT(&W->h.client);
/*
Atom rt;
int s, rf, tag = -1, screen = -1, flags = -1, i;

View File

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