summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXMenu.c
diff options
context:
space:
mode:
authorculler <culler>2020-08-04 14:47:00 (GMT)
committerculler <culler>2020-08-04 14:47:00 (GMT)
commit24bb9dda59ff526f18fee2b721f9cb5edb845297 (patch)
tree6f824ebac9edab22d8f89b7caee62ee580884eba /macosx/tkMacOSXMenu.c
parent82fa36590eab7415072e7d56195fca78277676c7 (diff)
parent6115c6c774ebf6d95e16b18fd3378d691f26722d (diff)
downloadtk-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.c98
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,