Skip to content

core: Dispatch textInput to focused non-TextField objects - #24151

Open
falpi wants to merge 1 commit into
ruffle-rs:masterfrom
falpi:add-text-input-event-dispatch
Open

core: Dispatch textInput to focused non-TextField objects#24151
falpi wants to merge 1 commit into
ruffle-rs:masterfrom
falpi:add-text-input-event-dispatch

Conversation

@falpi

@falpi falpi commented Jul 7, 2026

Copy link
Copy Markdown

Summary

Typed characters were only delivered to native text fields. When any other
interactive object held focus — in particular a Sprite running a Text Layout
Framework EditManager, as used by Flex Spark TextInput / TextArea /
ComboBox — the character was dropped, so those controls displayed their
content but could not be typed into.

Flash Player dispatches a flash.events.TextEvent of type TEXT_INPUT to
whatever InteractiveObject has focus. This makes Ruffle do the same.

Root cause

In player.rs, character input, text-control and IME events were routed to the
focused object only when it was a native EditText:

if !key_press_handled
    && let Some(text) = context.focus_tracker.get_as_edit_text()
{
    if let InputEvent::TextInput { codepoint } = &event {
        text.text_input(codepoint.to_string(), context);
    }
    // … TextControl, Ime …
}

FocusTracker::get_as_edit_text() returns Some only for a native EditText.
When focus was on any other object the whole block was skipped and the character
was discarded — it was never dispatched anywhere. Raw KeyboardEvents were not
gated this way (they already reached the focused object), so navigation keys
arrived but the character content did not.

Reproduction

Minimal AS3: a focused Sprite that listens for TEXT_INPUT. Before this patch
typing produces nothing; after it, each keystroke is delivered.

import flash.display.Sprite;
import flash.events.TextEvent;

var box:Sprite = new Sprite();
box.graphics.beginFill(0xEEEEEE);
box.graphics.drawRect(0, 0, 200, 100);
addChild(box);

// Focus a non-TextField interactive object.
stage.focus = box;

box.addEventListener(TextEvent.TEXT_INPUT, function(e:TextEvent):void {
    trace("TEXT_INPUT: " + e.text);
});
// Type on the keyboard: without the patch nothing is traced; with it,
// each character is traced. This is the mechanism TLF/Spark editing relies on.

Fix

Turn the block into an if / else if: the native EditText path is unchanged
and still handled first; when the focused object is an ActionScript 3 interactive
object other than a text field, dispatch a bubbling, cancelable textInput
TextEvent to it (built with the same helper the native path uses). Dispatch is
gated to AS3 targets, consistent with the neighbouring KeyboardEvent code.

Because an EditText is always caught by the first branch, its native insertion,
its own textInput dispatch, restrict filtering and IME/text-control handling
are byte-for-byte the same as before. The new branch runs only for focused
objects that previously received nothing, so the change is strictly additive.

Notes

  • KeyboardEvents already reached focused objects, so arrow/navigation keys were
    unaffected; only the character channel was missing.
  • IME composition and text-control commands to non-text-field focus are left as a
    follow-up (they still take the native EditText path). Latin/ASCII typing — the
    reported gap — is fully covered.

Checklist

  • I, a human, have self-reviewed this PR and fully understand the changes within.
  • I have made or updated tests where possible.
  • All of my commits are properly scoped, compile successfully, and pass all tests.
  • This PR does not make sense to split up into smaller PRs.
  • An LLM was involved in the authoring of this code.

@kjarosh

kjarosh commented Jul 7, 2026

Copy link
Copy Markdown
Member

We can't accept code without tests, this applies to every PR you've sent (as mentioned in previous PRs). Also, we require a human to be in the loop, and your submissions look 100% automated.

@falpi

falpi commented Jul 7, 2026

Copy link
Copy Markdown
Author

We can't accept code without tests, this applies to every PR you've sent (as mentioned in previous PRs). Also, we require a human to be in the loop, and your submissions look 100% automated.

I am the "human in the loop" you mentioned, in the sense that the fixes stem from bugs or improvements I am personally discovering and testing as I go. Unfortunately, I lack the time to develop tests systematically, which is why I try to attach at least a code example for testing purposes to the PR. Sadly, that is the best I can do for now. If the conditions for accepting the PR aren't met, that’s fine. Would you still be interested in having the PR submitted—if only to give you the chance to pick up useful ideas? Otherwise, I’ll refrain from opening it and simply keep the branches available for an "enterprise build" I’ve already set up in my fork.

@kjarosh

kjarosh commented Jul 7, 2026

Copy link
Copy Markdown
Member

We are open to code contributions, but we cannot just accept code unconditionally.

Generating hundreds of lines docs using LLMs is not enough. Frankly, such docs are not even useful, because what can we do with them? They contain hundreds of claims that something works this way or that way, but who's gonna verify that? This requires immense effort from our side, and at this point I'm not sure if anyone is ever going to try to make it.

If you want to get your code merged to Ruffle, the first thing you need to do is write tests which verify your claims. Only then we can talk about the code. If your plan is to just throw thousands of lines of AI-generated code at us and expect it to get merged unconditionally, that is not gonna happen.

We can use AI tools as well, the reason we require a human in the loop is that generating code with LLMs is only a tiny part of the contribution. If you're not gonna do the rest, someone else will have to, or no one will.

If your contribution is finding bugs and analyzing root causes and you absolutely don't care about the rest, you should focus on filing issues and describing bugs you've found, not filing PRs with untested, SWF-specific, AI-generated code.

@falpi

falpi commented Jul 7, 2026

Copy link
Copy Markdown
Author

We are open to code contributions, but we cannot just accept code unconditionally.

Generating hundreds of lines docs using LLMs is not enough. Frankly, such docs are not even useful, because what can we do with them? They contain hundreds of claims that something works this way or that way, but who's gonna verify that? This requires immense effort from our side, and at this point I'm not sure if anyone is ever going to try to make it.

If you want to get your code merged to Ruffle, the first thing you need to do is write tests which verify your claims. Only then we can talk about the code. If your plan is to just throw thousands of lines of AI-generated code at us and expect it to get merged unconditionally, that is not gonna happen.

We can use AI tools as well, the reason we require a human in the loop is that generating code with LLMs is only a tiny part of the contribution. If you're not gonna do the rest, someone else will have to, or no one will.

If your contribution is finding bugs and analyzing root causes and you absolutely don't care about the rest, you should focus on filing issues and describing bugs you've found, not filing PRs with untested, SWF-specific, AI-generated code.

It seems to me that you enjoy being argumentative.

First of all, I have no expectation that you integrate anything. I don't necessarily need you to accept the PRs; I submit them primarily as a courtesy to the community. So, your tone is out of line—at the very least, you could simply say "no thanks."

Furthermore, you keep claiming that I’m adding thousands of untested lines of code, even though I just told you that I rigorously test everything I submit. You should be grateful to have someone testing your high-quality code against real-world enterprise workloads, rather than just Flash games.

Finally, it isn't true that they always involve thousands of lines of code; some PRs fix bugs or address basic gaps in the Ruffle codebase and consist of just a few lines—meaning a maintainer could integrate them in five minutes, if you're interested in doing so.

You’ve said everything except answer my one question: are you interested in having the PRs submitted—so that at least some of you have the chance to evaluate them—or not? Please answer yes or no.

Thanks.

@falpi
falpi force-pushed the add-text-input-event-dispatch branch from f8d11a0 to 0843dff Compare July 7, 2026 21:01
Typed characters were delivered only when a native TextField held focus
(via FocusTracker::get_as_edit_text). When any other interactive object
had focus — for example a Sprite hosting a Text Layout Framework
EditManager, as used by the Flex Spark TextInput/TextArea/ComboBox
controls — the character was dropped and the component could not be
typed into.

Flash Player dispatches a flash.events.TextEvent of type TEXT_INPUT to
whatever InteractiveObject holds focus, which is how such components
receive keyboard input. Mirror that: when the focused object is an
ActionScript 3 interactive object other than a native text field,
dispatch a bubbling, cancelable textInput TextEvent to it. The existing
native EditText path is unchanged, and raw KeyboardEvents already reached
focused objects, so only character input was missing.
@falpi
falpi force-pushed the add-text-input-event-dispatch branch from 0843dff to 523d42e Compare July 7, 2026 23:31
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