Tk Source Code

View Ticket
Login
Ticket UUID: 1474465
Title: Debian 8 focus test failures
Type: Bug Version: obsolete: 8.5a4
Submitter: vincentdarley Created on: 2006-04-21 22:47:13
Subsystem: 55. [focus] Assigned To: nobody
Priority: 2 Severity: Minor
Status: Closed Last Modified: 2026-10-17 10:34:05
Resolution: Fixed Closed By: nemethi
    Closed on: 2026-10-17 10:34:05
Description:
The following tests fail (and given the serious 'lost focus' bug in 
TkAqua, it is plausible that something here is important):

focus.test

==== focus-1.1 Tk_FocusCmd procedure FAILED
==== Contents of test case:

    focusClear
    focus

---- Result was:
.t
---- Result should have been (exact matching):

==== focus-1.1 FAILED


==== focus-1.3 Tk_FocusCmd procedure FAILED
==== Contents of test case:

    focusClear
    focus .t.b3
    focus

---- Result was:
.t.b3
---- Result should have been (exact matching):

==== focus-1.3 FAILED


==== focus-1.12 Tk_FocusCmd procedure, -displayof option FAILED
==== Contents of test case:

    focusClear
    focus .t
    focus -displayof .t.b3

---- Result was:
.t
---- Result should have been (exact matching):

==== focus-1.12 FAILED


==== focus-1.19 Tk_FocusCmd procedure, -force option FAILED
==== Contents of test case:

    focusClear
    focus .t.b1
    set x  [list [focus]]
    focus -force .t.b1
    lappend x [focus]

---- Result was:
.t.b1 .t.b1
---- Result should have been (exact matching):
{} .t.b1
==== focus-1.19 FAILED
User Comments: nemethi (claiming to be Csaba Nemethi) added on 2026-10-17 10:34:05:

Closing the ticket.


serhiy.storchaka added on 2026-09-27 06:59:38:

Jan merged branch focus-test-xfocus to [db7cd2265c|main] and [8d4d9b335b|core-9-0-branch]. Backported to [627e9b9c1c|core-8-6-branch].


serhiy.storchaka added on 2026-09-25 21:54:19:

History of the failing tests:

  • focus-2.6, 2.7 and 2.9 are older than the repository. They unit-test TkFocusFilterEvent by generating FocusIn/FocusOut events with various details on the wrapper window, as if they came from the X server.
  • [185b0e79ee] (2008, fix for [1389270fff]) made generated focus events bypass TkFocusFilterEvent, so these tests could not pass any more (since 8.6.0). In 2020 they were constrained with failsOnUbuntu, later renamed to failsOnCILinux.
  • focus-5.1 is also older than the repository and originally expected {.t .t {}}. In 1999 [345cee8ff6] ("fixed broken test") changed it to {.t {} {}}. But send defers all other events while it waits for the reply, so the FocusOut is not processed when [focus] is read. The fix is an update after the send, as bll suggested in 2020 and fvogel did in [c879e9ad11] ([1642750fff]).
  • In 2023 fvogel's unmerged branch less_tests_constraints_focus tried to distinguish Tk's internal focus events from generated ones.
  • Other tests (focus-2.10, 2.15-2.17 and some focus-1.x, 3.x and 4.x) fail only with some window managers. focusClear relies on another application taking the focus, and some window managers refuse this or give the focus back later.

There are now two alternative fixes:

  • focus-test-wrapper-events changes the library: events generated for a wrapper window are processed as real ones, so the old tests work again.
  • focus-test-xfocus changes only the tests. The new test command testxfocus moves the real X focus, and focus-2.6, 2.7 and 2.9 use it instead of generated events. focusClear falls back to setting the X focus to None. With it, focus.test passes without a window manager and with fvwm, icewm, twm, i3, openbox and mutter (Xwayland).

testxfocus is also added by the unmerged branches focus-after-grab ([220892fff]), x11-embed-focus-return ([a4fa3ad2d6]) and x11-override-redirect-focus ([a53a902ac6]), so its cost is shared. This branch only adds the none and pointerroot arguments.

I leave the choice between the two branches to the core developers.


serhiy.storchaka added on 2026-09-19 16:03:25:

focus-2.6, 2.7 and 2.9 fail even without a window manager: since [185b0e79ee] generated focus events do not change the focus, so they could not simulate the X server any more. Now events generated for a wrapper window (only reachable via testwrapper) are processed as real ones. focus-5.1 needed an update after the send. Fixed in [7c561b978f] (branch focus-test-wrapper-events).


fvogel added on 2023-01-29 22:08:30:

In commit [a5eaa33f] I'm working around KDE's focus stealing prevention that leads to focus tests failures still on Debian 11. This commit is a first step: Don't use the background machinery to ensure the current app has no focussed window, rather recycle proc fixfocus instead (and rename it to focusClear). With this commit there is no failure anymore on Debian 11 before focus-2.1.

Then in commit [00bdaf0f] I have flagged several focus-2.* tests with 'knownBug'. Indeed, commit [185b0e79] that fixed [1389270fff] made a change in how <FocusIn> and <FocusOut> events are handled. This change was not compatible with the expected results of these tests. Fact is [00bdaf0f] changes the flagged tests results, which I have marked 'knownBug' for this reason. Whether the expected results should be changed as a consequence of [00bdaf0f], or whether [00bdaf0f] introduced a regression is not clear to me. This problem remained undetected since 2008 (probably because these tests used to be constrained with nonPortable so far, thus were not routinely run).


marc_culler (claiming to be Marc Culler) added on 2020-09-09 20:36:45:
Changing the title, since this does not affect macOS at this point.

bll added on 2020-07-02 00:56:47:
On a debian 10 derivative with XFCE, 2.6, 2.7, 2.9, 5.1 fail.
XFCE has both "focus stealing prevention" and "honor standard ICCCM focus hints"
settings that can be changed. (I use on and off settings in an attempt to prevent
focus stealing; maybe it is slightly helpful).
6.1 fails if I have both focus stealing and honor icccm hints on.

I can figure out the commands to change the wm settings from the command line
for xfce, gnome, kde if that is helpful, but I don't think it will be.

I don't know what all those detail fields are indicative of or what use they 
have, so I can't understand 2.[679].

Switching toplevels is dependent on window manager and window manager settings,
and timing issues, so it's rather difficult to test.

This seems to fix 5.1.  Seems like a timing issue to me.
     set result [focus]
     send [dobg {tk appname}] {focus -force .; update}
+    update

fvogel added on 2020-07-01 20:06:55:

Debian 10 with KDE: I have just discovered that the number of focus tests failures decreases dramatically if the focus stealing prevention (in the KDE settings) is adjusted from its default "Low" to "None". This makes sense!

With that change, focus -force . does the exected thing, and many focus related tests do PASS again.

So these failures are a result of KDE trying to prevent applications from stealing the focus from under the user's feet, which is considered as a bad behavior from applications.

The problem is that the tests really need to force focus in order to test the [focus] Tk command.

So what could we do?

  • Temporarily remove the focus stealing prevention when running the Tk test suite. I have no idea about how to do that.
  • Change the code of focus -force ... to bypass the focus stealing prevention from KDE. Even if this was possible, and if I knew how to do that, I don't think it's desirable because in production code user's settings would no longer be respected.
  • Not test the focus command when the focus stealing prevention would make it fail. That is, constraint all concerned tests by some constraint that would be true when focus stealing prevention is higher than "None". How could we detect this from Tk? How portable would this be?

Kind of stuck... Advices?


fvogel added on 2018-07-06 18:04:45:
Zero failure for focus.test on macOS though.

fvogel added on 2016-09-03 15:06:31:

I believe the focus removal machinery in focus.test does just not work with the KDE 4.14.2 window manager on Debian 8.

In proc focusClear we have:

dobg {focus -force .; update}

This is supposed to force the focus to be on the "." toplevel from another wish instance created in the background (see namespace eval bg {...} machinery).

But the above call to dobg does not succeed in moving the focus to the other (background) application.

As if the specific wm I use (KDE 4.14.2) denied this focus move.

It works however with Gnome 2.30.2 on Debian 6...

I think this problem triggers most or perhaps all the failures reported here.

I don't know how to fix this.


fvogel added on 2016-08-20 10:17:45:
These focus tests also fail for me on Linux Debian 8 with core-8-6-branch.

In addition to the four failed tests from the original report I see:


==== focus-2.6 TkFocusFilterEvent procedure, FocusIn events FAILED
==== Contents of test case:

    focus .t.b1
    focus .
    update
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    set focusInfo {}
    set x [focus]
    event gen . <KeyPress-x>
    list $x $focusInfo

---- Result was:
. {press . x}
---- Result should have been (exact matching):
.t.b1 {press .t.b1 x}
==== focus-2.6 FAILED



==== focus-2.7 TkFocusFilterEvent procedure, FocusOut events FAILED
==== Contents of test case:

    set result {}
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
            NotifyNonlinearVirtual NotifyPointer NotifyPointerRoot
            NotifyVirtual} {
            focus -force .t.b1
            event gen [testwrapper .t] <FocusOut> -detail $detail
            update
            lappend result [focus]
    }
    return $result

---- Result was:
.t.b1 .t.b1 .t.b1 .t.b1 .t.b1 .t.b1 .t.b1
---- Result should have been (exact matching):
{} .t.b1 {} {} .t.b1 .t.b1 {}
==== focus-2.7 FAILED



==== focus-2.9 TkFocusFilterEvent procedure, FocusOut events FAILED
==== Contents of test case:

    focus .t.b1
    event gen [testwrapper .] <FocusOut> -detail NotifyAncestor
    focus

---- Result was:
.t.b1
---- Result should have been (exact matching):

==== focus-2.9 FAILED



==== focus-2.10 TkFocusFilterEvent procedure, Enter events FAILED
==== Contents of test case:

    set result {}
    focus .t.b1
    focusClear
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
                NotifyNonlinearVirtual NotifyVirtual} {
            event gen [testwrapper .t] <Enter> -detail $detail -focus 1
            update
            lappend result [focus]
            event gen [testwrapper .t] <Leave> -detail NotifyAncestor
            update
    }
    return $result

---- Result was:
.t.b1 .t.b1 .t.b1 .t.b1 .t.b1
---- Result should have been (exact matching):
.t.b1 {} .t.b1 .t.b1 .t.b1
==== focus-2.10 FAILED



==== focus-2.13 TkFocusFilterEvent procedure, Enter events FAILED
==== Contents of test case:

    focus .t.b1
    focusClear
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    set focusInfo {}
    update
    return $focusInfo

---- Result was:

---- Result should have been (exact matching):
in .t NotifyVirtual
in .t.b1 NotifyAncestor

==== focus-2.13 FAILED



==== focus-2.15 TkFocusFilterEvent procedure, Leave events FAILED
==== Contents of test case:

    set result {}
    focus .t.b1
    foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
            NotifyNonlinearVirtual NotifyVirtual} {
            focusClear
            event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
            update
            event gen [testwrapper .t] <Leave> -detail $detail
            update
            lappend result [focus]
    }
    return $result

---- Result was:
.t.b1 .t.b1 .t.b1 .t.b1 .t.b1
---- Result should have been (exact matching):
{} .t.b1 {} {} {}
==== focus-2.15 FAILED



==== focus-2.16 TkFocusFilterEvent procedure, Leave events FAILED
==== Contents of test case:

    focusClear
    focus .t.b1
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    update
    set focusInfo {}
    event gen [testwrapper .t] <Leave> -detail NotifyAncestor
    update
    return $focusInfo

---- Result was:

---- Result should have been (exact matching):
out .t.b1 NotifyAncestor
out .t NotifyVirtual

==== focus-2.16 FAILED



==== focus-2.17 TkFocusFilterEvent procedure, Leave events FAILED
==== Contents of test case:

    focusClear
    focus .t.b1
    event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
    update
    set focusInfo {}
    event gen .t.b1 <Leave> -detail NotifyAncestor
    event gen [testwrapper .] <Leave> -detail NotifyAncestor
    update
    list $focusInfo [focus]

---- Result was:
{} .t.b1
---- Result should have been (exact matching):
{out .t.b1 NotifyAncestor
out .t NotifyVirtual
} {}
==== focus-2.17 FAILED



==== focus-4.2 TkFocusDeadWindow procedure FAILED
==== Contents of test case:

    focusSetup
    update
    focus -force .t.b2
    focus .b
    update
    destroy .t.b2
    update
    focus

---- Result was:
.t
---- Result should have been (exact matching):
.b
==== focus-4.2 FAILED



==== focus-5.1 ChangeXFocus procedure, don't take focus unless have it FAILED
==== Contents of test case:

    setupbg
    focusSetup
    focus -force .t
    update
    set result [focus]
    send [dobg {tk appname}] {focus -force .; update}
    lappend result [focus]
    focus .t.b2
    update
    lappend result [focus]

---- Result was:
.t .t {}
---- Result should have been (exact matching):
.t {} {}
==== focus-5.1 FAILED


(the latter being already reported in [1642750])