From 3197c7892f9dd4bc2ba841ee794a84272d5e86d2 Mon Sep 17 00:00:00 2001 From: ivan tkachenko Date: Tue, 2 Aug 2022 11:44:01 +0300 Subject: [PATCH] effects/{private,desktopgrid,overview}: Guard against function execution when component is being destroyed Accept drop events correctly and use returned value (action) of Drag.drop() to guard against the situation where the delegate is about to be destroyed. This does not fix any bugs per se, except suppressing a warning about undefined targetScreen being printed to a console on every window dropped onto a different virtual desktop. --- src/effects/desktopgrid/qml/DesktopView.qml | 12 ++++++++++-- src/effects/overview/qml/DesktopBar.qml | 11 +++++++---- src/effects/private/qml/WindowHeapDelegate.qml | 9 ++++++++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/effects/desktopgrid/qml/DesktopView.qml b/src/effects/desktopgrid/qml/DesktopView.qml index d2c32946a4..9cfbbe33e5 100644 --- a/src/effects/desktopgrid/qml/DesktopView.qml +++ b/src/effects/desktopgrid/qml/DesktopView.qml @@ -30,15 +30,21 @@ FocusScope { onEntered: { drag.accepted = true; } - onDropped: { + onDropped: drop => { + drop.accepted = true; if (drag.source instanceof DesktopView) { // dragging a desktop as a whole - if (desktopView === drag.source) { + if (drag.source === desktopView) { + drop.action = Qt.IgnoreAction; return; } effect.swapDesktops(drag.source.desktop.x11DesktopNumber, desktop.x11DesktopNumber); } else { // dragging a KWin::Window + if (drag.source.desktop === desktopView.desktop.x11DesktopNumber) { + drop.action = Qt.IgnoreAction; + return; + } drag.source.desktop = desktopView.desktop.x11DesktopNumber; } } @@ -96,6 +102,8 @@ FocusScope { y = 0; } Drag.active: dragHandler.active + Drag.proposedAction: Qt.MoveAction + Drag.supportedActions: Qt.MoveAction Drag.source: desktopView Drag.hotSpot: Qt.point(width * 0.5, height * 0.5) width: parent.width diff --git a/src/effects/overview/qml/DesktopBar.qml b/src/effects/overview/qml/DesktopBar.qml index e4b6b6ca2f..6058bb5767 100644 --- a/src/effects/overview/qml/DesktopBar.qml +++ b/src/effects/overview/qml/DesktopBar.qml @@ -199,10 +199,13 @@ Item { id: dropArea anchors.fill: parent - onEntered: { - drag.accepted = true; - } - onDropped: { + onDropped: drop => { + drop.accepted = true; + // dragging a KWin::Window + if (drag.source.desktop === delegate.desktop.x11DesktopNumber) { + drop.action = Qt.IgnoreAction; + return; + } drag.source.desktop = delegate.desktop.x11DesktopNumber; } } diff --git a/src/effects/private/qml/WindowHeapDelegate.qml b/src/effects/private/qml/WindowHeapDelegate.qml index 0d9548f960..82d2008c68 100644 --- a/src/effects/private/qml/WindowHeapDelegate.qml +++ b/src/effects/private/qml/WindowHeapDelegate.qml @@ -92,6 +92,8 @@ Item { state: thumb.activeDragHandler.active ? "drag" : "normal" Drag.active: thumb.activeDragHandler.active + Drag.proposedAction: Qt.MoveAction + Drag.supportedActions: Qt.MoveAction Drag.source: thumb.client Drag.hotSpot: Qt.point( thumb.activeDragHandler.centroid.pressPosition.x * thumb.targetScale, @@ -324,7 +326,12 @@ Item { if (active) { thumb.activeDragHandler = this; } else { - thumbSource.Drag.drop(); + var action = thumbSource.Drag.drop(); + if (action === Qt.MoveAction) { + // this whole component is in the process of being destroyed due to drop onto + // another virtual desktop (not another screen). + return; + } var globalPos = targetScreen.mapToGlobal(centroid.scenePosition); effect.checkItemDroppedOutOfScreen(globalPos, thumbSource); }