diff --git a/wmfs2/src/client.c b/wmfs2/src/client.c index e608561..2475a50 100644 --- a/wmfs2/src/client.c +++ b/wmfs2/src/client.c @@ -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); diff --git a/wmfs2/src/event.c b/wmfs2/src/event.c index 1101298..738d2ce 100644 --- a/wmfs2/src/event.c +++ b/wmfs2/src/event.c @@ -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 diff --git a/wmfs2/src/infobar.h b/wmfs2/src/infobar.h index 66b4eb5..2f156b2 100644 --- a/wmfs2/src/infobar.h +++ b/wmfs2/src/infobar.h @@ -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: diff --git a/wmfs2/src/tag.c b/wmfs2/src/tag.c index a51a5a0..88e37ac 100644 --- a/wmfs2/src/tag.c +++ b/wmfs2/src/tag.c @@ -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) diff --git a/wmfs2/src/tag.h b/wmfs2/src/tag.h index 12c44cf..19db6da 100644 --- a/wmfs2/src/tag.h +++ b/wmfs2/src/tag.h @@ -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); diff --git a/wmfs2/src/wmfs.c b/wmfs2/src/wmfs.c index 9f86f4b..5573c44 100644 --- a/wmfs2/src/wmfs.c +++ b/wmfs2/src/wmfs.c @@ -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; diff --git a/wmfs2/src/wmfs.h b/wmfs2/src/wmfs.h index fb730f4..ea4f276 100644 --- a/wmfs2/src/wmfs.h +++ b/wmfs2/src/wmfs.h @@ -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);