-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Move text editing Actions to EditableTextState
#90684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move text editing Actions to EditableTextState
#90684
Conversation
- Adds a `Focus` widget to the `EditableText` tree. Fixes flutter#90562 - Improves vertical caret movement: flutter#75572 - Introduces `TextEditingValue.replaced` - `TextSelection.base` and `TextSelection.extent` no longer inherits the text affinity from the `TextSelection` when the selection is not collapsed. - Removes `TextEditingActionTarget`. Reimplemented text editing `Intent`s and `Action`s in `EditableTextState`. - `DirectionalFocusAction` no longer does the `is EditableText` type check or assumes the focus node is attached to `EditableText`'s `BuildContext`.
703b6af to
1d588a5
Compare
…tter into text-editing-actions
1d588a5 to
eb807af
Compare
77ba82a to
eb98d65
Compare
|
Argh, just ran into the removal of |
|
@passsy sorry for the breakage, the removal wasn't considered a breaking change because no test failed on that (see https://github.com/flutter/flutter/wiki/Tree-hygiene#1-determine-if-your-change-is-a-breaking-change). Registering your tests (https://github.com/flutter/tests) will hopefully prevent such breakages in the future. Also I'm a bit curious why |
|
I'd like to give some context: The wiredash sdk wraps the full app, including the users The version of wiredash using We have a // Both DefaultTextEditingShortcuts and WidgetsApp.defaultActions are
// required to make text edits like deletion of characters possible on macOS
child: DefaultTextEditingShortcuts(
child: DefaultTextEditingActions(
child: WiredashTheme(
data: _theme,
child: MediaQueryFromWindow(
// Directionality required for all Text widgets
child: Directionality(
textDirection:
widget.options?.textDirection ?? TextDirection.ltr,
// Localizations required for all Flutter UI widgets
child: Localizations(
locale: widget.options?.currentLocale ?? window.locale,
delegates: const [
DefaultMaterialLocalizations.delegate,
DefaultCupertinoLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
This breaking change leaves us in a unfortunate state. To support users before and after this breaking changes we have to release and support two different versions of the sdk. SDK before this change:
SDK after this change:
It's also not possible to ship our own |
|
Thanks for the context. The easiest workaround I can think of is to remap the backspace key on macOS to your own private intent and handle it yourself. But the framework actually shouldn't be handling shortcuts on macOS as on macOS users can define their own custom system-wide shortcuts, so the current default macOS shortcuts in the framework are probably going to be removed soon and when that happens it will likely break the workaround. In general the desktop support is still in beta so these things are still subject to change.
That's probably because |
Not sure why this is not marked as breaking change, but aside of that this made it impossible for other editable implementations to re-use the default editable actions implemented in the SDK itself. Now they will have to implement those from scratch or copy-paste what's now private in EditableTextState. Both options are rather undesirable. |
|
Here is our definition of a breaking change, I believe this didn't break any external tests at the time? I agree with you 100% about exposing this logic to the public. I should have brought it up in this review. It will be vital for users that are implementing their own text editors to be able to reuse our shortcuts logic. How would you prefer this to be exposed, similar to how it was before this PR? @Renzo-Olivares and I are going to be working on getting these shortcuts to work with this text editor demo by exposing them in some way. |
|
The previous solution with |
|
@matthew-carroll and SuperEditor folks may be able to provide more inputs here as well. |
|
@pulyaevskiy what's the question? |
|
Flutter provides default set of shortcuts for handling common texting editing operations (e.g. move cursor up/down/left/right, jump word left/right, similar for selection, copy-paste, and so on). Before this change, most of those shortcuts were encapsulated in a class called This PR, removed I believe there is little to no reason for different "editable" implementations to come up with their own handling for these shortcuts and there should be some sort of API interface to leverage the built-in logic (possibly with an option to override some of it). |
|
@pulyaevskiy That point sounds reasonable in theory. If lots of people are applying the same rules, for the same reasons, and those rules and reasons change for everyone at the same time, then it would be counterproductive for Flutter to have a secret implementation and then force everyone else to figure it out. I have found the monolithic nature of Flutter's text input widgets a problem in general. This sounds like it's probably an extension of that issue. It sounds like the existing monolith is incentivizing the expansion of the monolith, rather than breaking things down into useful pieces. My guess is that if IME content editing, text layout, and gesture controls were each well encapsulated, this situation probably wouldn't have come up to begin with. That composition probably would have forced these actions to be made publicly available. But, I've harped on this point for over a year now. There's not much more I can say on that front. Unless and until Flutter is willing to do the legwork to break down the text monolith, I think we're likely to see growth of the monolith, not composable tools. Most of Super Editor's implementation is a re-invention of the tools that are baked into that monolith - we couldn't use them without using all of |
|
Well, it sounds like @justinmc and the team are planning some work on making at least this part of text editing behavior a bit more modular? I do agree though that EditableText/RenderEditable do not make it easy to reuse the functionality, but I also can understand that it is hard to come up with a generic interface if you only have (focus) one use case to begin with (that being a basic text field). Also to be clear, the team did introduce My only concern with the original implementation of |
|
There are definitely some new pieces being introduced, and that's good. I'm not sure how far those pieces can go with all the stuff combined under the surface. I guess we'll see. I would agree that objects should be preferred over mixins whenever possible. Mixins should be reserved for situations where you have to assume some other superclass, such as a mixin on a |
|
It's high priority for me to get this logic exposed again because a fully featured rich text editor is pretty impractical without it, as you two have attested. I'm definitely on board with doing it in a composable way if we can come up with a better design than TextEditingActionTarget. I've created an issue specifically for this that we can keep up to date with progress: #97830. |
|
Just to clarify, I doubt Super Editor will use this. We already have handlers for every key that might be pressed on the keyboard. Others may want it, including Zefyr. |
Focuswidget to theEditableTexttree. Fixes EditableText should use a Focus widget instead of managing its own FocusNode #90562TextEditingValue.replacedTextSelection.baseandTextSelection.extentno longer inherits the text affinity from theTextSelectionwhen the selection is not collapsed.TextEditingActionTarget. Reimplemented text editingIntents andActions inEditableTextState.DirectionalFocusActionno longer does theis EditableTexttype check or assumes the focus node is attached toEditableText'sBuildContext.Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.