Tk Source Code

View Ticket
Login
Ticket UUID: 546607
Title: problem with cursor change
Type: Bug Version: 9.1.0
Submitter: nobody Created on: 2002-04-20 21:58:02
Subsystem: 68. Win Window Operations Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2026-10-29 15:59:04
Resolution: Fixed Closed By: nemethi
    Closed on: 2026-10-29 15:59:04
Description:
I have a problem with cursor change using Tkogl (opengl extension) under Windows.
   Tkogl creates Tk_Window-window (A) and opengl-window (B) as a child of A.
   B is not Tk_Window. B just posts some messages to its parent (A) so I have no
   problem with bindings and with cursor change. But I can see the desired cursor (over B)
   only when I move the mouse or press the button. As soon as I stop moving or release the button 
-   the cursor changes to IDC_ARROW.

    It happens because of "mouseTimer" that is created in Tk_PointerEvent(hwnd, x, y) 
(tkWinPointer.c line 149).
    MouseTimerProc calls Tk_PointerEvent(NULL, pos.x, pos.y) (tkWinPointer.c line 239).

    Note that hwnd is NULL, so Tk_PointerEvent "must" find hwnd.

     hwnd = WindowFromPoint(pos); (tkWinPointer.c line 139).

    WindowFromPoint returns hwnd of B (rightly) which is not Tk_Window.
    When
 
     tkwin = Tk_HWNDToWindow(hwnd); (tkWinPointer.c line 141)

    so tkwin is NULL now.

    After this
     Tk_UpdatePointer(tkwin, pos.x, pos.y, state); (tkWinPointer.c line 145)
    with tkwin==NULL will change cursor to "None".
    
    I see two simple ways to avoid this problem - 
     1. Not to change cursor to "None" in UpdateCursor(winPtr) (TkPointer.c line 546) when 
winPtr==NULL.
     2. Replace 
      tkwin = Tk_HWNDToWindow(hwnd); (tkWinPointer.c line 141)
     with
      tkwin = NULL;
      while (tkwin==NULL && hwnd!=NULL) {
       tkwin = Tk_HWNDToWindow(hwnd);
       hwnd = GetParent(hwnd);
      }
User Comments: nemethi (claiming to be Csaba Nemethi) added on 2026-10-29 15:59:04:

Backported to core-9-0-branch and core-8-6-branch by commits [fef2f0d0] and [3602edd9]. Closing the ticket.


jan.nijtmans added on 2026-10-23 14:29:40:

Fixed on [e836917d|trunk]

If CI build is clean, can be merged further.


serhiy.storchaka added on 2026-10-22 22:49:16:

Confirmed on Windows 11 with current main: over a window which Tk does not own, inside a frame with -cursor watch, the cursor turns into the arrow as soon as the mouse stops. With branch win-foreign-cursor the frame cursor stays.


serhiy.storchaka added on 2026-09-23 21:58:01:

Still reproducible in 9.1b1 on Windows 11, and the analysis in the report is still accurate.

Tk_HWNDToWindow returns NULL over a window Tk does not own, so Tk_UpdatePointer calls UpdateCursor(NULL), which ends in TkpSetCursor(None) and loads IDC_ARROW. The 250 ms mouse timer repeats it, overwriting the cursor set by the owner of that window.

A fix is proposed in branch win-foreign-cursor, the first of the two suggestions in the report: leave the cursor alone when there is no Tk window under the pointer.