Tk Source Code

View Ticket
Login
Ticket UUID: 220892
Title: focus changes forgotten during grab
Type: Bug Version: obsolete: 8.5a2
Submitter: welch Created on: 2000-11-01 01:32:38
Subsystem: 69. Events Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2026-10-16 10:35:08
Resolution: Fixed Closed By: jan.nijtmans
    Closed on: 2026-10-16 09:52:05
Description:
OriginalBugID: 4167 Bug
Version: 8.3b1
SubmitDate: '2000-02-14'
LastModified: '2000-02-25'
Severity: SER
Status: UnAssn
Submitter: techsupp
ChangedBy: hobbs
OS: All Unix
OSVersion: SGI Irix 6.5


Comments:
Same bug with Tcl/Tk 8.3.0 and 8.0.5

ReproducibleScript:
#!/bin/env wish8.3

#
# Tk bug report, focus changes forgotten during grab
#
# Here is the scenario I have encountered on unix machines.
#
# My application brings up a small window which reports progress on a
# typically short 5 second calculation and presents a cancel button.
# The window does a pointer grab because the user cannot do other
# operations while the calculation is being performed, ie it is a modal
# dialog.  The user moves the pointer and the main application window
# is given the focus by the window manager.  The progress report window
# disappears because the calculation finishes.  Now the user tries typing
# input to the main window (like a menu accelerator) and the application
# does not receive it.
# 
# If you use the Tk focus command with no arguments at this point, Tk returns
# an empty string.  Tk believes the application does not have the focus, even
# though the window manager highlights its window frame showing that it does
# have the focus.  The problem happens because the focus change that occured
# while the progress report window had a grab was thrown away by Tk.  The
# problem is particularly common when your window manager changes focus
# whenever the pointer is moved into a new window (the default on SGI Unix
# machines where I see the problem).
# 
# There is no way for the application to deal with the fact that Tk "forgets"
# that the application has the focus during a grab.  This should be changed
# so that Tk correctly changes the keyboard focus during a grab.  This is
# the behaviour implied by the Tk grab documentation:  "During local grabs,
# keyboard events (key presses and key releases) are delivered as usual...".
# 
# It looks to me that the fix needs to be in source file generic/tkGrab.c
# but I do not have a patch.
# 
# Here is a wish8.3 script that demonstrates the problem.
# 

label .label -justify left -text {
  Click in this window to create a grabbing window.
  The grabbing window will go away after 5 seconds.
  If you switch focus to the main window during the
  grab by clicking on the main window frame, Tk will
  not remember that focus change.  It will report that
  there is no focus window, ie it thinks some other
  application has the focus.
}
pack .label

label .report
pack .report

bind . <ButtonPress> {
    toplevel .t
    wm transient .t .
    update
    focus .t
    grab set .t
    label .t.label -justify left -text {
This window has a grab set.
In 5 seconds it will go away.
    }
    pack .t.label
    after 5000 {
destroy .t
after 1000 {
    .report configure -text  "Tk reports the focus window to be '[focus]'"
}
    }
}
User Comments: serhiy.storchaka added on 2026-10-16 10:35:08:

Thank you, Jan, for the review and merging.

Also in core-8-6-branch: the test focus-10.1 came with [576e8ccaae] and the fix with [21834bb981]. It failed there before and passes now.


jan.nijtmans added on 2026-10-16 09:52:05:

Fixed in [5587d9602d1e75cd|trunk] and core-9-0-branch


serhiy.storchaka added on 2026-09-22 06:29:42:

Added test focus-10.1 in [25164463ce]. It uses a new test command testxfocus ?window? (generic/tkTest.c, X11 only) which returns the Tk window with the X input focus, and with an argument first sets the X focus to the wrapper of the window's toplevel, as a window manager does. Before the fix the toplevel which received the X focus during the grab does not get the Tk focus after the grab is released.

The same command is added on the branch for [a4fa3ad2d6], and the branch for [a53a902ac6] has a simpler version of it without the optional argument. Merging them will conflict in generic/tkTest.c and tests/constraints.tcl: keep the version with the optional argument (it is a superset) and one constraint line, and keep the tests of all branches.


serhiy.storchaka added on 2026-09-19 16:40:24:

Focus events for windows excluded by a grab are ignored on purpose, so that key events keep going to the grab window, but the focus change was then lost when the grab ended. Now the toplevel which received the focus during the grab gets it when the grab is released. Fixed in [083154ff2d] (branch focus-after-grab).


hobbs added on 2004-05-04 03:12:45:
Logged In: YES 
user_id=72656

This is still a current bug, but only for unix when it is
possible to select the parent during a grab.