[BUG] Windows: main window silently becomes always-on-top after stealth auto-update (z-order anchor restored behind the topmost taskbar)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Title:
Windows: main window silently becomes always-on-top after stealth auto-update (z-order anchor restored behind the topmost taskbar)
---
Summary
After a silent auto-update and relaunch, the Claude desktop main window acquiresWS_EX_TOPMOST and stays pinned above every other window. No user action and no
setting is involved, and nothing is persisted, so it is invisible to the app's own
configuration.
Environment
- Claude desktop 1.44121.4.0, Windows, MSIX/Store install
- Windows 10 Pro 22H2 (build 19045), x64
Symptom
Alt-Tab appears broken. Focus does move to the other window, but Claude keeps
painting over it, so nothing seems to happen. Minimizing Claude is the only way to
see anything else. This reads to users as "always on top got switched on somehow" —
but no such toggle was touched, and config.json contains no alwaysOnTop key.
Root cause
[stealth-relaunch] saves a z-order anchor on quit via getWindowAbove(ourHwnd), then
on relaunch restores position with moveWindowBehind(ourHwnd, anchor).
When Claude is the frontmost normal window at quit time, the window directly above it
in Z-order is necessarily the lowest topmost window — frequently Shell_TrayWnd (the
taskbar), which carries WS_EX_TOPMOST (ExStyle 0x00000088).
Windows maintains the invariant that all topmost windows sit above all non-topmost ones.SetWindowPos(hwnd, <topmost window>, ...) therefore promotes the positioned window into
the topmost band and sets WS_EX_TOPMOST on it. No setAlwaysOnTop() call is involved,
which is why nothing is written to config and why the app has no idea it happened.
Because the anchor is chosen blindly, this should reproduce on most stealth relaunches
where Claude was the frontmost window at quit.
Evidence
From %LOCALAPPDATA%\Claude\logs\main.log (dates stripped):
11:13:50 [info] [stealth-relaunch] Saved z-order anchor: 0x10372 (above our 0x50836)
11:13:54 [info] [stealth-relaunch] Loaded z-order anchor: 0x10372
11:13:55 [info] [stealth-relaunch] Restored z-order: our 0x40862 behind anchor 0x10372
0x10372wasShell_TrayWnd, confirmed independently viaFindWindow("Shell_TrayWnd", NULL).- Main window ExStyle after the restore:
0x00080108— includesWS_EX_TOPMOST (0x8). - Expected:
0x00080100.
Minimal reproduction
Standalone — does not require Claude, and demonstrates the OS behavior directly.
Creates a 1x1 normal window, inserts it behind the taskbar exactly asmoveWindowBehind() does, and re-reads the extended style.
Add-Type -AssemblyName System.Windows.Forms, System.Drawing
Add-Type -TypeDefinition @'
using System; using System.Runtime.InteropServices;
public class ZT {
[DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr h, int i);
[DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr h, IntPtr a, int x,int y,int cx,int cy, uint f);
[DllImport("user32.dll", CharSet=CharSet.Unicode)] public static extern IntPtr FindWindow(string c, string n);
}
'@
$tray = [ZT]::FindWindow("Shell_TrayWnd", $null)
"anchor ExStyle=0x{0:X8}" -f [ZT]::GetWindowLong($tray, -20)
$f = New-Object System.Windows.Forms.Form
$f.FormBorderStyle='None'; $f.ShowInTaskbar=$false
$f.Size = New-Object System.Drawing.Size(1,1)
$f.Show(); [System.Windows.Forms.Application]::DoEvents()
"BEFORE ExStyle=0x{0:X8}" -f [ZT]::GetWindowLong($f.Handle, -20)
[void][ZT]::SetWindowPos($f.Handle, $tray, 0,0,0,0, 0x13) # NOSIZE|NOMOVE|NOACTIVATE
"AFTER ExStyle=0x{0:X8}" -f [ZT]::GetWindowLong($f.Handle, -20)
$f.Close()
Observed output:
anchor ExStyle=0x00000088
BEFORE ExStyle=0x00010000
AFTER ExStyle=0x00010008 <-- WS_EX_TOPMOST (0x8) set by the OS
Suggested fix
Any of, smallest first:
- After
moveWindowBehind(), re-assert non-topmost:
SetWindowPos(hwnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE).
- At save time, reject an anchor carrying
WS_EX_TOPMOSTand walk down the Z-order to
the first non-topmost window instead.
- Skip the z-order restore when the saved anchor is topmost or no longer valid.
(1) is the smallest safe change; (2) fixes it at the source.
Workaround
Restart the app, or clear the flag externally withSetWindowPos(hwnd, HWND_NOTOPMOST, ...) over each claude.exe top-level window.
What Should Happen?
Always on top should not be set by default as it is a distruptive block to user experience. it requires users to minimize claude app to see other apps/windows.
Error Messages/Logs
Steps to Reproduce
Install claude on windows 10 latest version, then launching it. Then launch other apps to open more windows.
trying to alt+tab we see the issue.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
Claude 1.44121.4 (0d57a2) 2026-09-02T23:50:20.000Z
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
PowerShell
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗