Skip to content

fix(linux): force XWayland on KDE Wayland (Electron 39)#495

Closed
DamianPala wants to merge 1 commit into
OpenWhispr:mainfrom
DamianPala:fix/kde-xwayland-fix
Closed

fix(linux): force XWayland on KDE Wayland (Electron 39)#495
DamianPala wants to merge 1 commit into
OpenWhispr:mainfrom
DamianPala:fix/kde-xwayland-fix

Conversation

@DamianPala

@DamianPala DamianPala commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Summary

On Electron 39 the app silently ends up on native Wayland on KDE, which breaks the overlay bubble (centered instead of corner, steals focus, doesn't stay on top). This replaces the broken appendSwitch approach with a self-relaunch that actually gets the flag to Chromium in time.

Problem

PR #470 used appendSwitch("ozone-platform-hint", "x11") to force XWayland on KDE. On E39 this does nothing because the ozone platform is selected during Chromium init, before any JS runs. ELECTRON_OZONE_PLATFORM_HINT env var was also removed in E39 (electron#48001).

On native Wayland, overlay windows are fundamentally broken:

  • setPosition()/setBounds() ignored by the compositor (electron#40886)
  • showInactive() not supported on Wayland (electron#48436)
  • focusable: false is X11-only
  • KDE focus stealing prevention doesn't work for native Wayland apps (KDE Bug #488060)

VS Code hit the same wall with appendSwitch for ozone and closed it as "not planned" (microsoft/vscode#135191).

Solution

Self-relaunch with --ozone-platform=x11 before require("electron"), so the flag is on the real command line when Chromium initializes. The old appendSwitch KDE branch is removed since it has no effect on E39.

Side effects are minor: extra PID (parent exits immediately), Ctrl+C in terminal doesn't kill child (detached). Doesn't matter for .desktop launches.

An alternative used by some Electron apps is a bash wrapper script that execs the real binary with the flag (no extra process, Ctrl+C works). Cleaner but requires an afterPack hook and touches the packaging pipeline. Could be a follow-up.

Test plan

  • KDE Wayland: overlay in correct position, no focus steal
  • KDE Wayland: KGlobalAccel shortcut + paste work
  • GNOME/Hyprland/macOS/Windows: no behavior change

Tested on Kubuntu 25.10, KDE Plasma 6, E39.8.1 / E39.8.3.

On Electron 39+, appendSwitch("ozone-platform-hint", "x11") has no
effect — the ozone platform is selected during Chromium init, before
any JS runs. This causes the app to silently start on native Wayland
on KDE, breaking overlay positioning, focus, and always-on-top.

Self-relaunch with --ozone-platform=x11 before require("electron")
is the only way to get the flag onto the native command line in time.
@DamianPala
DamianPala marked this pull request as ready for review March 24, 2026 19:07
@DamianPala

DamianPala commented Mar 25, 2026

Copy link
Copy Markdown
Contributor Author

I have been thinking about this more. The self-relaunch works but it's not great long-term - extra PID, Ctrl+C doesn't kill the child in terminal, etc.

Looking at how other apps handle this on Linux, several use a wrapper script pattern:

  • Chrome - google-chrome bash wrapper that sets up env and exec -a "$0" the real chrome binary
  • Brave - brave-browser wrapper > brave binary, same pattern as Chrome
  • Mullvad VPN - mullvad-vpn wrapper detects Wayland compositors, adds --ozone-platform=wayland, execs mullvad-gui

The pattern: rename the real binary (e.g. open-whispr -> open-whispr-bin), ship a small bash wrapper as open-whispr that detects KDE Wayland and adds --ozone-platform=x11, then execs the real binary.

Could be done with an afterPack hook in electron-builder - rename binary, write wrapper script, done. Works with deb, rpm, AppImage, tar.gz. electron-builder already has this pattern built-in for Flatpak (useWaylandFlags option), just not for other targets. MQTT-Explorer is a reference implementation of this exact approach with afterPack.

Bonus: if we add a flags.conf reader to the wrapper (~/.config/open-whispr-flags.conf), users can add their own Chromium flags without rebuilding. One flag per line, # for comments — same convention as chrome-flags.conf / brave-flags.conf (those are read at the C++ level in Chromium, but since Electron doesn't support this natively, we'd implement it in the wrapper).

I can prepare a PR with the wrapper approach if you're interested. The self-relaunch in this PR works as a quick fix, but the wrapper would be the proper solution.

EDIT: reviewed pattern examples.

@gabrielstein-mem0

Copy link
Copy Markdown

Thank you so much for the work on this! Closing for now since it's been superseded by #498, which includes this self-relaunch fix plus the remaining hotkey registration, clipboard timing, and dev-mode fixes needed for KDE Wayland.

1 similar comment
@gabrielste1n

Copy link
Copy Markdown
Collaborator

Thank you so much for the work on this! Closing for now since it's been superseded by #498, which includes this self-relaunch fix plus the remaining hotkey registration, clipboard timing, and dev-mode fixes needed for KDE Wayland.

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