nextcloud / nextcloud/desktop

[Bug]: Startup tray popup holds an X11 grab during blocking I/O, freezing all desktop input

Open Beginner friendly
#10,610 2 comments 1 reaction 0 assignees View on GitHub
os: :penguin: Linux
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.