[comp.windows.x] Focus in DECwindows ???

sritacco@hpdmd48.HP.COM (Steve Ritacco) (07/12/90)

Is there a way to get dxwm (the DECwindows window manager) to let
window focus follow the mouse pointer.  I hate having to click in
a window to make it get the focus.  I looked in the documentation
and couldn't find a way to do this.

Thanks

west@gsrc.dec.com (Jim West (Stealth Contractor)) (07/13/90)

In article <15510007@hpdmd48.HP.COM>, sritacco@hpdmd48.HP.COM 
(Steve Ritacco) writes...

-Is there a way to get dxwm (the DECwindows window manager) to let
-window focus follow the mouse pointer.  I hate having to click in
-a window to make it get the focus.  I looked in the documentation
-and couldn't find a way to do this.
- 
-Thanks

  Here's a hack program that will do what you want.  It goes against the
grain of the DECwindows window manager...but it does work.

NOTE: Totally %100 UNSUPPORTED !!

cut here -----------------------------------------------------------------

/*    
  autofocus.c: Crude hack to do uwm-style focus management.
               Author: Dave Burleigh

*/
#include <stdio.h>
#include <stdlib.h>
#ifdef vms
#include <decw$include/X.h>
#include <decw$include/Xlib.h>
#include <decw$include/Xutil.h>
#else
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif

#define forever           while(1)

static Window GetWMRoot();
static Window FrameOf();        /* Recursive */
static XWMHints *GetWMHints();  /* Recursive */
static int IgnoreDeadWindow();

main(argc,argv)
   unsigned int argc;
   char *argv[];
{
   Display *display;
   char *display_name[10];
   Window wmroot,current,*children,*child;
   XWMHints *wmhints;
   int nchildren,i;

   /* Open the default display */

   strcat(strcpy(display_name,getenv("SYS$NODE")),"0");

   if (!(display = XOpenDisplay(display_name))) {
      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,StructureNotifyMask|
                               SubstructureNotifyMask|
                               KeyPressMask);

   /* Find out which children have set window manager hints */

   for (i = 0, child = children; i < nchildren; ++i, ++child) {
      if (wmhints = GetWMHints(display,*child,&current)) {
         XSelectInput(display,current,EnterWindowMask);
         XFree(wmhints);
      }
   }
   XFree(children);

   /* 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;
      XDestroyWindowEvent *destroy = (XDestroyWindowEvent *)&event;

      XNextEvent(display,&event);
      switch (event.type) {
         case MapNotify: if (wmhints = GetWMHints(display,map->window,
                                                  &current)) {
                            XSelectInput(display,current,EnterWindowMask);
                            XFree(wmhints);
                         }
                         break;

         case EnterNotify: XSetInputFocus(display,enter->window,
                                          RevertToParent,CurrentTime);
			   XMapRaised(display,enter->window);
                           break;

         case DestroyNotify: if (destroy->window == wmroot) {
                                fprintf(stderr,"Window Manager exited.\n");
                                exit(0);
                             }
      }
   }
}

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)) {
            XFree(children);
            return wmhints;
         }
      }
      if (nchildren) XFree(children);
      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,found;
   register int i;

   /* Find first full-screen child of root */

   window = RootWindow(display,DefaultScreen(display));
   found = False;

   forever {
     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);
        found = width == DisplayWidth(display,DefaultScreen(display)) &&
                height == DisplayHeight(display,DefaultScreen(display));
        if (found) break;
     }
     if (found) break;
     if (*nchildren) XFree(*children);
     sleep(5);
   }

   /* Find first full-screen child of first full-screen child of root */

   window = *child;
   XFree(*children);
   found = False;

   forever {
     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);
        found = width == DisplayWidth(display,DefaultScreen(display)) &&
                height == DisplayHeight(display,DefaultScreen(display));
        if (found) break;
     }
     if (found) break;
     if (*nchildren) XFree(*children);
     sleep(5);
   }

   /* Found window manager's pseudo-root; return it & its children */

   window = *child;
   XFree(*children);
   XQueryTree(display,window,&root,&parent,children,nchildren);
   return window;
}

static int IgnoreDeadWindow(display,error)
   Display *display;
   XErrorEvent *error;
{
   if (error->request_code == 42)  /* Bad Window Id */
      return;
   else XSetErrorHandler(NULL);
}

static Window FrameOf(display,window,wmroot)    /* recursive */
   Display *display;
   Window window,wmroot;
{
   Window root,parent,*children;
   int nchildren;

   XQueryTree(display,window,&root,&parent,&children,&nchildren);
   return parent == wmroot ? window : FrameOf(display,parent,wmroot);
}



----------------------------------------------------------------------
 Jim West                      |  The Schainker Converse
 west@gsrc.dec.com             |  to Hoare's Law :
                               |
 These are my opinions.        |   Inside every small problem
 Digital has no idea           |     is a larger problem struggling
 what I'm  saying.             |       to get out.
----------------------------------------------------------------------

alex@lvd1.bme.ohio-state.edu (Alex Savchenko) (07/14/90)

In article <1427@shodha.dec.com>, west@gsrc.dec.com (Jim West (Stealth
Contractor)) writes:
> - 
> -Thanks
> 
>   Here's a hack program that will do what you want.  It goes against the
> grain of the DECwindows window manager...but it does work.
> 
> NOTE: Totally %100 UNSUPPORTED !!
> 
> 

	Sorry, Jim, I couldnt reach you by e-mail. Thanks so much for
	this program! It really works! I think Steve is not the only
	one who is annoyed by dxwm behavior. Me too!

	I ported it to my evironment: DS3100, Ultrix Worksystem V2.1
(Rev. 14) XR3. In order this program to work here I had to make slight changes
which can be useful if someone will port it to similar environment.
Though this is 100% unsupported code, I want to offer a patch (just so)
:-)

--------------------------------------------------- cut here
*** autofocus.old	Fri Jul 13 15:58:30 1990
--- autofocus.c	Fri Jul 13 15:53:18 1990
***************
*** 3,12 ****
                 Author: Dave Burleigh
  
  */
  #include <stdio.h>
- #include <stdlib.h>
  #ifdef vms
  #include <decw$include/X.h>
  #include <decw$include/Xlib.h>
  #include <decw$include/Xutil.h>
  #else
--- 3,12 ----
                 Author: Dave Burleigh
  
  */
  #include <stdio.h>
  #ifdef vms
+ #include <stdlib.h>
  #include <decw$include/X.h>
  #include <decw$include/Xlib.h>
  #include <decw$include/Xutil.h>
  #else
***************
*** 33,41 ****
--- 33,48 ----
     int nchildren,i;
  
     /* Open the default display */
  
+ #ifdef vms
     strcat(strcpy(display_name,getenv("SYS$NODE")),"0");
+ #else
+    {
+ 	register char *node;
+ 	strcpy(display_name, (node = getenv("DISPLAY"))? node : ":0.0");
+    }
+ #endif
  
     if (!(display = XOpenDisplay(display_name))) {
        fprintf(stderr,"Can't open display\n");
        exit(0);

-----------------------------------------------------------------------
Thanks again,
---- alex