dnkl/foot
41
2.0k
Fork
You've already forked foot
243

Custom OSC for xdg-activation #2201

Open
opened 2025年10月18日 16:53:17 +02:00 by silversquirl · 4 comments

Describe your feature request

Some terminal applications, for example Kakoune, use a client-server model and may wish to switch focus from one terminal window to another. There is currently no way to do this without resorting to compositor-specific hacks.

I would like to request a custom OSC sequence for this, looking something like the following:
(code is a placeholder since I don't really know what OSCs are available - is there a resource anywhere that lists all known escape sequences across all terminals?)

  • Request an activation token with OSC code ; ? ST
    Response from the terminal is in the form OSC code ; token ST
    The seat and serial of the token should be set to the last keyboard, mouse button, or focus event that was sent (via escape codes) to the application running inside the terminal. The surface should be set to the terminal's surface, and the app id should be left unset.
  • Activate the current terminal with OSC code ; token ST

The spec for xdg-activation-v1 doesn't appear to place any restrictions on what the token string actually is, but in practice I think it's safe to assume it won't contain any control characters, and won't be just a single question mark.

### Describe your feature request Some terminal applications, for example Kakoune, use a client-server model and may wish to switch focus from one terminal window to another. There is currently no way to do this without resorting to compositor-specific hacks. I would like to request a custom OSC sequence for this, looking something like the following: (`code` is a placeholder since I don't really know what OSCs are available - is there a resource anywhere that lists all known escape sequences across all terminals?) - Request an activation token with `OSC` `code` `;` `?` `ST` Response from the terminal is in the form `OSC` `code` `;` `token` `ST` The seat and serial of the token should be set to the last keyboard, mouse button, or focus event that was sent (via escape codes) to the application running inside the terminal. The surface should be set to the terminal's surface, and the app id should be left unset. - Activate the current terminal with `OSC` `code` `;` `token` `ST` The spec for xdg-activation-v1 doesn't appear to place any restrictions on what the token string actually *is*, but in practice I think it's safe to assume it won't contain any control characters, and won't be just a single question mark.

FWIW I have a hacky script for a related use case: it creates a new terminal window with a new Kakoune client connecting to the same Kakoune server as the currently focused window.
I do this by putting hostname and Kakoune's session-name into my OSC 0 window title,
and have my script extract them from swaymsg -t get_tree | jq -r '.. | select(.focused? == true) | .name'

This means that I don't use Kakoune's :terminal,:new or :focus commands, as they don't work across SSH.

Compositor-independent solution sounds nice.

I don't know much about Wayland; do you want the Kakoune server to store each client's activation token as it connects?
I wonder if this is really needed; the Kakoune client's TTY might be enough.
I don't think the Kakoune server can access that directly, but it can be added (like it already writes OSC 0).

FWIW I have a hacky script for a related use case: it creates a new terminal window with a new Kakoune client connecting to the same Kakoune server as the currently focused window. I do this by putting hostname and Kakoune's session-name into my OSC 0 window title, and have my script extract them from `swaymsg -t get_tree | jq -r '.. | select(.focused? == true) | .name'` This means that I don't use Kakoune's `:terminal`,`:new` or `:focus` commands, as they don't work across SSH. Compositor-independent solution sounds nice. I don't know much about Wayland; do you want the Kakoune server to store each client's activation token as it connects? I wonder if this is really needed; the Kakoune client's TTY might be enough. I don't think the Kakoune server can access that directly, but it can be added (like it already writes OSC 0).

In the context of Kakoune specifically, the wayland implementation of :focus would need to do the following:

  1. track which client currently has focus, using a FocusIn hook
  2. when :focus is run, request an activation token by sending the proposed OSC to the terminal of the currently focused client
  3. when the activation token is received, send it to the terminal of the client that is requesting to be focused

Kakoune doesn't currently have a way for plugins to reliably send and receive escape codes, but either the support for this OSC could be implemented natively within Kakoune's terminal UI, or functionality could be added to allow plugins to do this :)

In the context of Kakoune specifically, the wayland implementation of `:focus` would need to do the following: 1. track which client currently has focus, using a `FocusIn` hook 2. when `:focus` is run, request an activation token by sending the proposed OSC to the terminal of the currently focused client 3. when the activation token is received, send it to the terminal of the client that is requesting to be focused Kakoune doesn't currently have a way for plugins to reliably send and receive escape codes, but either the support for this OSC could be implemented natively within Kakoune's terminal UI, or functionality could be added to allow plugins to do this :)

I daily drive kakoune, and its focus capabilities currently fall apart when you use foot -s and footclient. It will focus a seemingly random window instead of the one it wants. Would this OSC fix this issue?

I daily drive kakoune, and its focus capabilities currently fall apart when you use `foot -s` and `footclient`. It will focus a seemingly random window instead of the one it wants. Would this OSC fix this issue?

@raiguard yes

@raiguard yes
Sign in to join this conversation.
No Branch/Tag specified
master
osc-5522
sixel-heap-buffer-overflow
releases/1.27
releases/1.26
releases/1.25
releases/1.24
multi-cursor
releases/1.23
pixman-16f-2
releases/1.22
releases/1.21
releases/1.20
releases/1.19
releases/1.18
releases/1.17
releases/1.16
releases/1.15
releases/1.14
releases/1.13
releases/1.12
releases/1.11
releases/1.10
releases/1.9
releases/1.8
releases/1.7
releases/1.6
releases/1.5
releases/1.4
releases/1.3
releases/1.2
releases/1.1
releases/1.0
1.27.0
1.26.1
1.26.0
1.25.0
1.24.0
1.23.1
1.23.0
1.22.3
1.22.2
1.22.1
1.22.0
1.21.0
1.20.2
1.20.1
1.20.0
1.19.0
1.18.1
1.18.0
1.17.2
1.17.1
1.17.0
1.16.2
1.16.1
1.16.0
1.15.3
1.15.2
1.15.1
1.15.0
1.14.0
1.13.1
1.13.0
1.12.1
1.12.0
1.11.0
1.10.3
1.10.2
1.10.1
1.10.0
1.9.2
1.9.1
1.9.0
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.3
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
0.9.0
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
3 participants
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
dnkl/foot#2201
Reference in a new issue
dnkl/foot
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?