feat: Sway keymap for notification response #1

Open
opened 2026-06-09 16:26:28 +00:00 by casper · 0 comments
Owner

Notification Dispatch

Overview

$mod+n responds to the most recent visible notification. A dispatch system matches notification properties against a set of named handlers and executes the first match. Unmatched notifications fall back to default mako invocation.

Keybind

$mod+n in modules/sway/src/keymaps.conf, invoking a dispatch script.

Dispatch system

Notification target

The dispatch system always acts on the most recent notification, consistent with how makoctl dismiss behaves without an explicit -n flag.

Matching model

Each handler declares one or more field conditions. All conditions must match exactly for the handler to fire (AND semantics). Matchable fields are those exposed by makoctl list -j:

  • app_name
  • summary
  • body
  • urgency

Dismissal

On handler success, the notification is dismissed.

On fallback (no matching handler), the notification is dismissed regardless of whether it had invokable actions.

On handler failure (see per-handler failure modes), the notification is left visible.

Fallback

When no handler matches, the dispatch script calls makoctl invoke then dismisses.

Notification listener

Purpose

Handler logic that needs to identify the originating window of a notification must resolve the D-Bus sender PID at notification arrival time. The listener intercepts org.freedesktop.Notifications.Notify calls on the session bus, resolves each sender's connection name to a PID via org.freedesktop.DBus.GetConnectionUnixProcessID, and writes the mapping notification_id → sender_pid to a state file.

Lifecycle

Started via exec in the sway config. Scoped to the sway session.

State file

A temporary file updated by the listener. Read by handlers that require originating-window resolution.

Handlers

Claude Code

Match

Field Value
summary Claude Code

Action

Switch to the terminal window that originated the notification.

Window identification:

  1. Look up the sender PID for the current notification ID in the listener state file.
  2. Walk the process tree from the sender PID upward until a terminal process is found.
  3. Use sway IPC to focus the workspace containing that window, then focus the window.

Failure mode

If the originating window cannot be found (process gone, window closed), the handler exits silently. The notification is left visible.

# Notification Dispatch ## Overview `$mod+n` responds to the most recent visible notification. A dispatch system matches notification properties against a set of named handlers and executes the first match. Unmatched notifications fall back to default mako invocation. ## Keybind `$mod+n` in `modules/sway/src/keymaps.conf`, invoking a dispatch script. ## Dispatch system ### Notification target The dispatch system always acts on the most recent notification, consistent with how `makoctl dismiss` behaves without an explicit `-n` flag. ### Matching model Each handler declares one or more field conditions. All conditions must match exactly for the handler to fire (AND semantics). Matchable fields are those exposed by `makoctl list -j`: - `app_name` - `summary` - `body` - `urgency` ### Dismissal On handler success, the notification is dismissed. On fallback (no matching handler), the notification is dismissed regardless of whether it had invokable actions. On handler failure (see per-handler failure modes), the notification is left visible. ### Fallback When no handler matches, the dispatch script calls `makoctl invoke` then dismisses. ## Notification listener ### Purpose Handler logic that needs to identify the originating window of a notification must resolve the D-Bus sender PID at notification arrival time. The listener intercepts `org.freedesktop.Notifications.Notify` calls on the session bus, resolves each sender's connection name to a PID via `org.freedesktop.DBus.GetConnectionUnixProcessID`, and writes the mapping `notification_id → sender_pid` to a state file. ### Lifecycle Started via `exec` in the sway config. Scoped to the sway session. ### State file A temporary file updated by the listener. Read by handlers that require originating-window resolution. ## Handlers ### Claude Code **Match** | Field | Value | |---|---| | `summary` | `Claude Code` | **Action** Switch to the terminal window that originated the notification. Window identification: 1. Look up the sender PID for the current notification ID in the listener state file. 2. Walk the process tree from the sender PID upward until a terminal process is found. 3. Use sway IPC to focus the workspace containing that window, then focus the window. **Failure mode** If the originating window cannot be found (process gone, window closed), the handler exits silently. The notification is left visible.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
casper/dotfiles#1
No description provided.