Fix FloatBar disappearing after minimization or monitor disconnect#194
Fix FloatBar disappearing after minimization or monitor disconnect#194Juafeis wants to merge 3 commits into
Conversation
|
Thanks for the PR, I will review this ASAP. |
|
P2: |
|
Good catch. Now the coordinate handling should be strict and unit-safe. remember_geometry now checks is_minimized() and only rejects the exact physical (-32000, -32000) sentinel; the restore path likewise rejects only the exact persisted sentinel observed in this bug. The scaled-range heuristic has been removed, so legitimate negative multi-monitor origins are preserved. I also added a regression test that verifies physical (-8000, -8000) is remembered. |
|
Btw, something even more important I found: this is not limited to using Show Desktop or reopening CodexBar. On my two-monitor setup, the FloatBar was on the Windows primary display. Simply powering that display off while CodexBar was still running caused Windows to mark the live FloatBar window as minimized and move it to the exact physical position I have pushed the additional changes in I reproduced the failure on CodexBar 0.42.0, recovered the bar on the remaining monitor at |
Finesssee
left a comment
There was a problem hiding this comment.
Request changes — thermo-nuclear + ponytail review
Direction is right: do not persist Windows park coordinates; relocate when the live window is off every connected display; cover show + settings reapply + move. Please address the blockers below before merge.
Blockers
-
Visibility must use full monitor bounds, not work area (
floatbar/window.rs—ensure_visible_on_active_monitor)- Today “on-screen” means intersects some monitor work area.
- Taskbar-style floatbar is intentionally placed in the reserved taskbar strip (existing
showfirst-launch uses fullmonitor.size()). - A bar fully in that strip has zero work-area intersection and will be yanked to primary on every move/resize/
apply_state. - Fix: split concerns —
- Visibility / “still on a connected display” → intersect against
monitor.position()+monitor.size()(full bounds). - Fallback placement → keep work-area + style-aware padding.
- Visibility / “still on a connected display” → intersect against
-
Do not
Settings::load()on every Moved/Resized (floatbar/mod.rs)- Hot path hits disk+deserialize only to read
float_bar_style, and style is only needed when relocation actually runs. - Fix: probe visibility first; load style (or default
"floating") only inside the relocate branch; or thread style from an already-loaded snapshot onapply_state/show.
- Hot path hits disk+deserialize only to read
-
Stored-geometry reject is logical vs physical (HiDPI gap)
geometry_storestores logical coords (remember_geometrydivides by scale).is_windows_minimized_positiondocuments exact physical(-32000, -32000).- At scale 1.25/1.5/2.0, previously parked geometry becomes e.g.
-25600/-21333/-16000and passes the exact check. - Fix: scale-aware / range-based reject (or reject if restored physical bounds do not intersect any monitor), and clear the bad entry when relocating. Keep live
outer_positionequality on physical-32000as-is.
Non-blocking (preferred in same pass)
- Prefer atomic relocate+persist in one call so the event handler does not rely on early-return + synthetic
Movedto re-persist. - One shared default-origin helper for first-open and recovery (they already disagree: full monitor vs work area).
- After
unminimize+ move, re-assertapply_no_activate/apply_always_on_topso recovery does not steal focus. - Add a unit test: “window fully in monitor bounds but outside work area remains visible” once (1) is fixed.
Ponytail (complexity only)
- Inline
should_remember_physical_position(one-line wrapper). - Collapse dual
WebviewWindow/Windowtrait paste if&Windowis enough. - Drop style load from the hot path (same as blocker 2).
- Share placement formula with first-open.
Net: ~−30–50 lines possible after the above.
Please push an update addressing blockers 1–3 (and ideally the non-blocking items). Happy to re-review quickly after that.
|
Thanks for the original fix — the recovery direction was right. We cannot push onto the fork branch ( → #200 Addressed from the request-changes review:
Please close this draft PR in favor of #200 when convenient, or say if you prefer to cherry-pick the tip commit onto your branch instead. |
|
Closing as superseded by #200 (original fix + review blockers, rebased onto main). |
Summary
Problem and reproduction
There are two confirmed ways for the FloatBar to disappear while Show Floating Bar remains enabled.
Reproduction A: minimization
Win+D) so Windows minimizes/parks the FloatBar window.%APPDATA%\CodexBar\window_geometry.json.Reproduction B: primary-monitor disconnect
%APPDATA%\CodexBar\window_geometry.json.In the second reproduction, observed on CodexBar 0.42.0, Windows immediately changed the FloatBar entry to:
The native FloatBar window was also reported as minimized. Removing only the invalid
floatbargeometry entry and restarting CodexBar restored it on the remaining 1920x1080 monitor at(780, 8).Root cause
The FloatBar window-event handler persisted every
Moved,Resized, andCloseRequestedevent. On Windows, minimizing the window or disconnecting its monitor can park it at the physical coordinate(-32000, -32000). The startup path trusted that stored position, so a transient Windows window-management state became permanent application state.The original guard only prevented that invalid state from being saved/restored. The primary-monitor disconnect reproduction also shows that the running window must be recovered immediately and that any other stale position from a disconnected display must be validated against the current monitor topology.
Fix
The persistence path now skips geometry when Tauri reports the window as minimized and strictly rejects the raw physical
(-32000, -32000)sentinel.The FloatBar now also checks its actual physical bounds against every active monitor work area:
If it no longer intersects an active monitor, CodexBar unminimizes it when needed and moves it near the top or bottom center of the current primary monitor, preserving the selected FloatBar style. Because this check uses physical window and monitor coordinates end to end, legitimate layouts with negative origins such as
(-8000, -8000)remain valid.Validation
cargo test -p codexbar-desktop-tauri— 312 passedcargo clippy -p codexbar-desktop-tauri --all-targets --no-deps -- -D warnings— passedcargo fmt --all— passedgit diff --check— passed(780, 8)The repository-wide
cargo clippy -p codexbar-desktop-tauri --all-targets -- -D warningsstill reports two pre-existingcollapsible_matchwarnings inrust/src/providers/claude/cli_reset.rs(lines 278 and 283); this PR does not touch that code.