Skip to content

feat: add kde wayland support#240

Merged
Merrit merged 1 commit intomainfrom
kde-wayland
Mar 21, 2026
Merged

feat: add kde wayland support#240
Merrit merged 1 commit intomainfrom
kde-wayland

Conversation

@Merrit
Copy link
Copy Markdown
Owner

@Merrit Merrit commented Feb 7, 2025

On KDE Plasma + Wayland, window management is no longer possible through
X11 tools (xdotool, wmctrl). This commit introduces a KDE-specific backend
that uses KWin scripting and D-Bus to provide the same suspend/resume
functionality on that platform.

How it works:

  • At startup on a KDE Wayland session, two KWin scripts are loaded via the
    KWin D-Bus API (org.kde.KWin). list_windows_kde.js enumerates all open
    windows and pushes them to Nyrna over D-Bus. active_window_kde.js sets
    up a persistent workspace.windowActivated listener that sends every
    subsequent focus change to Nyrna in real time.
  • Nyrna registers its own session D-Bus service (codes.merritt.Nyrna) via a
    generated NyrnaDbus object. The two KWin scripts call methods on this
    service (updateWindows, updateActiveWindow) to deliver their data.
  • Window minimize/restore on KDE Wayland is handled by writing a transient
    KWin script to disk and loading it each time it is needed, because the KWin
    scripting API does not expose a direct minimize/restore D-Bus call.

Architecture changes:

  • NativePlatform() is replaced by an async NativePlatform.initialize()
    factory. The extra async step is needed on Linux to resolve the session
    type, set up D-Bus, and (on KDE Wayland) load the KWin scripts before the
    rest of the app starts.
  • activeWindow() (async method) is replaced by an activeWindow mutable
    field updated by checkActiveWindow(). On KDE Wayland the field is kept
    current by the persistent D-Bus subscription, so checkActiveWindow() only
    needs to wait (poll up to 2 s) for the initial value.
  • A new SessionType value type combines DisplayProtocol (wayland / x11 /
    unknown) with DesktopEnvironment (kde / gnome / xfce / unknown). It is
    populated once during Linux.initialize() and exposed as a synchronous
    getter, removing the need for async session-type checks later.
  • ActiveWindowService selects the X11 or Wayland code path based on
    SessionType. ActiveWindowX11 and ActiveWindowWayland hold the
    platform-specific logic.
  • Window IDs are now String instead of int to accommodate KDE Wayland's
    UUID-style internalId values. X11 integer IDs are stringified.
  • NativePlatform.dispose() tears down D-Bus connections and cancels KWin
    script subscriptions. AppCubit.close() and the toggle-mode code path in
    main() both call it.

Wayland support can be extended in the future for other DEs, using the shared infrastructure introduced here.

@Merrit Merrit force-pushed the kde-wayland branch 4 times, most recently from 350c8eb to 976926a Compare February 8, 2025 17:30
@Merrit Merrit force-pushed the kde-wayland branch 2 times, most recently from 3198ecc to 965cba3 Compare March 21, 2026 19:39
@Merrit Merrit self-assigned this Mar 21, 2026
@Merrit Merrit added the enhancement New feature or request label Mar 21, 2026
@Merrit Merrit merged commit 15a5847 into main Mar 21, 2026
3 checks passed
@Merrit Merrit deleted the kde-wayland branch March 21, 2026 19:58
@Merrit Merrit mentioned this pull request Mar 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant