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:
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);