Skip to content

fix: route notification jumps to the originating session client - #141

Merged
mohak34 merged 8 commits into
mohak34:mainfrom
kriss-spy:codex/fix-kde-embedded-focus-actions
Oct 17, 2026
Merged

mohak34 merged 8 commits into
mohak34:mainfrom
kriss-spy:codex/fix-kde-embedded-focus-actions

Conversation

@kriss-spy

@kriss-spy kriss-spy commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #133: completion in an Obsidian or VS Code terminal can jump to unrelated Ghostty. KDE rejected KWin UUIDs, startup capture could select another foreground app, and V2's first-client claim could let a client without the completed session open own the notification and its click.

Delivery: client with the session family open → event claim → completed-session selection → captured host-window activation.

KDE capture accepts UUIDs and numeric IDs, prioritizes an explicit host ID, and otherwise resolves terminal/editor process ancestry with PID-constrained kdotool searches. Both V1 and V2 await bounded asynchronous capture. Ambiguous targets fail open with no jump action; failed activation does not choose another terminal. Captured IDs stay client-local instead of becoming inherited environment overrides.

V2 clients now publish their open tabs/current session route in private temporary presence files. Clients with the session family open take priority; the existing event claim still limits delivery to one eligible client per machine. If no eligible client has it open, a client falls back after a brief grace. Dead/stale presence, unusable storage and unavailable UI APIs preserve fail-open delivery. Presence is refreshed on events and every second, expires after five seconds, and is removed on disposal. A jump selects the event's session through the V2 tab/router API before activating its host window. focusOnClick=false leaves session navigation disabled.

Evidence

  • Before: A subprocess test with live Ghostty, VS Code and Obsidian clients, the same project/workspace, and a session open only in Obsidian produced popup:ghostty and jump:ghostty when Ghostty received completion first. A separate KDE regression captured foreground Ghostty for a background VS Code client.
  • After: Both regressions pass. Checks cover owner priority, no-owner fallback, replay dedupe, tabs-disabled routes, child-family matching, closed/stale/malformed presence, workspace isolation, disposal, missing APIs/storage, click navigation, UUIDs and exact host activation.
  • Combined local validation: 55 focused tests across eight files, typecheck and build pass. PR-only routing/registry/entrypoint checks and typecheck also pass after integration.
  • Manual built-package check: three separate Node clients, fake kdotool and a private D-Bus notification daemon. Ghostty and VS Code received the completion first and sent no popup; Obsidian sent exactly one. The action selected the expected session and requested activation of the pinned Obsidian UUID. All clients disposed and exited cleanly. This sent no desktop notifications and moved no windows.
  • Read-only probes on Fedora/KDE confirmed VS Code PID-to-window matching and the Obsidian window UUID. Flatpak's host launcher has no Obsidian process ancestry; it must pass an explicit host ID across the boundary, as documented. The user's local Obsidian launcher was configured separately to do so. After installing the combined local build, all three live clients hot-reloaded and published presence: only the Obsidian client has the reported session open; Ghostty and VS Code do not. Live user click validation after Obsidian reloads its launcher setting remains outstanding. macOS, Windows, other compositors and live GNOME were not tested on hardware.

Merge Danger

Door: Two-way. No configuration migration.

Blast Radius: V2. This intentionally refines the prior first-client delivery policy to prefer an eligible client with the session open, while preserving fallback alerts and one-per-machine claims. V2 built-in jump-back also selects the completed session. V1 retains its delivery policy and window-only jump. KDE window targeting applies to both versions; server commands, configuration defaults, other window backends and pane checks retain their existing behavior. README, SPEC and CHANGELOG describe the policy and limitations.

The plugin does not switch between separate host-managed embedded terminals or supervise interactive clients. Linux popup action lifetime is addressed separately in #142.

Generated with GPT-6 in Codex.

@kriss-spy kriss-spy changed the title fix(kde): accept UUID host windows for focus and jump-back fix(kde): target the originating terminal and editor window Oct 11, 2026
@kriss-spy kriss-spy changed the title fix(kde): target the originating terminal and editor window fix: route notification jumps to the originating session client Oct 11, 2026
@kriss-spy
kriss-spy marked this pull request as ready for review October 14, 2026 14:46
mohak34 and others added 4 commits October 17, 2026 22:21
…atch KWin IDs on X11, publish route roots

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	CHANGELOG.md
#	src/tui.ts
@mohak34
mohak34 merged commit ca4a044 into mohak34:main Oct 17, 2026
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.

Investigate notifier focus suppression and jump-back for embedded OpenCode terminals

2 participants