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

Customising shortcuts

Open claresudbery opened this issue 1 year ago • 6 comments

Is there an existing issue for this?

The question

Hi I want to disable some keyboard shortcuts in the Quill editor. I found this page which suggests I can add characterShortcutEvents, but I can find no characterShortcutEvents parameter to QuillEditorConfigurations. I'm looking at editor_configurations.dart and all I can see is customShortcuts. Has characterShortcutEvents been deprecated Should I be using customShortcuts instead? Is there any documentation for that?

configurations: QuillEditorConfigurations(
        characterShortcutEvents: [],
      ),

claresudbery avatar Oct 10 '24 16:10 claresudbery

CharacterShortcutEvent and SpaceShortcutEvent are just events that are called when a key is pressed on the keyboard. What you want would be more the events that are executed when we press more than two keys (example of this would be: CTRL + V).

In this case I don't know what to recommend. It's a part that I don't know much about. I'll try to investigate to see if I can suggest any changes.

This comment will be updated soon

CatHood0 avatar Oct 28 '24 18:10 CatHood0

In quill there are few types of shortcuts:

  • characterShortcutEvents: key / character bound to an action
  /// Contains all the events that will be handled when
  /// the exact characters satifies the condition. This mean
  /// if you press asterisk key, if you have a `CharacterShortcutEvent` with
  /// the asterisk then that event will be handled
  ///
  /// Supported by:
  ///
  ///    - Web
  ///    - Desktop
  /// ### Example
  ///```dart
  /// // you can get also the default implemented shortcuts
  /// // calling [standardSpaceShorcutEvents]
  ///final defaultShorcutsImplementation =
  ///               List.from([...standardCharactersShortcutEvents])
  ///
  ///final boldFormat = CharacterShortcutEvent(
  ///   key: 'Shortcut event that will format current wrapped text in asterisk'
  ///   character: '*',
  ///   handler: (controller) {...your implementation}
  ///);
  ///```
  @experimental
  final List<CharacterShortcutEvent> characterShortcutEvents;
  • spaceShortcutEvents: literally "spacebar" key
  /// Contains all the events that will be handled when
  /// space key is pressed
  ///
  /// Supported by:
  ///
  ///    - Web
  ///    - Desktop
  ///
  /// ### Example
  ///```dart
  /// // you can get also the default implemented shortcuts
  /// // calling [standardSpaceShorcutEvents]
  ///final defaultShorcutsImplementation =
  ///       List.from([...standardSpaceShorcutEvents])
  ///
  ///final spaceBulletList = SpaceShortcutEvent(
  ///   character: '-',
  ///   handler: (QuillText textNode, controller) {...your implementation}
  ///);
  ///```
  @experimental
  final List<SpaceShortcutEvent> spaceShortcutEvents;
  • customShortcuts: Key Combinations bound to actions. There is an extensive documentation on how to use them: https://docs.flutter.dev/ui/interactivity/actions-and-shortcuts#shortcuts But if you want to disable some shortcuts, e.g. Ctrl + V, you can use "DoNothingIntent":
customShortcuts: <LogicalKeySet, Intent> {
  LogicalKeySet(LogicalKeyboardKey.control,  LogicalKeyboardKey.keyV):
  DoNothingIntent(),
}

Maksim-Nikolaev avatar Nov 16 '24 04:11 Maksim-Nikolaev

In quill there are few types of shortcuts:

  • characterShortcutEvents: key / character bound to an action
  /// Contains all the events that will be handled when
  /// the exact characters satifies the condition. This mean
  /// if you press asterisk key, if you have a `CharacterShortcutEvent` with
  /// the asterisk then that event will be handled
  ///
  /// Supported by:
  ///
  ///    - Web
  ///    - Desktop
  /// ### Example
  ///```dart
  /// // you can get also the default implemented shortcuts
  /// // calling [standardSpaceShorcutEvents]
  ///final defaultShorcutsImplementation =
  ///               List.from([...standardCharactersShortcutEvents])
  ///
  ///final boldFormat = CharacterShortcutEvent(
  ///   key: 'Shortcut event that will format current wrapped text in asterisk'
  ///   character: '*',
  ///   handler: (controller) {...your implementation}
  ///);
  ///```
  @experimental
  final List<CharacterShortcutEvent> characterShortcutEvents;
  • spaceShortcutEvents: literally "spacebar" key
  /// Contains all the events that will be handled when
  /// space key is pressed
  ///
  /// Supported by:
  ///
  ///    - Web
  ///    - Desktop
  ///
  /// ### Example
  ///```dart
  /// // you can get also the default implemented shortcuts
  /// // calling [standardSpaceShorcutEvents]
  ///final defaultShorcutsImplementation =
  ///       List.from([...standardSpaceShorcutEvents])
  ///
  ///final spaceBulletList = SpaceShortcutEvent(
  ///   character: '-',
  ///   handler: (QuillText textNode, controller) {...your implementation}
  ///);
  ///```
  @experimental
  final List<SpaceShortcutEvent> spaceShortcutEvents;
  • customShortcuts: Key Combinations bound to actions. There is an extensive documentation on how to use them: https://docs.flutter.dev/ui/interactivity/actions-and-shortcuts#shortcuts But if you want to disable some shortcuts, e.g. Ctrl + V, you can use "DoNothingIntent":
customShortcuts: <LogicalKeySet, Intent> {
  LogicalKeySet(LogicalKeyboardKey.control,  LogicalKeyboardKey.keyV):
  DoNothingIntent(),
}

This looks good. It's not directly related but I noticed that on Windows shortcuts like "- " or "1. " create lists but not on mobile. I also tried the specific markdown setting but it didn't help on Android and works without that setting on Windows.

Sesa1988 avatar Nov 26 '24 00:11 Sesa1988

That is a limitation of Flutter. We will need to create a separate package to catch soft keyboard events (the function of Focus widget)

CatHood0 avatar Nov 26 '24 00:11 CatHood0

We will need to create a separate package to catch soft keyboard events

It's a bit difficult on Android since there is no efficient way. It's possible that by checking the height window and layout changes with ViewTreeObserver (Android API), this approach may not work consistently across all devices and use cases (e.g., when using floating keyboards). On iOS, it's similar but more straightforward to implement.

Though what exactly do we need in here?

EchoEllet avatar Nov 27 '24 19:11 EchoEllet

I found a simpler solution which is to implement the TextInputClient in a different way (I already made these changes separately and it works as it should on all platforms, it even allows us to use Shotcuts without being limited due to the platform, although I am struggling with the error that the TextEditingValue is not correctly synchronized).

CatHood0 avatar Mar 01 '25 10:03 CatHood0