From 485614f2df7f90b8d4a2fe8740c7b2686166b393 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Fri, 25 Jan 2008 12:55:44 +0100 Subject: [PATCH] rewrite focus handling - arrange() does not focus() anymore - restore dropping events infra - add client_unfocus() - grabbuttons() where we should and add root_grabbuttons() for root window --- awesome.c | 15 ++++++++-- client.c | 42 +++++++++++++-------------- event.c | 21 ++++---------- layout.c | 18 ++++-------- layout.h | 2 +- structs.h | 2 ++ window.c | 87 ++++++++++++++++++++++++++++--------------------------- window.h | 3 +- 8 files changed, 93 insertions(+), 97 deletions(-) diff --git a/awesome.c b/awesome.c index 4c3b3317..1438c6c6 100644 --- a/awesome.c +++ b/awesome.c @@ -290,7 +290,7 @@ main(int argc, char *argv[]) loadawesomeprops(screen); ewmh_set_supported_hints(screen); /* call this to at least grab root window clicks */ - window_grabbuttons(screen, None, False, True); + window_root_grabbuttons(screen); } handler = p_new(event_handler *, LASTEvent); @@ -393,7 +393,18 @@ main(int argc, char *argv[]) { XNextEvent(dpy, &ev); if(handler[ev.type]) - handler[ev.type](&ev); + handler[ev.type](&ev); /* call handler */ + + /* drop events requested to */ + if(globalconf.drop_events) + { + /* need to resync */ + XSync(dpy, False); + while(XCheckMaskEvent(dpy, globalconf.drop_events, &ev)); + globalconf.drop_events = NoEventMask; + } + + /* need to resync */ XSync(dpy, False); } diff --git a/client.c b/client.c index 3663a68a..5ad9814f 100644 --- a/client.c +++ b/client.c @@ -144,12 +144,22 @@ client_updatetitle(Client *c) widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); } +static void +client_unfocus(Client *c) +{ + XSetWindowBorder(globalconf.display, c->win, + globalconf.screens[c->screen].colors_normal[ColBorder].pixel); + widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); +} + /** Ban client and unmap it * \param c the client */ void -client_ban(Client * c) +client_ban(Client *c) { + if(globalconf.focus->client == c) + client_unfocus(c); XUnmapWindow(globalconf.display, c->win); window_setstate(c->win, IconicState); } @@ -163,17 +173,6 @@ focus(Client *c, int screen) { int phys_screen = get_phys_screen(screen); - /* unfocus current selected client */ - if(globalconf.focus->client) - { - widget_invalidate_cache(globalconf.focus->client->screen, WIDGET_CACHE_CLIENTS); - window_grabbuttons(get_phys_screen(globalconf.focus->client->screen), - globalconf.focus->client->win, False, True); - XSetWindowBorder(globalconf.display, globalconf.focus->client->win, - globalconf.screens[screen].colors_normal[ColBorder].pixel); - } - - /* if c is NULL or invisible, take next client in the focus history */ if(!c || (c && !client_isvisible(c, screen))) { @@ -183,20 +182,18 @@ focus(Client *c, int screen) for(c = globalconf.clients; c && (c->skip || !client_isvisible(c, screen)); c = c->next); } - if(c) - { - XSetWindowBorder(globalconf.display, c->win, globalconf.screens[screen].colors_selected[ColBorder].pixel); - window_grabbuttons(phys_screen, c->win, True, True); - } + /* unfocus current selected client */ + if(globalconf.focus->client) + client_unfocus(globalconf.focus->client); /* save sel in focus history */ focus_add_client(c); - if(globalconf.focus->client) + if(c) { - widget_invalidate_cache(screen, WIDGET_CACHE_CLIENTS); - XSetInputFocus(globalconf.display, - globalconf.focus->client->win, RevertToPointerRoot, CurrentTime); + XSetWindowBorder(globalconf.display, c->win, + globalconf.screens[screen].colors_selected[ColBorder].pixel); + XSetInputFocus(globalconf.display, c->win, RevertToPointerRoot, CurrentTime); restack(screen); } else @@ -204,7 +201,9 @@ focus(Client *c, int screen) RootWindow(globalconf.display, phys_screen), RevertToPointerRoot, CurrentTime); + widget_invalidate_cache(screen, WIDGET_CACHE_CLIENTS); ewmh_update_net_active_window(phys_screen); + globalconf.drop_events |= EnterWindowMask; } /** Manage a new client @@ -300,7 +299,6 @@ client_manage(Window w, XWindowAttributes *wa, int screen) } XSelectInput(globalconf.display, w, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); - window_grabbuttons(phys_screen, c->win, False, True); /* handle xshape */ if(globalconf.have_shape) diff --git a/event.c b/event.c index 543e8dbb..599033c8 100644 --- a/event.c +++ b/event.c @@ -122,7 +122,7 @@ handle_event_buttonpress(XEvent *e) && ev->button == Button1) { XAllowEvents(globalconf.display, ReplayPointer, CurrentTime); - window_grabbuttons(get_phys_screen(c->screen), c->win, True, True); + window_grabbuttons(get_phys_screen(c->screen), c->win, True); } else handle_mouse_button_press(c->screen, ev->button, ev->state, globalconf.buttons.client, NULL); @@ -233,29 +233,20 @@ handle_event_enternotify(XEvent * e) Client *c; XCrossingEvent *ev = &e->xcrossing; int screen; - Tag **curtags; if(ev->mode != NotifyNormal) return; - if((c = get_client_bywin(globalconf.clients, ev->window)) - && globalconf.screens[c->screen].sloppy_focus - && c != globalconf.focus->client) + if((c = get_client_bywin(globalconf.clients, ev->window))) { - focus(c, c->screen); - curtags = get_current_tags(c->screen); - if (c->isfloating || curtags[0]->layout->arrange == layout_floating) - window_grabbuttons(get_phys_screen(c->screen), c->win, True, False); - p_delete(&curtags); + window_grabbuttons(get_phys_screen(c->screen), c->win, False); + if(globalconf.screens[c->screen].sloppy_focus) + focus(c, c->screen); } else - { for(screen = 0; screen < ScreenCount(e->xany.display); screen++) if(ev->window == RootWindow(e->xany.display, screen)) - focus(NULL, screen); - if((c = globalconf.focus->client)) - window_grabbuttons(c->screen, c->win, False, False); - } + window_root_grabbuttons(screen); } void diff --git a/layout.c b/layout.c index 4e11b9c8..50ba141c 100644 --- a/layout.c +++ b/layout.c @@ -57,9 +57,6 @@ arrange(int screen) { Client *c; Layout *curlay = get_current_layout(screen); - Window client_win, root_win; - int x, y, d; - unsigned int m; for(c = globalconf.clients; c; c = c->next) { @@ -77,33 +74,28 @@ arrange(int screen) { c->newcomer = False; client_unban(c); + if(globalconf.screens[screen].new_get_focus) + focus(c, screen); } if(!globalconf.screens[screen].allow_lower_floats) layout_raise_floatings(screen); - c = focus_get_current_client(screen); - focus(c, screen); - if(c && XQueryPointer(globalconf.display, RootWindow(globalconf.display, get_phys_screen(screen)), - &root_win, &client_win, &x, &y, &d, &d, &m) && - (root_win == None || client_win == None || client_win == root_win)) - window_grabbuttons(c->screen, c->win, False, False); - /* reset status */ globalconf.screens[screen].need_arrange = False; } -Bool +int layout_refresh(void) { int screen; - Bool arranged = False; + int arranged = 0; for(screen = 0; screen < globalconf.nscreen; screen++) if(globalconf.screens[screen].need_arrange) { arrange(screen); - arranged = True; + arranged++; } return arranged; diff --git a/layout.h b/layout.h index 90a8f830..9a81c39e 100644 --- a/layout.h +++ b/layout.h @@ -40,7 +40,7 @@ struct Layout DO_SLIST(Layout, layout, p_delete); -Bool layout_refresh(void); +int layout_refresh(void); Layout * get_current_layout(int); void restack(int); void loadawesomeprops(int); diff --git a/structs.h b/structs.h index 4fac9afd..3132f0ed 100644 --- a/structs.h +++ b/structs.h @@ -328,6 +328,8 @@ struct AwesomeConf tag_client_node_t *tclink; /** Command line passed to awesome */ char *argv; + /** EventMask to drop before each XEvent treatement */ + long drop_events; }; #endif diff --git a/window.c b/window.c index 90392ca2..edfbf3d7 100644 --- a/window.c +++ b/window.c @@ -93,55 +93,56 @@ window_configure(Window win, Area geometry, int border) * \param raised True if the client is above other clients */ void -window_grabbuttons(int screen, - Window win, - Bool focused, - Bool raised) +window_grabbuttons(int screen, Window win, Bool raised) { Button *b; - XUngrabButton(globalconf.display, AnyButton, AnyModifier, win); - - if(focused) + if(!raised) { - if(!raised) - XGrabButton(globalconf.display, Button1, NoSymbol, win, False, - BUTTONMASK, GrabModeSync, GrabModeAsync, None, None); - - for(b = globalconf.buttons.client; b; b = b->next) - { - XGrabButton(globalconf.display, b->button, b->mod, win, False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - XGrabButton(globalconf.display, b->button, b->mod | LockMask, win, False, - BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); - XGrabButton(globalconf.display, b->button, b->mod | globalconf.numlockmask, win, False, - BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); - XGrabButton(globalconf.display, b->button, b->mod | globalconf.numlockmask | LockMask, - win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); - } - - XUngrabButton(globalconf.display, AnyButton, AnyModifier, RootWindow(globalconf.display, screen)); + XGrabButton(globalconf.display, Button1, NoSymbol, + win, False, BUTTONMASK, GrabModeSync, GrabModeAsync, None, None); + XGrabButton(globalconf.display, Button1, NoSymbol | LockMask, + win, False, BUTTONMASK, GrabModeSync, GrabModeAsync, None, None); + XGrabButton(globalconf.display, Button1, NoSymbol | globalconf.numlockmask, + win, False, BUTTONMASK, GrabModeSync, GrabModeAsync, None, None); + XGrabButton(globalconf.display, Button1, NoSymbol | globalconf.numlockmask | LockMask, + win, False, BUTTONMASK, GrabModeSync, GrabModeAsync, None, None); } - else - { - XGrabButton(globalconf.display, AnyButton, AnyModifier, win, False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - for(b = globalconf.buttons.root; b; b = b->next) - { - XGrabButton(globalconf.display, b->button, b->mod, - RootWindow(globalconf.display, screen), False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - XGrabButton(globalconf.display, b->button, b->mod | LockMask, - RootWindow(globalconf.display, screen), False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - XGrabButton(globalconf.display, b->button, b->mod | globalconf.numlockmask, - RootWindow(globalconf.display, screen), False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - XGrabButton(globalconf.display, b->button, b->mod | globalconf.numlockmask | LockMask, - RootWindow(globalconf.display, screen), False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - } + for(b = globalconf.buttons.client; b; b = b->next) + { + XGrabButton(globalconf.display, b->button, b->mod, + win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); + XGrabButton(globalconf.display, b->button, b->mod | LockMask, + win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); + XGrabButton(globalconf.display, b->button, b->mod | globalconf.numlockmask, + win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); + XGrabButton(globalconf.display, b->button, b->mod | globalconf.numlockmask | LockMask, + win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); + } + + XUngrabButton(globalconf.display, AnyButton, AnyModifier, RootWindow(globalconf.display, screen)); +} + +void +window_root_grabbuttons(int screen) +{ + Button *b; + + for(b = globalconf.buttons.root; b; b = b->next) + { + XGrabButton(globalconf.display, b->button, b->mod, + RootWindow(globalconf.display, screen), False, BUTTONMASK, + GrabModeAsync, GrabModeSync, None, None); + XGrabButton(globalconf.display, b->button, b->mod | LockMask, + RootWindow(globalconf.display, screen), False, BUTTONMASK, + GrabModeAsync, GrabModeSync, None, None); + XGrabButton(globalconf.display, b->button, b->mod | globalconf.numlockmask, + RootWindow(globalconf.display, screen), False, BUTTONMASK, + GrabModeAsync, GrabModeSync, None, None); + XGrabButton(globalconf.display, b->button, b->mod | globalconf.numlockmask | LockMask, + RootWindow(globalconf.display, screen), False, BUTTONMASK, + GrabModeAsync, GrabModeSync, None, None); } } diff --git a/window.h b/window.h index d5cf9116..3fff3348 100644 --- a/window.h +++ b/window.h @@ -27,7 +27,8 @@ int window_setstate(Window, long); long window_getstate(Window); Status window_configure(Window, Area, int); -void window_grabbuttons(int, Window, Bool, Bool); +void window_grabbuttons(int, Window, Bool); +void window_root_grabbuttons(int); void window_setshape(int, Window); int window_settrans(Window, double); SimpleWindow * simplewindow_new(int, int, int, unsigned int, unsigned int, unsigned int);