[BUG] [Desktop][Linux] titleBarOverlay applied to every window on Linux (Windows-only API) leaves untitled, unclosable 800x600 orphan windows

Status Open
Maintainer reply None cached
Activity 0 comments · opened Jul 26, 2026

Summary

On Linux, Claude Desktop creates BrowserWindows with titleBarStyle: "hidden" and then
calls setTitleBarOverlay() on them. setTitleBarOverlay is Windows-only in Electron,
so the call throws on Linux and is swallowed. The result is a window whose native title bar
is hidden with nothing drawn in its place and no WM_NAME — an untitled, chrome-less
orphan window that the window manager cannot address.

The app's own code acknowledges the platform restriction:

titleBarOverlay: (e, t) => rle() && t && typeof t == "object"
    ? e.setTitleBarOverlay(t)
    : !rle() && t && Pa("titleBarOverlay only works on Windows")

…but a separate call site applies it unconditionally to every window and discards the error:

ow.getAllWindows().forEach(o => {
  if (AUe.get(o) !== i) try { o.setTitleBarOverlay(r), AUe.set(o, i) }
  catch { _.info("Failed to set title bar overlay, this is probably expected") }
})

Evidence

~/.config/Claude/logs/main.log292 occurrences over 3 days, continuous:

[info] Failed to set title bar overlay, this is probably expected

Resulting window, via xprop / xdotool:

| id | size | WM_CLASS | WM_NAME | state |
|---|---|---|---|---|
| A | 898x1166 | com.anthropic.claude | Claude | viewable (the real window) |
| B | 800x600 | com.anthropic.claude | '' (empty) | viewable, renders blank |

Window B carries the real application class, not a helper class — it is a genuine app
window. 800x600 is Electron's untouched default BrowserWindow size, i.e. the window was
created and its chrome setup failed before anything else was applied.

Impact

  1. The window is not closable by normal means. With no title and no title bar, wmctrl -ic

/ _NET_CLOSE_WINDOW are ignored. XKillClient would terminate the entire app's X
connection, taking every Claude window with it. The only safe remedy is xdotool windowunmap,
which hides rather than closes it.

  1. It is indistinguishable from the real window to automation. Any tool selecting a window

by application class and a size heuristic can pick the blank one. Input sent to it is
silently lost — it renders nothing and reports no error.

  1. Screen-reading/accessibility tooling sees a blank rectangle with no title to

disambiguate it from the real window.

Reproduction

  1. Run Claude Desktop on Linux (X11).
  2. grep -c 'Failed to set title bar overlay' ~/.config/Claude/logs/main.log — non-zero.
  3. `for w in $(xdotool search --class com.anthropic.claude); do

echo "$w '$(xdotool getwindowname $w)' $(xdotool getwindowgeometry $w | tail -1)"; done`
— one or more windows with an empty name at 800x600.

Suggested fix

Guard the call site the same way the setter is already guarded, rather than relying on
try/catch:

ow.getAllWindows().forEach(o => {
  if (!rle()) return;              // Windows only — skip entirely elsewhere
  if (AUe.get(o) !== i) { o.setTitleBarOverlay(r); AUe.set(o, i) }
})

And on non-Windows platforms avoid pairing titleBarStyle: "hidden" with an overlay that
cannot be drawn — either keep the native decoration or render an in-page title bar — so
windows always carry a WM_NAME.

Environment

  • Claude Desktop 1.24012.9 (Linux)
  • Linux, X11, Cinnamon
  • Electron 42.7.0 / Chromium 148 / Node 24.18

View original on GitHub ↗