[Bug]: Startup tray popup holds an X11 grab during blocking I/O, freezing all desktop input
- Dominant language
- C++
- Stars
- 3.9k
- Forks
- 1k
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 123
Description
On Linux the client opens its tray window during startup, and that window takes an X11 pointer and keyboard grab. Immediately afterwards the same (GUI) thread goes into `FolderMan::setupFolders()`, which opens the sync journal and creates the inotify watches synchronously. If the sync folder lives on slow storage that takes a while, and the grab just sits there for the whole time.
Effect is that the entire desktop stops accepting input. No clicks, no keystrokes, in any application. Everything keeps rendering — videos keep playing, the compositor and the shell are perfectly fine — they just never see any input events. Looks exactly like the machine has locked up.
My sync folder is on a 4-disk btrfs raid10 of spinning disks, 395 MB `.sync_*.db`, ~71k directories. Cold start gives me around 22 seconds of dead input. On an SSD it's probably short enough that people just see a flicker and never report it.
### Steps to reproduce
1. Put a large-ish sync folder on slow storage. To simulate a cold boot without rebooting, drop the journal from the page cache first: `posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED)` on `.sync_*.db`.
2. Start the client.
3. Try to click or type anywhere while it starts up.
### Expected behaviour
Startup shouldn't take an input grab at all, and certainly shouldn't hold one across blocking I/O.
### Client version / environment
`nextcloud-client-git` 34.0.1.r315.g8aaf6d1, Arch Linux, KDE Plasma on X11.
### What I measured
The grab lines up exactly with the account restore:
```
14:56:36.060 [info] nextcloud.gui.account.manager accountmanager.cpp:719 Restored: 0 unknown certs.
14:56:57.889 [warning] nextcloud.gui.application application.cpp:722 Account(s) setup result: AccountsRestoreSuccess
```
I polled `XGrabPointer`/`XGrabKeyboard` from a separate process every 250 ms across startup. 87 of 252 samples came back `AlreadyGrabbed` for pointer *and* keyboard, covering 14:56:36 to 14:56:57 — the same window as above.
At the same time I polled `/proc//stat` for `Xorg`, `kwin_x11` and `plasmashell`: none of them ever left `S` state, so nothing was actually hung. Only the client sat in `D`/`filemap_get_pages` the whole time. Input simply had nowhere to go.
That also means a D-Bus based responsiveness check shows nothing — plasmashell answered introspection calls in 2 ms throughout. Took me a while to figure out I was measuring the wrong thing.
### Cause
`Systray::Systray()` wires the popup to `accountAdded`:
https://github.com/nextcloud/desktop/blob/df75cd874/src/gui/systray.cpp#L170-L172
The comment above it says this is meant for the wizard, so that adding an account opens the tray centered rather than wherever the cursor happens to be. But `accountAdded` is also emitted by `AccountManager::restore()` during startup, so the popup opens on every single launch. `Application::setupAccountsAndFolders()` then continues into `FolderMan::setupFolders()` on the same thread and blocks there.
### Suggested fix
Only open the popup for accounts added at runtime. I have a small patch here that adds a `startupFinished` flag to `Systray`, sets it at the end of `setupAccountsAndFolders()`, and returns early from the lambda before that point. Keeps the wizard behaviour, drops the startup grab. Happy to open a PR if that direction looks right.
The bigger issue underneath is that `setupFolders()` does blocking disk I/O on the GUI thread at all, but that's a much larger change and the grab is what turns it into a system-wide freeze.
Contributor guide
Research direction
Start in src/gui/systray.cpp at the accountAdded connection, then trace Application::setupAccountsAndFolders() into AccountManager::restore() and FolderMan::setupFolders(). Reproduce startup on Linux/X11 with a slow or cold sync journal and verify that the tray popup does not hold pointer or keyboard grabs while folder setup performs blocking I/O.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100