You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
UI Freeze: Area selection overlay triggers unexpectedly and locks the screen when exiting Settings in Instant Mode #1945
When I select the area recording option in the Cap UI, switch to Instant mode, and then open the Settings menu, a logical bug occurs when I try to exit Settings. The system immediately triggers the area selection overlay, even though I haven't clicked 'Start Recording' or the 'Area' button.
At this point, the selection interface freezes, making the computer appear completely unresponsive. My entire desktop is covered by an invisible, semi-transparent overlay. All mouse interactions and most keyboard inputs are completely intercepted. I can't see anything, and right-clicking anywhere brings up the Cap context menu. The only way to recover is to force-kill the application or click 'Refresh' in the Cap context menu.
Reproduction
Select the area recording option in the Cap UI.
Switch to Instant mode.
Open the Settings menu, and then exit it.
Observe the screen after exiting the Settings menu.
Additional Context
Cap version:0.5.1
Operating system, version:Windows 11 - 10.0.26200
Device (optional): Dual monitors with identical resolution and size(HKC Display)
The root cause is in the Settings window close handler at apps/desktop/src-tauri/src/lib.rs:5138-5162. When the Settings window is destroyed, it unconditionally calls show_overlay() for any existing TargetSelectOverlay windows:
CapWindowId::Settings => {for(label, window)in app.webview_windows(){ifletOk(id) = CapWindowId::from_str(&label){match id {CapWindowId::TargetSelectOverlay{ .. } => {show_overlay(&window);// Shows overlay regardless of current targetMode}// ...}}}}
The show_overlay() function (windows.rs:108-111) enables cursor events and shows the window:
The issue is that the overlay window may still exist from when the user selected area mode, but the frontend targetMode state has changed. When Settings closes, the backend restores the overlay without checking whether the frontend actually wants it displayed.
A fix would need to either:
Check the current targetMode from RecordingSettingsStore before calling show_overlay() and only show if targetMode is still "area"
Or emit a RequestSetTargetMode event with the current stored target mode so the frontend can decide whether to show the overlay
Or close the overlay windows when switching away from area mode, rather than just hiding them
This is similar to the pattern used for the Main window restoration in the same handler, where it properly coordinates with restore_main_window_inputs(). The overlay restoration needs similar coordination with the frontend state.
Related: #1915 discusses area picker issues on Windows with multi-monitor setups, and PR #1412 covers the Settings window close behavior.
Yes,That's definitely the exact same issue. I'm also running Windows on a dual-monitor setup and selected 'Area Mode'
Hardware: Dual monitors with identical resolution and size(HKC Display)
I traced this one through the Rust side and I think the mechanism is narrower than "the Settings close handler unconditionally restores overlays" — there's a specific state-lifetime bug. Posting the trace since I can't build the desktop crate in my environment to verify a patch (the build script needs the cap-muxer/cap-exporter sidecars and Spacedrive.framework, which aren't checked in).
With restore_target_select_overlays = true, that records every currently visible overlay into a restore set (windows.rs:158-166 → remember_overlay_for_restore), then hides them.
Note the ||: a label in the restore set is shown regardless of whether the window is currently visible.
Where it goes wrong
The restore set is written when Settings opens and only read when Settings closes. Nothing invalidates it in between. set_recording_mode (recording_settings.rs:92-96) is the whole command:
It persists the mode and repaints the tray. It does not touch WindowFocusManager, so a stale "restore these overlays" instruction from the previous mode survives the switch and fires on Settings close. That matches the reported repro exactly — pick Area, switch to Instant, open Settings, close it, and an overlay you never asked for appears.
It also explains @wubie052's follow-up that Studio and Display mode trigger it too: the trigger isn't a specific mode, it's any mode change between the remember and the restore.
Worth noting close_target_select_overlay_windows already calls clear_overlay_restore_labels() (target_select_overlay.rs:322) — so the invalidation primitive exists and is used on the explicit-close path. The mode-change path just doesn't call it.
Why it locks the screen rather than showing a visible overlay
show_overlay brings back a full-screen transparent window that intercepts input. In Instant mode the overlay UI has no reason to render its selection chrome, so the user gets an invisible click-eating surface — which is the "screen is frozen, right-click shows the Cap menu" symptom.
Suggested fix
Clearing the pending restore in set_recording_mode looks like the minimal correct change, reusing the existing primitive:
I wrote that and it's a two-line change, but I don't want to open a PR I can't compile — the desktop crate needs prebuilt sidecars I don't have. If a maintainer wants it as a PR anyway I'm happy to push it, or it's small enough to just apply directly.
One thing I'd want checked by someone who can run it: whether the restore should be cleared on mode change specifically, or whether the || in restore_main_and_target_select_windows should additionally require the overlay to still be relevant to the current mode. The former is minimal; the latter is more defensive if there are other paths that can stale the set.
Thanks for reporting this! This issue is in our old Tauri-based desktop app, which we've now fully replaced with a new native app (built on GPUI) from Cap 0.6.1 on macOS, Windows and Linux. We hope it's a much better experience for you. If you still see this problem in 0.6.1 or later, reply here and we'll reopen it.
Activity
linear commentedon Jun 25, 2026
CAP-738
tembo commentedon Jun 25, 2026
The root cause is in the Settings window close handler at
apps/desktop/src-tauri/src/lib.rs:5138-5162. When the Settings window is destroyed, it unconditionally callsshow_overlay()for any existingTargetSelectOverlaywindows:The
show_overlay()function (windows.rs:108-111) enables cursor events and shows the window:The issue is that the overlay window may still exist from when the user selected area mode, but the frontend
targetModestate has changed. When Settings closes, the backend restores the overlay without checking whether the frontend actually wants it displayed.A fix would need to either:
targetModefromRecordingSettingsStorebefore callingshow_overlay()and only show iftargetModeis still "area"RequestSetTargetModeevent with the current stored target mode so the frontend can decide whether to show the overlayThis is similar to the pattern used for the
Mainwindow restoration in the same handler, where it properly coordinates withrestore_main_window_inputs(). The overlay restoration needs similar coordination with the frontend state.Related: #1915 discusses area picker issues on Windows with multi-monitor setups, and PR #1412 covers the Settings window close behavior.
wubie052 commentedon Jun 25, 2026
Yes,That's definitely the exact same issue. I'm also running Windows on a dual-monitor setup and selected 'Area Mode'
Hardware: Dual monitors with identical resolution and size(HKC Display)
wubie052 commentedon Jun 25, 2026
Also, just to add to this: the bug is also triggered when returning from the Settings window while in Studio mode, or when Display mode is selected.
DPS0340 commentedon Jul 25, 2026
I traced this one through the Rust side and I think the mechanism is narrower than "the Settings close handler unconditionally restores overlays" — there's a specific state-lifetime bug. Posting the trace since I can't build the desktop crate in my environment to verify a patch (the build script needs the
cap-muxer/cap-exportersidecars andSpacedrive.framework, which aren't checked in).The path
hide_recording_windows(app, true)(windows.rs:1403).restore_target_select_overlays = true, that records every currently visible overlay into a restore set (windows.rs:158-166→remember_overlay_for_restore), then hides them.CapWindowId::Settings => restore_main_and_target_select_windows(app)(lib.rs:5722).take_overlay_restore_labels()and callsshow_overlay(&window)for every label in it —lib.rs:6163-6169:Note the
||: a label in the restore set is shown regardless of whether the window is currently visible.Where it goes wrong
The restore set is written when Settings opens and only read when Settings closes. Nothing invalidates it in between.
set_recording_mode(recording_settings.rs:92-96) is the whole command:It persists the mode and repaints the tray. It does not touch
WindowFocusManager, so a stale "restore these overlays" instruction from the previous mode survives the switch and fires on Settings close. That matches the reported repro exactly — pick Area, switch to Instant, open Settings, close it, and an overlay you never asked for appears.It also explains @wubie052's follow-up that Studio and Display mode trigger it too: the trigger isn't a specific mode, it's any mode change between the remember and the restore.
Worth noting
close_target_select_overlay_windowsalready callsclear_overlay_restore_labels()(target_select_overlay.rs:322) — so the invalidation primitive exists and is used on the explicit-close path. The mode-change path just doesn't call it.Why it locks the screen rather than showing a visible overlay
show_overlaybrings back a full-screen transparent window that intercepts input. In Instant mode the overlay UI has no reason to render its selection chrome, so the user gets an invisible click-eating surface — which is the "screen is frozen, right-click shows the Cap menu" symptom.Suggested fix
Clearing the pending restore in
set_recording_modelooks like the minimal correct change, reusing the existing primitive:I wrote that and it's a two-line change, but I don't want to open a PR I can't compile — the desktop crate needs prebuilt sidecars I don't have. If a maintainer wants it as a PR anyway I'm happy to push it, or it's small enough to just apply directly.
One thing I'd want checked by someone who can run it: whether the restore should be cleared on mode change specifically, or whether the
||inrestore_main_and_target_select_windowsshould additionally require the overlay to still be relevant to the current mode. The former is minimal; the latter is more defensive if there are other paths that can stale the set.richiemcilroy commentedon Oct 20, 2026
Thanks for reporting this! This issue is in our old Tauri-based desktop app, which we've now fully replaced with a new native app (built on GPUI) from Cap 0.6.1 on macOS, Windows and Linux. We hope it's a much better experience for you. If you still see this problem in 0.6.1 or later, reply here and we'll reopen it.