flutter-quill icon indicating copy to clipboard operation
flutter-quill copied to clipboard

[Android]serious problem, using a physical keyboard doesn't work to select which part of the text to write in

Open jonasbernardo opened this issue 8 months ago • 12 comments

Have you checked for an existing issue?

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]

jonasbernardo avatar Apr 05 '25 09:04 jonasbernardo

If you delete everything and there are few lines, this problem does not occur, but if there are many lines this problem appears.

jonasbernardo avatar Apr 05 '25 09:04 jonasbernardo

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

jonasbernardo avatar Apr 05 '25 09:04 jonasbernardo

This is already being fixed on #2510

CatHood0 avatar Apr 05 '25 11:04 CatHood0

@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

jonasbernardo avatar Apr 17 '25 09:04 jonasbernardo

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 avatar Apr 17 '25 23:04 CatHood0

@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.

Lamda303 avatar Apr 29 '25 07:04 Lamda303

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.

EchoEllet avatar Apr 29 '25 07:04 EchoEllet

@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.

jonasbernardo avatar May 02 '25 13:05 jonasbernardo

@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); }

jonasbernardo avatar May 02 '25 14:05 jonasbernardo

@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?

jonasbernardo avatar May 02 '25 14:05 jonasbernardo

@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.

CatHood0 avatar May 07 '25 03:05 CatHood0

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.

ioma8 avatar Aug 27 '25 08:08 ioma8