Skip to content

feat(linux): add opt-in X11 backend for tray-anchored positioning - #3218

Merged
afonsojramos merged 3 commits into
mainfrom
feat/linux-x11-backend
Aug 26, 2026
Merged

feat(linux): add opt-in X11 backend for tray-anchored positioning#3218
afonsojramos merged 3 commits into
mainfrom
feat/linux-x11-backend

Conversation

@afonsojramos

@afonsojramos afonsojramos commented Aug 24, 2026

Copy link
Copy Markdown
Member

Summary

Adds a Linux-only "Use X11 backend (restart required)" setting under System settings. When enabled, Gitify starts with --ozone-platform=x11, which restores tray-anchored window positioning.

Why

Electron 38 changed the default --ozone-platform-hint to auto (electron#35630), so on Electron 43 a Wayland session gets a native Wayland client. Under Wayland an app cannot position its own window (setPosition is a no-op, getPosition reads back [0, 0]) and the tray icon reports no coordinates over StatusNotifierItem, so the compositor decides placement and the popup lands centre-screen. That is #2341.

This is a protocol design decision rather than an Electron bug, so no future release fixes it. Running under XWayland is the only way to get anchored positioning back.

Why opt-in rather than forced

Forcing X11 would fix placement for everyone but degrade every Wayland user: XWayland means blurrier fractional scaling, no per-monitor DPI, and it breaks on Wayland-only setups without XWayland installed. It would also override a session choice the user already made. Notably teams-for-linux is moving the other way, removing its forced --ozone-platform=x11 now that Wayland has matured.

The tradeoff is genuinely user-specific (a HiDPI laptop user may prefer crisp text; a multi-monitor desktop user probably wants anchoring), so it belongs in the user's hands. Defaulting to false keeps current behaviour unchanged. If feedback shows most Linux users want anchoring, flipping the default later is a one-line change.

Why it needs a restart, and why a file

The Ozone platform is read during startup, so the switch must be appended before app.whenReady() — earlier than any renderer exists.

Every other setting lives in the renderer (Zustand → localStorage), which the main process cannot read at that point. So this one setting is mirrored to a marker file in userData, following the existing FirstRun marker precedent:

  • src/main/ozone.ts owns the marker: isX11BackendEnabled(), setX11Backend(), applyOzonePlatform().
  • src/main/index.ts calls applyOzonePlatform() at module load, before app.whenReady().
  • Toggling the setting sends UPDATE_USE_X11_BACKEND to main, which writes/removes the marker. The label says "restart required" and the tooltip repeats it.

applyOzonePlatform() is a no-op off Linux even if a marker exists, so a profile synced from a Linux machine can't affect macOS or Windows.

Refs #2341


Update: verified on hardware, plus a required companion switch

@alexey-anufriev tested a build of this branch on Kubuntu 25.10 / Plasma 6 Wayland (#2341) and confirmed two things.

The mechanism works. The log line proves the full chain on a real packaged Linux build:

[applyOzonePlatform] X11 backend enabled, forcing --ozone-platform=x11

But X11 alone was not enough. With only the ozone switch, the GPU process segfaulted repeatedly and no window ever painted:

GPU process exited unexpectedly: exit_code=139   (x3)   # 128 + 11 = SIGSEGV
XGetWindowAttributes failed for window 1

The tray icon appeared and responded to clicks, but the popup never rendered, which is worse than the centre-screen placement this setting exists to fix.

The cause was Vulkan, and the reporter's own Wayland log named it:

'--ozone-platform=wayland' is not compatible with Vulkan. Consider switching to '--ozone-platform=x11' or disabling Vulkan

Chromium skips Vulkan under Wayland because the two are incompatible, then initialises it once X11 is in play. On the NVIDIA proprietary driver (RTX 3080 Ti, nvidia kernel driver) that initialisation segfaults the GPU process.

Two candidates were tested on the affected machine:

flags result
A --ozone-platform=x11 --disable-features=Vulkan window correctly placed, no errors
B --ozone-platform=x11 --disable-gpu window correctly placed, no errors

Both work, so A was chosen: it keeps hardware acceleration, where --disable-gpu would throw all of it away to solve one broken code path.

applyOzonePlatform() now appends both switches together, and a test asserts they travel as a pair, since shipping the ozone switch alone reintroduces the no-window failure. Wayland users are unaffected: neither switch is applied unless the setting is on. The tooltip now mentions the Vulkan tradeoff.

Verified as exactly the flag combination that was tested on the affected hardware, rather than an equivalent-looking one.

@afonsojramos
afonsojramos requested a review from setchy as a code owner August 24, 2026 10:58
@github-actions github-actions Bot added the enhancement New feature or enhancement to existing functionality label Aug 24, 2026
@sonarqubecloud

Copy link
Copy Markdown

@afonsojramos
afonsojramos merged commit d7df927 into main Aug 26, 2026
23 checks passed
@afonsojramos
afonsojramos deleted the feat/linux-x11-backend branch August 26, 2026 00:08
@github-actions github-actions Bot added this to the Release 7.x.x milestone Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or enhancement to existing functionality

Development

Successfully merging this pull request may close these issues.

On Kubuntu 25.10 modal window apperas in the middle of the screen

1 participant