summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
authormarc_culler <marc.culler@gmail.com>2020-09-09 19:25:22 (GMT)
committermarc_culler <marc.culler@gmail.com>2020-09-09 19:25:22 (GMT)
commit22e941ecb6c39df473fa3ed938bdaeb0784aff76 (patch)
tree3dc6aad5318db4c0ef8251851ac29fa1291092be /macosx
parentc0cbf2de196d27643e7267a53c37d4bf4810ffef (diff)
downloadtk-22e941ecb6c39df473fa3ed938bdaeb0784aff76.zip
tk-22e941ecb6c39df473fa3ed938bdaeb0784aff76.tar.gz
tk-22e941ecb6c39df473fa3ed938bdaeb0784aff76.tar.bz2
Fix [ab1feaea9c]: Aqua initialization issues exposed by Scid vs Mac.
Diffstat (limited to 'macosx')
-rw-r--r--macosx/tkMacOSXInit.c91
-rw-r--r--macosx/tkMacOSXSubwindows.c27
-rw-r--r--macosx/tkMacOSXWm.c6
3 files changed, 78 insertions, 46 deletions
diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c
index 51c1e37..2cf4b0c 100644
--- a/macosx/tkMacOSXInit.c
+++ b/macosx/tkMacOSXInit.c
@@ -285,7 +285,6 @@ TkpInit(
if (!initialized) {
struct stat st;
-
initialized = 1;
/*
@@ -340,15 +339,15 @@ TkpInit(
[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.
+ * WARNING: The finishLaunching method runs asynchronously. 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];
@@ -377,35 +376,47 @@ TkpInit(
Tcl_DoOneEvent(TCL_WINDOW_EVENTS | TCL_DONT_WAIT);
/*
- * If we don't have a TTY and stdin is a special character file of
+ * If we don't have a TTY or stdin is a special character file of
* length 0, (e.g. /dev/null, which is what Finder sets when double
* clicking Wish) then use the Tk based console interpreter.
*/
- if (getenv("TK_CONSOLE") ||
- (!isatty(0) && (fstat(0, &st) ||
- (S_ISCHR(st.st_mode) && st.st_blocks == 0)))) {
- Tk_InitConsoleChannels(interp);
- Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
- Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
- 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.
- */
-
- if (Tcl_GetStartupScript(NULL) == NULL) {
- const char *intvar = Tcl_GetVar2(interp,
- "tcl_interactive", NULL, TCL_GLOBAL_ONLY);
-
- if (intvar == NULL) {
- Tcl_SetVar2(interp, "tcl_interactive", NULL, "1",
- TCL_GLOBAL_ONLY);
+ if (!isatty(0) && (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0))) {
+ if (getenv("TK_CONSOLE")) {
+ Tk_InitConsoleChannels(interp);
+ Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDIN));
+ Tcl_RegisterChannel(interp, Tcl_GetStdChannel(TCL_STDOUT));
+ 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.
+ */
+
+ if (Tcl_GetStartupScript(NULL) == NULL) {
+ const char *intvar = Tcl_GetVar2(interp,
+ "tcl_interactive", NULL, TCL_GLOBAL_ONLY);
+
+ if (intvar == NULL) {
+ Tcl_SetVar2(interp, "tcl_interactive", NULL, "1",
+ TCL_GLOBAL_ONLY);
+ }
}
- }
- if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
- return TCL_ERROR;
+ if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ } else {
+
+ /*
+ * When launched as a macOS application with no console,
+ * redirect stderr and stdout to /dev/null. This avoids waiting
+ * forever for those files to become writable if the underlying
+ * Tcl program tries to write to them with a puts command.
+ */
+
+ FILE *null = fopen("/dev/null", "w");
+ dup2(fileno(null), STDOUT_FILENO);
+ dup2(fileno(null), STDERR_FILENO);
}
}
@@ -433,6 +444,18 @@ TkpInit(
TkMacOSXIconBitmapObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "::tk::mac::GetAppPath",
TkMacOSXGetAppPathCmd, NULL, NULL);
+
+ /*
+ * The root window has been created and mapped, but XMapWindow deferred its
+ * call to makeKeyAndOrderFront because the first call to XMapWindow
+ * occurs too early in the initialization process for that. Process idle
+ * tasks now, so the root window is configured, then order it front.
+ */
+
+ while(Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {};
+ for (NSWindow *window in [NSApp windows]) {
+ [window makeKeyAndOrderFront:NSApp];
+ }
return TCL_OK;
}
diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c
index 002eae6..682fbb3 100644
--- a/macosx/tkMacOSXSubwindows.c
+++ b/macosx/tkMacOSXSubwindows.c
@@ -143,6 +143,7 @@ XMapWindow(
TkWindow *winPtr = macWin->winPtr;
NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
XEvent event;
+ static Bool initialized = NO;
/*
* Under certain situations it's possible for this function to be called
@@ -172,12 +173,14 @@ XMapWindow(
TkMacOSXApplyWindowAttributes(winPtr, win);
[win setExcludedFromWindowsMenu:NO];
- [NSApp activateIgnoringOtherApps:NO];
+ [NSApp activateIgnoringOtherApps:initialized];
[view addTkDirtyRect: [view bounds]];
- if ([win canBecomeKeyWindow]) {
- [win makeKeyAndOrderFront:NSApp];
- } else {
- [win orderFrontRegardless];
+ if (initialized) {
+ if ([win canBecomeKeyWindow]) {
+ [win makeKeyAndOrderFront:NSApp];
+ } else {
+ [win orderFrontRegardless];
+ }
}
} else {
TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);
@@ -233,11 +236,15 @@ XMapWindow(
* Generate VisibilityNotify events for window and all mapped children.
*/
- event.xany.send_event = False;
- event.xany.display = display;
- event.xvisibility.type = VisibilityNotify;
- event.xvisibility.state = VisibilityUnobscured;
- NotifyVisibility(winPtr, &event);
+ if (initialized) {
+ event.xany.send_event = False;
+ event.xany.display = display;
+ event.xvisibility.type = VisibilityNotify;
+ event.xvisibility.state = VisibilityUnobscured;
+ NotifyVisibility(winPtr, &event);
+ } else {
+ initialized = YES;
+ }
return Success;
}
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 6b7871f..a72874e 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -1827,7 +1827,7 @@ WmDeiconifyCmd(
ZoomState : NormalState);
[win setExcludedFromWindowsMenu:NO];
TkMacOSXApplyWindowAttributes(winPtr, win);
- [win orderFront:nil];
+ [win orderFront:NSApp];
if (wmPtr->icon) {
Tk_UnmapWindow((Tk_Window)wmPtr->icon);
}
@@ -6124,6 +6124,8 @@ TkMacOSXMakeRealWindowExist(
NSRect contentRect = NSMakeRect(5 - structureRect.origin.x,
TkMacOSXZeroScreenHeight() - (TkMacOSXZeroScreenTop() + 5 +
structureRect.origin.y + structureRect.size.height + 200), 200, 200);
+ if (wmPtr->hints.initial_state == WithdrawnState) {
+ }
TKWindow *window = [[winClass alloc] initWithContentRect:contentRect
styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
if (!window) {
@@ -6921,7 +6923,7 @@ ApplyContainerOverrideChanges(
[macWindow setExcludedFromWindowsMenu:YES];
[macWindow setStyleMask:styleMask];
if (wmPtr->hints.initial_state == NormalState) {
- [macWindow orderFront:nil];
+ [macWindow orderFront:NSApp];
}
if (wmPtr->container != NULL) {
wmPtr->flags |= WM_TOPMOST;