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;
}

Reply via email to