Files
hermes-agent/apps/desktop/electron
brooklyn! 6e64e6b9c6 fix(desktop): Windows glass windows stop rendering when they lose focus (#91307)
* fix(desktop): stop layering Windows glass windows, and don't make them transparent

A Windows chat window under glass rendered while focused and went dead the
moment it lost it. Two things put it on a compositing path DWM will not draw
acrylic behind, both no-ops that looked free:

`opacity: windowOpacity()` was passed on every window. Under glass on Windows
fade is 0, so the value is always 1 — but Electron's `SetOpacity` calls
`SetLayered()` and `SetLayeredWindowAttributes(..., LWA_ALPHA)` before it looks
at the value, and nothing ever takes `WS_EX_LAYERED` back off. A layered window
composites through the legacy redirection surface, which Windows documents as
mutually exclusive with `UpdateLayeredWindow`. Opacity is now only passed when
the state actually fades, and the runtime path keeps setting it for a window
that is already faded so it can still come back to opaque.

`transparent: true` was set on every glass-capable Windows chat window, on the
premise that DWM materials only reach the client area that way (electron#49443,
which was closed as need-info against an EOL Electron 28). They do not need it:
`IsTranslucent` answers yes off `background_material_` alone, which is what
gives the page its transparent default backing, and `SetBackgroundMaterial`
flips widget translucency live. Its one gate is a frameless window, and
`titleBarStyle: 'hidden'` already satisfies it. What `transparent` did add was
permanent — the widget pinned to kTranslucent for the window's whole life, so
even glass-OFF windows paid a DirectComposition redraw per frame
(electron#39895), plus the documented transparent-window limits, including that
a resizable transparent window is unsupported and breaks (electron#48421).

Both landed latent in #89837 and only surfaced when #90587 turned glass on by
default and dropped the opaque backing that had been hiding them.

* docs(desktop): name the one thing the opacity guard cannot undo

Electron exposes no way back off WS_EX_LAYERED, so a Windows window that has
been faded once keeps the layered compositing path until it is recreated. Not
opening the door on the default path is the whole of the fix; say so where the
guard lives rather than leaving a reviewer to work out the gap.
2026-08-21 05:57:14 +00:00
..
2026-08-14 22:16:25 +00:00