Пример #1
0
void 
XDestroyWindow(
    Display* display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    GWorldPtr destPort;

    /*
     * Remove any dangling pointers that may exist if
     * the window we are deleting is being tracked by
     * the grab code.
     */

    TkPointerDeadWindow(macWin->winPtr);
    macWin->toplevel->referenceCount--;
    
    
    if (Tk_IsTopLevel(macWin->winPtr)) {
	DisposeRgn(macWin->clipRgn);
	DisposeRgn(macWin->aboveClipRgn);
	
	/*
	 * Delete the Mac window and remove it from the windowTable.
	 * The window could be NULL if the window was never mapped.
	 * However, we don't do this for embedded windows, they don't
	 * go in the window list, and they do not own their portPtr's.
	 */
	 
	if (!(Tk_IsEmbedded(macWin->winPtr))) {
            destPort = TkMacGetDrawablePort(window);
	    if (destPort != NULL) {
	        TkMacWindowList *listPtr, *prevPtr;
	    
	        TkMacUnregisterMacWindow(destPort);
	        DisposeWindow((WindowRef) destPort);
	    
	        for (listPtr = tkMacWindowListPtr, prevPtr = NULL;
	    	        tkMacWindowListPtr != NULL;
	    	        prevPtr = listPtr, listPtr = listPtr->nextPtr) {
	            if (listPtr->winPtr == macWin->winPtr) {
	                if (prevPtr == NULL) {
	            	    tkMacWindowListPtr = listPtr->nextPtr;
	                } else {
	            	    prevPtr->nextPtr = listPtr->nextPtr;
	                }
	                ckfree((char *) listPtr);
	                break;
	            }
	        }
	    }
	}
	
	macWin->portPtr = NULL;
	
	/*
	 * Delay deletion of a toplevel data structure untill all
	 * children have been deleted.
	 */
	if (macWin->toplevel->referenceCount == 0) {
	    ckfree((char *) macWin->toplevel);
	}
    } else {
        destPort = TkMacGetDrawablePort(window);
	if (destPort != NULL) {
	    SetGWorld(destPort, NULL);
	    TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
	}
	if (macWin->winPtr->parentPtr != NULL) {
	    TkMacInvalClipRgns(macWin->winPtr->parentPtr);
	}
	DisposeRgn(macWin->clipRgn);
	DisposeRgn(macWin->aboveClipRgn);
	
	if (macWin->toplevel->referenceCount == 0) {
	    ckfree((char *) macWin->toplevel);
	}
	ckfree((char *) macWin);
    }
}
Пример #2
0
void
XDestroyWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *) window;
    WindowRef winRef;

    /*
     * Remove any dangling pointers that may exist if the window we are
     * deleting is being tracked by the grab code.
     */

    TkPointerDeadWindow(macWin->winPtr);
    macWin->toplevel->referenceCount--;

    if (!Tk_IsTopLevel(macWin->winPtr)) {
	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
	if (macWin->winPtr->parentPtr != NULL) {
	    TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
	}
	if (macWin->visRgn) {
	    CFRelease(macWin->visRgn);
	}
	if (macWin->aboveVisRgn) {
	    CFRelease(macWin->aboveVisRgn);
	}

	if (macWin->toplevel->referenceCount == 0) {
	    ckfree((char *) macWin->toplevel);
	}
	ckfree((char *) macWin);
	return;
    }

    /*
     * We are relying on the Activate Mac OS event to pass the focus away from
     * a window that is getting Destroyed to the Front non-floating window. BUT
     * we don't get activate events when a floating window is destroyed, since
     * the front non-floating window doesn't in fact get activated... So maybe
     * we can check here and if we are destroying a floating window, we can
     * pass the focus back to the front non-floating window...
     */

    if (macWin->grafPtr != NULL) {
	TkWindow *focusPtr = TkGetFocusWin(macWin->winPtr);

	if (focusPtr == NULL
		|| (focusPtr->mainPtr->winPtr == macWin->winPtr)) {
	    winRef = TkMacOSXDrawableWindow(window);
	    if (TkpIsWindowFloating (winRef)) {
		Window window = TkMacOSXGetXWindow(ActiveNonFloatingWindow());

		if (window != None) {
		    TkMacOSXGenerateFocusEvent(window, 1);
		}
	    }
	}
    }
    if (macWin->visRgn) {
	CFRelease(macWin->visRgn);
    }
    if (macWin->aboveVisRgn) {
	CFRelease(macWin->aboveVisRgn);
    }

    /*
     * Delete the Mac window and remove it from the windowTable. The window
     * could be NULL if the window was never mapped. However, we don't do this
     * for embedded windows, they don't go in the window list, and they do not
     * own their portPtr's.
     */

    if (!Tk_IsEmbedded(macWin->winPtr)) {
	WindowRef winRef = TkMacOSXDrawableWindow(window);

	if (winRef) {
	    TkMacOSXWindowList *listPtr, *prevPtr;
	    WindowGroupRef group;

	    if (GetWindowProperty(winRef, 'Tk  ', 'TsGp', sizeof(group), NULL,
		    &group) == noErr) {
		TkDisplay *dispPtr = TkGetDisplayList();
		ItemCount i = CountWindowGroupContents(group,
			kWindowGroupContentsReturnWindows);
		WindowRef macWin;
		WindowGroupRef newGroup;
		Window window;

		while (i > 0) {
		    ChkErr(GetIndexedWindow, group, i--, 0, &macWin);
		    if (!macWin) {
			continue;
		    }

		    window = TkMacOSXGetXWindow(macWin);
		    newGroup = NULL;
		    if (window != None) {
			TkWindow *winPtr = (TkWindow *)
				Tk_IdToWindow(dispPtr->display, window);

			if (winPtr && winPtr->wmInfoPtr) {
			    newGroup = GetWindowGroupOfClass(
				    winPtr->wmInfoPtr->macClass);
			}
		    }
		    if (!newGroup) {
			newGroup =
				GetWindowGroupOfClass(kDocumentWindowClass);
		    }
		    ChkErr(SetWindowGroup, macWin, newGroup);
		}
		ChkErr(SetWindowGroupOwner, group, NULL);
		ChkErr(ReleaseWindowGroup, group);
	    }
	    TkMacOSXUnregisterMacWindow(winRef);
	    DisposeWindow(winRef);

	    for (listPtr=tkMacOSXWindowListPtr, prevPtr=NULL;
		    tkMacOSXWindowListPtr != NULL;
		    prevPtr=listPtr, listPtr=listPtr->nextPtr) {
		if (listPtr->winPtr == macWin->winPtr) {
		    if (prevPtr == NULL) {
			tkMacOSXWindowListPtr = listPtr->nextPtr;
		    } else {
			prevPtr->nextPtr = listPtr->nextPtr;
		    }
		    ckfree((char *) listPtr);
		    break;
		}
	    }
	}
    }

    macWin->grafPtr = NULL;

    /*
     * Delay deletion of a toplevel data structure untill all children have
     * been deleted.
     */

    if (macWin->toplevel->referenceCount == 0) {
	ckfree((char *) macWin->toplevel);
    }
}