| /*
<<< STAR::BULOVA$DISK:[NOTES$LIBRARY]DECWINDOWS.NOTE;1 >>>
-< DECwindows Standard Programming Environment >-
================================================================================
Note 667.10 CYCLE 10 of 10
ENT::BURLEIGH "A simple desultory phillipic" 151 lines 29-JUL-1988 10:31
-< uwm-style input focus hack >-
--------------------------------------------------------------------------------
The following heresy provides pointer-location-driven
input focus. Seems to work for me, but hasn't been
exhaustively tested. Compile and run as a detached
process.
Use at your own risk ;-]
Dave
*/
/*
autofocus.c: Crude hack to do uwm-style focus management.
Author: (chooses to remain anonymous)
*/
#include <stdio.h>
#include <decw$include/Xlib.h>
#include <decw$include/Xutil.h>
#define forever while(1)
static Window GetWMRoot();
static XWMHints *GetWMHints(); /* Recursive */
static int IgnoreDeadWindow();
main(argc,argv)
unsigned int argc;
char *argv[];
{
Display *display;
Window wmroot,current,*children,*child;
XWMHints *wmhints;
int nchildren,i;
/* Open the default display */
if (!(display = XOpenDisplay(NULL))) {
fprintf(stderr,"Can't open display\n");
exit(0);
}
/* Find the window manager's pseudo-root window & its children */
wmroot = GetWMRoot(display,&children,&nchildren);
XSelectInput(display,wmroot,SubstructureNotifyMask);
/* Find out which children have set window manager hints */
for (i = 0, child = children; i < nchildren; ++i, ++child) {
if (wmhints = GetWMHints(display,*child,¤t)) {
XSelectInput(display,current,EnterWindowMask);
XFree(wmhints);
}
}
/* Ignore error when we try to set focus on a window which has died
since we received the EnterWindow event */
XSetErrorHandler(IgnoreDeadWindow);
forever {
XEvent event;
XMapEvent *map = (XMapEvent *)&event;
XEnterWindowEvent *enter = (XEnterWindowEvent *)&event;
XNextEvent(display,&event);
switch (event.type) {
case MapNotify: if (wmhints = GetWMHints(display,
map->window,
¤t)) {
XSelectInput(display,current,EnterWindowMask);
XFree(wmhints);
}
break;
case EnterNotify: XSetInputFocus(display,enter->window,
RevertToPointerRoot,CurrentTime);
}
}
}
static XWMHints *GetWMHints(display,window,app_window) /* Recursive */
Display *display;
Window window,*app_window;
{
XWMHints *wmhints;
if (wmhints = XGetWMHints(display,window)) {
*app_window = window;
return wmhints;
}
else {
Window root,parent,*children,*child,current = window;
int i,nchildren;
XQueryTree(display,current,&root,&parent,&children,&nchildren);
for (i = 0, child = children; i < nchildren; ++i, ++child) {
if (wmhints = GetWMHints(display,*child,app_window))
return wmhints;
}
return NULL;
}
}
static Window GetWMRoot(display,children,nchildren)
Display *display;
Window **children;
int *nchildren;
{
Window window,root,parent,*child;
XWMHints *wmhints;
int x,y,width,height,bw,depth;
register int i;
window = RootWindow(display,DefaultScreen(display));
XQueryTree(display,window,&root,&parent,children,nchildren);
/* Find first full-screen child of root */
for (i = 0, child = *children; i < *nchildren; ++i, ++child) {
XGetGeometry(display,*child,&root,&x,&y,&width,&height,&bw,&depth);
if (width == DisplayWidth(display,DefaultScreen(display)) &&
height == DisplayHeight(display,DefaultScreen(display))) break;
};
/* Find first full-screen child of first full-screen child of root */
window = *child;
XQueryTree(display,window,&root,&parent,children,nchildren);
for (i = 0, child = *children; i < *nchildren; ++i, ++child) {
XGetGeometry(display,*child,&root,&x,&y,&width,&height,&bw,&depth);
if (width == DisplayWidth(display,DefaultScreen(display)) &&
height == DisplayHeight(display,DefaultScreen(display))) break;
};
/* Found window manager's pseudo-root; return it & its children */
window = *child;
XQueryTree(display,window,&root,&parent,children,nchildren);
return window;
}
static int IgnoreDeadWindow(display,error)
Display *display;
XErrorEvent *error;
{
if (error->request_code == 42) /* Life, the Universe, & Everything */
return;
else XSetErrorHandler(NULL);
}
|