Hi Anselm, > It appears to me that both the onscreen keyboard and the client with > the input focus should have a selfg border -- at least that makes most > sense in my opinion.
But you need to be able to distinguish between dwm's _selected_ (for tagging, closing etc.) client and X's _focused_ client. Killing your terminal window on accident could be awful. > Introducing another couple just for that sounds quite over-engineered > to me. Agreed. What I would propose is the attached series of patches for hg import: The first renames focus() to selclient() and focusstack() to selstack(). The second adds a new focus() function calling XSetInputFocus() and saving the client in a global foc (analogue to sel) variable; it then implements isfocusable based on the Gottox port + selfgcolor border for focused, but unselected windows. By the way, your last commits have "a...@null" as the author? Regards, Peter
>From 21a07081c462ba83851d4bc120fd02be3692fe7a Mon Sep 17 00:00:00 2001 From: Peter Hartlich <[email protected]> Date: Mon, 9 Feb 2009 01:13:29 +0059 Subject: [PATCH 1/2] rename focus to selclient, focusstack to selstack --- config.def.h | 4 +- dwm.c | 114 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/config.def.h b/config.def.h index bb60471..03dc235 100644 --- a/config.def.h +++ b/config.def.h @@ -56,8 +56,8 @@ static Key keys[] = { { MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_j, selstack, {.i = +1 } }, + { MODKEY, XK_k, selstack, {.i = -1 } }, { MODKEY, XK_h, setmfact, {.f = -0.05} }, { MODKEY, XK_l, setmfact, {.f = +0.05} }, { MODKEY, XK_Return, zoom, {0} }, diff --git a/dwm.c b/dwm.c index db9e9c0..489fe0e 100644 --- a/dwm.c +++ b/dwm.c @@ -149,9 +149,7 @@ static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[C static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); static void enternotify(XEvent *e); static void expose(XEvent *e); -static void focus(Client *c); static void focusin(XEvent *e); -static void focusstack(const Arg *arg); static Client *getclient(Window w); static unsigned long getcolor(const char *colstr); static long getstate(Window w); @@ -175,6 +173,8 @@ static void resizemouse(const Arg *arg); static void restack(void); static void run(void); static void scan(void); +static void selclient(Client *c); +static void selstack(const Arg *arg); static void setclientstate(Client *c, long state); static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); @@ -288,7 +288,7 @@ arrange(void) { for(nt = 0, c = nexttiled(clients); c; c = nexttiled(c->next), nt++); showhide(stack, nt); - focus(NULL); + selclient(NULL); if(lt[sellt]->arrange) lt[sellt]->arrange(); restack(); @@ -329,7 +329,7 @@ buttonpress(XEvent *e) { click = ClkWinTitle; } else if((c = getclient(ev->window))) { - focus(c); + selclient(c); click = ClkClientWin; } @@ -603,9 +603,9 @@ enternotify(XEvent *e) { if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) return; if((c = getclient(ev->window))) - focus(c); + selclient(c); else - focus(NULL); + selclient(NULL); } void @@ -617,29 +617,6 @@ expose(XEvent *e) { } void -focus(Client *c) { - if(!c || !ISVISIBLE(c)) - for(c = stack; c && !ISVISIBLE(c); c = c->snext); - if(sel && sel != c) { - grabbuttons(sel, False); - XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]); - } - if(c) { - if(c->isurgent) - clearurgent(c); - detachstack(c); - attachstack(c); - grabbuttons(c, True); - XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - } - else - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - sel = c; - drawbar(); -} - -void focusin(XEvent *e) { /* there are some broken focus acquiring clients */ XFocusChangeEvent *ev = &e->xfocus; @@ -647,32 +624,6 @@ focusin(XEvent *e) { /* there are some broken focus acquiring clients */ XSetInputFocus(dpy, sel->win, RevertToPointerRoot, CurrentTime); } -void -focusstack(const Arg *arg) { - Client *c = NULL, *i; - - if(!sel) - return; - if (arg->i > 0) { - for(c = sel->next; c && !ISVISIBLE(c); c = c->next); - if(!c) - for(c = clients; c && !ISVISIBLE(c); c = c->next); - } - else { - for(i = clients; i != sel; i = i->next) - if(ISVISIBLE(i)) - c = i; - if(!c) - for(; i; i = i->next) - if(ISVISIBLE(i)) - c = i; - } - if(c) { - focus(c); - restack(); - } -} - Client * getclient(Window w) { Client *c; @@ -1236,6 +1187,55 @@ scan(void) { } void +selclient(Client *c) { + if(!c || !ISVISIBLE(c)) + for(c = stack; c && !ISVISIBLE(c); c = c->snext); + if(sel && sel != c) { + grabbuttons(sel, False); + XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]); + } + if(c) { + if(c->isurgent) + clearurgent(c); + detachstack(c); + attachstack(c); + grabbuttons(c, True); + XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + } + else + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + sel = c; + drawbar(); +} + +void +selstack(const Arg *arg) { + Client *c = NULL, *i; + + if(!sel) + return; + if (arg->i > 0) { + for(c = sel->next; c && !ISVISIBLE(c); c = c->next); + if(!c) + for(c = clients; c && !ISVISIBLE(c); c = c->next); + } + else { + for(i = clients; i != sel; i = i->next) + if(ISVISIBLE(i)) + c = i; + if(!c) + for(; i; i = i->next) + if(ISVISIBLE(i)) + c = i; + } + if(c) { + selclient(c); + restack(); + } +} + +void setclientstate(Client *c, long state) { long data[] = {state, None}; @@ -1491,7 +1491,7 @@ unmanage(Client *c) { detach(c); detachstack(c); if(sel == c) - focus(NULL); + selclient(NULL); XUngrabButton(dpy, AnyButton, AnyModifier, c->win); setclientstate(c, WithdrawnState); free(c); @@ -1701,7 +1701,7 @@ zoom(const Arg *arg) { return; detach(c); attach(c); - focus(c); + selclient(c); arrange(); } -- 1.6.1.2
>From 4b76309f2ecbc95ab032d0b13dad8a898d9a9721 Mon Sep 17 00:00:00 2001 From: Peter Hartlich <[email protected]> Date: Mon, 9 Feb 2009 01:22:08 +0059 Subject: [PATCH 2/2] implement isfocusable --- dwm.c | 23 ++++++++++++++++++++--- 1 files changed, 20 insertions(+), 3 deletions(-) diff --git a/dwm.c b/dwm.c index 489fe0e..0557143 100644 --- a/dwm.c +++ b/dwm.c @@ -86,7 +86,7 @@ struct Client { int basew, baseh, incw, inch, maxw, maxh, minw, minh; int bw, oldbw; unsigned int tags; - Bool isfixed, isfloating, isurgent; + Bool isfixed, isfloating, isurgent, isfocusable; Client *next; Client *snext; Window win; @@ -149,6 +149,7 @@ static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[C static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); static void enternotify(XEvent *e); static void expose(XEvent *e); +static void focus(Client *c); static void focusin(XEvent *e); static Client *getclient(Window w); static unsigned long getcolor(const char *colstr); @@ -232,6 +233,7 @@ static Bool otherwm; static Bool running = True; static Client *clients = NULL; static Client *sel = NULL; +static Client *foc = NULL; static Client *stack = NULL; static Cursor cursor[CurLast]; static Display *dpy; @@ -617,11 +619,17 @@ expose(XEvent *e) { } void +focus(Client *c) { + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + foc = c; +} + +void focusin(XEvent *e) { /* there are some broken focus acquiring clients */ XFocusChangeEvent *ev = &e->xfocus; if(sel && ev->window != sel->win) - XSetInputFocus(dpy, sel->win, RevertToPointerRoot, CurrentTime); + focus(sel); } Client * @@ -824,6 +832,7 @@ manage(Window w, XWindowAttributes *wa) { c->w = wa->width; c->h = wa->height; c->oldbw = wa->border_width; + c->isfocusable = True; if(c->w == sw && c->h == sh) { c->x = sx; c->y = sy; @@ -845,6 +854,7 @@ manage(Window w, XWindowAttributes *wa) { XSetWindowBorder(dpy, w, dc.norm[ColBorder]); configure(c); /* propagates border_width, if size doesn't change */ updatesizehints(c); + updatewmhints(c); XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); grabbuttons(c, False); updatetitle(c); @@ -1201,7 +1211,13 @@ selclient(Client *c) { attachstack(c); grabbuttons(c, True); XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + if(c->isfocusable) { + if(foc && foc != c) + XSetWindowBorder(dpy, foc->win, dc.norm[ColBorder]); + focus(c); + } + else if(foc) + XSetWindowBorder(dpy, foc->win, dc.sel[ColFG]); } else XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); @@ -1642,6 +1658,7 @@ updatewmhints(Client *c) { } else c->isurgent = (wmh->flags & XUrgencyHint) ? True : False; + c->isfocusable = !(wmh->flags & InputHint) || wmh->input; XFree(wmh); } -- 1.6.1.2
