rust-windowing / rust-windowing/winit

macOS: typed characters are reported as spaces when using remote Android keyboard input

Open
#4,613 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

B - bug DS - appkit
Dominant language
Rust
Stars
6.2k
Forks
1.3k
Avg merge
2d 19h
Merged PRs (30d)
9

Description

Description

When typing into a winit app on macOS through Chrome Remote Desktop from an Android device, typed characters are delivered to the app as spaces.

This happens with the standard Android keyboard mode in Chrome Remote Desktop. Each typed character appears to arrive from AppKit as an NSEvent whose keyCode is 49 (Space), while NSEvent.characters() contains the actual typed
character.

winit currently derives the KeyboardInput text from the keycode-derived logical key, so downstream receives:

physical_key = Code(Space)
logical_key  = Named(Space)
text         = Some(" ")

But AppKit still has the correct produced text in NSEvent.characters(). For example, typing t produces an event where:

keyCode      = 49
characters   = "t"

The expected winit event should preserve the physical key as Space if that is what AppKit reports, but the produced text should use the actual text from NSEvent.characters():

physical_key = Code(Space)
logical_key  = Character("t")
text         = Some("t")

This makes text input unusable for apps accessed remotely from Android through Chrome Remote Desktop. The app receives a sequence of spaces instead of the text the user typed.

This is not an IME preedit/commit issue in the affected path. KeyboardInput events are emitted, but their logical_key and text lose the produced character.

Observed behavior

Typing test through Chrome Remote Desktop's standard Android keyboard produces events like:

KeyboardInput {
    state: Pressed,
    physical_key: Code(Space),
    logical_key: Named(Space),
    text: Some(" "),
}

Repeated for each typed character.

Expected behavior

If NSEvent.characters() contains non-control, non-space text, winit should preserve that as the produced text even when the keycode maps to Space.

For example:

KeyboardInput {
    state: Pressed,
    physical_key: Code(Space),
    logical_key: Character("t"),
    text: Some("t"),
}
Local downstream patch

I worked around this downstream by adjusting macOS create_key_event to detect the case where the keycode maps to Named(Space) but NSEvent.characters() contains non-space printable text. In that case, winit keeps the physical key as Space but reports the produced text as Key::Character(...).

The intent is:

  • keep physical_key keycode-derived
  • keep real Space as Space
  • ignore control text
  • do not apply this for Cmd/Ctrl shortcuts
  • use NSEvent.characters() for the produced typed character when AppKit provides it

My workaround is here https://github.com/worka-ai/winit/commit/17b3fac080828cf448cc0b13610e644bbec9e11f

Do you want me to do a PR or just close this? I don't know how much of an edge case this is, it happened in a Fission UI when I was connecting to my desktop from an Android device...not exactly the most common thing to do.

macOS version
Product name: macOS
Product version: 26.1
Winit version

0.30.13

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the macOS create_key_event path and compare the keycode-derived logical key with NSEvent.characters(), using the Chrome Remote Desktop behavior described here. Preserve the keycode-derived physical Space while using non-control, non-space characters for the produced text, without changing real Space or Cmd/Ctrl shortcuts. Verify the resulting KeyboardInput shape against the expected example and the reported remote typing case.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.