Skip to content

Prevent external updates during composition/focus#6237

Closed
FeodorFitsner wants to merge 1 commit intomainfrom
codeeditor-ime
Closed

Prevent external updates during composition/focus#6237
FeodorFitsner wants to merge 1 commit intomainfrom
codeeditor-ime

Conversation

@FeodorFitsner
Copy link
Contributor

@FeodorFitsner FeodorFitsner commented Mar 1, 2026

Track the last control-provided value and selection and avoid applying external value/selection updates while the editor has focus and the user is composing text. Added _lastControlValue and _lastControlSelection, an _isComposing getter, and _shouldApplyExternalState to gate updates. Value/selection handlers now only apply control changes when they actually changed in the control and applying them won't interfere with an in-progress composition or focused editing session.

Fix #6211

Summary by Sourcery

Prevent external value and selection updates from interfering with in-progress text composition or focused editing in the code editor control.

Bug Fixes:

  • Avoid overwriting the editor content with external value updates while the editor has focus and the user is composing text.
  • Avoid applying external selection changes from the control when they would conflict with the current focused editing or composition state.

Enhancements:

  • Track the last control-provided value and selection so external updates are only applied when they actually change.

Track the last control-provided value and selection and avoid applying external value/selection updates while the editor has focus and the user is composing text. Added _lastControlValue and _lastControlSelection, an _isComposing getter, and _shouldApplyExternalState to gate updates. Value/selection handlers now only apply control changes when they actually changed in the control and applying them won't interfere with an in-progress composition or focused editing session.

Fix #6211
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

@cloudflare-workers-and-pages
Copy link

Deploying flet-examples with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6b67560
Status: ✅  Deploy successful!
Preview URL: https://c8de6914.flet-examples.pages.dev
Branch Preview URL: https://codeeditor-ime.flet-examples.pages.dev

View logs

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the Flutter-side CodeEditorControl state synchronization so IME composition and focused editing sessions aren’t disrupted by externally-provided value/selection updates (addressing #6211).

Changes:

  • Track last control-provided value and selection via _lastControlValue / _lastControlSelection.
  • Add composition detection (_isComposing) and a gating helper (_shouldApplyExternalState) to suppress unsafe external state application while focused/composing.
  • Apply control value/selection updates only when they differ and pass the new gating rules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +185 to 192
final valueChangedInControl = value != _lastControlValue;
_lastControlValue = value;
if (value != null &&
value != controllerValue &&
_shouldApplyExternalState(incomingChanged: valueChangedInControl)) {
_setValue(value);
_value = value;
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_lastControlValue is updated before the external value is applied. If a control-side value change arrives while the editor is focused and composing, _shouldApplyExternalState blocks applying it, but _lastControlValue still advances—so on subsequent builds valueChangedInControl becomes false and the external update can be dropped permanently (e.g., a programmatic value update during IME composition will never apply even after composition ends/blur). Consider tracking the last applied control value (or keeping a pending external value) and only advancing _lastControlValue after the update is actually applied / when not composing, so suppressed updates can be applied later when it’s safe.

Copilot uses AI. Check for mistakes.
Comment on lines +200 to 204
_lastControlSelection = explicitSelection;
if (explicitSelection != null &&
explicitSelection != _controller.selection &&
_shouldApplyExternalState(incomingChanged: selectionChangedInControl)) {
_controller.selection = explicitSelection;
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same pattern for selection: _lastControlSelection is updated even when an incoming selection change is suppressed due to focus/composition. That can prevent a queued control-side selection update from ever being applied later (after composition ends or focus is lost). Consider only updating the "last seen/applied" selection marker when the selection is actually applied, or store a pending selection to apply once _isComposing becomes false.

Suggested change
_lastControlSelection = explicitSelection;
if (explicitSelection != null &&
explicitSelection != _controller.selection &&
_shouldApplyExternalState(incomingChanged: selectionChangedInControl)) {
_controller.selection = explicitSelection;
if (explicitSelection == null) {
// Control explicitly cleared selection; record this immediately.
_lastControlSelection = null;
} else if (explicitSelection != _controller.selection &&
_shouldApplyExternalState(incomingChanged: selectionChangedInControl)) {
_controller.selection = explicitSelection;
_lastControlSelection = explicitSelection;

Copilot uses AI. Check for mistakes.
@cloudflare-workers-and-pages
Copy link

Deploying flet-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6b67560
Status: ✅  Deploy successful!
Preview URL: https://b9cc26ee.flet-docs.pages.dev
Branch Preview URL: https://codeeditor-ime.flet-docs.pages.dev

View logs

@FeodorFitsner FeodorFitsner deleted the codeeditor-ime branch March 2, 2026 00:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: CodeEditor IME input on Windows resets caret and inserts both Pinyin and Chinese

2 participants