Import Tk 8.6.10

This commit is contained in:
Steve Dower
2020-09-24 22:55:34 +01:00
parent 5ba5cbc9af
commit 42c69189d9
365 changed files with 24323 additions and 12832 deletions

View File

@@ -30,24 +30,10 @@ static char scriptPath[PATH_MAX + 1] = "";
#pragma mark TKApplication(TKInit)
@interface TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification;
@end
#define TKApplication_NSApplicationDelegate <NSApplicationDelegate>
@interface TKApplication(TKWindowEvent) TKApplication_NSApplicationDelegate
- (void) _setupWindowNotifications;
@end
@interface TKApplication(TKMenus)
- (void) _setupMenus;
@end
@implementation TKApplication
@synthesize poolLock = _poolLock;
@synthesize macMinorVersion = _macMinorVersion;
@synthesize isDrawing = _isDrawing;
@synthesize simulateDrawing = _simulateDrawing;
@end
/*
@@ -59,7 +45,7 @@ static char scriptPath[PATH_MAX + 1] = "";
@implementation TKApplication(TKInit)
- (void) _resetAutoreleasePool
{
if([self poolLock] == 0) {
if ([self poolLock] == 0) {
[_mainPool drain];
_mainPool = [NSAutoreleasePool new];
} else {
@@ -116,7 +102,6 @@ static char scriptPath[PATH_MAX + 1] = "";
_defaultMainMenu = nil;
[self _setupMenus];
/*
* Initialize event processing.
*/
@@ -132,11 +117,27 @@ static char scriptPath[PATH_MAX + 1] = "";
-(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.
* 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.
* The call to activateIgnoringOtherApps was moved here to avoid this.
* However, with the release of macOS 10.15 (Catalina) this was no longer
* sufficient. (See ticket bf93d098d7.) Apparently apps were being
* activated automatically, and this was sometimes being done too early.
* As a workaround we deactivate and then reactivate the app, even though
* Apple says that "Normally, you shouldnt invoke this method".
*/
[NSApp deactivate];
[NSApp activateIgnoringOtherApps: YES];
/*
* Process events to ensure that the root window is fully initialized. See
* ticket 56a1823c73.
*/
[NSApp _lockAutoreleasePool];
while (Tcl_DoOneEvent(TCL_WINDOW_EVENTS| TCL_DONT_WAIT)) {}
[NSApp _unlockAutoreleasePool];
}
- (void) _setup: (Tcl_Interp *) interp
@@ -156,7 +157,7 @@ static char scriptPath[PATH_MAX + 1] = "";
* Record the OS version we are running on.
*/
int minorVersion;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000
Gestalt(gestaltSystemVersionMinor, (SInt32*)&minorVersion);
#else
NSOperatingSystemVersion systemVersion;
@@ -166,15 +167,15 @@ static char scriptPath[PATH_MAX + 1] = "";
[NSApp setMacMinorVersion: minorVersion];
/*
* We are not drawing yet.
* We are not drawing right now.
*/
[NSApp setIsDrawing:NO];
[NSApp setSimulateDrawing:NO];
/*
* Be our own delegate.
*/
[self setDelegate:self];
/*
@@ -187,6 +188,7 @@ static char scriptPath[PATH_MAX + 1] = "";
* If no icon has been set from an Info.plist file, use the Wish icon from
* the Tk framework.
*/
NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
@"CFBundleIconFile"];
if (!iconFile) {
@@ -315,8 +317,8 @@ TkpInit(
}
/*
* Instantiate our NSApplication object. This needs to be
* done before we check whether to open a console window.
* Instantiate our NSApplication object. This needs to be done before
* we check whether to open a console window.
*/
NSAutoreleasePool *pool = [NSAutoreleasePool new];
@@ -330,8 +332,44 @@ TkpInit(
[TKApplication sharedApplication];
[pool drain];
[NSApp _setup:interp];
/*
* WARNING: The finishLaunching method runs asynchronously, apparently
* in a separate thread. This creates a race between the
* initialization of the NSApplication and the initialization of Tk.
* If Tk wins the race bad things happen with the root window (see
* below). If the NSApplication wins then an AppleEvent created during
* launch, e.g. by dropping a file icon on the application icon, will
* be delivered before the procedure meant to to handle the AppleEvent
* has been defined. This is now handled by processing the AppleEvent
* as an idle task. See tkMacOSXHLEvents.c.
*/
[NSApp finishLaunching];
/*
* Create a Tk event source based on the Appkit event queue.
*/
Tk_MacOSXSetupTkNotifier();
/*
* If Tk initialization wins the race, the root window is mapped before
* the NSApplication is initialized. This can cause bad things to
* happen. The root window can open off screen with no way to make it
* appear on screen until the app icon is clicked. This will happen if
* a Tk application opens a modal window in its startup script (see
* ticket 56a1823c73). In other cases, an empty root window can open
* on screen and remain visible for a noticeable amount of time while
* the Tk initialization finishes (see ticket d1989fb7cf). The call
* below forces Tk to block until the Appkit event queue has been
* created. This seems to be sufficient to ensure that the
* NSApplication initialization wins the race, avoiding these bad
* window behaviors.
*/
Tcl_DoOneEvent(TCL_WINDOW_EVENTS | TCL_DONT_WAIT);
/*
* If we don't have a TTY and stdin is a special character file of
* length 0, (e.g. /dev/null, which is what Finder sets when double
@@ -347,8 +385,8 @@ TkpInit(
Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDERR));
/*
* Only show the console if we don't have a startup script
* and tcl_interactive hasn't been set already.
* Only show the console if we don't have a startup script and
* tcl_interactive hasn't been set already.
*/
if (Tcl_GetStartupScript(NULL) == NULL) {
@@ -365,9 +403,14 @@ TkpInit(
}
}
}
/*
* Initialize the NSServices object here. Apple's docs say to do this
* in applicationDidFinishLaunching, but the Tcl interpreter is not
* initialized until this function call.
*/
Tk_MacOSXSetupTkNotifier();
TkMacOSXServices_Init(interp);
}
if (tkLibPath[0] != '\0') {
Tcl_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
@@ -382,7 +425,7 @@ TkpInit(
TkMacOSXStandardAboutPanelObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tk::mac::iconBitmap",
TkMacOSXIconBitmapObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tk::mac::GetAppPath", TkMacOSXGetAppPath, NULL, NULL);
return TCL_OK;
}
@@ -422,7 +465,58 @@ TkpGetAppName(
}
Tcl_DStringAppend(namePtr, name, -1);
}
/*
*----------------------------------------------------------------------
*
* TkMacOSXGetAppPath --
*
* Returns the path of the Wish application bundle.
*
* Results:
* Returns the application path.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int TkMacOSXGetAppPath(
ClientData cd,
Tcl_Interp *ip,
int objc,
Tcl_Obj *const objv[])
{
CFURLRef mainBundleURL = CFBundleCopyBundleURL(CFBundleGetMainBundle());
/*
* Convert the URL reference into a string reference.
*/
CFStringRef appPath = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
/*
* Get the system encoding method.
*/
CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
/*
* Convert the string reference into a C string.
*/
char *path = (char *) CFStringGetCStringPtr(appPath, encodingMethod);
Tcl_SetResult(ip, path, NULL);
CFRelease(mainBundleURL);
CFRelease(appPath);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*