Skip to content

fix: Windows notch leaves the topmost band and never returns to it #304

Description

@PedroMendes22

Bug Description

On Windows the notch window leaves the topmost band of the z-order while keeping
WS_EX_TOPMOST set on itself, so it sinks behind ordinary windows and stays there. The
style bit still says "always on top"; the z-order no longer agrees.

tauri.conf.json declares alwaysOnTop: true once, at window creation, and nothing ever
asserts it again — the only set_always_on_top call in the tree is in dropzones.rs,
during a drag. So once the window has been pushed out of the band, nothing recovers it
short of restarting the app.

Measured over 60 samples at 500 ms, notch on the right edge, single monitor:

z-order index WS_EX_TOPMOST
notch window (Tauri App) 11 set
foreground window (Chrome) 3 not set

60 of 60 samples had the notch below the foreground window. A single
SetWindowPos(hwnd, HWND_TOPMOST, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE) moved it from
index 11 to index 2 immediately.

This is not a regression: the topmost-related code is identical between v1.14.0 and
v1.16.0. What made it visible here was restarting the app after an upgrade. I could not
identify what demotes the window in the first place — the point of the report is that
nothing puts it back.

Steps to Reproduce

  1. Run Codenotch on Windows with the notch visible.
  2. Get the notch window out of the topmost band. Another process calling
    SetWindowPos(notch, HWND_NOTOPMOST, …) does it deterministically; in normal use it
    happened on its own here, during ordinary window switching.
  3. Switch between windows of other applications.
  4. The notch is drawn behind them, and stays behind them for the rest of the session.

Expected Behavior

The notch stays above ordinary windows for the whole session, the way it does on the Mac,
without needing a restart.

Affected Provider (if applicable)

UI / Notch Presentation

Environment & macOS Version

Windows 11 Pro 10.0.26200, x64, single 1920×1080 monitor at 100%

Codenotch Version

1.16.0, built from source at tag v1.16.0. The build carries two local patches of my own, both confined to the HTTP setup in codex.rs / usage.rs (swapping ureq's bundled roots for schannel, because a TLS-intercepting AV here reissues certificates). Neither touches window management.

Additional Context

Two independent failure modes, and neither implies the other — a fix that only checks
one misses the other:

  1. the style bit is cleared outright (e.g. HWND_NOTOPMOST from another process);
  2. the style bit survives while the window sits below ordinary windows anyway — the case
    measured above.

set_always_on_top(true) is not enough to fix it. tao only applies a window-flag
change on a diff, and its ALWAYS_ON_TOP flag is already true, so the call is a no-op
exactly when you need it. SetWindowPos has to be called directly.

What I am running locally is a small watchdog next to the existing ones
(start_pointer_watchdog, start_work_area_watch): every 2 s, if the window has left the
band by either test above, re-assert with SetWindowPos(HWND_TOPMOST). It is asserted only
when the window really has left the band, so it does not fight windows that are legitimately
topmost. Over a session it logged 3 assertions, not one per tick.

Verified by clearing the bit deliberately: the window returned to index 2 in under 900 ms.

Happy to open a PR with that watchdog if the approach looks right to you.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions