Skip to content

fix(linux): present player controls as a WM-managed overlay window - #512

Draft
jfb112697 wants to merge 3 commits into
NuvioMedia:Devfrom
jfb112697:fix/linux-wm-overlay-window
Draft

jfb112697 wants to merge 3 commits into
NuvioMedia:Devfrom
jfb112697:fix/linux-wm-overlay-window

Conversation

@jfb112697

Copy link
Copy Markdown

Problem

On XWayland the Linux player's controls were composited by snapshotting a composite-redirected WebKitGTK child window into mpv (overlay-add). That pipeline:

  • costs a per-frame readback/upload (a 100MB-class texture push at HiDPI sizes) that made the whole UI sluggish during playback
  • misbehaves driver-dependently (NVIDIA GBM failures, Mesa alpha issues), needing watchdog resets and rate limiting

Solution

Present the controls as a separate managed borderless toplevel, transient for the app window (XSetTransientForHint) and geometry-synced to the host canvas:

  • the compositor blends its ARGB surface with real alpha — native-speed controls with zero snapshot cost
  • normal window management stacks/covers/minimizes it together with the app, so it no longer floats over other applications or survives minimize
  • skip_taskbar/skip_pager hints plus KDE's _KDE_NET_WM_STATE_SKIP_SWITCHER keep it out of the taskbar, pager, and alt-tab switcher
  • WebKitGTK keeps the forced software-rendering path (NUVIO_WEBKIT_ALLOW_GPU opts out); NUVIO_OVERLAY_SNAPSHOT=1 restores the legacy snapshot pipeline as an escape hatch

Testing

Validated interactively on KWin/Wayland + Mesa (amdgpu): controls render and animate at full frame rate during 4K playback, minimize/restore and alt-tab behave like any owned window, keyboard shortcuts and cursor show/hide work through player open/close cycles.

Note: stacked on #511 (jpackage classpath fix) — that commit is included here since this work was verified in packaged builds.

The jpackage Linux launcher pipe-transfers the serialized config with a
single read; with many jars it exceeds the pipe capacity, truncates, and
SIGSEGVs in jvmLauncherStartJvm. Collapse app.classpath to a directory
wildcard in the packaged .cfg files.
XWayland never alpha-blends child windows, so the composite-redirect +
snapshot pipeline paid a per-frame cost and misbehaved on some drivers.
Present the controls as a separate managed borderless toplevel, transient
for the app window and geometry-synced to the host canvas: the compositor
blends its ARGB surface with real alpha, and normal window management
covers/minimizes/stacks it with the app instead of floating over other
applications. NUVIO_OVERLAY_SNAPSHOT=1 restores the legacy pipeline.
The managed transient overlay would otherwise appear as its own alt-tab
entry next to the app window. _KDE_NET_WM_STATE_SKIP_SWITCHER is appended
post-map (EWMH client-initiated state change) so GDK's initial
_NET_WM_STATE write cannot drop it, and is ignored harmlessly by
compositors that do not know the atom.
@skoruppa

Copy link
Copy Markdown
Member

yeah... no, we tried this approach. It does not work. It causes too many problems

@yagomolano

Copy link
Copy Markdown

Tested this branch on a setup not covered by the original validation: hybrid GPU laptop on Hyprland.

Setup: Arch Linux, Hyprland (Wayland), Nuvio 0.1.21-alpha via XWayland, Intel Iris Xe + NVIDIA RTX 2050 (proprietary driver), system libmpv 0.41.

How: compiled player_bridge.cpp from fix/linux-wm-overlay-window against system webkit2gtk-4.1/mpv headers and swapped the resulting libplayer_bridge.so into the 0.1.21-alpha jar. No full rebuild needed.

Result: on the stock snapshot pipeline the controls overlay was completely invisible on this driver combo (video played, GUI never rendered). With this PR the controls render and are fully interactive, and the player closes back to the library correctly. Log confirms toplevel mode engaged: overlay toplevel mode: managed transient, no reparent, no redirect.

Happy to share build flags or fuller logs if useful.

@KhooLy
KhooLy marked this pull request as draft September 3, 2026 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants