From 31a979371ee30bb93667de218d223dad7da258c5 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Mon, 18 Jan 2021 13:34:43 -0800 Subject: [PATCH] mobile/hackery: try to prevent QLM race condition Apparently in some cases there is a race condition where the action to delete a dive is still running while a corresponding QML object (but not that action itself) is being deleted, likely because the action is becoming invisible once the dive is actually deleted. I'm speculating that this may be somewhere inside the delegates for the repeater showing the actions in the context drawer. This commit is a bit of a convoluted hack. We create a property to hold the dive id to be deleted and then call a function to delete that dive via a timer. This of course creates a blatant race condition in itself - but the user is extremely unlikely to be able to use the context menu to delete two different dives within 100ms. The code tries to keep that race window as small as possible. There has got to be a better way to do this. Signed-off-by: Dirk Hohndel --- mobile-widgets/qml/DiveList.qml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/mobile-widgets/qml/DiveList.qml b/mobile-widgets/qml/DiveList.qml index 7c04deddb..a6cdc8683 100644 --- a/mobile-widgets/qml/DiveList.qml +++ b/mobile-widgets/qml/DiveList.qml @@ -278,11 +278,40 @@ Kirigami.ScrollablePage { visible: currentItem && currentItem.myData && !currentItem.myData.isTrip onTriggered: manager.toggleDiveInvalid(currentItem.myData.id) } + Timer { + // this waits a tenth of a second and then deletes the dive - + // this way the Action in the contextDrawer can complete its signal handler before + // having the visual QML element going away and being deleted (which could cause a crash) + id: delayedDelete + interval: 100 + onTriggered: { + var myDiveToDelete = diveToDelete // try to minimize the window for a race + diveToDelete = -1 + if (myDiveToDelete !== -1) { + manager.appendTextToLog("now deleting dive id " + myDiveToDelete) + manager.deleteDive(myDiveToDelete) + } else { + manager.appendTextToLog("delayedDelete triggered with dive id -1"); + } + } + } + property int diveToDelete: -1 property QtObject deleteAction: Kirigami.Action { text: qsTr("Delete dive") icon { name: ":/icons/trash-empty.svg" } visible: currentItem && currentItem.myData && !currentItem.myData.isTrip - onTriggered: manager.deleteDive(currentItem.myData.id) + onTriggered: { + if (diveToDelete === -1) { + diveToDelete = currentItem.myData.id + manager.appendTextToLog("setting timer to delete dive " + diveToDelete) + delayedDelete.start() + contextDrawer.close() + manager.appendTextToLog("closed drawer, done with the action") + } else { + manager.appendTextToLog("deleteAction triggered with diveToDelete already set to " + + diveToDelete + " -- ignoring just to be safe"); + } + } } property QtObject mapAction: Kirigami.Action { text: qsTr("Show on map")