Skip to content

Commit

Permalink
QCocoaDrag: reset the stored NSView when it gets destroyed
Browse files Browse the repository at this point in the history
QCocoaDrag stores the last NSView that received an input event, which
becomes a dangling pointer when the NSView gets destroyed. Inform the
QCocoaDrag when NSView's destructor runs, so that it can reset the
pointer (and reset the NSEvent pointer as well) when the destroyed
NSView is the stored one.

With this change alone we'd end up triggering the Q_ASSERT later on in
QCocoaDrag::drag, as m_lastEvent is now nil so the NSWindow will be nil
as well. QCocoaDrag::drag cannot do anything useful if m_lastEvent is
nil, so exit early.

Pick-to: 6.8 6.5
Fixes: QTBUG-116554
Change-Id: I5949d728d05adcf3d4a32c91f7e181393bef0422
Reviewed-by: Tor Arne Vestbø <[email protected]>
  • Loading branch information
vohi authored and torarnv committed Nov 8, 2024
1 parent 6661b95 commit 720ce9b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/plugins/platforms/cocoa/qcocoadrag.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class QCocoaDrag : public QPlatformDrag
* event and view when handling an event in QNSView
*/
void setLastInputEvent(NSEvent *event, NSView *view);
void viewDestroyed(NSView *view);

void setAcceptedAction(Qt::DropAction act);
void exitDragLoop();
Expand Down
15 changes: 14 additions & 1 deletion src/plugins/platforms/cocoa/qcocoadrag.mm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@
m_lastView = view;
}

void QCocoaDrag::viewDestroyed(NSView *view)
{
if (view == m_lastView) {
if (m_lastEvent.window.contentView == view) {
[m_lastEvent release];
m_lastEvent = nil;
}
m_lastView = nil;
}
}

QMimeData *QCocoaDrag::dragMimeData()
{
if (m_drag)
Expand Down Expand Up @@ -95,9 +106,11 @@

Qt::DropAction QCocoaDrag::drag(QDrag *o)
{
m_drag = o;
m_executed_drop_action = Qt::IgnoreAction;
if (!m_lastEvent)
return m_executed_drop_action;

m_drag = o;
QMacPasteboard dragBoard(CFStringRef(NSPasteboardNameDrag), QUtiMimeConverter::HandlerScopeFlag::DnD);
m_drag->mimeData()->setData("application/x-qt-mime-type-name"_L1, QByteArray("dummy"));
dragBoard.setMimeData(m_drag->mimeData(), QMacPasteboard::LazyRequest);
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/platforms/cocoa/qnsview.mm
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ - (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
[m_mouseMoveHelper release];

// FIXME: Replace with __weak or someting equivalent
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
nativeDrag->viewDestroyed(self);

[super dealloc];
}

Expand Down

0 comments on commit 720ce9b

Please sign in to comment.