From e96e4906c8cb2a8810f969579446f6d151954586 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 23 May 2024 17:46:48 +0800 Subject: [PATCH] Work around one Android bug and document another * etc/PROBLEMS (Runtime problems specific to Android): Document deficiency of "Android Keyboard (AOSP)." * java/org/gnu/emacs/EmacsView.java (showOnScreenKeyboard): Revert yesterday's change. * java/org/gnu/emacs/EmacsWindow.java (toggleOnScreenKeyboard): Sync with the UI thread after displaying the on-screen keyboard. --- etc/PROBLEMS | 14 ++++++++++++++ java/org/gnu/emacs/EmacsView.java | 9 --------- java/org/gnu/emacs/EmacsWindow.java | 27 +++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 77856087367..da861ebe6e7 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -3650,6 +3650,20 @@ result that the next redisplay recenters the window around this outdated position. There is no solution but installing a more cooperative--and preferably free--input method. +** The default input method sometimes performs edits out of place in large buffers. + +When first reactivated in a window after having been dismissed, certain +heuristics applied by the "Android Keyboard (AOSP)" input method to +detect unresponsive text editors, which are ill-adapted to buffers +greater than a few thousand characters in length, conclude that Emacs is +misbehaving, so that the input method ignores updates to the position of +point reported around the time of its activation, and edits suggested by +the input method are inserted in a previously reported location that +might be wildly removed from the current insertion point. This is a bug +in the input method that can be easily reproduced by inserting lengthy +documents into any text editor, with no real solution except avoiding +edit suggestions from recently-reactivated input methods. + * Build-time problems ** Configuration diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index db270b796e8..244a3a02166 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java @@ -777,15 +777,6 @@ else if (child.getVisibility () != GONE) imManager.showSoftInput (this, 0); isCurrentlyTextEditor = true; - - /* The OS text editing widget unconditionally reports the current - values of the selection to the input method after calls to - showSoftInput, which is redundant if inputConnection exists but - is now relied upon in such circumstances by the OS's default - input method, and must therefore be faithfully reproduced on our - part. */ - if (inputConnection != null) - EmacsNative.requestSelectionUpdate (window.handle); } public void diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 483ba0dbced..5a4e04ae169 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java @@ -20,12 +20,16 @@ package org.gnu.emacs; import java.lang.IllegalStateException; + import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; -import java.util.LinkedHashMap; import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; + import android.app.Activity; import android.content.ClipData; @@ -1620,23 +1624,38 @@ else if (EmacsWindow.this.isMapped) public void toggleOnScreenKeyboard (final boolean on) { + FutureTask task; + /* Even though InputMethodManager functions are thread safe, `showOnScreenKeyboard' etc must be called from the UI thread in order to avoid deadlocks if the calls happen in tandem with a call to a synchronizing function within `onCreateInputConnection'. */ - EmacsService.SERVICE.runOnUiThread (new Runnable () { + task = new FutureTask (new Callable () { @Override - public void - run () + public Void + call () { if (on) view.showOnScreenKeyboard (); else view.hideOnScreenKeyboard (); + return null; } }); + + /* Block Lisp until this request to display the on-screen keyboard + is registered by the UI thread, or updates arising from a + redisplay that are reported between the two events will be liable + to run afoul of the IMM's cache of selection positions and never + reach the input method, if it is currently hidden, as input + methods receive outdated selection information reported during + the previous call to `onCreateInputConnection' when first + displayed. + + Chances are this is a long-standing bug in the system. */ + EmacsService.syncRunnable (task); } public String