Repository navigation
fix(hud): restore the Linux HUD from the tray and keep the vertical bar on screen on Wayland - #1272
Conversation
On GNOME Wayland, "Hide recording bar" minimized the HUD and the tray's Open could not bring it back: GNOME only showed an "openscreen is ready" notification. xdg-shell has set_minimized and nothing to undo it, Chromium's Wayland Show() returns early on a toplevel that still exists, and the activation focus() then requests carries no fresh token, which mutter turns into that notification. hide() destroys the toplevel and show() maps a new one, so the tray's Open, a second launch and the global shortcut all bring the bar back. Linux only: Windows and macOS keep minimize().
On GNOME Wayland, switching the HUD to the vertical bar left its bottom controls off screen: the window came out 648x1080 on a 1080p display and the compositor kept its top-left where the horizontal one had been, so it ran from y 186 to 1266, the record button under the dock and Open Studio, language, hide and quit below the screen edge. Wayland has no protocol for a client to learn where the shell's panels are, so Chromium's screen.availHeight is the display's full height there. The vertical tray asks for more than it can have, so it was granted all 1080px: a window that cannot fit below GNOME's 32px top bar, whose bottom controls stayed out of reach wherever it was dragged. And mutter only moves a client-resized window back into the work area when it fits there. On Linux, when the platform reported the whole height as free, the HUD now budgets 128px less (GNOME's top bar plus a bottom dock at Ubuntu's largest icon size). The vertical window then fits: it can be dragged fully on screen, and mutter's fully-onscreen constraint puts a flipped tray back on screen when the window was inside the work area before. X11, Windows and macOS report their panels and are unchanged, and so is the horizontal tray.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Summary
Two HUD fixes for Linux, found in the manual e2e pass of the installed
v2.1.0-rc.1.debon Ubuntu 24.04, GNOME Shell 46, native Wayland (Electron 41.2.1, ozone auto → Wayland), 1920×1080 at 100 %, 32 px top bar, Ubuntu dock at the bottom. One commit per defect, independent of each other, so they can be cherry-picked ontorelease/v2.1.0separately. A third defect from the same pass is analysed below and deliberately left out.1. Tray → Open did not bring back a hidden HUD (
573ba3ca)Observed. Hide recording bar minimized the HUD and the app kept running. Tray (AppIndicator) → Open then made GNOME show only an "“openscreen” is ready" notification, and the HUD stayed minimized. Clicking the app's dock icon did restore it.
Root cause (read in Chromium's
ui/ozone/platform/wayland/host/wayland_toplevel_window.ccand mutter 46):set_minimizedand no request to undo it. A Wayland client cannot un-minimize itself.showMainWindow()callsrestore(),show(),focus(). On WaylandRestore()leaves a minimized window toShow(), andWaylandToplevelWindow::Show()returns at once when thexdg_toplevelstill exists. So neither call did anything.focus()→Activate()asks for an xdg-activation token tied to the app's last input serial. That serial is not from the tray click, which happens in gnome-shell. mutter refuses the activation and flags the window as demanding attention, and gnome-shell turns that into the "is ready" notification.Fix. On Linux,
hud-overlay-hidecallshide()instead ofminimize(). Chromium destroys thexdg_toplevel, and theshow()already inshowMainWindow()maps a new one, which the compositor displays. It should also take focus when it is mapped: mutter'sintervening_user_event_occurredreturns FALSE for a Wayland window with no user time. This fixes every caller ofshowMainWindow(): tray Open, a second launch (second-instance), and the global shortcut where it can register. On X11 the HUD is alreadyskipTaskbar, so a minimized HUD had no taskbar entry and the tray was its only way back anyway;hide()changes nothing there that a user can see. Windows and macOS keepminimize().Trade-off (Wayland only). The new toplevel is placed by the compositor, so the HUD does not come back exactly where it was hidden. A Wayland client cannot set its own position, so this cannot be avoided. The dock icon no longer brings the bar back either, because no window is mapped; the tooltip already says "Show it again from the tray icon". While a recording is running the tray menu holds only Stop Recording, on every platform, so the way back mid-take is to launch the app again (the dock or the app grid). That raises
second-instance, which shows the HUD.2. The vertical bar ran off the screen (
3e262901)Observed. The horizontal HUD window measured 910×696 (AT-SPI), with the 528×54 bar at window-relative (191, 622). Switch to vertical bar resized it to 648×1080 (bar 54×499 at (297, 561)), and the compositor kept its top-left at about (150, 186). So the window ran from y 186 to y 1266 on a 1080 px display: Record sat under the dock, and Open Studio, language, Hide and Quit were below the screen edge.
Root cause.
WaylandOutput::UpdateMetricsnever fills the work-area insets thatWaylandScreen::AddOrUpdateDisplayapplies. Soscreen.availHeightis 1080. The vertical tray asks for more than that (bar + 470 px panel reserve + 120 px hysteresis = 1141), socomputeHudWindowSizecapped it at the reported 1080. That window cannot fit under the 32 px top bar, because mutter keeps a window's top edge inside the work area on a client-started move. Its bottom controls were out of reach wherever it was dragged: the window top stops at y 32, so the bar's bottom stays at y ≥ 1092.meta_window_wayland_finish_move_resize). The positionhudResizeBoundscomputes is ignored, so the bottom-anchored bar moved down by the growth. mutter does move a client-resized window back inside the work area (constrain_fully_onscreen), but only when the window fits there. The HUD is not resizable, so mutter cannot shrink it either (the window kept its 1080 px), and a 1080 px window does not fit.Fix.
computeHudAvailableHeight()(inhudGeometry.ts). On Linux, when the platform reports the whole display height as free, the HUD budgets 128 px less: GNOME's top bar plus a bottom dock at Ubuntu's largest icon size. On a 1080 px display the vertical tray now asks for 952 px. That fits, so:The horizontal tray's window is unchanged (696 px either way). X11 publishes the panels, so its
availHeightis already smaller thanheight. Windows (where a full-height work area means an auto-hidden taskbar) and macOS are not touched.3. Not fixed here: the HUD cannot be dragged into the upper part of the screen
Observed. Dragging up stops the bar at y ≈ 681 (horizontal) or 593 (vertical), because the transparent reserve above the bar is part of the window and mutter keeps the window's top edge below the top bar.
Why there is no change for it. The reserve is where the device-settings panel (up to 470 px), the language menu, notices and toasts open above the bar without resizing the window. On Wayland the client cannot position its window and cannot learn where it is (
getPosition()andgetCursorScreenPoint()are fictions there). Every in-window layout I looked at trades one defect for another:The Linux HUD also keeps its whole window inside the work area by design (
HUD_CLAMPS_CONTENTinwindows.ts, because Linux has no click-through), so X11 has the same reach limit. Changing that is a design change, not a fix for a frozen release branch. Options formain:Menu.popup(), which is anxdg_popupthe compositor positions relative to the HUD and keeps on screen;Workaround on GNOME today. Super+drag the bar. mutter's own modifier-drag is
META_GRAB_OP_WINDOW_FLAG_UNCONSTRAINEDand may take the window's top above the top bar, which anxdg_toplevel.movemay not (mutter 46window.c,constraints.c). It holds until the HUD next resizes itself (a layout flip, a notice).Related issue
Refs the manual e2e pass of
v2.1.0-rc.1on Ubuntu 24.04 / GNOME 46 Wayland (no issue filed).Type of change
Release impact
Desktop impact
Screenshots / video
None. These changes were written without launching the app: another session was driving the desktop. See the manual steps below.
Testing
Unit tests:
electron/windows.hudHide.test.ts(new): Hide recording bar callshide()on Linux andminimize()on Windows and macOS.process.platformis pinned per case, and the module is re-imported becausewindows.tsreads the platform at import.src/components/launch/hudGeometry.test.ts:computeHudAvailableHeighton Wayland, X11, Windows and macOS. The reported 54×499 vertical bar was granted 1080 px before and now fits between GNOME's top bar and a dock of 80 px; the bar does not scroll internally and still has room for a full popover. The horizontal tray's window is identical.src/components/launch/LaunchWindow.test.tsx: on a Linux display reporting its whole height free, the HUD asks for at most 1080 − 128 px for the vertical bar. Verified failing without the fix: it asks for 1080.npx vitest --run src/components/launch electron/windows*.test.ts electron/hudWindowBounds.test.ts: 198 passed.npm run test: 4720 passed. The only failures are the 5electron/mcp/*suites, which cannot import@modelcontextprotocol/sdkbecause thenode_modulesthis worktree borrowed predates that dependency. That is a local setup gap; CI installs withnpm ci.npx tsc --noEmit,npx tsc -p tsconfig.test.json --noEmit: clean apart from the same missing-SDK errors inelectron/mcp/*.npm run lint: no new diagnostics.Manual verification on GNOME Wayland (needs a real session)
Use a build of this branch, on Ubuntu 24.04 / GNOME 46 Wayland with the dock at the bottom, launched from a shell with
OPENSCREEN_DISABLE_CONTENT_PROTECTION=1. Checkecho $XDG_SESSION_TYPE→wayland.openscreenlaunch instead of the tray: same result.--ozone-platform=x11) the vertical tray's size must not change, since X11 reports the panels. On Windows and macOS Hide recording bar still minimizes.What only a real session can confirm:
🤖 Generated with Claude Code
Summary by CodeRabbit