wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 43b906efff1c9fb86499d646bf8dcc0fe0aea411
parent c46e7e5b622670ea1528ab9ac3c9c8c47adc872c
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Tue, 25 Apr 2006 15:48:33 +0200

implemented sloppy focus, this time it seems to work pretty well (because the queue is flushed from enter events in each situation they would interfere with default behavior)


Diffstat:
cmd/wm/client.c | 9+++++++--
cmd/wm/event.c | 26+++++++++++++++++++++++++-
cmd/wm/view.c | 5+----
cmd/wm/wm.h | 1+
4 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -75,7 +75,7 @@ create_client(Window w, XWindowAttributes *wa) fwa.override_redirect = 1; fwa.background_pixmap = ParentRelative; fwa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask - | ExposureMask | ButtonPressMask; + | EnterWindowMask | ExposureMask | ButtonPressMask; c->framewin = XCreateWindow(dpy, root, c->rect.x, c->rect.y, c->rect.width + 2 * def.border, @@ -133,7 +133,6 @@ map_client(Client *c) void unmap_client(Client *c) { - ungrab_mouse(c->win, AnyModifier, AnyButton); XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask); XUnmapWindow(dpy, c->win); XSelectInput(dpy, c->win, CLIENT_MASK); @@ -365,6 +364,7 @@ manage_client(Client *c) reparent_client(c, c->framewin, c->rect.x, c->rect.y); update_views(); + flush_enter_events(); } static int @@ -401,6 +401,7 @@ destroy_client(Client *c) XSync(dpy, False); XSetErrorHandler(wmii_error_handler); XUngrabServer(dpy); + flush_enter_events(); } Client * @@ -508,6 +509,7 @@ select_client(Client *c, char *arg) return; } focus_client(a->frame.data[i]->client); + flush_enter_events(); } void @@ -564,6 +566,7 @@ Swaparea: if(idx_of_area(a)) arrange_column(a, False); focus_client(c); + flush_enter_events(); } void @@ -613,6 +616,7 @@ send_client_to(Client *c, char *arg) to = v->area.data[i]; } send_to_area(to, a, c); + flush_enter_events(); } void @@ -628,6 +632,7 @@ resize_all_clients() resize_client(c, &c->frame.data[c->sel]->rect, False); } } + flush_enter_events(); } /* convenience function */ diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -14,6 +14,7 @@ static void handle_buttonpress(XEvent * e); static void handle_configurerequest(XEvent * e); static void handle_destroynotify(XEvent * e); +static void handle_enternotify(XEvent * e); static void handle_expose(XEvent * e); static void handle_keypress(XEvent * e); static void handle_keymapnotify(XEvent * e); @@ -33,6 +34,7 @@ init_x_event_handler() handler[ButtonPress] = handle_buttonpress; handler[ConfigureRequest] = handle_configurerequest; handler[DestroyNotify] = handle_destroynotify; + handler[EnterNotify] = handle_enternotify; handler[Expose] = handle_expose; handler[KeyPress] = handle_keypress; handler[KeymapNotify] = handle_keymapnotify; @@ -52,6 +54,13 @@ check_x_event(IXPConn *c) } } +void +flush_enter_events() +{ + XEvent ev; + while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); +} + static void handle_buttonpress(XEvent *e) { @@ -184,6 +193,21 @@ handle_destroynotify(XEvent *e) } static void +handle_enternotify(XEvent *e) +{ + XCrossingEvent *ev = &e->xcrossing; + Client *c; + + if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) + return; + + if((c = frame_of_win(ev->window))) { + if(c != sel_client_of_view(view.data[sel])) + focus(c); + } +} + +static void handle_expose(XEvent *e) { XExposeEvent *ev = &e->xexpose; @@ -218,13 +242,13 @@ handle_maprequest(XEvent *e) if(!XGetWindowAttributes(dpy, ev->window, &wa)) return; + if(wa.override_redirect) { XSelectInput(dpy, ev->window, (StructureNotifyMask | PropertyChangeMask)); return; } - /* there're client which send map requests twice */ if(!client_of_win(ev->window)) manage_client(create_client(ev->window, &wa)); } diff --git a/cmd/wm/view.c b/cmd/wm/view.c @@ -34,7 +34,6 @@ create_view(char *name) create_area(v); cext_vattach(vector_of_views(&view), v); qsort(view.data, view.size, sizeof(View *), comp_view_name); - sel = idx_of_view(v); return v; } @@ -257,13 +256,11 @@ restack_view(View *v) wins[n++] = a->frame.data[a->sel]->client->framewin; for(j = a->frame.size - 1; j >= 0; j--) { Client *c = a->frame.data[j]->client; + ungrab_mouse(c->framewin, AnyModifier, AnyButton); if((v->sel == i) && (a->sel == j)) { - ungrab_mouse(c->framewin, AnyModifier, AnyButton); grab_mouse(c->framewin, def.mod, Button1); grab_mouse(c->framewin, def.mod, Button3); } - else - grab_mouse(c->framewin, AnyModifier, Button1); if(j == a->sel) continue; wins[n++] = c->framewin; diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -244,6 +244,7 @@ Area *new_right_column(View *v); /* event.c */ void init_x_event_handler(); void check_x_event(IXPConn *c); +void flush_enter_events(); /* frame.c */ Frame *create_frame(Area *a, Client *c);