2009/10/9, Jacob Todd <jaketodd...@gmail.com>: >> dwm focuses new client. >> Should your tool trick dwm, making it believe, that the client selected >> (through a list as the desired client isn't visible to be selected with >> the keyboard or the mouse) has "disappeared" from the X client list, >> and then makes it "reappear" as a new one? > I think we need to look at focusstack, setclientstate, and windowtoclient in > dwm.c. Sounds like a piece of crap.
>> Or a tool which gets informations direct from dwm client list, translate >> it >> into a human readable list and give focus to a selected client? You can hack lsw to print window ids (if it doesn't). I attach a patch for dwm to focus _NET_ACTIVE_WINDOW and setfocus utility to set _NET_ACTIVE_WINDOW.
diff -u dwm-5.7.2/dwm.c dwm-5.7.2-focus/dwm.c --- dwm-5.7.2/dwm.c 2009-09-27 23:20:23.000000000 +0400 +++ dwm-5.7.2-focus/dwm.c 2009-10-09 19:55:19.000000000 +0400 @@ -57,7 +57,7 @@ /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ -enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */ +enum { NetSupported, NetWMName, NetActiveWindow, NetLast }; /* EWMH atoms */ enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ @@ -161,6 +161,7 @@ static void cleanup(void); static void cleanupmon(Monitor *mon); static void clearurgent(Client *c); +static void clientmessage(XEvent *e); static void configure(Client *c); static void configurenotify(XEvent *e); static void configurerequest(XEvent *e); @@ -249,6 +250,7 @@ static unsigned int numlockmask = 0; static void (*handler[LASTEvent]) (XEvent *) = { [ButtonPress] = buttonpress, + [ClientMessage] = clientmessage, [ConfigureRequest] = configurerequest, [ConfigureNotify] = configurenotify, [DestroyNotify] = destroynotify, @@ -521,6 +523,22 @@ } void +clientmessage(XEvent *e) { + XClientMessageEvent *ev = &e->xclient; + Client *c; + Monitor *m; + + if(ev->message_type == netatom[NetActiveWindow]) { + if((m = wintomon(ev->window)) && m != selmon) { + unfocus(selmon->sel); + selmon = m; + } + if((c = wintoclient(ev->window))) + focus(c); + } +} + +void configure(Client *c) { XConfigureEvent ce; @@ -1493,6 +1511,7 @@ wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); /* init cursors */ cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
#include <stdio.h> #include <string.h> #include <locale.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> Display *dpy; int screen; Window root; static Atom NetActiveWindow; void focus(Window w){ XEvent ev; ev.type = ClientMessage; ev.xclient.window = w; ev.xclient.message_type = NetActiveWindow; ev.xclient.format = 32; ev.xclient.data.l[0] = 0; ev.xclient.data.l[1] = CurrentTime; XSendEvent(dpy, root, False, (SubstructureNotifyMask|SubstructureRedirectMask), &ev); } int main(int argc, char *argv[]) { dpy = XOpenDisplay(0); Window win; if(!dpy) { fprintf(stderr, "cannot open display\n"); return 1; } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); NetActiveWindow = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); sscanf(argv[1], "0x%x", &win); focus(win); XCloseDisplay(dpy); return 0; }