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
# 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
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
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)
{
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;
}
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;
}
/* 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,
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;
}
else
{
+ /* Otherwise, it is relative to the last character in
+ TEXT. */
+
wanted
= marker_position (f->conversion.compose_region_end);
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;
/* 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;