Skip to content

macos/applescript: derive key event text and codepoint#13180

Closed
paaloeye wants to merge 2 commits into
ghostty-org:mainfrom
paaloeye:feat/applescript-send-key-text-part-1
Closed

macos/applescript: derive key event text and codepoint#13180
paaloeye wants to merge 2 commits into
ghostty-org:mainfrom
paaloeye:feat/applescript-send-key-text-part-1

Conversation

@paaloeye

@paaloeye paaloeye commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Executing the send key AppleScript command is broken for printable characters. The generated KeyEvent lacks both text representation and unshiftedCodepoint. Consequently, Ghostty ignores or failed to process letters and spaces sent via AppleScript.

Minimal repro (doesn't work as expected with stable and tip):

Warning

This sends date to all opened terminals/surfaces

tell application "Ghostty"
    set allTerms to terminals

    repeat with t in allTerms
        send key "d" to t -- doesn't work 
        send key "a" to t -- ditto
        send key "t" to t -- ditto
        send key "e" to t -- ditto
        send key "enter" to t
    end repeat

   display dialog ("Broadcasted to " & (count of allTerms) & " terminal(s).")
end tell

This, however, does work (from documentation):

set cmd to "date"

tell application "Ghostty"
    set allTerms to terminals

    repeat with t in allTerms
        input text cmd to t
        send key "enter" to t
    end repeat

    display dialog ("Broadcasted to " & (count of allTerms) & " terminal(s).")
end tell

It has a different effect when one wants to broadcast on character per character (e.g. synchronise
two or more Kakoune or NeoVim, etc)

This PR fixes that by using UCKeyTranslate to retrieve the current keyboard layout, translate the simulated keycodes, and correctly populate these missing fields before sending the key event.

I have tested this locally using the US International keyboard layout as well as US proper, and it successfully translates the keycodes. I'd appreciate if someone with German or French layout test it.

I have also added some smoke tests to verify the AppleScript key event mapping. These are isolated in a separate commit; if you find them too noisy, I am happy to get rid of them.

An AppleScript send key command that cannot type standard letters is not particularly useful. Ensuring key events carry their respective text and codepoints is necessary for basic automation to function.

Note

I am also happy to create a tracking issue if Ghosttty's workflow requires it.

Changes

ScriptKeyEventCommand.swift : Translated key codes to character text and unshifted codepoints using UCKeyTranslate .
KeyEventCommandTests.swift: Added basic unit tests

AI Disclosure

Important

This PR was prepared using Antigravity CLI. The AI helped to discover UCKeyTranslate Carbon API.

Previously, when executing the `send key` AppleScript command, the
generated key events only contained the key code and modifiers, but
lacked both the input text representation and the unshifted codepoint.
This caused the terminal to ignore or fail to process printable
characters sent via AppleScript.

Now, use `UCKeyTranslate` to look up the current keyboard layout and
derive both the simulated input text and the unshifted codepoint
associated with the key code. These are then passed to the resulting
key event, enabling proper typing and input handling for keys sent via
AppleScript.
@paaloeye paaloeye requested a review from a team as a code owner July 4, 2026 12:19
@bo2themax

bo2themax commented Jul 4, 2026

Copy link
Copy Markdown
Member

I don't quite get what your use case is. Can you make an example of where current implementation doesn't work?

And be careful, this pr description already violates our ai policy.

@paaloeye

paaloeye commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Can you make an example of where current implementation doesn't work?

@bo2themax Of course, I'll trim the description and add a detailed explanation where current implementation breaks.
Cheers for the reply and my bad about violating AI policy!

@paaloeye

paaloeye commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@bo2themax I've updated the description. Let me know if you have any questions. Cheers!

@paaloeye paaloeye force-pushed the feat/applescript-send-key-text-part-1 branch from 87f98f6 to de0bcac Compare July 4, 2026 18:36

/// extracted translation logic to map a Ghostty key to its generated text and unshifted codepoint,
/// primarily so it can be unit-tested without instantiating an `NSScriptCommand`.
struct ScriptKeyEventTranslator {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need UCKeyTranslate here, ppl who use it should know which key they are trying to type.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KeymapDarwin.zig already using it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me clarify one thing.

Are you saying that the below should be able to derive .text in KeymapDarwin.zig (via UCKeyTranslate)?

let keyEvent = Ghostty.Input.KeyEvent(
    key: key,
    action: action,
    mods: mods
)

And my use case/repro should work without the fix?

@bo2themax

Copy link
Copy Markdown
Member

Please see #13205, I don't like using UCKeyTranslate directly in swift. Your findings and ideas are legit tho, thanks.

@bo2themax bo2themax closed this Jul 5, 2026
@paaloeye

paaloeye commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Please see #13205, I don't like using UCKeyTranslate directly in swift. Your findings and ideas are legit tho, thanks.

Awesome! I'll test it in my setup.

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.

2 participants