Manage focus/client buttons grabbing
This commit is contained in:
parent
c1727da152
commit
350c789482
@ -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);
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user