Tk Source Code

View Ticket
Login
Ticket UUID: 1391053
Title: Win32 nonclient double-click causes spurious Button-1 in app
Type: Bug Version: 8.6.18, 9.0.5, 9.1b1
Submitter: a_kovalenko Created on: 2005-12-27 05:32:27
Subsystem: 68. Win Window Operations Assigned To: aku
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2026-10-26 20:09:11
Resolution: Fixed Closed By: nemethi
    Closed on: 2026-10-26 20:09:11
Description:
The bug is a long-standing one, so there may be
duplicate reports (though I've not found them). The
patch solving the problem is attached.

When I maximize a Tk window by double-clicking its
title bar, and the mouse cursor is then located within
a Tk window (this one or another), the window under the
cursor receives <Button-1>. The same thing may be
observed when closing a dialog window with
double-clicking its system menu button (there are 
traditional workarounds for it).

The problem is caused by the following thing: when a
non-client area of a decorative frame receives a mouse
click, this event comes to WmProc() as WM_NCLBUTTONDOWN
(or other WM_NC* message of this kind). Normal mouse
clicks cause Tk to query the current mouse state
immediately (Tk_PointerEvent()), but non-client clicks
don't. So the next call to Tk_PointerEvent() will
notice that the button is down, and a new event will be
generated... but the windows may be already moved,
maximized, closed since the real click has happened.
This is exactly the case when the non-client click is
to maximize or close a window.

The solution (see attachment) is to call
Tk_PointerEvent immediately when WM_NCLBUTTONDOWN or
its counterparts are received in WmProc(). 

If someone decide to refactor the patch by putting the
WM_NC*-related code in TranslateWinEvent(), I want him
to remember that the defWindowProc _must_ be always
called for these events. It's sooo easy to forget it,
and forgetting it will cause a Very Bad Thing.
User Comments: nemethi (claiming to be Csaba Nemethi) added on 2026-10-26 20:09:11:

Serhiy, many thanks for fixing this long-standing bug! Merged into main, core-9-0-branch, and core-8-6-branch by commits [b3616e16], [dda7e89d], and [0b557a2d].


serhiy.storchaka added on 2026-09-28 19:43:18:

Still reproducible on Windows 11 with 8.6 and 9.1, if the second press of the double-click is held a little: maximizing a window by double-clicking the title bar, stretching it vertically by double-clicking its upper or lower border, or closing a dialog by double-clicking its system menu icon, produces <Button-1> in the Tk window which is now under the pointer. Besides the pointer update, the spurious press also comes from CheckForPointer() when the closed toplevel is destroyed.

Proposed fix in branch win-nonclient-buttons: buttons pressed in the non-client area which are still down after the default processing are ignored until they are released. It does not use the attached patch.


a_kovalenko added on 2005-12-27 13:57:23:

File Added - 161176: badclick-win32-v2.patch

a_kovalenko added on 2005-12-27 13:57:19:
Logged In: YES 
user_id=241496

Hmm.. Here is the new patch, good enough for myself but
maybe too ugly. Introduces NOCURSOR_MASK flag that causes
Tk_UpdatePointer not to update the cursor. Tk_UpdatePointer
is now called directly from tkWinWm.c.

a_kovalenko added on 2005-12-27 13:20:34:
Logged In: YES 
user_id=241496

The patch needs more work: UpdateCursor() should not be
called on NC* events...

a_kovalenko added on 2005-12-27 12:32:29:

File Added - 161164: badclick-win32.patch

Attachments: