Subject: Re: FVWM: Re: Bug also in FvwmTabs

From: Scott Smedley <[email-masked]>
Date: Thu, 27 Nov 2003 12:17:01 +1100

Hi Tobias,

I've moved this thread to the fvwm-workers list as the discussion
is a bit technical.

: Changing the SetInputFocus() to 
: "$xServer->SetInputFocus($winId, 'Parent', 'CurrentTime');"
: its all working flawless.

Hmmm, it is interesting that this solves your problem. Earlier versions
of FvwmTabs used to do exactly this, but caused focussing race conditions.
(ie. moving the mouse cursor quickly over a tab-manager & onto another
window would leave the focus on the tab-manager, not the window under
the mouse.)

A side note:
The use of the $tabWin{$tId}{focusTimestamp} was a workaround because
there doesn't appear to be any way to get the timestamp for the
WM_TAKE_FOCUS event. I just use the timestamp from the EnterNotify
event.

: The variables in $tabWin{$tId}{focusTimestamp} does look ok though, but
: i dont have any knowledge about the X11-Protocol. Perhaps you know
: what could be wrong.

Hmmm, the only issue I can think of (that would cause the problem you
describe) is a situation where the XServer (for whatever reason) looks
at the timestamp & decides that it is "old" & ignores the SetInputFocus()
call. (effectively the mechanism used to avoid focussing race conditions.)

ie. suppose in your X server the EnterNotify event is triggered
*before* the WM_TAKE_FOCUS event (which would cause FvwmTabs to
use an "old" timestamp) & in my X server the events are triggered
in the opposite order which would lead to a valid timestamp.

All this is just a hypothesis. It (the hypothesis) needs to be tested.
Let's start with your X server - what version are you using?

Remind me again: this problem only occurs when you switch desks?

: Hopefully i could help you finding the bug.

A good clue! Hopefully we'll get to the bottom of this soon. :)

SCoTT. :)
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Tobias <[email-masked]>
Date: Thu, 27 Nov 2003 19:11:57 +0100

Hi Scott

On Thu, 27 Nov 2003 12:17:01 +1100

> I've moved this thread to the fvwm-workers list as the discussion

Just added myself to the list.

> in the opposite order which would lead to a valid timestamp.
(As far as i understand the code the EnterNotify does set the timestamp.
That means EnterNotify should be called before WM_TAKE_FOCUS). 

> All this is just a hypothesis. It (the hypothesis) needs to be tested.

I have done the following:

1) Redirected the callback func at
"
$tl->protocol('WM_TAKE_FOCUS', [\&takeFocus, $tId]);
" to a similar with different STDERR output.

In every tried situation there are 2 WM_TAKE_FOCUS first and then 
1 EnterNotify-event.

2 Questions: 
- Why are there 2 WM_TAKE_FOCUS signals ?
- If only EnterNotify does set the timestamp how could the
 WM_TAKE_FOCUS work right now ? 

According to http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7:
----
Windows with the atom WM_TAKE_FOCUS in their WM_PROTOCOLS property may receive a ClientMessage event from the window manager (as described in section 4.2.8) with WM_TAKE_FOCUS in its data[0] field and a valid timestamp (i.e. not CurrentTime ) in its data[1] field. If they want the focus, they should respond with a SetInputFocus request with its window field set to the window of theirs that last had the input focus or to their default input window, and the time field set to the timestamp in the message. For further information, see section 4.2.7.
----
Cannot this be done instead ? (I dont found examplecode on the web, and dont know much
perl/tk on my own to test it out).

2) 
i commented the WM_TAKE_FOCUS callback func!

The EnterNotify-Event does _work_ if i focus(via mouse) some other
window on current desktop. (situation 1)
---
Got a EnterNotify event: event_y = 741, flags = 2, mode = Normal, event_x = 17, time = 8186630, name = EnterNotify, focus = 0, child = 8389563, event = 8389562, state = 0, detail = Virtual, sequence_number = 1017, root_x = 151, root = 118, same_screen = 1, root_y = 777, code = 7
inside EnterNotify:8186630
inside takeFocus:8186630
---

But if i switch the Desktop (via keyboard)
forth and back, the EnterNotify-Event is triggered but focus not gained. (situation 2)
---
Got a EnterNotify event: event_y = 982, flags = 2, mode = Normal, event_x = 191, time = 8158642, name = EnterNotify, focus = 0, child = 8389563, event = 8389562, state = 8, detail = Virtual, sequence_number = 905, root_x = 325, root = 118, same_screen = 1, root_y = 1018, code = 7
inside EnterNotify:8158642
inside takeFocus:8158642
---

3) I did increment(1) and decrement(2) the timestamp manually.

If i do (1) or (2) with some high number (eg 8000) the focus is
not gained in situation 1! There seems to be some kind of
protection. This could lead to the conclusion that the timestamp
of the EnterNotify-event in situation 2 is too wrong (too old/new)
and therefore got ignored.
Unfortinatly i dont know how to get the "CurrentTime" in perl to
check for differences.

> Let's start with your X server - what version are you using?

x11-base/xfree-4.3.0-r3 *  (including some gentoo patches :( )
dev-perl/X11-Protocol-0.52 *
dev-lang/tk-8.3.4-r1 *
dev-perl/perl-tk-800.025 *

> Remind me again: this problem only occurs when you switch desks?

As descriped in Situation 2.

Greets 
Tobias

---

From: Scott Smedley <[email-masked]>
Date: Fri, 28 Nov 2003 10:35:35 +1100

Hi Tobias,

A nice bit of sleuthing! :)

: In every tried situation there are 2 WM_TAKE_FOCUS first and then 
: 1 EnterNotify-event.

Hmmm, I get this sequence of events every time I focus a tab-manager window:
WM_TAKE_FOCUS
WM_TAKE_FOCUS
EnterNotify
WM_TAKE_FOCUS
EnterNotify
WM_TAKE_FOCUS

(Am wondering: how come you get 3 events & I get 6?)

: 2 Questions: 
: - Why are there 2 WM_TAKE_FOCUS signals ?

BIIK - Buggered if I know.

: - If only EnterNotify does set the timestamp how could the
:  WM_TAKE_FOCUS work right now ? 

Yeah, this would be the problem. For some reason I get a WM_TAKE_FOCUS
*after* an EnterNotify event which means I've got a valid timestamp.

: According to http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7:
: ----
: Windows with the atom WM_TAKE_FOCUS in their WM_PROTOCOLS property may receive a ClientMessage event from the window manager (as described in section 4.2.8) with WM_TAKE_FOCUS in its data[0] field and a valid timestamp (i.e. not CurrentTime ) in its data[1] field. If they want the focus, they should respond with a SetInputFocus request with its window field set to the window of theirs that last had the input focus or to their default input window, and the time field set to the timestamp in the message. For further information, see section 4.2.7.
: ----
: Cannot this be done instead ?

This is the workaround I was talking about. Perl/Tk doesn't provide any
way to get the timestamp (ie. data[1]) I posted a question about it on
comp.lang.perl.tk on 8-Nov but noone could help. I think I need to delve
into the Perl/Tk source code.

: The EnterNotify-Event does _work_ if i focus(via mouse) some other
: window on current desktop. (situation 1)
: ---
: Got a EnterNotify event: event_y = 741, flags = 2, mode = Normal, event_x = 17, time = 8186630, name = EnterNotify, focus = 0, child = 8389563, event = 8389562, state = 0, detail = Virtual, sequence_number = 1017, root_x = 151, root = 118, same_screen = 1, root_y = 777, code = 7
: inside EnterNotify:8186630
: inside takeFocus:8186630
: 
: But if i switch the Desktop (via keyboard)
: forth and back, the EnterNotify-Event is triggered but focus not gained. (situation 2)
: ---
: Got a EnterNotify event: event_y = 982, flags = 2, mode = Normal, event_x = 191, time = 8158642, name = EnterNotify, focus = 0, child = 8389563, event = 8389562, state = 8, detail = Virtual, sequence_number = 905, root_x = 325, root = 118, same_screen = 1, root_y = 1018, code = 7
: inside EnterNotify:8158642
: inside takeFocus:8158642

Err, this is contrary to your first statement. (about always getting 2
WM_TAKE_FOCUS events then 1 EventNotify event)

Anyway. In both cases you are getting an EnterNotify event *before*
WM_TAKE_FOCUS (which is good). That suggests that the problem is an old
timestamp, but I don't understand why the timestamp value would be ok
normally but not when you switch desks.

: 3) I did increment(1) and decrement(2) the timestamp manually.
: 
: If i do (1) or (2) with some high number (eg 8000) the focus is
: not gained in situation 1!

I would expect this. If it's too new the X server will probably ignore
it. (events can't occur in the future unless you're Marty McFly) & if
it's too old then the focussing event will have been superceeded.

: This could lead to the conclusion that the timestamp
: of the EnterNotify-event in situation 2 is too wrong (too old/new)
: and therefore got ignored.

If it's too new it's a bug in the X server - ie. unlikely. I think
the problem must be that the timestamp is too old.

: Unfortinatly i dont know how to get the "CurrentTime" in perl to
: check for differences.

Well only the X server knows about the current time of course. You can
query it but by the time you get a response time has passed. :)

: x11-base/xfree-4.3.0-r3 *  (including some gentoo patches :( )

Hmmm, I'm on:
 XFree86 Version 4.3.0 (Red Hat Linux release: 4.3.0-2)

Anyway, the ideal solution would be to be able to get at the timestamp
of the WM_TAKE_FOCUS event. I think I'll delve into the Perl/Tk
source on the w/end & see if I can nut it out.

SCoTT. :)

---

From: Tobias <[email-masked]>
Date: Fri, 28 Nov 2003 11:26:39 +0100

On Fri, 28 Nov 2003 10:35:35 +1100

> (Am wondering: how come you get 3 events & I get 6?)

i just retested it. My sequence is - as said- normaly 
WM_TAKE_FOCUS
WM_TAKE_FOCUS
EnterNotify.

(sometimes it is different. dont know why)

There is no EnterNotify *before* WM_TAKE_FOCUS!

> WM_TAKE_FOCUS events then 1 EventNotify event)

No, because in _this_ test i disabled the WM_TAKE_FOCUS callback. I meant 
that the EnterNotify _alone_ can get the focus in situation 1 but not
in situation 2.

> normally but not when you switch desks.

You misunderstood. In all cases there is no EnterNotify *before* WM_TAKE_FOCUS!
(see above)

Conclusion:
We now presume WM_TAKE_FOCUS does not work *before* EnterNotify due to wrong
timestamp. And in all two situations there are (on my computer at least) no 
WM_TAKE_FOCUS directly after EnterNotify.
That would mean only EnterNotify-Event can set the focus (for me).
But in reality EnterNotify does set the focus only in situation 1, but not in 2. 
That means we have 2 ways of fixing the bug:
1) Solve the problem why EnterNotify does not get focus on situation 2 and 
completely disable WM_TAKE_FOCUS.
2) Fix WM_TAKE_FOCUS and live with the additional EnterNotify-Events which do
not work in situation 2.

> source on the w/end & see if I can nut it out.

Yes, that would be the best.

Greets
Tobias