Tk Source Code

View Ticket
Login
Ticket UUID: 9654e3889af3b7a3784cb285389082c7e19ebe4d
Title: Widgets on aqua no longer receive <Deactivate> events
Type: Bug Version: trunk
Submitter: nemethi Created on: 2025-12-27 13:10:18
Subsystem: 66. Aqua Window Operations Assigned To: marc_culler
Priority: 5 Medium Severity: Severe
Status: Closed Last Modified: 2025-12-27 20:04:12
Resolution: Fixed Closed By: marc_culler
    Closed on: 2025-12-27 20:04:12
Description:

With the current Tk trunk version the widgets on the windowing system aqua no longer receive <Deactivate> events.  As a result, the widgets and their elements no longer switch to the background state, thus their colors no longer change accordingly.

This is easy to see, e.g, by running the Widget Demo, and can be reproduced with the aid of the simple script shown below:

bind . <Deactivate> { puts "received <Deactivate> event" }

When running this script, no  "received <Deactivate> event"  message is output when the wish window is no longer the active one.

User Comments: marc_culler (claiming to be Marc Culler) added on 2025-12-27 20:04:12:
The fix has been merged into trunk and back-ported to core-9-0-branch.

I am closing the ticket.

marc_culler (claiming to be Marc Culler) added on 2025-12-27 19:51:49:
However, the wikndowActivation code in the tip of core-9-0-branch is the
same as the code in trunk.  So this change to trunk will need to be back-
ported to core-9-0-branch.

I am going to merge the bugfix branch and do the backport now.

marc_culler (claiming to be Marc Culler) added on 2025-12-27 19:46:44:
Hi Csaba,

Yes!  That explains everything.  Thanks.

nemethi (claiming to be Csaba Nemethi) added on 2025-12-27 19:19:50:
Marc, the fix works for me, thanks again for it!

In Tk 9.0.1 we have the following code:

- (void) windowActivation: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    NSString *name = [notification name];
    Bool flag = [name isEqualToString:NSWindowDidBecomeKeyNotification];
    if (winPtr && flag) {
        NSPoint location = [NSEvent mouseLocation];
        int x = location.x;
        int y = floor(TkMacOSXZeroScreenHeight() - location.y);
        /*
         * The Tk event target persists when there is no key window but
         * gets reset when a new window becomes the key window.
         */
 
        [NSApp setTkEventTarget: winPtr];
 
        /* 
         * Call Tk_UpdatePointer if the pointer is in the window.
         */

        NSView *view = [w contentView];
        NSPoint viewLocation = [view convertPoint:location fromView:nil];
        if (NSPointInRect(viewLocation, NSInsetRect([view bounds], 2, 2))) {
            Tk_UpdatePointer((Tk_Window) winPtr, x, y, [NSApp tkButtonState]);
        }
    }
    if (winPtr && Tk_IsMapped(winPtr)) {
        GenerateActivateEvents(winPtr, flag);
    }
}

Here the 2nd argument of GenerateActivateEvents is the boolean value flag.  Maybe this is the explanation that you are looking for.

marc_culler (claiming to be Marc Culler) added on 2025-12-27 18:52:35:
The code in windowActivate did not change between 9.0 and 9.1, and
neither one called GenerateActivateEvents in the case when a window
resigned keyWindow status.  So I would be very interested in an
explanation of what mechanism was causing <Deactivate> to be sent
in 9.0.  I find that very puzzling.

nemethi (claiming to be Csaba Nemethi) added on 2025-12-27 18:34:36:
Marc, many thanks for the quick fix, I will test it ASAP.  I don't know whether the transition to the deactivated state used to work when running Tk built from trunk.  But it definitely works with Tk 9.0.1.  I am not sure about later versions (I have only built and tested Tk 9.0.1 and trunk).

marc_culler (claiming to be Marc Culler) added on 2025-12-27 17:37:09:
Csaba, I have pushed a 3-line fix in branch bug-9654e3889a.

Are you sure that this used to work?  The fix is straightforward - just
call GenerateActivateEvents when a TKWindow resigns the role of keyWindow.
But I don't see any sign of such a call having been removed and I don't
see how it could have worked correctly without that call.