[Android]serious problem, using a physical keyboard doesn't work to select which part of the text to write in
Have you checked for an existing issue?
- [x] I have searched the existing issues
Flutter Quill Version
11.2.0
Steps to Reproduce
tap anywhere on the text in the quill example
try to type with the physical keyboard
tap with mouse or finger on another part of the text
try to type with physical keyboard
https://github.com/user-attachments/assets/717022a7-a934-4d49-a24e-89b0016e8278
Expected results
that the keyboard writes in the part I touched where the cursor appeared
Actual results
write to the old cursor
Additional Context
https://github.com/user-attachments/assets/4bd75e46-177c-47ef-aa39-0354717932e5
Screenshots / Video demonstration
[Attach media here]
Logs
[Paste logs here]
If you delete everything and there are few lines, this problem does not occur, but if there are many lines this problem appears.
tested with flutter 3.29.2, 3.27.3 tested with flutter_quill: 11.2.0, v11.0.0-dev.21, v11.0.0-dev.20, v10.8.5 all have the same problem
@CatHood0 @EchoEllet
This is already being fixed on #2510
@CatHood0 @EchoEllet I tested using the modifications made and the problem persists, could you give me any tips so I can fix it?
the physical keyboard does not type in the correct position using the mouse or finger to change the position, only the virtual keyboard types in the right place https://github.com/CatHood0/flutter-quill/tree/better_soft_keyboard_support
https://github.com/user-attachments/assets/afc8beec-5b3f-474f-b140-365e9bfb9c8f
could you give me any tips so I can fix it?
I can't give you any type, as I have no idea what could be causing this. In fact, since it was updated to use Flutter versions after 3.24, which have had many problems since then.
@CatHood0 @jonasbernardo The root cause is that _keyboardVisible in raw_editor_state.dart remains false when using a physical keyboard. While QuillRawEditorState attempts to detect hardware keyboard visibility through _hardwareKeyboardEvent(), typing alphanumeric characters (a-z, 0-9) does not trigger this callback. However, when pressing modifier keys (such as Shift, Backspace, or Tab), the detection works as expected and _keyboardVisible is properly set to true.
The root cause is that _keyboardVisible in raw_editor_state.dart remains false when using a physical keyboard. While QuillRawEditorState attempts to detect hardware keyboard visibility through
That's actually a good explanation. One way to work around it is to detect whether a physical keyboard is being used via platform specific code.
@Lamda303 @EchoEllet @CatHood0 After some testing, if you press the backspace key, it starts working again and you can type normally in other cursor positions.
@Lamda303 @EchoEllet I managed to solve the problem, the code already has a way to detect the physical keyboard, but it was only being applied to the iOS simulator, here is how to solve it, just use this initstate, in the class: QuillRawEditorState
void initState() {
super.initState();
_shortcutActionsManager = EditorKeyboardShortcutsActionsManager(
rawEditorState: this,
context: context,
);
if (_clipboardStatus != null) {
_clipboardStatus!.addListener(_onChangedClipboardStatus);
}
_scrollController = widget.config.scrollController;
_scrollController.addListener(_updateSelectionOverlayForScroll);
_cursorCont = CursorCont(
show: ValueNotifier<bool>(widget.config.showCursor),
style: widget.config.cursorStyle,
tickerProvider: this,
);
// Floating cursor
_floatingCursorResetController = AnimationController(vsync: this);
_floatingCursorResetController.addListener(onFloatingCursorResetTick);
if (kIsWeb == false) {
HardwareKeyboard.instance.addHandler(_hardwareKeyboardEvent);
}
if (isKeyboardOS) {
_keyboardVisible = true;
} else if (!kIsWeb && isFlutterTest) {
// treat tests like a keyboard OS
_keyboardVisible = true;
} else {
// treat iOS Simulator like a keyboard OS
isIOSSimulator().then((isIosSimulator) {
if (isIosSimulator) {
_keyboardVisible = true;
} else {
_keyboardVisibilityController = KeyboardVisibilityController();
_keyboardVisible = _keyboardVisibilityController!.isVisible;
_keyboardVisibilitySubscription =
_keyboardVisibilityController?.onChange.listen((visible) {
_keyboardVisible = visible;
if (visible) {
_onChangeTextEditingValue(!_hasFocus);
}
});
}
});
}
controller.addListener(_didChangeTextEditingValueListener);
if (!widget.config.readOnly) {
// listen to composing range changes
composingRange.addListener(_onComposingRangeChanged);
// Focus
widget.config.focusNode.addListener(_handleFocusChanged);
}
}
I removed: HardwareKeyboard.instance.addHandler(_hardwareKeyboardEvent); and put it outside, so it wouldn't run only on the iOS simulator: if (kIsWeb == false) { HardwareKeyboard.instance.addHandler(_hardwareKeyboardEvent); }
@CatHood0 thanks to: @Lamda303 and @EchoEllet Thanks to yours tips I was able to solve the problem Can anyone tell me if this has any negative impact?
@CatHood0 thanks to: @Lamda303 and @EchoEllet Thanks to yours tips I was able to solve the problem
I think it's great that you've managed to resolve this. I haven't been able to be active at the moment due to complications. It will take me about a month to adjust to the new pace of things happening around me.
I apologize for not having given any sign of life and not helping you with this.
Can anyone tell me if this has any negative impact?
The only way to know would be to test it on all possible devices (Android, iOS, and desktop) and see if it works as usual with the editor.
We'd also add some testing to ensure these changes actually work as they should when they're supposed to.
This is still not working. When using physical keyboard on iOS or android, the cursor jumps to previous position when typing, even when i put it to other position by tapping there. Its really annoying. Here is stacktrace of breakpoint where the cursor position jumps to the bad (previous) place:
QuillController._updateSelection (quill_controller.dart:486)
QuillController.replaceText (quill_controller.dart:323)
RawEditorStateTextInputClientMixin.updateEditingValue (raw_editor_state_text_input_client_mixin.dart:237)
TextInput._updateEditingValue (text_input.dart:2238)
TextInput._handleTextInputInvocation (text_input.dart:2070)
TextInput._loudlyHandleTextInputInvocation (text_input.dart:1951)
MethodChannel._handleAsMethodCall (platform_channel.dart:611)
MethodChannel.setMethodCallHandler.<anonymous closure> (platform_channel.dart:601)
_DefaultBinaryMessenger.setMessageHandler.<anonymous closure> (binding.dart:653)
_invoke2 (hooks.dart:363)
_ChannelCallbackRecord.invoke (channel_buffers.dart:45)
_Channel.push (channel_buffers.dart:136)
ChannelBuffers.push (channel_buffers.dart:344)
PlatformDispatcher._dispatchPlatformMessage (platform_dispatcher.dart:802)
_dispatchPlatformMessage (hooks.dart:277)
This needs fixing asap.