summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorculler <culler>2024-06-10 15:37:44 (GMT)
committerculler <culler>2024-06-10 15:37:44 (GMT)
commit338762b617f55c9699753c8f38f582bf70b23dee (patch)
tree8d05b190e6d88eb530660fc96c5c59d3ffa2597e /generic
parent06a4ba5407ebd451d8ab5d56bb06fad34f24766f (diff)
parent3f0a126393198d3f6e0dff58e479ee9cab5b213d (diff)
downloadtk-338762b617f55c9699753c8f38f582bf70b23dee.zip
tk-338762b617f55c9699753c8f38f582bf70b23dee.tar.gz
tk-338762b617f55c9699753c8f38f582bf70b23dee.tar.bz2
New branch: merges the crossing events fix (sans processevents) with cgimage drawing
Diffstat (limited to 'generic')
-rw-r--r--generic/tkWindow.c53
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.
*/