2009/10/9, Jacob Todd <[email protected]>:
>> 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;
}