Roshani's KDE & GSoC Blog

Weeks 9 & 10: Multi-Select and Mobile Selection Mode

Over the last two weeks, I worked on adding multi-select support for deleting multiple entries at once. It sounded like a straightforward feature at first, but it ended up leading me down an interesting debugging involving an asynchronous race condition.

Multi-Select with Ctrl+Click and Shift+Click (!44)

KeepSecret now supports the standard multi-selection behavior users expect from desktop applications. You can Ctrl+click to select or deselect individual entries, and Shift+click to select a range of entries. I also updated the right-click behavior so that if you right-click on an unselected entry, it becomes the current selection first.

Another improvement was simplifying the delete logic. Previously, deleting a single entry and deleting multiple entries followed different code paths. Now both actions share the same implementation, making the code cleaner and easier to maintain.

While working on this feature, I also fixed a few small UI issues. The entry details panel would sometimes open unexpectedly after a right-click, occasionally close when it shouldn't, or remain visible even after the selected wallet had been deleted. These edge cases are now handled correctly.

The Race Condition

Deleting multiple entries at once would sometimes fail with a confusing libsecret-CRITICAL error and a “Could not retrieve the secret value” message. The problem was inconsistent—it could happen with the first item or with one of the later items.

I first checked a few possible causes, like stale proxy-model indices and timing issues between deletion and model updates. Eventually, I found the real problem.

When an item was loaded, it also started an asynchronous request to fetch its secret. But the delete operation could run before that request finished. If the item was deleted first, the callback would later try to access an item that no longer existed.

Since we don't need the actual secret value when deleting an entry, I changed the loading process to skip that unnecessary request. This removed the race condition instead of trying to work around the timing issue.

Mobile-Friendly Selection Mode (!46)

I added a touch-friendly version of the desktop multi-select feature. Long-pressing an entry enters selection mode, where checkboxes appear and tapping entries toggles their selection. It reuses the existing selection logic, so the Delete Selected Secrets action works without any changes.

Nate Graham also suggested that this pattern could eventually be useful as a reusable component for other mobile apps. Marco Martin is testing the long-press behavior on a touch device next, since it currently also gets triggered by clicking and holding with a mouse.