Skip to content

KDE: window enumeration + raise, and reverse-DNS layout identity fixes (#133) - #158

Merged
jonocodes merged 2 commits into
mainfrom
issue-133
Aug 15, 2026
Merged

KDE: window enumeration + raise, and reverse-DNS layout identity fixes (#133)#158
jonocodes merged 2 commits into
mainfrom
issue-133

Conversation

@jonocodes

Copy link
Copy Markdown
Owner

Closes #133 (field-verification follow-ups).

Changes

Two commits:

  1. feat(kde): window enumeration + raise, reaching GNOME parity (3a345a7)
    KWin script pushes the active window + full window list into a daemon-owned org.deckd.Focus; daemon serves GetActiveWindow / ListWindows, and raise is enqueued-and-polled by the KWin script. Verified live on Plasma 6.5.6 Wayland.

  2. fix(layouts): reverse-DNS identity matching + packaging-suffix labels (c2d5bd2)
    Two live field bugs found while verifying KDE backend advertises watch_windows/raise_window it can't fulfill #133:

    • Layout.matches_identity matched identities exactly, so a bare konsole token never matched KDE/GNOME's reverse-DNS wm_class (org.kde.konsole) — Konsole silently fell to the default layout. Now also matches the identity's last dotted segment; full tokens still match only their exact identity.
    • _humanize_identity took the last dotted segment, so org.telegram.desktop labeled "Desktop" instead of "Telegram". Now strips trailing .desktop/.app packaging segments first.

Verification

  • Full daemon suite: 713 passed (3 new tests for the fixes)
  • pyright clean on changed lines
  • Live on KDE Plasma 6.5.6 Wayland: konsole resolves to the Terminal layout, Telegram labels correctly, both layout buttons and raise work end-to-end

Environment note

On the verification machine, layout buttons (uinput injection) required granting /dev/uinput access (udev rule + input group) — fixed in the separate host config repo, not this PR.

jonocodes and others added 2 commits August 15, 2026 07:24
The #133 short-term fix dropped KdeFocusBackend to focus-only because the
KWin script could only push the active window in. This follow-up teaches the
KWin script + daemon cache to answer enumeration and raise, so KDE honestly
re-advertises watch_windows / raise_window / raise_app.

Grounded in a primary-source pass over KWin master (windowList(), writable
workspace.activeWindow, and — the crux — a QTimer global in the script
sandbox), the push architecture is extended both directions the outbound-only
callDBus constraint allows:

- Enumeration inverts to push: the KWin script pushes the full window list
  (UpdateWindowList) into the same cache the daemon serves back on
  ListWindows(); the inherited GnomeShellFocusBackend.watch_windows gdbus-poll
  is answered unchanged.
- Raise inverts to enqueue-and-poll: since the daemon can't call into KWin,
  raise_window / raise_app resolve the id against the daemon's own cached
  window list and enqueue it; the script drains the queue on a QTimer tick
  (DrainPendingRaises) and sets workspace.activeWindow.

Wire shape stays byte-identical to GNOME: resourceClass -> wm_class,
desktopFileName -> sandboxed_app_id, focused-first ordering, 0-based
workspace index, retired-id -> RaiseWindowFailed. skipTaskbar is the sole
enumeration filter (KDE's native switcher signal), matching GNOME's
inclusiveness.

Tests: cache/service/backend covered test-first in tests/test_platform_kde.py;
the real main.js is driven headless via a node:vm sandbox in the new
scripts/test_kwin_focus_bridge.mjs (wired into `just test` / `test-focus-wire`).
docs/PLATFORM-PARITY.md flips the KDE column to ✓ (parity test #136 stays
green) and documents the inverted plumbing; docs/TESTING.md notes the rows are
code-and-CI truth, unverified on hardware.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…#133)

Konsole (org.kde.konsole) fell to the default layout because the layout
matcher compared identities exactly, and a bare `konsole` token never
matched KDE/GNOME's reverse-DNS wm_class. Running-windows labels took the
last dotted segment, so org.telegram.desktop labeled 'Desktop' instead of
'Telegram'.

- matches_identity also matches the identity's last dotted segment against
  layout tokens (org.kde.konsole -> konsole); full tokens still match only
  their own exact identity.
- _humanize_identity strips trailing .desktop/.app packaging segments
  before the last-dotted-segment split.
- Tests for both; PLATFORM-PARITY.md KDE bullet updated.
@jonocodes
jonocodes merged commit b16a533 into main Aug 15, 2026
1 of 2 checks passed
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.

KDE backend advertises watch_windows/raise_window it can't fulfill

1 participant