From 475ccfcf64b85ca4f5742484e9b2a7e7ce42325e Mon Sep 17 00:00:00 2001 From: rk Date: Wed, 5 Nov 2025 00:51:52 +0800 Subject: [PATCH] expose IME composing range in QuillController --- lib/src/controller/quill_controller.dart | 15 +++++++++++++++ .../raw_editor_state_text_input_client_mixin.dart | 7 +++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/src/controller/quill_controller.dart b/lib/src/controller/quill_controller.dart index 0d2d291a4..709996830 100644 --- a/lib/src/controller/quill_controller.dart +++ b/lib/src/controller/quill_controller.dart @@ -1,5 +1,6 @@ import 'dart:math' as math; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart' show ClipboardData, Clipboard; import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart'; @@ -48,6 +49,20 @@ class QuillController extends ChangeNotifier { selection: const TextSelection.collapsed(offset: 0), ); + // Expose current IME composing range for filtering out intermediate edits. + final ValueNotifier _composingRangeNotifier = + ValueNotifier(TextRange.empty); + + /// Current IME (Chinese/Japanese etc input method) composing range. + /// This can be used to filter out intermediate edits that happen during IME composition. + ValueListenable get composing => _composingRangeNotifier; + + @internal + void setComposingRange(TextRange range) { + if (_composingRangeNotifier.value == range) return; + _composingRangeNotifier.value = range; + } + final QuillControllerConfig config; /// Document managed by this controller. diff --git a/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart b/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart index bbd3837e0..c1edf6ce9 100644 --- a/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart +++ b/lib/src/editor/raw_editor/raw_editor_state_text_input_client_mixin.dart @@ -19,8 +19,11 @@ mixin RawEditorStateTextInputClientMixin on EditorState set _lastKnownRemoteTextEditingValue(TextEditingValue? value) { __lastKnownRemoteTextEditingValue = value; - if (composingRange.value != value?.composing) { - composingRange.value = value?.composing ?? TextRange.empty; + final newRange = value?.composing ?? TextRange.empty; + if (composingRange.value != newRange) { + composingRange.value = newRange; + // Forward composing range to the controller + widget.controller.setComposingRange(newRange); } }