summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/org/gnu/emacs/EmacsInputConnection.java66
-rw-r--r--java/org/gnu/emacs/EmacsNative.java2
-rw-r--r--java/org/gnu/emacs/EmacsService.java25
-rw-r--r--java/org/gnu/emacs/EmacsView.java3
4 files changed, 81 insertions, 15 deletions
diff --git a/java/org/gnu/emacs/EmacsInputConnection.java b/java/org/gnu/emacs/EmacsInputConnection.java
index 1bcc9a62a81..f8dce5dfa79 100644
--- a/java/org/gnu/emacs/EmacsInputConnection.java
+++ b/java/org/gnu/emacs/EmacsInputConnection.java
@@ -50,6 +50,11 @@ public final class EmacsInputConnection implements InputConnection
/* The handle ID associated with that view's window. */
private short windowHandle;
+ /* Number of batch edits currently underway. Used to avoid
+ synchronizing with the Emacs thread after each
+ `endBatchEdit'. */
+ private int batchEditCount;
+
/* Whether or not to synchronize and call `updateIC' with the
selection position after committing text.
@@ -110,6 +115,10 @@ public final class EmacsInputConnection implements InputConnection
Log.d (TAG, "beginBatchEdit");
EmacsNative.beginBatchEdit (windowHandle);
+
+ /* Keep a record of the number of outstanding batch edits here as
+ well. */
+ batchEditCount++;
return true;
}
@@ -125,7 +134,14 @@ public final class EmacsInputConnection implements InputConnection
Log.d (TAG, "endBatchEdit");
EmacsNative.endBatchEdit (windowHandle);
- return true;
+
+ /* Subtract one from the UI thread record of the number of batch
+ edits currently under way. */
+
+ if (batchEditCount > 0)
+ batchEditCount -= 1;
+
+ return batchEditCount > 0;
}
public boolean
@@ -584,21 +600,50 @@ public final class EmacsInputConnection implements InputConnection
return text;
}
-
- /* Override functions which are not implemented. */
-
@Override
- public Handler
- getHandler ()
+ public TextSnapshot
+ takeSnapshot ()
{
- return null;
+ TextSnapshot snapshot;
+
+ /* Return if the input connection is out of date. */
+ if (view.icSerial < view.icGeneration)
+ return null;
+
+ snapshot = EmacsNative.takeSnapshot (windowHandle);
+
+ if (EmacsService.DEBUG_IC)
+ Log.d (TAG, ("takeSnapshot: "
+ + snapshot.getSurroundingText ().getText ()
+ + " @ " + snapshot.getCompositionEnd ()
+ + ", " + snapshot.getCompositionStart ()));
+
+ return snapshot;
}
@Override
public void
closeConnection ()
{
+ batchEditCount = 0;
+ }
+
+
+ public void
+ reset ()
+ {
+ batchEditCount = 0;
+ }
+
+
+ /* Override functions which are not implemented. */
+
+ @Override
+ public Handler
+ getHandler ()
+ {
+ return null;
}
@Override
@@ -617,13 +662,6 @@ public final class EmacsInputConnection implements InputConnection
}
@Override
- public TextSnapshot
- takeSnapshot ()
- {
- return null;
- }
-
- @Override
public boolean
clearMetaKeyStates (int states)
{
diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java
index 2fcbf8b94ef..9e87c419f95 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -26,6 +26,7 @@ import android.graphics.Bitmap;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.SurroundingText;
+import android.view.inputmethod.TextSnapshot;
public final class EmacsNative
{
@@ -230,6 +231,7 @@ public final class EmacsNative
public static native SurroundingText getSurroundingText (short window,
int left, int right,
int flags);
+ public static native TextSnapshot takeSnapshot (short window);
/* Return the current value of the selection, or -1 upon
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java
index 96216e51cf4..2fe4e8c4146 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -767,8 +767,31 @@ public final class EmacsService extends Service
public void
resetIC (EmacsWindow window, int icMode)
{
+ int oldMode;
+
if (DEBUG_IC)
- Log.d (TAG, "resetIC: " + window);
+ Log.d (TAG, "resetIC: " + window + ", " + icMode);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
+ && (oldMode = window.view.getICMode ()) == icMode
+ /* Don't do this if there is currently no input
+ connection. */
+ && oldMode != IC_MODE_NULL)
+ {
+ if (DEBUG_IC)
+ Log.d (TAG, "resetIC: calling invalidateInput");
+
+ /* Android 33 and later allow the IM reset to be optimized out
+ and replaced by a call to `invalidateInput', which is much
+ faster, as it does not involve resetting the input
+ connection. */
+
+ icBeginSynchronous ();
+ window.view.imManager.invalidateInput (window.view);
+ icEndSynchronous ();
+
+ return;
+ }
window.view.setICMode (icMode);
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java
index 278c6025902..aba1184b0c2 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -681,6 +681,9 @@ public final class EmacsView extends ViewGroup
if (inputConnection == null)
inputConnection = new EmacsInputConnection (this);
+ else
+ /* Clear several pieces of state in the input connection. */
+ inputConnection.reset ();
/* Return the input connection. */
return inputConnection;