AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.98k stars 2.25k forks source link

Android IME GetExtractedText only returns current line #17353

Open tkefauver opened 3 weeks ago

tkefauver commented 3 weeks ago

Describe the bug

GetExtractedText is supposed to be relative to the full contents of a textbox. Avalonia textboxes only return information about the current line.

To Reproduce

To reproduce you'll need a whole keyboard service here's a basic setup:

  1. Create an xplat solution and extend InputMethodService in the android project, declared like this:
    [Service(Name = "com.CompanyName.ExampleInputMethodService")]
    public class ExampleInputMethodService : InputMethodService
    ...
  2. Add this to AndroidManifest.xml:
    <service
    android:name="com.CompanyName.ExampleInputMethodService"
    android:exported="true"
    android:label="ExampleKeyBoard"
    android:permission="android.permission.BIND_INPUT_METHOD">
    <meta-data
      android:name="android.view.im"
      android:resource="@xml/method"/>
    <intent-filter>
    <action
        android:name="android.view.InputMethod"/>
    </intent-filter>
    </service>
  3. Create method.xml in Resources/xml like this:
    <?xml version="1.0" encoding="utf-8"?>
    <input-method xmlns:android="http://schemas.android.com/apk/res/android">
    <subtype android:imeSubtypeMode="keyboard"/>
    </input-method>
  4. Override OnStartInput and call GetExtractedText like this:
    public override void OnStartInput(EditorInfo attribute, bool restarting) {
     var request = new ExtractedTextRequest();
     ExtractedText response= this.CurrentInputConnection.GetExtractedText(request, GetTextFlags.WithStyles);
    }
  5. Override OnCreateInputView and create/inflate some view (this might not be necessary)
  6. Run ControlCatalog.Android, select TextBox then one of the multiline examples
  7. Observe that the response info is relative to the current line only

Expected behavior

The Text,SelectionStart,SelectionEnd properties in response should be relative to the full multiline text

Avalonia version

11.1.4

OS

Android

Additional context

This is just a way to demonstrate the issue. Other IInputConnection methods like GetTextBeforeCursor and GetTextAfterCursor do the same thing

Gillibald commented 3 weeks ago

Everything is related to the current composition region and that is the current surrounding text. The surrounding text is the current line because that is the biggest context that is needed to be able to do auto completion etc.

There is no point in querying the whole text. Keep in mind a text buffer has no limitations.

Where is the bug?

tkefauver commented 3 weeks ago

There is no point in querying the whole text.

You limit the length in the request, its supposed to be able to provide the whole text.

tkefauver commented 3 weeks ago

It only provides info for the VISUAL line from wherever it wraps which could be in the middle of hyphenated word and completion needs the full word.

Another example if the caret is at the beginning of some line it'll report SelectionStart == 0. When you move to the beginning of ANOTHER line, it'll still report 0! Which means there's no comparable way to know the caret changed without also looking at the new line querying the connection every cursor change (becomes inefficient).

Its just not how other native textboxes respond to the API's. So I guess this is more of a feature request than bug...

Gillibald commented 3 weeks ago

https://developer.android.com/reference/android/view/inputmethod/ExtractedText

This clearly states ExtractedText is just some portion of the whole text that is currently being editited.

I agree that wrapped text lines should not be split we can fix that.