Random freezing #1

Open
opened 2026-07-22 19:55:20 +08:00 by Breadway · 2 comments
Owner

When I search for something, sometimes the window freezes and the only way to fix it is to exit and open again

When I search for something, sometimes the window freezes and the only way to fix it is to exit and open again
Author
Owner

Investigated on 2026-08-06. Traced the full search path (main()run_ui()search.connect_changed()fuzzy_matches()/fuzzy_score(), plus breadbox-shared's desktop-entry/icon-cache/config loading and breadbox-sync's manifest writer) and found no blocking I/O, locks, channels, or threads anywhere in the codebase — it's entirely single-threaded on the GTK main loop, and every function in the search/filter/sort path is bounded, in-memory, and non-blocking. breadbox-sync is a fully offline batch tool, not something breadbox talks to at runtime, and it writes manifest.json atomically (tmp file + rename), so there's no race there either.

No definitive root cause found, so no fix was made — didn't want to guess-patch something unrelated. Two ranked hypotheses, neither implemented:

  1. Wayland/gtk4-layer-shell keyboard-grab issuewindow.set_keyboard_mode(KeyboardMode::Exclusive) is a known trouble spot for some compositors: the window can stop receiving keystrokes on reopen while the process itself is fine (matches "only fix is quit and reopen"). This would be a compositor interaction, not fixable purely in breadbox's code.
  2. Per-keystroke resort cost on large entry counts — every keystroke does a full re-sort with repeated to_lowercase() allocations, which could read as a stutter under load but wouldn't explain an indefinite freeze.

To narrow this down: when it freezes, does the window disappear/stop rendering entirely, or does it stay visible but just stop responding to keystrokes? That would help distinguish (1) from an actual process hang.

Investigated on 2026-08-06. Traced the full search path (`main()` → `run_ui()` → `search.connect_changed()` → `fuzzy_matches()`/`fuzzy_score()`, plus `breadbox-shared`'s desktop-entry/icon-cache/config loading and `breadbox-sync`'s manifest writer) and found no blocking I/O, locks, channels, or threads anywhere in the codebase — it's entirely single-threaded on the GTK main loop, and every function in the search/filter/sort path is bounded, in-memory, and non-blocking. `breadbox-sync` is a fully offline batch tool, not something breadbox talks to at runtime, and it writes `manifest.json` atomically (tmp file + rename), so there's no race there either. No definitive root cause found, so no fix was made — didn't want to guess-patch something unrelated. Two ranked hypotheses, neither implemented: 1. **Wayland/gtk4-layer-shell keyboard-grab issue** — `window.set_keyboard_mode(KeyboardMode::Exclusive)` is a known trouble spot for some compositors: the window can stop receiving keystrokes on reopen while the process itself is fine (matches "only fix is quit and reopen"). This would be a compositor interaction, not fixable purely in breadbox's code. 2. **Per-keystroke resort cost** on large entry counts — every keystroke does a full re-sort with repeated `to_lowercase()` allocations, which could read as a stutter under load but wouldn't explain an indefinite freeze. To narrow this down: when it freezes, does the window disappear/stop rendering entirely, or does it stay visible but just stop responding to keystrokes? That would help distinguish (1) from an actual process hang.
Author
Owner

User confirms: window stays visible, just stops responding to keystrokes when it freezes.

This is consistent with hypothesis 1 (keyboard-grab/compositor issue) but doesn't fully rule out a true main-loop hang, since a frozen GTK main loop would also just leave the last-rendered frame on screen (Wayland surfaces are client-painted, so "visible" alone doesn't prove the loop is still running).

Next time it happens, a couple of cheap checks would disambiguate:

  • Hover the mouse over the window/list items during the freeze. If hover-highlight still updates, the GTK main loop is alive and it's specifically input (keyboard) that's stuck — points hard at hypothesis 1. If hover does nothing either, the whole loop is blocked — a real hang, and worth revisiting the "no blocking calls found" conclusion (maybe under conditions not covered by static tracing, e.g. filesystem stalls on the desktop-entry directories).
  • ps -o pid,stat,%cpu -C breadbox during the freeze — S/D state with near-0% CPU means it's blocked waiting on something (I/O or a lock); a busy R state pegged at 100% means it's spinning, which would point at something like a runaway match/sort loop instead.
  • If launched from a terminal, note whether anything prints to stderr right as it freezes.

Leaving this here for whenever it's caught in the act again.

User confirms: window stays visible, just stops responding to keystrokes when it freezes. This is consistent with hypothesis 1 (keyboard-grab/compositor issue) but doesn't fully rule out a true main-loop hang, since a frozen GTK main loop would also just leave the last-rendered frame on screen (Wayland surfaces are client-painted, so "visible" alone doesn't prove the loop is still running). Next time it happens, a couple of cheap checks would disambiguate: - **Hover the mouse over the window/list items during the freeze.** If hover-highlight still updates, the GTK main loop is alive and it's specifically input (keyboard) that's stuck — points hard at hypothesis 1. If hover does nothing either, the whole loop is blocked — a real hang, and worth revisiting the "no blocking calls found" conclusion (maybe under conditions not covered by static tracing, e.g. filesystem stalls on the desktop-entry directories). - **`ps -o pid,stat,%cpu -C breadbox`** during the freeze — `S`/`D` state with near-0% CPU means it's blocked waiting on something (I/O or a lock); a busy `R` state pegged at 100% means it's spinning, which would point at something like a runaway match/sort loop instead. - If launched from a terminal, note whether anything prints to stderr right as it freezes. Leaving this here for whenever it's caught in the act again.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Breadway/breadbox#1
No description provided.