[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 *);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- feature/android 189a91bfb69: Update Android port,
Po Lu <=