Skip to content

Per-client active-pane resolution for Client.attached_pane #675

@tony

Description

@tony

What ships

`Client.attached_pane` (and possibly `Client.attached_window`) backed
by the `client_active_pane` format token from `list-clients`,
falling back to the existing `window.active_pane` cascade when the
`CLIENT_ACTIVEPANE` flag is unset on the client.

Problem solved

When a user enables `select-pane -P` (which sets tmux's
`CLIENT_ACTIVEPANE` flag), each attached client tracks an independent
active pane. libtmux today returns the window's active pane regardless,
silently mis-reporting which pane the client is viewing.

The current resolution in `src/libtmux/client.py:Client.attached_pane`
cascades through `session → curw → window.active_pane`. tmux's
`format_defaults` does the same cascade for tokens without `ft->wp`,
but the per-client variant has a different code path:
`server_client_get_pane()` consults `CLIENT_ACTIVEPANE` and returns
the client's own pane when set.

Verified against tmux source:

  • `cmd-list-clients.c:90` — calls `format_defaults(ft, l[i], NULL, NULL, NULL)`
  • `format.c:5870` — cascade fills `wp = wl->window->active` when `wp == NULL && wl != NULL`
  • `server-client.c:2683` — `server_client_get_pane()` honors `CLIENT_ACTIVEPANE`
  • `tmux.1:1069` — documents the `active-pane` window option

Why this is its own shipment

Requires:

  1. Declaring `client_active_pane` as a typed field on `Obj` with the
    appropriate `FIELD_VERSION` gate (verify tmux's CHANGES — the
    token was introduced before 3.2a, so likely no gating needed).
  2. A test fixture that enables `select-pane -P` and a second attached
    client to exercise the per-client behavior.
  3. Documentation update for `Client.attached_pane` that distinguishes
    the cascade fallback from the per-client resolution.

Material enough to warrant its own review.

Dependency

If #674 ("Type hints for tmux 3.4+ format tokens")
has landed, declaring `client_active_pane` is a lighter touch.
Otherwise this PR will need to declare the field independently.

Acceptance criteria

  • `Client.attached_pane` consults `client_active_pane` first,
    falls back to `window.active_pane` when unset
  • Regression test: create a session with two attached clients,
    enable `select-pane -P`, focus a different pane in each
    client, assert each `client.attached_pane` returns the
    correct per-client view
  • Docstring on `Client.attached_pane` explains the
    cascade-vs-per-client resolution and references the
    `active-pane` window option

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions