Re: fun with window managers.. (help!)



----- Original Message -----
From: "Havoc Pennington" <hp redhat com>
To: "Bill Haneman" <bill haneman sun com>
Cc: <gtk-devel-list gnome org>
Sent: Friday, November 09, 2001 8:47 PM
Subject: Re: fun with window managers.. (help!)


>
> Bill Haneman <bill haneman sun com> writes:
> > I am running sawfish 0.36, which claims to respect WM_TAKE_FOCUS.  But
> > it looks as though GDK maybe always calls XSetInputFocus() when it
> > receives WM_TAKE_FOCUS, which is not what we want.  Furthermore I am
> > warned that sawfish may not respect these settings if they are called on
> > already-mapped windows, but it looks to me as though I can't set them on
> > GDK windows unless they have already been mapped, since I can't change
> > the initial property/flag settings on gdk_window_new(), can I ?
>
> Basically all window managers I've looked at do not properly comply
> with the ICCCM on this (i.e. they do not allow "output only"
> clients). With a compliant window manager, the "xev" utility won't get
> any key events. With most window managers it does.
>
> Sawfish has a config option to make it ICCCM compliant in this
> respect. I'm not sure what the default is.

I have once written a little test program to experiment with the 4 ICCCM
focus modes.
It is not polished at all, but it is good enough to find wm problems with
focus handling.

Maybe it is of interest to you (and wm authors, thus I CC'ed wm-spec-list)

Matthias



/* This example experiments with the 4 ICCCM focus modes. */

#include <X11/Xlib.h>
#include <X11/Xutil.h>

char *window_name[] = { "No Input", "Passive", "Locally Active",
		       "Globally Active", "Satellite" };

int input_hint[] = { False, True, True, False, False };
int take_focus[] = { False, False, True, True, False };

Window
input_window (Display *d, int screen, int i)
{
  Window win;
  XWMHints wm_hints;

  win = XCreateSimpleWindow (d, RootWindow (d, screen),
			     10, 10, 150, 10, 0,
			     WhitePixel (d, screen), WhitePixel (d, screen));

  XSelectInput (d, win, ButtonPressMask|FocusChangeMask|KeyPressMask);

  XStoreName (d, win, window_name[i]);

  wm_hints.flags = InputHint;
  wm_hints.input = input_hint[i];

  XSetWMHints (d, win, &wm_hints);
  if (take_focus[i])
    {
      Atom protocols[1];
      protocols[0] = XInternAtom (d, "WM_TAKE_FOCUS", False);
      XSetWMProtocols (d, win, protocols, 1);
    }

  return win;
}

int main (int argc, char *argv[])
{
  Display *d;
  int screen, i;
  Window window, win[5];
  XWindowAttributes xatt;
  Atom atom;
  XEvent ev;

  d = XOpenDisplay (NULL);

  screen = DefaultScreen (d);

  for (i = 0; i < 5; i++)
    {
      win[i] = input_window (d, screen, i);
      XMapWindow (d, win[i]);
    }

  while (1)
    {
      XNextEvent (d, &ev);

      for (i = 0; i < 5; i++)
	{
	  window = ev.xany.window;
	  if (win[i] == window)
	    {
	      printf("event on window \"%s\": ", window_name[i]);
	      switch (ev.xany.type)
		{
		case FocusIn:
		  printf ("FocusIn\n");
		  break;
		case FocusOut:
		  printf ("FocusOut\n");
		  break;
		case ButtonPress:
		  printf ("ButtonPress\n");
		case KeyPress:
		  printf ("KeyPress %s\n",
			  XKeysymToString (XLookupKeysym (&ev.xkey, 0)));
		  break;
		case ClientMessage:
		  atom = ev.xclient.data.l[0];
		  printf ("ClientMessage %s\n", XGetAtomName (d, atom));
		  if (atom == XInternAtom (d, "WM_TAKE_FOCUS", False))
		    {
		      if (i == 2)
			{
			  printf ("\t...do nothing\n");
			}
		      else if (i == 3)
			{
			  if (XGetWindowAttributes (d, win[4], &xatt)
			      && (xatt.map_state == IsViewable))
			    {
			      printf ("\t...setting focus on our own\n");
			      XSetInputFocus (d, win[4], RevertToParent,
					      ev.xclient.data.l[1]);
			    }
			  else
			    {
			      printf ("\t...but we are not viewable\n");
			    }
			}
		    }
		  break;
		default:
		  printf ("event %d\n", ev.xany.type);
		}
	    }
	}
    }

  return 0;
}









[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]