Skip to content

Add Option to Disable On-Screen Keyboard When Cursor Is Placed Manually #2587

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

Open
1 task done
ppamorim opened this issue May 30, 2025 · 0 comments
Open
1 task done
Labels
enhancement New feature or request

Comments

@ppamorim
Copy link

ppamorim commented May 30, 2025

Have you checked for an existing issue?

Use case

It would be highly beneficial to introduce an option that disables the on-screen keyboard when the user manually places the cursor in a text field. This feature is particularly useful in scenarios where speech-to-text (STT) input is the primary method of text entry, as it prevents unnecessary keyboard pop-ups that can obstruct the view and disrupt the flow of dictation.

In our application, we plan to implement an "edit mode" that explicitly allows users to toggle keyboard visibility. When edit mode is active, the keyboard will appear as expected upon cursor placement. Otherwise, users relying on STT can place the cursor without triggering the keyboard.

Use Case:

  • A user using speech-to-text wants to correct or insert text in a specific part of a document.
  • Placing the cursor triggers the keyboard, blocking part of the UI and interfering with the STT interface.
  • With this feature enabled, the keyboard remains hidden unless the user explicitly enters edit mode.

Proposal

Add a toggle to suppress the keyboard when the cursor is placed outside of edit mode.


Update 1: After some investigation, I found that changing the function openConnectionIfNeeded() we can indeed cancel the signal that force open the keyboard by not calling _textInputConnection!.show();

void openConnectionIfNeeded() {
    if (!shouldCreateInputConnection) {
      return;
    }
    //...
    if (!widget.config.disableKeyboard) {
      _textInputConnection!.show();
    }
  }

I could open a PR to introduce this change, but now I am not sure if we should create a custom FocusNode called QuillFocusNode extends FocusNode or set a flag on the QuillRawEditorConfig. The solution using the QuillFocusNode appears to be more direct as it's tightly coupled with the focus action. But it would need additional code to handle the instance QuillFocusNode to detect this configuration. Please let me know if you have any suggestions.


Update 2: We are able to enable/disable the keyboard and keep the focus active, we have done that by:

  • Create a special FocusNode:
import 'package:flutter/widgets.dart';

class QuillFocusNode extends FocusNode {

  QuillFocusNode({
    super.debugLabel,
    @Deprecated(
      'Use onKeyEvent instead. '
      'This feature was deprecated after v3.18.0-2.0.pre.',
    )
    super.onKey,
    super.onKeyEvent,
    super.skipTraversal,
    super.canRequestFocus,
    super.descendantsAreFocusable,
    super.descendantsAreTraversable,
    bool keyboardEnabled = true,
  }) : _keyboardEnabled = keyboardEnabled;

  bool _keyboardEnabled = true;

  bool get keyboardEnabled => _keyboardEnabled;

  set keyboardEnabled(bool value) {
    if (_keyboardEnabled != value) {
      _keyboardEnabled = value;
      // Required otherwise the keyboard doesn't close/open automatically.
      unfocus();
      // Required otherwise requestFocus() does nothing and the keyboard 
      // is not shown.
      WidgetsBinding.instance.addPostFrameCallback((_) {
        requestFocus();
      });
    }
  }
}
  • On the function openConnectionIfNeeded() from raw_editor_state_text_input_client_mixin.dart:
void openConnectionIfNeeded() {
  if (!shouldCreateInputConnection) {
    return;
  }
  //...
  // If the keyboard is disabled, only request focus for the editor's focus 
  // node and do not open or show the software keyboard.
  if (_keyboardEnabled) {
    _textInputConnection!.show();
  }
}

bool get _keyboardEnabled {
  if (widget.config.focusNode is QuillFocusNode) {
    final focusNode = widget.config.focusNode as QuillFocusNode;
    return focusNode.keyboardEnabled;
  }
  return true;
}
  • In the widget, you can:
final QuillFocusNode _editorFocusNode = QuillFocusNode();

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Flutter Quill Example'),
      actions: [
        IconButton(
          icon: Icon(Icons.edit),
          tooltip: 'Toggle edit mode',
          onPressed: () {
            _editorFocusNode.keyboardEnabled = !_editorFocusNode.keyboardEnabled;
          },
        ),
        Expanded(
          child: QuillEditor(
            focusNode: _editorFocusNode,
          )
        )
      ]
    )
  );
}

The proposed change can be found in my PR from our fork: T-Pro#1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant