summaryrefslogtreecommitdiff
path: root/java/org/gnu/emacs/EmacsInputConnection.java
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-05-06 11:32:56 +0800
committerPo Lu <luangruo@yahoo.com>2023-05-06 11:32:56 +0800
commit3198b7dc565e0e41d40b6c23509c285e96044a83 (patch)
treec9193f1b8825c30fac483ed66e02eb9181397668 /java/org/gnu/emacs/EmacsInputConnection.java
parent96f9fe6514a2139373c50e19a77fd217ef62e6ef (diff)
Update Android port
* cross/verbose.mk.android: Get rid of badly aligned ANDROID_CC messages. * java/org/gnu/emacs/EmacsInputConnection.java (syncAfterCommit) (extractAbsoluteOffsets): Add workarounds for several kinds of machines. (commitText, getExtractedText): Likewise. * src/textconv.c (really_commit_text): Improve definition of POSITION. (get_extracted_text): Default to providing at least 4 characters.
Diffstat (limited to 'java/org/gnu/emacs/EmacsInputConnection.java')
-rw-r--r--java/org/gnu/emacs/EmacsInputConnection.java85
1 files changed, 81 insertions, 4 deletions
diff --git a/java/org/gnu/emacs/EmacsInputConnection.java b/java/org/gnu/emacs/EmacsInputConnection.java
index 7b40fcff99e..d13b48288ce 100644
--- a/java/org/gnu/emacs/EmacsInputConnection.java
+++ b/java/org/gnu/emacs/EmacsInputConnection.java
@@ -26,6 +26,8 @@ import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.TextSnapshot;
import android.view.KeyEvent;
+import android.os.Build;
+
import android.util.Log;
/* Android input methods, take number six. See textconv.c for more
@@ -37,6 +39,34 @@ public final class EmacsInputConnection extends BaseInputConnection
private EmacsView view;
private short windowHandle;
+ /* Whether or not to synchronize and call `updateIC' with the
+ selection position after committing text.
+
+ This helps with on screen keyboard programs found in some vendor
+ versions of Android, which rely on immediate updates to the point
+ position after text is commited in order to place the cursor
+ within that text. */
+
+ private static boolean syncAfterCommit;
+
+ /* Whether or not to return empty text with the offset set to zero
+ if a request arrives that has no flags set and has requested no
+ characters at all.
+
+ This is necessary with on screen keyboard programs found in some
+ vendor versions of Android which don't rely on the documented
+ meaning of `ExtractedText.startOffset', and instead take the
+ selection offset inside at face value. */
+
+ private static boolean extractAbsoluteOffsets;
+
+ static
+ {
+ if (Build.MANUFACTURER.equalsIgnoreCase ("Huawei")
+ || Build.MANUFACTURER.equalsIgnoreCase ("Honor"))
+ extractAbsoluteOffsets = syncAfterCommit = true;
+ };
+
public
EmacsInputConnection (EmacsView view)
{
@@ -85,11 +115,32 @@ public final class EmacsInputConnection extends BaseInputConnection
public boolean
commitText (CharSequence text, int newCursorPosition)
{
+ int[] selection;
+
if (EmacsService.DEBUG_IC)
Log.d (TAG, "commitText: " + text + " " + newCursorPosition);
EmacsNative.commitText (windowHandle, text.toString (),
newCursorPosition);
+
+ if (syncAfterCommit)
+ {
+ /* Synchronize with the Emacs thread, obtain the new
+ selection, and report it immediately. */
+
+ selection = EmacsNative.getSelection (windowHandle);
+
+ if (EmacsService.DEBUG_IC && selection != null)
+ Log.d (TAG, "commitText: new selection is " + selection[0]
+ + ", by " + selection[1]);
+
+ if (selection != null)
+ /* N.B. that the composing region is removed after text is
+ committed. */
+ view.imManager.updateSelection (view, selection[0],
+ selection[1], -1, -1);
+ }
+
return true;
}
@@ -203,16 +254,42 @@ public final class EmacsInputConnection extends BaseInputConnection
getExtractedText (ExtractedTextRequest request, int flags)
{
ExtractedText text;
+ int[] selection;
if (EmacsService.DEBUG_IC)
- Log.d (TAG, "getExtractedText: " + request + " " + flags);
+ Log.d (TAG, "getExtractedText: " + request.hintMaxChars + ", "
+ + request.hintMaxLines + " " + flags);
+
+ /* If a request arrives with hintMaxChars, hintMaxLines and flags
+ set to 0, and the system is known to be buggy, return an empty
+ extracted text object with the absolute selection positions. */
+
+ if (extractAbsoluteOffsets
+ && request.hintMaxChars == 0
+ && request.hintMaxLines == 0
+ && flags == 0)
+ {
+ /* Obtain the selection. */
+ selection = EmacsNative.getSelection (windowHandle);
+ if (selection == null)
+ return null;
- text = EmacsNative.getExtractedText (windowHandle, request,
- flags);
+ /* Create the workaround extracted text. */
+ text = new ExtractedText ();
+ text.partialStartOffset = -1;
+ text.partialEndOffset = -1;
+ text.text = "";
+ text.selectionStart = selection[0];
+ text.selectionEnd = selection[1];
+ }
+ else
+ text = EmacsNative.getExtractedText (windowHandle, request,
+ flags);
if (EmacsService.DEBUG_IC)
Log.d (TAG, "getExtractedText: " + text.text + " @"
- + text.startOffset + ":" + text.selectionStart);
+ + text.startOffset + ":" + text.selectionStart
+ + ", " + text.selectionEnd);
return text;
}