Browse Source

[Android] Fix multiline TextBox caret staying on previous line after autocorrect + Enter (#21900)

On Android, composing/autocorrect text is written as live text while only a
composition region is tracked. IME edit operations (commitText,
finishComposingText) are queued and flushed on EndBatchEdit, but SendKeyEvent
dispatched the key immediately, bypassing the queue.
When a soft keyboard batched "commit autocorrect + press Enter", the newline was
inserted before the queued commit flushed. The commit then applied with stale
pre-newline composition indices and reset the caret to the end of the committed
word, leaving it on the previous line instead of the new one.
Route SendKeyEvent through the command queue via a new KeyEventCommand so key
events apply in FIFO order with the queued edit commands, honoring Android's
InputConnection batch-edit ordering contract. The autocorrect now commits first,
then the newline is inserted, leaving the caret on the new line. Outside a batch
edit the key is still dispatched immediately, preserving existing behavior;
hardware key input uses a separate path and is unaffected.
Fixes #21895

Co-authored-by: Emmanuel Hansen <emmausssss@gmail.com>
pull/21967/head
Zeljko Predjeskovic 2 months ago
committed by GitHub
parent
commit
50eb2d75c3
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      src/Android/Avalonia.Android/Platform/Input/AvaloniaInputConnection.cs
  2. 16
      src/Android/Avalonia.Android/Platform/Input/EditCommand.cs
  3. 6
      src/Android/Avalonia.Android/Platform/Input/TextEditBuffer.cs

2
src/Android/Avalonia.Android/Platform/Input/AvaloniaInputConnection.cs

@ -311,7 +311,7 @@ namespace Avalonia.Android.Platform.Input
public bool SendKeyEvent(KeyEvent? e)
{
_inputMethod.View.DispatchKeyEvent(e);
QueueCommand(new KeyEventCommand(e));
return true;
}

16
src/Android/Avalonia.Android/Platform/Input/EditCommand.cs

@ -1,4 +1,5 @@
using System;
using Android.Views;
using Avalonia.Input.TextInput;
namespace Avalonia.Android.Platform.Input
@ -177,4 +178,19 @@ namespace Avalonia.Android.Platform.Input
buffer.Composition = default;
}
}
internal class KeyEventCommand : EditCommand
{
private readonly KeyEvent? _keyEvent;
public KeyEventCommand(KeyEvent? keyEvent)
{
_keyEvent = keyEvent;
}
public override void Apply(TextEditBuffer buffer)
{
buffer.DispatchKeyEvent(_keyEvent);
}
}
}

6
src/Android/Avalonia.Android/Platform/Input/TextEditBuffer.cs

@ -131,5 +131,11 @@ namespace Avalonia.Android.Platform.Input
Composition = null;
}
}
internal void DispatchKeyEvent(KeyEvent? keyEvent)
{
_textInputMethod?.View.DispatchKeyEvent(keyEvent);
}
}
}

Loading…
Cancel
Save