Skip to content

Stretch: raise/switch to an already-running app from the controller #20

Description

@jonocodes

Parent

#6 (stretch / future — not part of any current milestone)

What to build

Bidirectional focus: let a tap on the controller surface raise an already-running desktop application to the foreground. Today the GNOME Shell focus extension (deckd-focus@local) and daemon's watch_active_app only read focus; this ticket adds the write direction — "raise app X" — so a user can switch between open apps from the phone.

This is a stretch goal, explicitly out of scope of the v1 milestones (M3–M7). File now as a placeholder and design seed; no expectation of imminent work.

Why it's interesting

  • It closes a symmetry: deckd watches the desktop to swap the surface layout; raising apps would let the surface drive the desktop back. Without it, the surface is a one-way read of focus.
  • The app-aware model gives it a natural shape: the default layout could show a "running apps" row/column populated from watch_active_app, and tapping a tile raises that app.
  • Shares infrastructure with the existing focus backend — the GNOME Shell extension already enumerates windows; a second D-Bus method "RaiseApp(app_id_or_wm_class)" is a small extension to it on top of Main.activateWindow.

Why it's deferred

  • External signal of readiness: bidirectional focus is the single largest piece of platform coupling in deckd — every backend (GNOME Shell, X11, future macOS) needs both a read and a write side. The spec (deckd v1: milestones 3–7 implementation spec #6, design: Platform backend) deliberately scoped the spike to the read-only GNOME Shell extension because that was the riskiest unknown. The write side is separately risky on Wayland (no general "raise window" API; needs shell-extension JS, which is fragile across GNOME versions).
  • No emulator today: the daemon-side FakeFocusBackend only emits AppInfo events; raising needs a sink, so the test foundation grows. Not blocking, but work.
  • Out of scope per deckd v1: milestones 3–7 implementation spec #6 ("Out of Scope" only mentions hardware and macOS, but the focus direction is implicitly read-only by what M3-M7 build).

Acceptance criteria (when picked up)

  • GNOME Shell extension gains a RaiseApp(app_id | wm_class) D-Bus method that activates the matching window via Main.activateWindow (or equivalent); falls back gracefully on shell-version mismatch
  • Daemon gains a platform-backend method raise_active_app(app) (or a new action primitive raise: <app>) callable from a layout button
  • At least one new FakeFocusBackend-style sink for raising, with a WS-boundary test asserting a press → raised-app record
  • X11 path stays "unsupported" (no xdotool raise); errors are logged, not surfaced to the client
  • Optional but desirable: a "running apps" dynamic widget kind that lists apps the focus backend currently knows about. Note ADR-0005 (dynamic widget state) is explicitly deferred; this criterion may slip with it.

Blocked by

Nothing formal, but practically:

Further notes

  • Config stays the source of truth per deckd v1: milestones 3–7 implementation spec #6 ("nothing app-specific is ever hard-coded; all behavior lives in config"). The raise action should be a new primitive — either raise: firefox or a shaped dbus: action calling the extension method directly. The latter needs no daemon code change (the existing dbus: dispatch already fires arbitrary session-bus methods); the former is a cleaner UX. Probably start with the dbus: form to prove it works, then promote to a raise: primitive if it sticks.
  • iOS Safari PWA note (per deckd v1: milestones 3–7 implementation spec #6 further notes): irrelevant here; the surface just sends a press, the desktop side is the work.
  • Related: the auto-ignore feature (T5/T5: Dev UX — auto-ignore deckd window + deckctl layout override #11) holds the current layout when the deckd client browser gains focus. If a raise action makes the deckd browser itself the target (e.g. the user raises Chrome to verify something), auto-ignore should still hold — no extra work expected, but worth a regression check.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfocus-watcherActive-window / app-awareness detection

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions