diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkWindow.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 68f3406..64f6ce0 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -215,6 +215,17 @@ static int Initialize(Tcl_Interp *interp); static int NameWindow(Tcl_Interp *interp, TkWindow *winPtr, TkWindow *parentPtr, const char *name); static void UnlinkWindow(TkWindow *winPtr); + +/* + * This static variable only makes sense for macOS and Windows, which never + * have more than one display. It is set by TkCloseDisplay, and when set + * prevents sending Enter and Leave events when all of the windows in the + * display are being destroyed. Tk does not send those events on X11; that + * job is handled by the X server. + */ + +static int displayBeingClosed = 0; + /* *---------------------------------------------------------------------- @@ -239,6 +250,7 @@ static void TkCloseDisplay( TkDisplay *dispPtr) { + displayBeingClosed = 1; TkClipCleanup(dispPtr); if (dispPtr->name != NULL) { @@ -1334,6 +1346,39 @@ Tk_CreateWindowFromPath( *-------------------------------------------------------------- */ +#if defined(MAC_OSX_TK) || defined(_WIN32) +static void SendEnterLeaveForDestroy( + Tk_Window tkwin) +{ + int x, y; + unsigned int state; + Tk_Window pointerWin; + TkWindow *containerPtr; + + if (displayBeingClosed) { + return; + } + XQueryPointer(Tk_Display(tkwin), None, NULL, NULL, &x, &y, + NULL, NULL, &state); + pointerWin = Tk_CoordsToWindow(x, y, tkwin); + if (pointerWin == tkwin) { + if (!Tk_IsTopLevel(tkwin)) { + containerPtr = TkGetContainer((TkWindow *)pointerWin); + Tk_UpdatePointer((Tk_Window) containerPtr, x, y, state); + } + } + + if (pointerWin && (tkwin == Tk_Parent(pointerWin))) { + Tk_UpdatePointer(Tk_Parent(tkwin), x, y, state); + } +} +#else +static void SendEnterLeaveForDestroy( + TCL_UNUSED(Tk_Window)) +{ +} +#endif + void Tk_DestroyWindow( Tk_Window tkwin) /* Window to destroy. */ @@ -1353,6 +1398,10 @@ Tk_DestroyWindow( return; } + if ((winPtr->flags & TK_DONT_DESTROY_WINDOW) == 0) { + SendEnterLeaveForDestroy(tkwin); + } + winPtr->flags |= TK_ALREADY_DEAD; /* @@ -1523,7 +1572,7 @@ Tk_DestroyWindow( * Cleanup the data structures associated with this window. */ - if (winPtr->flags & TK_WIN_MANAGED) { + if (winPtr->wmInfoPtr && (winPtr->flags & TK_WIN_MANAGED)) { TkWmDeadWindow(winPtr); } else if (winPtr->flags & TK_WM_COLORMAP_WINDOW) { TkWmRemoveFromColormapWindows(winPtr); @@ -2612,7 +2661,7 @@ Tk_RestackWindow( TkWindow *otherPtr = (TkWindow *) other; /* - * Special case: if winPtr is a top-level window then just find the + * Special case: if winPtr is a toplevel window then just find the * top-level ancestor of otherPtr and restack winPtr above otherPtr * without changing any of Tk's childLists. */ |