In the nextEventMatchingMask method in macosx/tkMacOSXNotify.c, in this section:

@implementation TKApplication(TKNotify)
- (NSEvent *) nextEventMatchingMask: (NSUInteger) mask
        untilDate: (NSDate *) expiration inMode: (NSString *) mode
        dequeue: (BOOL) deqFlag
{
...
    int oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
    NSEvent *event = [[super nextEventMatchingMask:mask untilDate:expiration
            inMode:mode dequeue:deqFlag] retain];
    Tcl_SetServiceMode(oldMode);
...
}

we first set the service mode using Tcl_SetServiceMode, then we call the nextEventMatchingMask method of the superclass, and then we restore the original service mode.

The Tcl_SetServiceMode function (in generic/tclNotify.c) is the following:

int Tcl_SetServiceMode(int mode)
{
    int oldMode;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    oldMode = tsdPtr->serviceMode;
    tsdPtr->serviceMode = mode;
    Tcl_ServiceModeHook(mode);
    return oldMode;
}

Now the superclass nextEventMatchingMask method simply gets the next available event, but does not invoke any Tcl/Tk code. So setting tsdPtr->serviceMode has no consequences.

The Tcl_ServiceModeHook function (in macosx/tclMacOSXNotify.c) creates the runloop timer if it doesn’t already exist. But since we also call Tcl_SetServiceMode from Tk_MacOSXSetupTkNotifier during Tk initialization, the runloop timer already exist by the time we call nextEventMatchingMask.

So I think the two calls to Tcl_SetServiceMode in the nextEventMatchingMask method can be removed. The patch does just that. This patch was made relative to this patch which I submitted previously:


However, these two patches can be applied independently of each other.