From a95f9f1b08a27165ffce03db777aad7e1660a3b0 Mon Sep 17 00:00:00 2001 From: marc_culler Date: Sun, 19 Dec 2021 22:01:59 +0000 Subject: Add a property to TKWindow which indicates that the associated Tk window is being destroyed. --- macosx/tkMacOSXMouseEvent.c | 32 ++++++++++++++++++++------------ macosx/tkMacOSXPrivate.h | 2 ++ macosx/tkMacOSXWm.c | 2 ++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index 29a57aa..b96d487 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -124,6 +124,14 @@ enum { if (!isTestingEvent && !isMotionEvent) { return theEvent; } + } else if ([(TKWindow *) eventWindow isDead]) { + if ([eventWindow isKeyWindow]) { + [eventWindow resignKey]; + } + dragTarget = NULL; + target = TkMacOSXGetTkWindow([NSApp keyWindow]); + isDragging = NO; + [NSApp setTkEventTarget: target]; } else if (!NSPointInRect(viewLocation, [contentView bounds])) { isOutside = YES; } @@ -142,6 +150,7 @@ enum { } isDragging = YES; dragTarget = target; + break; case NSRightMouseDragged: case NSOtherMouseDragged: isMotionEvent = YES; @@ -291,20 +300,19 @@ enum { return theEvent; } } else { - if (isDragging) { - - /* - * The dragTarget window can be destroyed during a mouse drag by - * pressing Cmd-W without releasing the mouse button. This can - * lead to a crash. See [6be8b0b48c]. - */ - + if (isDragging && dragTarget) { TkWindow *dragPtr = (TkWindow *) dragTarget; - if(dragPtr == NULL || dragPtr->flags & TK_ALREADY_DEAD) { - target = (TkWindow *) TkMacOSXGetTkWindow([NSApp keyWindow]); - return theEvent; + TKWindow *dragWindow = nil; + if (dragPtr) { + dragWindow = (TKWindow *)TkMacOSXGetNSWindowForDrawable( + dragPtr->window); + } + if (!dragWindow) { + dragTarget = NULL; + target = NULL; + return theEvent; } - winPtr = TkMacOSXGetHostToplevel(dragPtr)->winPtr; + winPtr = TkMacOSXGetHostToplevel((TkWindow *) dragTarget)->winPtr; } else if (eventType == NSScrollWheel) { winPtr = scrollTarget; } else { diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index de0f5fd..c3b364f 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -451,9 +451,11 @@ VISIBILITY_HIDDEN #ifdef __i386__ /* The Objective C runtime used on i386 requires this. */ Window _tkWindow; + Bool _isDead; #endif } @property Window tkWindow; +@property Bool isDead; @end @interface TKWindow(TKWm) diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index c065d6c..cdfc1a1 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -363,6 +363,7 @@ static void RemoveTransient(TkWindow *winPtr); @implementation TKWindow: NSWindow @synthesize tkWindow = _tkWindow; +@synthesize isDead = _isDead; @end #pragma mark TKWindow(TKWm) @@ -1057,6 +1058,7 @@ TkWmDeadWindow( */ deadNSWindow = (TKWindow *)wmPtr->window; + [deadNSWindow setIsDead:YES]; if (deadNSWindow && !Tk_IsEmbedded(winPtr)) { NSWindow *parent = [deadNSWindow parentWindow]; [deadNSWindow setTkWindow:None]; -- cgit v0.12