emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 189a91bfb69: Update Android port


From: Po Lu
Subject: feature/android 189a91bfb69: Update Android port
Date: Fri, 2 Jun 2023 01:33:38 -0400 (EDT)

branch: feature/android
commit 189a91bfb699babd936dae48b96d71a332cac8d2
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Update Android port
    
    * java/org/gnu/emacs/EmacsInputConnection.java
    (EmacsInputConnection): Apply workarounds on Vivo devices as
    well.
    * src/android.c (sendKeyPress, sendKeyRelease): Clear counter.
    * src/androidgui.h (struct android_key_event): New field
    `counter'.
    * src/androidterm.c (handle_one_android_event): Generate
    barriers as appropriate.
    (JNICALL): Set `counter'.
    * src/frame.h (enum text_conversion_operation):
    * src/textconv.c (detect_conversion_events)
    (really_set_composing_text, handle_pending_conversion_events_1)
    (handle_pending_conversion_events, textconv_barrier):
    * src/textconv.h: Implement text conversion barriers and fix
    various typos.
---
 java/org/gnu/emacs/EmacsInputConnection.java | 11 ++---
 src/android.c                                |  2 +
 src/androidgui.h                             |  4 ++
 src/androidterm.c                            | 12 +++++-
 src/frame.h                                  |  1 +
 src/textconv.c                               | 60 +++++++++++++++++++++++++---
 src/textconv.h                               |  1 +
 7 files changed, 79 insertions(+), 12 deletions(-)

diff --git a/java/org/gnu/emacs/EmacsInputConnection.java 
b/java/org/gnu/emacs/EmacsInputConnection.java
index eb6fd5f2763..9ced7cb7aaf 100644
--- a/java/org/gnu/emacs/EmacsInputConnection.java
+++ b/java/org/gnu/emacs/EmacsInputConnection.java
@@ -66,11 +66,12 @@ public final class EmacsInputConnection extends 
BaseInputConnection
        || Build.MANUFACTURER.equalsIgnoreCase ("Honor"))
       extractAbsoluteOffsets = syncAfterCommit = true;
 
-    /* The Samsung keyboard takes `selectionStart' at face value if
-       some text is returned, and also searches for words solely
-       within that text.  However, when no text is returned, it falls
-       back to getTextAfterCursor and getTextBeforeCursor.  */
-    if (Build.MANUFACTURER.equalsIgnoreCase ("Samsung"))
+    /* The Samsung and Vivo keyboards take `selectionStart' at face
+       value if some text is returned, and also searches for words
+       solely within that text.  However, when no text is returned, it
+       falls back to getTextAfterCursor and getTextBeforeCursor.  */
+    if (Build.MANUFACTURER.equalsIgnoreCase ("Samsung")
+       || Build.MANUFACTURER.equalsIgnoreCase ("Vivo"))
       extractAbsoluteOffsets = true;
   };
 
diff --git a/src/android.c b/src/android.c
index 94587344eb5..e74d40a0cdb 100644
--- a/src/android.c
+++ b/src/android.c
@@ -2543,6 +2543,7 @@ NATIVE_NAME (sendKeyPress) (JNIEnv *env, jobject object,
   event.xkey.state = state;
   event.xkey.keycode = keycode;
   event.xkey.unicode_char = unicode_char;
+  event.xkey.counter = 0;
 
   android_write_event (&event);
   return event_serial;
@@ -2565,6 +2566,7 @@ NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
   event.xkey.state = state;
   event.xkey.keycode = keycode;
   event.xkey.unicode_char = unicode_char;
+  event.xkey.counter = 0;
 
   android_write_event (&event);
   return event_serial;
diff --git a/src/androidgui.h b/src/androidgui.h
index 02cc73809b9..9e604cdcb8c 100644
--- a/src/androidgui.h
+++ b/src/androidgui.h
@@ -277,6 +277,10 @@ struct android_key_event
   /* If this field is -1, then android_lookup_string should be called
      to retrieve the associated individual characters.  */
   unsigned int unicode_char;
+
+  /* If this field is non-zero, a text conversion barrier should be
+     generated with its value as the counter.  */
+  unsigned long counter;
 };
 
 typedef struct android_key_event android_key_pressed_event;
diff --git a/src/androidterm.c b/src/androidterm.c
index c302e3f2877..211faabf5c2 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -885,6 +885,11 @@ handle_one_android_event (struct android_display_info 
*dpyinfo,
       if (!f)
        goto OTHER;
 
+      if (event->xkey.counter)
+       /* This event was generated by `performEditorAction'.  Make
+          sure it is processed before any subsequent edits.  */
+       textconv_barrier (f, event->xkey.counter);
+
       wchar_t copy_buffer[129];
       wchar_t *copy_bufptr = copy_buffer;
       int copy_bufsiz = 128 * sizeof (wchar_t);
@@ -5178,7 +5183,10 @@ NATIVE_NAME (performEditorAction) (JNIEnv *env, jobject 
object,
 
   android_write_event (&event);
 
-  /* Finally, send the return key press.  */
+  /* Finally, send the return key press.  `counter' is set; this means
+     that a text conversion barrier will be generated once the event
+     is read, which will cause subsequent edits to wait until the
+     edits associated with this key press complete.  */
 
   event.xkey.type = ANDROID_KEY_PRESS;
   event.xkey.serial = ++event_serial;
@@ -5187,6 +5195,7 @@ NATIVE_NAME (performEditorAction) (JNIEnv *env, jobject 
object,
   event.xkey.state = 0;
   event.xkey.keycode = 66;
   event.xkey.unicode_char = 0;
+  event.xkey.counter = ++edit_counter;
 
   android_write_event (&event);
 }
@@ -5234,6 +5243,7 @@ NATIVE_NAME (performContextMenuAction) (JNIEnv *env, 
jobject object,
   event.xkey.state = 0;
   event.xkey.keycode = 66;
   event.xkey.unicode_char = 0;
+  event.xkey.counter = ++edit_counter;
 
   android_write_event (&event);
 }
diff --git a/src/frame.h b/src/frame.h
index e2900d1c15b..41b4cd444f6 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -89,6 +89,7 @@ enum text_conversion_operation
     TEXTCONV_SET_POINT_AND_MARK,
     TEXTCONV_DELETE_SURROUNDING_TEXT,
     TEXTCONV_REQUEST_POINT_UPDATE,
+    TEXTCONV_BARRIER,
   };
 
 /* Structure describing a single edit being performed by the input
diff --git a/src/textconv.c b/src/textconv.c
index d8166bcfd03..9003816e191 100644
--- a/src/textconv.c
+++ b/src/textconv.c
@@ -36,6 +36,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "buffer.h"
 #include "syntax.h"
 #include "blockinput.h"
+#include "keyboard.h"
 
 
 
@@ -522,7 +523,11 @@ detect_conversion_events (void)
 
   FOR_EACH_FRAME (tail, frame)
     {
-      if (XFRAME (frame)->conversion.actions)
+      /* See if there's a pending edit on this frame.  */
+      if (XFRAME (frame)->conversion.actions
+         && ((XFRAME (frame)->conversion.actions->operation
+              != TEXTCONV_BARRIER)
+             || (kbd_fetch_ptr == kbd_store_ptr)))
        return true;
     }
 
@@ -740,7 +745,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t 
position,
       Fset_marker_insertion_type (f->conversion.compose_region_end,
                                  Qt);
 
-      start = position;
+      start = PT;
     }
   else
     {
@@ -762,7 +767,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t 
position,
     record_buffer_change (start, PT, Qnil);
 
   /* Now move point to an appropriate location.  */
-  if (position < 0)
+  if (position <= 0)
     {
       wanted = start;
 
@@ -1198,6 +1203,19 @@ handle_pending_conversion_events_1 (struct frame *f,
     case TEXTCONV_REQUEST_POINT_UPDATE:
       really_request_point_update (f);
       break;
+
+    case TEXTCONV_BARRIER:
+      if (kbd_fetch_ptr != kbd_store_ptr)
+       emacs_abort ();
+
+      /* Once a barrier is hit, synchronize F's selected window's
+        `ephemeral_last_point' with its current point.  The reason
+        for this is because otherwise a previous keyboard event may
+        have taken place without redisplay happening in between.  */
+
+      if (w)
+       w->ephemeral_last_point = window_point (w);
+      break;
     }
 
   /* Signal success.  */
@@ -1231,7 +1249,7 @@ handle_pending_conversion_events (void)
   static int inside;
   specpdl_ref count;
   ptrdiff_t last_point;
-  struct window *w;
+  struct window *w, *w1;
 
   handled = false;
 
@@ -1242,8 +1260,6 @@ handle_pending_conversion_events (void)
     Vtext_conversion_edits = Qnil;
 
   inside++;
-  last_point = -1;
-  w = NULL;
 
   count = SPECPDL_INDEX ();
   record_unwind_protect_ptr (decrement_inside, &inside);
@@ -1251,6 +1267,8 @@ handle_pending_conversion_events (void)
   FOR_EACH_FRAME (tail, frame)
     {
       f = XFRAME (frame);
+      last_point = -1;
+      w = NULL;
 
       /* Test if F has any outstanding conversion events.  Then
         process them in bottom to up order.  */
@@ -1283,6 +1301,13 @@ handle_pending_conversion_events (void)
          if (!action)
            break;
 
+         /* If action is a barrier event and the keyboard buffer is
+            not yet empty, break out of the loop.  */
+
+         if (action->operation == TEXTCONV_BARRIER
+             && kbd_store_ptr != kbd_fetch_ptr)
+           break;
+
          /* Unlink this action.  */
          next = action->next;
          f->conversion.actions = next;
@@ -1515,6 +1540,29 @@ request_point_update (struct frame *f, unsigned long 
counter)
   input_pending = true;
 }
 
+/* Request that text conversion on F pause until the keyboard buffer
+   becomes empty.
+
+   Use this function to ensure that edits associated with a keyboard
+   event complete before the text conversion edits after the barrier
+   take place.  */
+
+void
+textconv_barrier (struct frame *f, unsigned long counter)
+{
+  struct text_conversion_action *action, **last;
+
+  action = xmalloc (sizeof *action);
+  action->operation = TEXTCONV_BARRIER;
+  action->data = Qnil;
+  action->next = NULL;
+  action->counter = counter;
+  for (last = &f->conversion.actions; *last; last = &(*last)->next)
+    ;;
+  *last = action;
+  input_pending = true;
+}
+
 /* Return N characters of text around point in F's old selected
    window.
 
diff --git a/src/textconv.h b/src/textconv.h
index e632a9dddcf..d4d0e9d7227 100644
--- a/src/textconv.h
+++ b/src/textconv.h
@@ -139,6 +139,7 @@ extern void textconv_set_point_and_mark (struct frame *, 
ptrdiff_t,
 extern void delete_surrounding_text (struct frame *, ptrdiff_t,
                                     ptrdiff_t, unsigned long);
 extern void request_point_update (struct frame *, unsigned long);
+extern void textconv_barrier (struct frame *, unsigned long);
 extern char *get_extracted_text (struct frame *, ptrdiff_t, ptrdiff_t *,
                                 ptrdiff_t *, ptrdiff_t *, ptrdiff_t *,
                                 ptrdiff_t *);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]