From: Po Lu Date: Sat, 6 May 2023 03:32:56 +0000 (+0800) Subject: Update Android port X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=3198b7dc565e0e41d40b6c23509c285e96044a83;p=emacs.git 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. --- diff --git a/cross/verbose.mk.android b/cross/verbose.mk.android index 7d07b978de2..998f9843c7d 100644 --- a/cross/verbose.mk.android +++ b/cross/verbose.mk.android @@ -27,16 +27,7 @@ AM_V_CC = AM_V_CXX = AM_V_CCLD = AM_V_CXXLD = -AM_V_ELC = -AM_V_ELN = AM_V_GEN = -AM_V_GLOBALS = -AM_V_NO_PD = -AM_V_RC = -AM_V_JAVAC = -AM_V_DX = -AM_V_AAPT = -AM_V_ZIPALIGN = else # Whether $(info ...) works. This is to work around a bug in GNU Make @@ -53,13 +44,12 @@ have_working_info = $(filter notintermediate,$(value .FEATURES)) # The workaround is done only for AM_V_ELC and AM_V_ELN, # since the bug is not annoying elsewhere. -AM_V_AR = @$(info $ AR $@) +AM_V_AR = @$(info $ AR $@) AM_V_at = @ -AM_V_CC = @$(info $ ANDROID_CC $@) -AM_V_CXX = @$(info $ ANDROID_CXX $@) -AM_V_CCLD = @$(info $ CCLD $@) -AM_V_CXXLD = @$(info $ CXXLD $@) - -AM_V_GEN = @$(info $ GEN $@) +AM_V_CC = @$(info $ CC $@) +AM_V_CXX = @$(info $ CXX $@) +AM_V_CCLD = @$(info $ CCLD $@) +AM_V_CXXLD = @$(info $ CXXLD $@) +AM_V_GEN = @$(info $ GEN $@) AM_V_NO_PD = --no-print-directory endif 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); - - text = EmacsNative.getExtractedText (windowHandle, 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; + + /* 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; } diff --git a/src/textconv.c b/src/textconv.c index 4fa92f43ecd..e1a73e91397 100644 --- a/src/textconv.c +++ b/src/textconv.c @@ -540,7 +540,11 @@ restore_selected_window (Lisp_Object window) /* Commit the given text in the composing region. If there is no composing region, then insert the text after F's selected window's - last point instead. Finally, remove the composing region. */ + last point instead. Finally, remove the composing region. + + Then, move point to POSITION relative to TEXT. If POSITION is + greater than zero, it is relative to the character at the end of + TEXT; otherwise, it is relative to the start of TEXT. */ static void really_commit_text (struct frame *f, EMACS_INT position, @@ -577,14 +581,16 @@ really_commit_text (struct frame *f, EMACS_INT position, Finsert (1, &text); record_buffer_change (start, PT, text); - /* Move to a the position specified in POSITION. */ + /* Move to a the position specified in POSITION. If POSITION is + less than zero, it is relative to the start of the text that + was inserted. */ - if (position < 0) + if (position <= 0) { wanted = marker_position (f->conversion.compose_region_start); - if (INT_SUBTRACT_WRAPV (wanted, position, &wanted) + if (INT_ADD_WRAPV (wanted, position, &wanted) || wanted < BEGV) wanted = BEGV; @@ -595,6 +601,9 @@ really_commit_text (struct frame *f, EMACS_INT position, } else { + /* Otherwise, it is relative to the last character in + TEXT. */ + wanted = marker_position (f->conversion.compose_region_end); @@ -631,9 +640,9 @@ really_commit_text (struct frame *f, EMACS_INT position, Finsert (1, &text); record_buffer_change (wanted, PT, text); - if (position < 0) + if (position <= 0) { - if (INT_SUBTRACT_WRAPV (wanted, position, &wanted) + if (INT_ADD_WRAPV (wanted, position, &wanted) || wanted < BEGV) wanted = BEGV; @@ -1533,8 +1542,9 @@ get_extracted_text (struct frame *f, ptrdiff_t n, /* Figure out the bounds of the text to return. */ if (n != -1) { - /* Make sure n is at least 2. */ - n = max (2, n); + /* Make sure n is at least 4, leaving two characters around + PT. */ + n = max (4, n); start = PT - n / 2; end = PT + n - n / 2;