summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
authorculler <culler>2019-11-17 16:53:11 (GMT)
committerculler <culler>2019-11-17 16:53:11 (GMT)
commit5fa1f5ca17abac3ec8d2d646fbf138502a0f4a59 (patch)
tree64e243c4c3c32c5add2d7c572c79957f1d63f6ad /macosx
parent321eba4fe5834e3df10efbbd71255704a011d2d8 (diff)
parent1dcfa065cbd9c94750fabda9313008e76e4d9c87 (diff)
downloadtk-5fa1f5ca17abac3ec8d2d646fbf138502a0f4a59.zip
tk-5fa1f5ca17abac3ec8d2d646fbf138502a0f4a59.tar.gz
tk-5fa1f5ca17abac3ec8d2d646fbf138502a0f4a59.tar.bz2
Fix [c4abd2b0f3]: rework stackorder command on all platforms, and prevent panics on macOS.
Diffstat (limited to 'macosx')
-rw-r--r--macosx/tkMacOSXWm.c77
1 files changed, 22 insertions, 55 deletions
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 70e9cd9..6cf1b53 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -3311,18 +3311,18 @@ WmStackorderCmd(
if (objc == 3) {
windows = TkWmStackorderToplevel(winPtr);
- if (windows == NULL) {
- Tcl_Panic("TkWmStackorderToplevel failed");
- }
-
- resultObj = Tcl_NewObj();
- for (windowPtr = windows; *windowPtr ; windowPtr++) {
- Tcl_ListObjAppendElement(NULL, resultObj,
+ if (windows != NULL) {
+ resultObj = Tcl_NewObj();
+ for (windowPtr = windows; *windowPtr ; windowPtr++) {
+ Tcl_ListObjAppendElement(NULL, resultObj,
TkNewWindowObj((Tk_Window) *windowPtr));
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ ckfree(windows);
+ return TCL_OK;
+ } else {
+ return TCL_ERROR;
}
- Tcl_SetObjResult(interp, resultObj);
- ckfree(windows);
- return TCL_OK;
} else {
TkWindow *winPtr2;
int index1 = -1, index2 = -1, result;
@@ -6623,7 +6623,7 @@ WmStackorderToplevelWrapperMap(
Tcl_HashEntry *hPtr;
int newEntry;
- if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)
+ if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr)
&& (winPtr->display == display)) {
hPtr = Tcl_CreateHashEntry(table,
(char*) TkMacOSXDrawableWindow(winPtr->window), &newEntry);
@@ -6644,8 +6644,8 @@ WmStackorderToplevelWrapperMap(
* This procedure returns the stack order of toplevel windows.
*
* Results:
- * An array of pointers to tk window objects in stacking order or else
- * NULL if there was an error.
+ * A NULL terminated array of pointers to tk window objects in stacking
+ * order or else NULL if there was an error.
*
* Side effects:
* None.
@@ -6660,57 +6660,24 @@ TkWmStackorderToplevel(
TkWindow *childWinPtr, **windows, **windowPtr;
Tcl_HashTable table;
Tcl_HashEntry *hPtr;
- Tcl_HashSearch search;
-
- /*
- * Map mac windows to a TkWindow of the wrapped toplevel.
- */
-
- Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
- WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
-
- windows = ckalloc((table.numEntries+1) * sizeof(TkWindow *));
-
- /*
- * Special cases: If zero or one toplevels were mapped there is no need to
- * enumerate Windows.
- */
-
- switch (table.numEntries) {
- case 0:
- windows[0] = NULL;
- goto done;
- case 1:
- hPtr = Tcl_FirstHashEntry(&table, &search);
- windows[0] = Tcl_GetHashValue(hPtr);
- windows[1] = NULL;
- goto done;
- }
-
NSArray *macWindows = [NSApp orderedWindows];
+ NSArray* backToFront = [[macWindows reverseObjectEnumerator] allObjects];
NSInteger windowCount = [macWindows count];
- if (!windowCount) {
- ckfree(windows);
- windows = NULL;
- } else {
- windowPtr = windows + table.numEntries;
- *windowPtr-- = NULL;
- for (NSWindow *w in macWindows) {
+ windows = windowPtr = ckalloc((windowCount + 1) * sizeof(TkWindow *));
+ if (windows != NULL) {
+ Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
+ WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
+ for (NSWindow *w in backToFront) {
hPtr = Tcl_FindHashEntry(&table, (char*) w);
if (hPtr != NULL) {
childWinPtr = Tcl_GetHashValue(hPtr);
- *windowPtr-- = childWinPtr;
+ *windowPtr++ = childWinPtr;
}
}
- if (windowPtr != windows-1) {
- Tcl_Panic("num matched toplevel windows does not equal num "
- "children");
- }
+ *windowPtr = NULL;
+ Tcl_DeleteHashTable(&table);
}
-
- done:
- Tcl_DeleteHashTable(&table);
return windows;
}