diff options
Diffstat (limited to 'macosx/tkMacOSXWm.c')
-rw-r--r-- | macosx/tkMacOSXWm.c | 226 |
1 files changed, 224 insertions, 2 deletions
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 4e4c9b4..d4afe64 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXWm.c,v 1.1.2.1 2001/10/15 09:22:00 wolfsuit Exp $ + * RCS: @(#) $Id: tkMacOSXWm.c,v 1.1.2.2 2002/02/05 02:25:17 wolfsuit Exp $ */ #include <Carbon/Carbon.h> @@ -1297,6 +1297,99 @@ Tk_WmCmd( } wmPtr->flags |= WM_UPDATE_SIZE_HINTS; goto updateGeom; + } else if ((c == 's') && (strncmp(argv[1], "stackorder", length) == 0) + && (length >= 2)) { + TkWindow **windows, **window_ptr; + + if ((argc != 3) && (argc != 5)) { + Tcl_AppendResult(interp, "wrong # arguments: must be \"", + argv[0], + " stackorder window ?isabove|isbelow? ?window?\"", + (char *) NULL); + return TCL_ERROR; + } + + if (argc == 3) { + windows = TkWmStackorderToplevel(winPtr); + if (windows == NULL) { + panic("TkWmStackorderToplevel failed"); + } else { + for (window_ptr = windows; *window_ptr ; window_ptr++) { + Tcl_AppendElement(interp, (*window_ptr)->pathName); + } + ckfree((char *) windows); + return TCL_OK; + } + } else { + TkWindow *winPtr2; + int index1=-1, index2=-1, result; + + winPtr2 = (TkWindow *) Tk_NameToWindow(interp, argv[4], tkwin); + if (winPtr2 == NULL) { + return TCL_ERROR; + } + + if (!Tk_IsTopLevel(winPtr2)) { + Tcl_AppendResult(interp, "window \"", winPtr2->pathName, + "\" isn't a top-level window", (char *) NULL); + return TCL_ERROR; + } + + if (!Tk_IsMapped(winPtr)) { + Tcl_AppendResult(interp, "window \"", winPtr->pathName, + "\" isn't mapped", (char *) NULL); + return TCL_ERROR; + } + + if (!Tk_IsMapped(winPtr2)) { + Tcl_AppendResult(interp, "window \"", winPtr2->pathName, + "\" isn't mapped", (char *) NULL); + return TCL_ERROR; + } + + /* + * Lookup stacking order of all toplevels that are children + * of "." and find the position of winPtr and winPtr2 + * in the stacking order. + */ + + windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr); + + if (windows == NULL) { + Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", + (char *) NULL); + return TCL_ERROR; + } else { + for (window_ptr = windows; *window_ptr ; window_ptr++) { + if (*window_ptr == winPtr) + index1 = (window_ptr - windows); + if (*window_ptr == winPtr2) + index2 = (window_ptr - windows); + } + if (index1 == -1) + panic("winPtr window not found"); + if (index2 == -1) + panic("winPtr2 window not found"); + + ckfree((char *) windows); + } + + c = argv[3][0]; + length = strlen(argv[3]); + if ((length > 2) && (c == 'i') + && (strncmp(argv[3], "isabove", length) == 0)) { + result = index1 > index2; + } else if ((length > 2) && (c == 'i') + && (strncmp(argv[3], "isbelow", length) == 0)) { + result = index1 < index2; + } else { + Tcl_AppendResult(interp, "bad argument \"", argv[3], + "\": must be isabove or isbelow", (char *) NULL); + return TCL_ERROR; + } + Tcl_SetIntObj(Tcl_GetObjResult(interp), result); + return TCL_OK; + } } else if ((c == 's') && (strncmp(argv[1], "state", length) == 0) && (length >= 2)) { if ((argc < 3) || (argc > 4)) { @@ -4203,4 +4296,133 @@ TkpChangeFocus(winPtr, force) */ return NextRequest(winPtr->display); -}
\ No newline at end of file +} + + +/* + *---------------------------------------------------------------------- + * + * TkWmStackorderToplevelWrapperMap -- + * + * This procedure will create a table that maps the reparent wrapper + * X id for a toplevel to the TkWindow structure that is wraps. + * Tk keeps track of a mapping from the window X id to the TkWindow + * structure but that does us no good here since we only get the X + * id of the wrapper window. Only those toplevel windows that are + * mapped have a position in the stacking order. + * + * + * Results: + * None. + * + * Side effects: + * Adds entries to the passed hashtable. + * + *---------------------------------------------------------------------- + */ +void +TkWmStackorderToplevelWrapperMap(winPtr, table) + TkWindow *winPtr; /* TkWindow to recurse on */ + Tcl_HashTable *table; /* Maps mac window to TkWindow */ +{ + TkWindow *childPtr; + Tcl_HashEntry *hPtr; + void *wrapper; + int newEntry; + + if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)) { + wrapper = (void *) TkMacOSXGetDrawablePort(winPtr->window); + + hPtr = Tcl_CreateHashEntry(table, + (char *) wrapper, &newEntry); + Tcl_SetHashValue(hPtr, winPtr); + } + + for (childPtr = winPtr->childList; childPtr != NULL; + childPtr = childPtr->nextPtr) { + TkWmStackorderToplevelWrapperMap(childPtr, table); + } +} + +/* + *---------------------------------------------------------------------- + * + * TkWmStackorderToplevel -- + * + * 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. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TkWindow ** +TkWmStackorderToplevel(parentPtr) + TkWindow *parentPtr; /* Parent toplevel window. */ +{ + WindowRef frontWindow; + TkWindow *childWinPtr, **windows, **window_ptr; + 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); + TkWmStackorderToplevelWrapperMap(parentPtr, &table); + + windows = (TkWindow **) 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] = (TkWindow *) Tcl_GetHashValue(hPtr); + windows[1] = NULL; + goto done; + } + + frontWindow = (WindowRef) FrontWindow(); + + if (frontWindow == NULL) { + ckfree((char *) windows); + windows = NULL; + } else { + window_ptr = windows + table.numEntries; + *window_ptr-- = NULL; + while (frontWindow != NULL) { + hPtr = Tcl_FindHashEntry(&table, (char *) frontWindow); + if (hPtr != NULL) { + childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr); + *window_ptr-- = childWinPtr; + } + frontWindow = GetNextWindow(frontWindow); + } + if (window_ptr != (windows-1)) + panic("num matched toplevel windows does not equal num children"); + } + + done: + Tcl_DeleteHashTable(&table); + return windows; +} + + + + + |