From 4d93c39841fcb541bd4bbb61c731c0444fabb2de Mon Sep 17 00:00:00 2001 From: culler Date: Fri, 24 Nov 2017 17:21:30 +0000 Subject: Remove calls to TransformProcessType. Avoid activating too early. Prepare for cleanup of TkpInit. Fixes the basic menu bar problem. --- macosx/tkMacOSXInit.c | 73 ++++++++++++++++++++------------------------- macosx/tkMacOSXSubwindows.c | 10 ++++++- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index 2bed5d1..29d68b2 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -110,12 +110,19 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt #endif } -- (void) _setupEventLoop +-(void)applicationWillFinishLaunching:(NSNotification *)aNotification { - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [self finishLaunching]; - [self setWindowsNeedUpdate:YES]; - [pool drain]; + /* Much of the NSApplication initialization should be moved here.*/ +} + +-(void)applicationDidFinishLaunching:(NSNotification *)notification +{ + /* + * It is not safe to force activation of the NSApp until this + * method is called. Activating too early can cause the menu + * bar to be unresponsive. + */ + [NSApp activateIgnoringOtherApps: YES]; } - (void) _setup: (Tcl_Interp *) interp @@ -126,6 +133,7 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt _defaultMainMenu = nil; [self _setupMenus]; [self setDelegate:self]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; #ifdef TK_MAC_DEBUG_NOTIFICATIONS [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_postedNotification:) name:nil object:nil]; @@ -284,20 +292,19 @@ TkpInit( TkMacOSXDbgMsg("Tcl_MacOSXOpenVersionedBundleResources failed"); } #endif - - { - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [[NSUserDefaults standardUserDefaults] registerDefaults: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], - @"_NSCanWrapButtonTitles", - [NSNumber numberWithInt:-1], - @"NSStringDrawingTypesetterBehavior", - nil]]; - [TKApplication sharedApplication]; - [pool drain]; - [NSApp _setup:interp]; - } + + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + [[NSUserDefaults standardUserDefaults] registerDefaults: + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], + @"_NSCanWrapButtonTitles", + [NSNumber numberWithInt:-1], + @"NSStringDrawingTypesetterBehavior", + nil]]; + [TKApplication sharedApplication]; + [pool drain]; + [NSApp _setup:interp]; + /* Check whether we are a bundled executable: */ bundleRef = CFBundleGetMainBundle(); @@ -334,34 +341,18 @@ TkpInit( if (!bundledExecutable) { /* - * If we are loaded into an executable that is not a bundled - * application, the window server does not let us come to the - * foreground. For such an executable, notify the window server - * that we are now a full GUI application. - */ - - OSStatus err = procNotFound; - ProcessSerialNumber psn = { 0, kCurrentProcess }; - - err = ChkErr(TransformProcessType, &psn, - kProcessTransformToForegroundApplication); - - /* * Set application icon to generic Tk icon, do it at idle time * instead of now to ensure tk_library is setup. */ - Tcl_DoWhenIdle(SetApplicationIcon, NULL); } - { - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [NSApp _setupEventLoop]; - TkMacOSXInitAppleEvents(interp); - TkMacOSXUseAntialiasedText(interp, -1); - TkMacOSXInitCGDrawing(interp, TRUE, 0); - [pool drain]; - } + pool = [NSAutoreleasePool new]; + [NSApp finishLaunching]; + TkMacOSXInitAppleEvents(interp); + TkMacOSXUseAntialiasedText(interp, -1); + TkMacOSXInitCGDrawing(interp, TRUE, 0); + [pool drain]; /* * FIXME: Close stdin & stdout for remote debugging otherwise we will diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index 12beb1b..2c036bb 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -149,7 +149,15 @@ XMapWindow( if (Tk_IsTopLevel(macWin->winPtr)) { if (!Tk_IsEmbedded(macWin->winPtr)) { NSWindow *win = TkMacOSXDrawableWindow(window); - [NSApp activateIgnoringOtherApps:YES]; + /* + * We want to activate Tk when a toplevel is mapped + * but we must not supply YES here. This is because + * during Tk initialization the root window is mapped + * before applicationDidFinishLaunching returns. Forcing + * the app to activate too early can make the menu bar + * unresponsive. + */ + [NSApp activateIgnoringOtherApps:NO]; if ( [win canBecomeKeyWindow] ) { [win makeKeyAndOrderFront:NSApp]; } -- cgit v0.12 From 85708596b600b95ccec076d13a7a3f19448c9d6f Mon Sep 17 00:00:00 2001 From: culler Date: Fri, 24 Nov 2017 20:35:13 +0000 Subject: Simplify and reorganize the initialization code. --- macosx/tkMacOSXInit.c | 143 ++++++++++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 70 deletions(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index 29d68b2..2559611 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -7,6 +7,7 @@ * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2005-2009 Daniel A. Steffen + * Copyright (c) 2017 Marc Culler * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -112,7 +113,46 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt -(void)applicationWillFinishLaunching:(NSNotification *)aNotification { - /* Much of the NSApplication initialization should be moved here.*/ + + /* + * Initialize notifications. + */ +#ifdef TK_MAC_DEBUG_NOTIFICATIONS + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_postedNotification:) name:nil object:nil]; +#endif + [self _setupWindowNotifications]; + [self _setupApplicationNotifications]; + + /* + * Construct the menu bar. + */ + _defaultMainMenu = nil; + [self _setupMenus]; + + /* + * Set the application icon. This is unnecessary when running Wish.app + * but it is easier than testing for that situation to just do it. + */ + NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"]; + if (path) { + NSImage *image = [[NSImage alloc] initWithContentsOfFile:path]; + if (image) { + [NSApp setApplicationIconImage:image]; + [image release]; + } + } + + /* + * Initialize event processing. + */ + TkMacOSXInitAppleEvents(_eventInterp); + + /* + * Initialize the graphics context. + */ + TkMacOSXUseAntialiasedText(_eventInterp, -1); + TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0); } -(void)applicationDidFinishLaunching:(NSNotification *)notification @@ -127,19 +167,26 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt - (void) _setup: (Tcl_Interp *) interp { + /* + * Remember our interpreter. + */ _eventInterp = interp; + + /* + * Install the global autoreleasePool. + */ _mainPool = [NSAutoreleasePool new]; [NSApp setPoolLock:0]; - _defaultMainMenu = nil; - [self _setupMenus]; + + /* + * Be our own delegate. + */ [self setDelegate:self]; + + /* + * Make sure we are allowed to open windows. + */ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; -#ifdef TK_MAC_DEBUG_NOTIFICATIONS - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_postedNotification:) name:nil object:nil]; -#endif - [self _setupWindowNotifications]; - [self _setupApplicationNotifications]; } - (NSString *) tkFrameworkImagePath: (NSString *) image @@ -293,67 +340,6 @@ TkpInit( } #endif - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [[NSUserDefaults standardUserDefaults] registerDefaults: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], - @"_NSCanWrapButtonTitles", - [NSNumber numberWithInt:-1], - @"NSStringDrawingTypesetterBehavior", - nil]]; - [TKApplication sharedApplication]; - [pool drain]; - [NSApp _setup:interp]; - - - /* Check whether we are a bundled executable: */ - bundleRef = CFBundleGetMainBundle(); - if (bundleRef) { - bundleUrl = CFBundleCopyBundleURL(bundleRef); - } - if (bundleUrl) { - /* - * A bundled executable is two levels down from its main bundle - * directory (e.g. Wish.app/Contents/MacOS/Wish), whereas an - * unbundled executable's main bundle directory is just the - * directory containing the executable. So to check whether we are - * bundled, we delete the last three path components of the - * executable's url and compare the resulting url with the main - * bundle url. - */ - - int j = 3; - CFURLRef url = CFBundleCopyExecutableURL(bundleRef); - - while (url && j--) { - CFURLRef parent = - CFURLCreateCopyDeletingLastPathComponent(NULL, url); - - CFRelease(url); - url = parent; - } - if (url) { - bundledExecutable = CFEqual(bundleUrl, url); - CFRelease(url); - } - CFRelease(bundleUrl); - } - - if (!bundledExecutable) { - /* - * Set application icon to generic Tk icon, do it at idle time - * instead of now to ensure tk_library is setup. - */ - Tcl_DoWhenIdle(SetApplicationIcon, NULL); - } - - pool = [NSAutoreleasePool new]; - [NSApp finishLaunching]; - TkMacOSXInitAppleEvents(interp); - TkMacOSXUseAntialiasedText(interp, -1); - TkMacOSXInitCGDrawing(interp, TRUE, 0); - [pool drain]; - /* * FIXME: Close stdin & stdout for remote debugging otherwise we will * fight with gdb for stdin & stdout @@ -396,6 +382,23 @@ TkpInit( return TCL_ERROR; } } + + /* + * Instantiate our NSApplication object. + */ + + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + [[NSUserDefaults standardUserDefaults] registerDefaults: + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], + @"_NSCanWrapButtonTitles", + [NSNumber numberWithInt:-1], + @"NSStringDrawingTypesetterBehavior", + nil]]; + [TKApplication sharedApplication]; + [pool drain]; + [NSApp _setup:interp]; + [NSApp finishLaunching]; } Tk_MacOSXSetupTkNotifier(); -- cgit v0.12 From 47e2a01f19fcb341ee2ec3e56c737ed55e208007 Mon Sep 17 00:00:00 2001 From: culler Date: Sat, 25 Nov 2017 00:14:31 +0000 Subject: Edited comment. --- macosx/tkMacOSXWm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 832cf2f..965edd5 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -930,8 +930,9 @@ TkWmDeadWindow( } } /* - * Process all events immediately to force the closed window - * to be deallocated. + * Process all window events immediately to force the closed window to + * be deallocated. But don't do this for the root window as that is + * unnecessary and can lead to segfaults. */ if (winPtr->parentPtr) { while (Tk_DoOneEvent(TK_WINDOW_EVENTS|TK_DONT_WAIT)) {} -- cgit v0.12 From cad96e2d77757feeed88a2e7974f8221cf4e393e Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 25 Nov 2017 03:49:04 +0000 Subject: Fix name for SetApplicationIcon function that had an incorrect name in the function description --- macosx/tkMacOSXInit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index 2559611..c695ca8 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -236,7 +236,7 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt /* *---------------------------------------------------------------------- * - * DoWindowActivate -- + * SetApplicationIcon -- * * Idle handler that sets the application icon to the generic Tk icon. * -- cgit v0.12 From 697ee9344178923ec3f086602a3a21916ee61f1b Mon Sep 17 00:00:00 2001 From: culler Date: Sat, 25 Nov 2017 05:08:18 +0000 Subject: Removed a function which is never called in the current version. --- macosx/tkMacOSXInit.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index c695ca8..5c8c0b7 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -236,38 +236,6 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt /* *---------------------------------------------------------------------- * - * SetApplicationIcon -- - * - * Idle handler that sets the application icon to the generic Tk icon. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -SetApplicationIcon( - ClientData clientData) -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"]; - if (path) { - NSImage *image = [[NSImage alloc] initWithContentsOfFile:path]; - if (image) { - [NSApp setApplicationIconImage:image]; - [image release]; - } - } - [pool drain]; -} - -/* - *---------------------------------------------------------------------- - * * TkpInit -- * * Performs Mac-specific interpreter initialization related to the -- cgit v0.12