[comp.windows.x] hacking on uwm

jkh@violet.berkeley.edu (Jordan K. Hubbard) (11/23/87)

I've been hacking on Your Favorite Window Manager and Mine :-), uwm
to add title bars, autoraise and various other dubiously useful features.
I'd like to get some comments on the hacks (to see if anyone has better
ideas, or just plain hates these for some reason) and then describe some
of the problems I'm having.

There are some new "variables" that uwm lets you set:

[no]resizeobscure --	Makes the resize popup window sit on the resized window
			(the way it is now) or the upper left corner of the
			screen (like mapwindow popups).

[no]titles --		Put title frobs on all windows that aren't icons,
			overriding map redirect or InputOnly.

titlefont --		Set the font to use for titles.

[no]autoraise --	Annoyingly raise windows on focus like the old xterm.

By default, the text portion of the title is centered. I'll add an
option to put it elsewhere if someone gives me a good enough reason.

I'm also currently doing the title bar manipulation myself, though
if someone can give me a good enough reason to use the toolkit (and let me
know the heck I'm supposed to get the event processing stuff to
cooperate without major re-write) I'll use that.

I've added a hack that allows you to set boolean variables from
menus. I.E. The following is now possible:

	menu = "MISC OPS" {
	"Nozap":	nozap
	"zap":		zap
	"noobscure":	noresizeobscure
	"Focus":	f.focus		# for context
	}

If anyone can think of a case where setting numerics and strings(!)
is useful, let me know. I added numerics, but the grammer for was
a little gross so I took then back out. One prefers to have yacc check
the legality of these things before they ever get executed, since
uwm may be backgrounded somewhere by then. Functionality is questionable
for all but booleans (and even then..) since the values are merely
changed, nothing else is notified. Changing a font on the fly would
do nothing, for example, since they're all allocated on startup.

Now for the PROBLEMS..

For AutoRaise:

Let me know if I'm wrong, but by default the focus is in whatever window
contains the pointer, yes? So, wouldn't it follow to assume that a window
would get FocusIn and FocusOut events for this? Nope. How about at least
knowing when the Focus is grabbed? Yeah.. that works. but hmmm. This is
strange. I get a FocusIn when I do an XSetInputFocus on my window, but
when I do the SetFocus on another window afterwards, I get no FocusOut
on the original! Yuck! Why is this? In my case, I just wanted to
select a FocusChangeMask on the rootwindow and (hopefully) know when
any children got or lost the focus. Zilch.

Ok, so we forget about that for the moment and use Enter/Leave for the
more trival pointer-focus case. Well. Just how do I see the Enter/Leaves for
everybody? uwm already selects Substructure{Notify,Redirect}Mask on the
RootWindow, but that doesn't pass up Enter/Leave events, so I
also selected Enter/Leave for the RootWindow, which naturally worked only
when you went from the root into a child or vice/versa. How do I know
when I leave one sibling for another? No events are generated for the
root window, that's for sure.

I know I could solve all (the enter/leave, not the focus) this by
reparenting everyone and selecting for all the parents, but I really don't
want to do that unless the person has selected title bars. I'd like
each option to do only what's necessary to make itself work and not
depend on any other options being set.
Of course, if that's the only possible way to make it work, then I guess
uwm is just going to reparent the world whether it likes it or not.

Am I missing something really big? I've read the event section of the
Xlib manual more times than I care to count.

					Jordan Hubbard
					U.C. Berkeley

P.S. with the exception of autoraise, everything should be releasable
in a day or so.

RWS@ZERMATT.LCS.MIT.EDU (Robert Scheifler) (11/24/87)

    Date: 23 Nov 87 20:41:01 GMT
    From: violet.berkeley.edu!jkh@jade.Berkeley.EDU  (Jordan K. Hubbard)

    Let me know if I'm wrong, but by default the focus is in whatever window
    contains the pointer, yes? So, wouldn't it follow to assume that a window
    would get FocusIn and FocusOut events for this? Nope.

Quite possible we blew it here (see also fix #56).  The thinking at the time
was that adding a focus boolean to enter/leave events would suffice, but it
hasn't been working out that way.

	     I get a FocusIn when I do an XSetInputFocus on my window, but
    when I do the SetFocus on another window afterwards, I get no FocusOut
    on the original! Yuck!

So submit a bug report.

					  Just how do I see the Enter/Leaves for
    everybody? uwm already selects Substructure{Notify,Redirect}Mask on the
    RootWindow,

As top-level windows get created, select for enter/leave on them.

							    How do I know
    when I leave one sibling for another? No events are generated for the
    root window, that's for sure.

Correct.

swick@ATHENA.MIT.EDU (Ralph R. Swick) (11/24/87)

FocusIn/Out events are generated only when the focus changes.  The 'default'
behavior of keyboard events going to the window containing the pointer is
actually PointerRoot focus.  Since the focus hasn't actually changed
when the pointer moves, there are no events.

EnterNotify is the way to go.  You can select this on each of the client
windows when you get the MapRequest; no need to re-parent.  You will have
to be careful when you have both titlebars and autoraise (you no longer
want EnterNotify on the children).  You'll also have to be careful about
the `oscillating menu syndrome' which will occur when you map the uwm
menu.

Glad you're doing this; I had started many months ago but quickly got
higher-priority things to do.

jkh@VIOLET.BERKELEY.EDU (11/24/87)

>Quite possible we blew it here (see also fix #56).  The thinking at the time
>was that adding a focus boolean to enter/leave events would suffice, but it
>hasn't been working out that way.

Any clues as to whether this is going to change, or are you/we going to
just live with it?

>	     I get a FocusIn when I do an XSetInputFocus on my window, but
>   when I do the SetFocus on another window afterwards, I get no FocusOut
>   on the original! Yuck!

>>So submit a bug report.

I will, now that I'm sure it's a bug and know where to look. I'd like
to submit a patch along with it, if possible.

>As top-level windows get created, select for enter/leave on them.

Sigh. I'd hoped to avoid that, since that also means I have to grab the
server and walk the tree to select on all the current windows as well.
No big deal, I guess, just a pain.

Anyway, thanks for the reply.

				Jordan

RWS@ZERMATT.LCS.MIT.EDU (Robert Scheifler) (11/25/87)

    Date: Tue, 24 Nov 87 12:45:23 PST
    From: jkh@violet.Berkeley.EDU

    >Quite possible we blew it here (see also fix #56).  The thinking at the time
    >was that adding a focus boolean to enter/leave events would suffice, but it
    >hasn't been working out that way.

    Any clues as to whether this is going to change, or are you/we going to
    just live with it?

Likely one of the things the Consortium will discuss at some point.

diamant@hpfclp.UUCP (12/03/87)

> EnterNotify is the way to go.  You can select this on each of the client
> windows when you get the MapRequest; no need to re-parent.  You will have
> to be careful when you have both titlebars and autoraise (you no longer
> want EnterNotify on the children).  You'll also have to be careful about
> the `oscillating menu syndrome' which will occur when you map the uwm
> menu.

I don't have a good feel for how the focus events have changed with X11, but
this seems like it can't be right.  It would make it impossible to correctly
implement a click listener model rather than the tracked one (one where
you have to perform an action to force input to move to a new window).

This is something that always bothered me about X10 applications too (like
xterm).  For instance, I seem to remember xterm having a highlighted border
on entry and exit even if the listener model was not tracked.  This is
WRONG.  It gave the user feedback that the input focus had changed, when
in fact it hadn't.  Using EnterNotify can't be the right answer, because
it will always lead to incorrect behavior when in a non-tracked listener.
Maybe some combination of EnterNotify and FocusIn would do the trick, but
EnterNotify by itself won't do it.

If I'm missing something here, please let me know, but if not, what we
are talking about is pretty important.  The whole idea of having focus events
and being able to select a tracked versus explicit listener is to remain
policy free.  If the code is written to assume one model, it is
no longer policy free, because it is biased towards a tracked listener.


John Diamant 				 UUCP: {hplabs,hpfcla}!hpfclp!diamant
Hewlett Packard Co.		ARPA Internet: diamant%hpfclp@hplabs.HP.COM
Fort Collins, CO

diamant@hpfclp.HP.COM (John Diamant) (12/07/87)

> > EnterNotify is the way to go.
> 
> this seems like it can't be right.  It would make it impossible to correctly
> implement a click listener model rather than the tracked one (one where
> you have to perform an action to force input to move to a new window).
> 
> Maybe some combination of EnterNotify and FocusIn would do the trick, but
> EnterNotify by itself won't do it.

Jordan pointed out to me (in a private letter) that there was a focus flag
in the event structures for Enter and Leave events.  It appears that using
this flag will resolve my concern about handling non-tracked listeners.
That flag tells you whether the input focus is in the window generating that
event.

I think the correct way to handle this would be to monitor all Enter and Leave
events, but to take action only on the value of the focus flag (don't care
whether this was an Enter or a Leave -- what matters is where the input
focus went).  Likewise, you still need to watch for FocusIn/FocusOut
events since in a non-tracked listener, the Focus will not come with a window
entry.  As I understand it, there will be no FocusIn or FocusOut events in
a tracked listener, which is fine if you are monitoring the focus flag on the
Enter and Leave events.

I would like to make a plea to all X11 application writers not to forget about
the non-tracked listener and pay attention to the focus in the way I've
described (unless of course my logic is wrong, in which case application
programmers should do it right!).

John Diamant 				 UUCP: {hplabs,hpfcla}!hpfclp!diamant
Hewlett Packard Co.		ARPA Internet: diamant%hpfclp@hplabs.HP.COM
Fort Collins, CO