[hackers] [wmii] Fix some focus bugs; cleanup.

From: Kris Maglione <jg_AT_suckless.org>
Date: Fri, 01 Jun 2007 01:10:20 -0000

changeset: 2126:eff4d9932d5f
user: Kris Maglione <jg_AT_suckless.org>
date: Mon Apr 23 18:31:35 2007 -0400
summary: Fix some focus bugs; cleanup.

diff -r 92d445bbd20f -r eff4d9932d5f cmd/wmii/area.c
--- a/cmd/wmii/area.c Mon Apr 23 13:42:07 2007 -0400
+++ b/cmd/wmii/area.c Mon Apr 23 18:31:35 2007 -0400
@@ -84,7 +84,7 @@ create_area(View *v, Area *pos, uint w)
         if(a == v->area)
                 a->floating = True;
 
- if((v->sel == nil) || (v->sel->floating && v->area == a->prev && a->next == nil))
+ if(v->sel == nil)
                 focus_area(a);
 
         if(!a->floating)
@@ -201,8 +201,6 @@ detach_from_area(Frame *f) {
         Client *c, *cp;
         Area *a;
         View *v;
- Area *ta;
- uint i;
 
         a = f->area;
         v = a->view;
@@ -224,10 +222,6 @@ detach_from_area(Frame *f) {
                 if(a->frame)
                         arrange_column(a, False);
                 else {
- i = 0;
- for(ta=v->area; ta != a; ta=ta->next)
- i++;
-
                         if(v->area->next->next)
                                 destroy_area(a);
                         else if((a->frame == nil) && (v->area->frame))
@@ -235,8 +229,7 @@ detach_from_area(Frame *f) {
 
                         arrange_view(v);
                 }
- }
- else if(!a->frame) {
+ }else if(!a->frame) {
                 if(c->trans) {
                         cp = win2client(c->trans);
                         if(cp && cp->frame) {
@@ -432,7 +425,7 @@ select_area(Area *a, char *arg) {
         if(!strcmp(arg, "toggle")) {
                 if(!a->floating)
                         ap = v->area;
- else if(v->revert)
+ else if(v->revert && v->revert != a)
                         ap = v->revert;
                 else
                         ap = v->area->next;
diff -r 92d445bbd20f -r eff4d9932d5f cmd/wmii/client.c
--- a/cmd/wmii/client.c Mon Apr 23 13:42:07 2007 -0400
+++ b/cmd/wmii/client.c Mon Apr 23 18:31:35 2007 -0400
@@ -86,9 +86,131 @@ create_client(XWindow w, XWindowAttribut
         return c;
 }
 
+void
+manage_client(Client *c) {
+ Rectangle r;
+ Point p;
+ Client *trans;
+ char *tags;
+
+ tags = gettextproperty(&c->w, "_WIN_TAGS");
+
+ if((trans = win2client(c->trans)))
+ strncpy(c->tags, trans->tags, sizeof(c->tags));
+ else if(tags)
+ strncpy(c->tags, tags, sizeof(c->tags));
+
+ free(tags);
+
+ r = c->w.r;
+ p.x = def.border;
+ p.y = labelh(def.font);
+ reparent_client(c, c->framewin, p);
+
+ if(!strlen(c->tags))
+ apply_rules(c);
+ else
+ apply_tags(c, c->tags);
+
+ if(c->w.hints->position) {
+ r = gravclient(c, r);
+ if(c->sel->area->floating)
+ resize_client(c, &r);
+ else
+ c->sel->revert = r;
+ }
+
+ if(!starting)
+ update_views();
+
+ if(c->sel->view == screen->sel)
+ focus(c, True);
+ flushevents(EnterWindowMask, False);
+}
+
 static int
 ignoreerrors(Display *d, XErrorEvent *e) {
         return 0;
+}
+
+void
+destroy_client(Client *c) {
+ int (*handler)(Display*, XErrorEvent*);
+ Rectangle r;
+ char *dummy;
+ Client **tc;
+ XEvent ev;
+
+ Debug fprintf(stderr, "client.c:destroy_client(%p) %s\n", c, c->name);
+
+ for(tc=&client; *tc; tc=&(*tc)->next)
+ if(*tc == c) {
+ *tc = c->next;
+ break;
+ }
+
+ XGrabServer(display);
+
+ /* In case the client is already unmapped */
+ handler = XSetErrorHandler(ignoreerrors);
+
+ if(c->sel) {
+ r = gravclient(c, ZR);
+ r = frame2client(nil, r);
+ }
+
+ dummy = nil;
+ update_client_views(c, &dummy);
+
+ unmap_client(c, WithdrawnState);
+ reparent_client(c, &scr.root, r.min);
+
+ write_event("DestroyClient 0x%x\n", (uint)c->w.w);
+
+ destroywindow(c->framewin);
+ sethandler(&c->w, nil);
+
+ XSync(display, False);
+ XSetErrorHandler(handler);
+
+ XUngrabServer(display);
+ flushevents(EnterWindowMask, False);
+
+ while(XCheckMaskEvent(display, StructureNotifyMask, &ev))
+ if(ev.type != UnmapNotify || ev.xunmap.window != c->w.w)
+ dispatch_event(&ev);
+
+ free(c);
+}
+
+/* Convenience functions */
+Client *
+selclient() {
+ if(screen->sel->sel->sel)
+ return screen->sel->sel->sel->client;
+ return nil;
+}
+
+Client *
+win2client(XWindow w) {
+ Client *c;
+ for(c=client; c; c=c->next)
+ if(c->w.w == w) break;
+ return c;
+}
+
+uint
+clientwin(Client *c) {
+ if(c)
+ return (uint)c->w.w;
+ return 0;
+}
+
+char *
+clientname(Client *c) {
+ if(c)
+ return c->name;
+ return "<nil>";
 }
 
 Rectangle
@@ -117,270 +239,36 @@ gravclient(Client *c, Rectangle rd) {
         return r;
 }
 
-void
-destroy_client(Client *c) {
- int (*handler)(Display*, XErrorEvent*);
- Rectangle r;
- char *dummy;
- Client **tc;
- XEvent ev;
-
- Debug fprintf(stderr, "client.c:destroy_client(%p) %s\n", c, c->name);
-
- for(tc=&client; *tc; tc=&(*tc)->next)
- if(*tc == c) {
- *tc = c->next;
- break;
- }
-
- XGrabServer(display);
-
- /* In case the client is already unmapped */
- handler = XSetErrorHandler(ignoreerrors);
-
- if(c->sel) {
- r = gravclient(c, ZR);
- r = frame2client(nil, r);
- }
-
- dummy = nil;
- update_client_views(c, &dummy);
-
- unmap_client(c, WithdrawnState);
- reparent_client(c, &scr.root, r.min);
-
- write_event("DestroyClient 0x%x\n", (uint)c->w.w);
-
- destroywindow(c->framewin);
- sethandler(&c->w, nil);
-
- XSync(display, False);
- XSetErrorHandler(handler);
-
- XUngrabServer(display);
- flushevents(EnterWindowMask, False);
-
- while(XCheckMaskEvent(display, StructureNotifyMask, &ev))
- if(ev.type != UnmapNotify || ev.xunmap.window != c->w.w)
- dispatch_event(&ev);
-
- free(c);
-}
-
-void
-manage_client(Client *c) {
- Rectangle r;
- Client *trans;
- char *tags;
-
- tags = gettextproperty(&c->w, "_WIN_TAGS");
-
- if((trans = win2client(c->trans)))
- strncpy(c->tags, trans->tags, sizeof(c->tags));
- else if(tags)
- strncpy(c->tags, tags, sizeof(c->tags));
-
- free(tags);
-
- r = c->w.r;
- reparent_client(c, c->framewin, Pt(def.border, labelh(def.font)));
-
- if(!strlen(c->tags))
- apply_rules(c);
- else
- apply_tags(c, c->tags);
-
- if(c->w.hints->position) {
- r = gravclient(c, r);
- if(c->sel->area->floating)
- resize_client(c, &r);
- else
- c->sel->revert = r;
- }
-
- if(!starting)
- update_views();
-
- if(c->sel->view == screen->sel)
- focus(c, True);
- flushevents(EnterWindowMask, False);
-}
-
-/* Handlers */
-static void
-configreq_event(Window *w, XConfigureRequestEvent *e) {
- Rectangle r;
+Rectangle
+frame_hints(Frame *f, Rectangle r, Align sticky) {
+ Rectangle or;
         Point p;
- Frame *f;
         Client *c;
 
- c = w->aux;
- f = c->sel;
+ c = f->client;
+ if(c->w.hints == nil)
+ return r;
+
+ or = r;
+ r = frame2client(f, r);
+ r = sizehint(c->w.hints, r);
+ r = client2frame(f, r);
+
+ if(!f->area->floating) {
+ /* Not allowed to grow */
+ if(Dx(r) > Dx(or))
+ r.max.x =r.min.x+Dx(or);
+ if(Dy(r) > Dy(or))
+ r.max.y = r.min.y+Dy(or);
+ }
 
         p = ZP;
- r = gravclient(c, ZR);
- if(e->value_mask&CWX)
- p.x = e->x - r.min.x;
- if(e->value_mask&CWY)
- p.y = e->y - r.min.y;
- if(e->value_mask&CWWidth)
- r.max.x = r.min.x + e->width;
- if(e->value_mask&CWHeight)
- r.max.y = r.min.y + e->height;
- if(e->value_mask&CWBorderWidth)
- c->border = e->border_width;
- r = rectaddpt(r, p);
- r = gravclient(c, r);
-
- if((Dx(r) == Dx(screen->r)) && (Dy(r) == Dy(screen->r))) {
- c->fullscreen = True;
- if(f) {
- if(!f->area->floating)
- send_to_area(f->view->area, f);
- focus_client(c);
- restack_view(f->view);
- }
- }
-
- if(c->sel->area->floating)
- resize_client(c, &r);
- else {
- c->sel->revert = r;
- configure_client(c);
- }
-}
-
-static void
-destroy_event(Window *w, XDestroyWindowEvent *e) {
- Debug fprintf(stderr, "client.c:destroy_event(%x)\n", (uint)w->w);
- destroy_client(w->aux);
-}
-
-static void
-enter_event(Window *w, XCrossingEvent *e) {
- Client *c;
-
- c = w->aux;
- if(e->detail != NotifyInferior) {
- if(screen->focus != c) {
- Debug fprintf(stderr, "enter_notify(c) => %s\n", c->name);
- focus(c, False);
- }
- set_cursor(c, cursor[CurNormal]);
- }else Debug
- fprintf(stderr, "enter_notify(c[NotifyInferior]) => %s\n", c->name);
-}
-
-static void
-focusin_event(Window *w, XFocusChangeEvent *e) {
- Client *c, *old;
-
- c = w->aux;
-
- print_focus(c, c->name);
-
- if(e->mode == NotifyGrab)
- screen->hasgrab = c;
-
- old = screen->focus;
- screen->focus = c;
- if(c != old) {
- if(c->sel)
- draw_frame(c->sel);
- if(old && old->sel)
- draw_frame(old->sel);
- }
-}
-
-static void
-focusout_event(Window *w, XFocusChangeEvent *e) {
- Client *c;
-
- c = w->aux;
-
- if((e->mode == NotifyWhileGrabbed) && (screen->hasgrab != &c_root)) {
- if((screen->focus) && (screen->hasgrab != screen->focus))
- screen->hasgrab = screen->focus;
- if(screen->hasgrab == c)
- return;
- }else if(e->mode != NotifyGrab) {
- if(screen->focus == c) {
- print_focus(&c_magic, "<magic>");
- screen->focus = &c_magic;
- }
- if(c->sel)
- draw_frame(c->sel);
- }
-}
-
-static void
-unmap_event(Window *w, XUnmapEvent *e) {
- Client *c;
-
- c = w->aux;
- if(!e->send_event)
- c->unmapped--;
- destroy_client(c);
-}
-
-static void
-map_event(Window *w, XMapEvent *e) {
- Client *c;
-
- c = w->aux;
- if(c == selclient())
- focus_client(c);
-}
-
-static void
-property_event(Window *w, XPropertyEvent *e) {
- Client *c;
-
- if(e->state == PropertyDelete)
- return;
-
- c = w->aux;
- prop_client(c, e->atom);
-}
-
-static Handlers handlers = {
- .configreq = configreq_event,
- .destroy = destroy_event,
- .enter = enter_event,
- .focusin = focusin_event,
- .focusout = focusout_event,
- .map = map_event,
- .unmap = unmap_event,
- .property = property_event,
-};
-
-Client *
-selclient() {
- if(screen->sel->sel->sel)
- return screen->sel->sel->sel->client;
- return nil;
-}
-
-Client *
-win2client(XWindow w) {
- Client *c;
- for(c=client; c; c=c->next)
- if(c->w.w == w) break;
- return c;
-}
-
-uint
-clientwin(Client *c) {
- if(c)
- return (uint)c->w.w;
- return 0;
-}
-
-char *
-clientname(Client *c) {
- if(c)
- return c->name;
- return "<nil>";
+ if((sticky&(EAST|WEST)) == EAST)
+ p.x = Dx(or) - Dx(r);
+ if((sticky&(NORTH|SOUTH)) == SOUTH)
+ p.y = Dy(or) - Dy(r);
+
+ return rectaddpt(r, p);
 }
 
 void
@@ -413,6 +301,72 @@ int
 int
 unmap_frame(Client *c) {
         return unmapwin(c->framewin);
+}
+
+void
+focus(Client *c, Bool restack) {
+ View *v;
+ Frame *f;
+
+ f = c->sel;
+ if(!f)
+ return;
+
+ v = f->area->view;
+ if(v != screen->sel)
+ focus_view(screen, v);
+ focus_frame(c->sel, restack);
+}
+
+void
+focus_client(Client *c) {
+ flushevents(FocusChangeMask, True);
+
+ Debug fprintf(stderr, "focus_client(%p[%x]) => %s\n", c, clientwin(c), clientname(c));
+
+ if(screen->focus != c) {
+ Debug fprintf(stderr, "\t%s => %s\n", clientname(screen->focus), clientname(c));
+ if(c)
+ setfocus(&c->w, RevertToParent);
+ else
+ setfocus(screen->barwin, RevertToParent);
+ XSync(display, False);
+ }
+
+ flushevents(FocusChangeMask, True);
+}
+
+void
+resize_client(Client *c, Rectangle *r) {
+ Frame *f;
+
+ f = c->sel;
+ resize_frame(f, *r);
+
+ if(f->area->view != screen->sel) {
+ unmap_client(c, IconicState);
+ unmap_frame(c);
+ return;
+ }
+
+ c->r = rectaddpt(f->crect, f->r.min);
+
+ if((f->area->mode == Colmax) && (f->area->sel != f)) {
+ unmap_frame(c);
+ unmap_client(c, IconicState);
+ }else if(f->collapsed) {
+ reshapewin(c->framewin, f->r);
+ map_frame(c);
+ unmap_client(c, IconicState);
+ }else {
+ reshapewin(&c->w, f->crect);
+ map_client(c);
+ reshapewin(c->framewin, f->r);
+ map_frame(c);
+ configure_client(c);
+ }
+
+ flushevents(FocusChangeMask|ExposureMask, True);
 }
 
 void
@@ -518,6 +472,7 @@ set_urgent(Client *c, Bool urgent, Bool
         }
 }
 
+/* X11 stuff */
 void
 update_class(Client *c) {
         char *str;
@@ -631,104 +586,155 @@ wmname:
         }
 }
 
-Rectangle
-frame_hints(Frame *f, Rectangle r, Align sticky) {
- Rectangle or;
+/* Handlers */
+static void
+configreq_event(Window *w, XConfigureRequestEvent *e) {
+ Rectangle r;
         Point p;
+ Frame *f;
         Client *c;
 
- c = f->client;
- if(c->w.hints == nil)
- return r;
-
- or = r;
- r = frame2client(f, r);
- r = sizehint(c->w.hints, r);
- r = client2frame(f, r);
-
- if(!f->area->floating) {
- /* Not allowed to grow */
- if(Dx(r) > Dx(or))
- r.max.x =r.min.x+Dx(or);
- if(Dy(r) > Dy(or))
- r.max.y = r.min.y+Dy(or);
- }
+ c = w->aux;
+ f = c->sel;
 
         p = ZP;
- if((sticky&(EAST|WEST)) == EAST)
- p.x = Dx(or) - Dx(r);
- if((sticky&(NORTH|SOUTH)) == SOUTH)
- p.y = Dy(or) - Dy(r);
-
- return rectaddpt(r, p);
-}
-
-void
-focus(Client *c, Bool restack) {
- View *v;
- Frame *f;
-
- f = c->sel;
- if(!f)
+ r = gravclient(c, ZR);
+ if(e->value_mask&CWX)
+ p.x = e->x - r.min.x;
+ if(e->value_mask&CWY)
+ p.y = e->y - r.min.y;
+ if(e->value_mask&CWWidth)
+ r.max.x = r.min.x + e->width;
+ if(e->value_mask&CWHeight)
+ r.max.y = r.min.y + e->height;
+ if(e->value_mask&CWBorderWidth)
+ c->border = e->border_width;
+ r = rectaddpt(r, p);
+ r = gravclient(c, r);
+
+ if((Dx(r) == Dx(screen->r)) && (Dy(r) == Dy(screen->r))) {
+ c->fullscreen = True;
+ if(f) {
+ if(!f->area->floating)
+ send_to_area(f->view->area, f);
+ focus_client(c);
+ restack_view(f->view);
+ }
+ }
+
+ if(c->sel->area->floating)
+ resize_client(c, &r);
+ else {
+ c->sel->revert = r;
+ configure_client(c);
+ }
+}
+
+static void
+destroy_event(Window *w, XDestroyWindowEvent *e) {
+ Debug fprintf(stderr, "client.c:destroy_event(%x)\n", (uint)w->w);
+ destroy_client(w->aux);
+}
+
+static void
+enter_event(Window *w, XCrossingEvent *e) {
+ Client *c;
+
+ c = w->aux;
+ if(e->detail != NotifyInferior) {
+ if(screen->focus != c) {
+ Debug fprintf(stderr, "enter_notify(c) => %s\n", c->name);
+ focus(c, False);
+ }
+ set_cursor(c, cursor[CurNormal]);
+ }else Debug
+ fprintf(stderr, "enter_notify(c[NotifyInferior]) => %s\n", c->name);
+}
+
+static void
+focusin_event(Window *w, XFocusChangeEvent *e) {
+ Client *c, *old;
+
+ c = w->aux;
+
+ print_focus(c, c->name);
+
+ if(e->mode == NotifyGrab)
+ screen->hasgrab = c;
+
+ old = screen->focus;
+ screen->focus = c;
+ if(c != old) {
+ if(c->sel)
+ draw_frame(c->sel);
+ if(old && old->sel)
+ draw_frame(old->sel);
+ }
+}
+
+static void
+focusout_event(Window *w, XFocusChangeEvent *e) {
+ Client *c;
+
+ c = w->aux;
+
+ if((e->mode == NotifyWhileGrabbed) && (screen->hasgrab != &c_root)) {
+ if((screen->focus) && (screen->hasgrab != screen->focus))
+ screen->hasgrab = screen->focus;
+ if(screen->hasgrab == c)
+ return;
+ }else if(e->mode != NotifyGrab) {
+ if(screen->focus == c) {
+ print_focus(&c_magic, "<magic>");
+ screen->focus = &c_magic;
+ }
+ if(c->sel)
+ draw_frame(c->sel);
+ }
+}
+
+static void
+unmap_event(Window *w, XUnmapEvent *e) {
+ Client *c;
+
+ c = w->aux;
+ if(!e->send_event)
+ c->unmapped--;
+ destroy_client(c);
+}
+
+static void
+map_event(Window *w, XMapEvent *e) {
+ Client *c;
+
+ c = w->aux;
+ if(c == selclient())
+ focus_client(c);
+}
+
+static void
+property_event(Window *w, XPropertyEvent *e) {
+ Client *c;
+
+ if(e->state == PropertyDelete)
                 return;
 
- v = f->area->view;
- if(v != screen->sel)
- focus_view(screen, v);
- focus_frame(c->sel, restack);
-}
-
-void
-focus_client(Client *c) {
- flushevents(FocusChangeMask, True);
-
- Debug fprintf(stderr, "focus_client(%p[%x]) => %s\n", c, clientwin(c), clientname(c));
-
- if(screen->focus != c) {
- Debug fprintf(stderr, "\t%s => %s\n", clientname(screen->focus), clientname(c));
- if(c)
- setfocus(&c->w, RevertToParent);
- else
- setfocus(screen->barwin, RevertToParent);
- XSync(display, False);
- }
-
- flushevents(FocusChangeMask, True);
-}
-
-void
-resize_client(Client *c, Rectangle *r) {
- Frame *f;
-
- f = c->sel;
- resize_frame(f, *r);
-
- if(f->area->view != screen->sel) {
- unmap_client(c, IconicState);
- unmap_frame(c);
- return;
- }
-
- c->r = rectaddpt(f->crect, f->r.min);
-
- if((f->area->mode == Colmax) && (f->area->sel != f)) {
- unmap_frame(c);
- unmap_client(c, IconicState);
- }else if(f->collapsed) {
- reshapewin(c->framewin, f->r);
- map_frame(c);
- unmap_client(c, IconicState);
- }else {
- reshapewin(&c->w, f->crect);
- map_client(c);
- reshapewin(c->framewin, f->r);
- map_frame(c);
- configure_client(c);
- }
-
- flushevents(FocusChangeMask|ExposureMask, True);
-}
-
+ c = w->aux;
+ prop_client(c, e->atom);
+}
+
+static Handlers handlers = {
+ .configreq = configreq_event,
+ .destroy = destroy_event,
+ .enter = enter_event,
+ .focusin = focusin_event,
+ .focusout = focusout_event,
+ .map = map_event,
+ .unmap = unmap_event,
+ .property = property_event,
+};
+
+/* Other */
 void
 newcol_client(Client *c, char *arg) {
         Frame *f;
diff -r 92d445bbd20f -r eff4d9932d5f cmd/wmii/frame.c
--- a/cmd/wmii/frame.c Mon Apr 23 13:42:07 2007 -0400
+++ b/cmd/wmii/frame.c Mon Apr 23 18:31:35 2007 -0400
@@ -371,9 +371,8 @@ focus_frame(Frame *f, Bool restack) {
         if(!a->floating && ((a->mode == Colstack) || (a->mode == Colmax)))
                 arrange_column(a, False);
 
- if((f != old)
- && (f->area == old_a))
- write_event("ClientFocus 0x%x\n", f->client->w.w);
+ if((f != old) && (f->area == old_a))
+ write_event("ClientFocus 0x%x\n", f->client->w.w);
 
         if(restack)
                 restack_view(v);
diff -r 92d445bbd20f -r eff4d9932d5f cmd/wmii/view.c
--- a/cmd/wmii/view.c Mon Apr 23 13:42:07 2007 -0400
+++ b/cmd/wmii/view.c Mon Apr 23 18:31:35 2007 -0400
@@ -68,6 +68,8 @@ create_view(const char *name) {
         write_event("CreateTag %s\n", v->name);
         create_area(v, nil, 0);
         new_column(v, v->area, 0);
+
+ focus_area(v->area->next);
 
         for(i=&view; *i; i=&(*i)->next)
                 if(strcmp((*i)->name, name) < 0)
@@ -166,13 +168,14 @@ select_view(const char *arg) {
 
 void
 attach_to_view(View *v, Frame *f) {
- Client *c = f->client;
-
+ Client *c;
+
+ c = f->client;
         c->revert = nil;
         if(c->trans || c->floating || c->fixedsize || c->fullscreen)
- v->sel = v->area;
+ focus_area(v->area);
         else if(starting && v->sel->floating)
- v->sel = v->area->next;
+ focus_area(v->area->next);
         attach_to_area(v->sel, f, False);
 }
 
Received on Fri Jun 01 2007 - 03:10:18 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:57:05 UTC