diff options
author | culler <culler> | 2020-08-04 14:47:00 (GMT) |
---|---|---|
committer | culler <culler> | 2020-08-04 14:47:00 (GMT) |
commit | 24bb9dda59ff526f18fee2b721f9cb5edb845297 (patch) | |
tree | 6f824ebac9edab22d8f89b7caee62ee580884eba /macosx/tkMacOSXMenu.c | |
parent | 82fa36590eab7415072e7d56195fca78277676c7 (diff) | |
parent | 6115c6c774ebf6d95e16b18fd3378d691f26722d (diff) | |
download | tk-24bb9dda59ff526f18fee2b721f9cb5edb845297.zip tk-24bb9dda59ff526f18fee2b721f9cb5edb845297.tar.gz tk-24bb9dda59ff526f18fee2b721f9cb5edb845297.tar.bz2 |
Merge 8.6 but remove HITheme and HIBackground colors which are only supported on 32-bit systems
Diffstat (limited to 'macosx/tkMacOSXMenu.c')
-rw-r--r-- | macosx/tkMacOSXMenu.c | 98 |
1 files changed, 85 insertions, 13 deletions
diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c index 1ed9408..9116275 100644 --- a/macosx/tkMacOSXMenu.c +++ b/macosx/tkMacOSXMenu.c @@ -95,7 +95,6 @@ static int gNoTkMenus = 0; /* This is used by Tk_MacOSXTurnOffMenus as * the flag that Tk is not to draw any * menus. */ static int inPostMenu = 0; -static unsigned long defaultBg = 0, defaultFg = 0; static SInt32 menuMarkColumnWidth = 0, menuIconTrailingEdgeMargin = 0; static SInt32 menuTextLeadingEdgeMargin = 0, menuTextTrailingEdgeMargin = 0; static SInt16 menuItemExtraHeight = 0, menuItemExtraWidth = 0; @@ -108,6 +107,65 @@ static void MenuSelectEvent(TkMenu *menuPtr); static void RecursivelyClearActiveMenu(TkMenu *menuPtr); static int ModifierCharWidth(Tk_Font tkfont); +#pragma mark TkBackgroundLoop + +/* + * The function TkMacOSXEventsCheckProc (in tkMacOSXNotify.c) is the "check + * proc" for the macOS event source. Its job is to remove NSEvents from the + * default event queue of the NSApplication. It does this by calling the + * method [NSApp nextEventMatchingMask: untilDate: inMode: dequeue:]. As a + * rule, when the untilDate is set to the distant past this method returns + * immediately. An exception to that rule is when the next event is the button + * press on a menu button. In that case, the method starts running a nested + * event loop in the mode NSEventTrackingRunLoopMode which does not return + * until the menu has been dismissed. In Tk 8.6.10 and earlier, this meant + * that the Tk event loop would block in its call to the check proc as long as + * the menu was posted. For example, opening a menu during the Rube Goldberg + * demo would cause the animation to stop. This was also the case for + * menubuttons. + * + * The TKBackground object below works around this problem, and allows a Tk + * event loop to run while a menu is open. It is a subclass of NSThread which + * inserts requests to call [NSApp _runBackgroundLoop] onto the queue + * associated with the NSEventTrackingRunLoopMode. One of these threads gets + * started in the callback [NSApp menuBeginTracking] and cancelled in [NSApp + * menuEndTracking]. + */ + +@interface TKBackgroundLoop: NSThread +@end + +@implementation TKBackgroundLoop +- (void) main +{ + NSArray *modeArray = [NSArray arrayWithObjects: NSEventTrackingRunLoopMode, + nil]; + while(1) { + + /* + * Queue a request to process Tk events during event tracking. + */ + + [NSApp performSelectorOnMainThread:@selector(_runBackgroundLoop) + withObject:nil + waitUntilDone:true + modes:modeArray]; + if (self.cancelled) { + [NSThread exit]; + } + + /* + * Allow the tracked events to be processed too. + */ + + [NSThread sleepForTimeInterval:0.001]; + } +} +@end + +TKBackgroundLoop *backgroundLoop = nil; + + #pragma mark TKMenu /* @@ -405,6 +463,12 @@ static int ModifierCharWidth(Tk_Font tkfont); #ifdef TK_MAC_DEBUG_NOTIFICATIONS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif + if (backgroundLoop) { + [backgroundLoop cancel]; + [backgroundLoop release]; + } + backgroundLoop = [[TKBackgroundLoop alloc] init]; + [backgroundLoop start]; //TkMacOSXClearMenubarActive(); //TkMacOSXPreprocessMenu(); } @@ -415,6 +479,11 @@ static int ModifierCharWidth(Tk_Font tkfont); #ifdef TK_MAC_DEBUG_NOTIFICATIONS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif + if (backgroundLoop) { + [backgroundLoop cancel]; + [backgroundLoop release]; + backgroundLoop = nil; + } if (!inPostMenu) { TkMacOSXClearMenubarActive(); } @@ -624,9 +693,20 @@ TkpConfigureMenuEntry( NSDictionary *attributes; int imageWidth, imageHeight; GC gc = (mePtr->textGC ? mePtr->textGC : mePtr->menuPtr->textGC); - Tcl_Obj *fontPtr = (mePtr->fontPtr ? mePtr->fontPtr : - mePtr->menuPtr->fontPtr); - + Tcl_Obj *fontPtr = (mePtr->fontPtr ? + mePtr->fontPtr : mePtr->menuPtr->fontPtr); + static unsigned long defaultBg, defaultFg; + static int initialized = 0; + + if (!initialized) { + TkColor *tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR); + defaultBg = tkColPtr->color.pixel; + ckfree(tkColPtr); + tkColPtr = TkpGetColor(NULL, DEF_MENU_FG); + defaultFg = tkColPtr->color.pixel; + ckfree(tkColPtr); + } + if (mePtr->image) { Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); image = TkMacOSXGetNSImageWithTkImage(mePtr->menuPtr->display, @@ -640,7 +720,6 @@ TkpConfigureMenuEntry( image = TkMacOSXGetNSImageWithBitmap(mePtr->menuPtr->display, bitmap, gc, imageWidth, imageHeight); if (gc->foreground == defaultFg) { - // Use a semantic foreground color by default [image setTemplate:YES]; } } @@ -1624,7 +1703,7 @@ Tk_MacOSXTurnOffMenus(void) void TkpMenuInit(void) { - TkColor *tkColPtr; + // TkColor *tkColPtr; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; @@ -1635,13 +1714,6 @@ TkpMenuInit(void) #undef observe [NSMenuItem setUsesUserKeyEquivalents:NO]; - tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR); - defaultBg = tkColPtr->color.pixel; - ckfree(tkColPtr); - tkColPtr = TkpGetColor(NULL, DEF_MENU_FG); - defaultFg = tkColPtr->color.pixel; - ckfree(tkColPtr); - ChkErr(GetThemeMetric, kThemeMetricMenuMarkColumnWidth, &menuMarkColumnWidth); ChkErr(GetThemeMetric, kThemeMetricMenuTextLeadingEdgeMargin, |