aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-06-02 13:31:40 +0800
committerPo Lu2023-06-02 13:31:40 +0800
commit189a91bfb699babd936dae48b96d71a332cac8d2 (patch)
tree73ccb99dfebc3c2bb0770781c120a37338bcf76a /src
parentc3c2289b29df2b723b9db93d9ea4cd5d04fc89a0 (diff)
downloademacs-189a91bfb699babd936dae48b96d71a332cac8d2.tar.gz
emacs-189a91bfb699babd936dae48b96d71a332cac8d2.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/android.c2
-rw-r--r--src/androidgui.h4
-rw-r--r--src/androidterm.c12
-rw-r--r--src/frame.h1
-rw-r--r--src/textconv.c60
-rw-r--r--src/textconv.h1
6 files changed, 73 insertions, 7 deletions
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,
2543 event.xkey.state = state; 2543 event.xkey.state = state;
2544 event.xkey.keycode = keycode; 2544 event.xkey.keycode = keycode;
2545 event.xkey.unicode_char = unicode_char; 2545 event.xkey.unicode_char = unicode_char;
2546 event.xkey.counter = 0;
2546 2547
2547 android_write_event (&event); 2548 android_write_event (&event);
2548 return event_serial; 2549 return event_serial;
@@ -2565,6 +2566,7 @@ NATIVE_NAME (sendKeyRelease) (JNIEnv *env, jobject object,
2565 event.xkey.state = state; 2566 event.xkey.state = state;
2566 event.xkey.keycode = keycode; 2567 event.xkey.keycode = keycode;
2567 event.xkey.unicode_char = unicode_char; 2568 event.xkey.unicode_char = unicode_char;
2569 event.xkey.counter = 0;
2568 2570
2569 android_write_event (&event); 2571 android_write_event (&event);
2570 return event_serial; 2572 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
277 /* If this field is -1, then android_lookup_string should be called 277 /* If this field is -1, then android_lookup_string should be called
278 to retrieve the associated individual characters. */ 278 to retrieve the associated individual characters. */
279 unsigned int unicode_char; 279 unsigned int unicode_char;
280
281 /* If this field is non-zero, a text conversion barrier should be
282 generated with its value as the counter. */
283 unsigned long counter;
280}; 284};
281 285
282typedef struct android_key_event android_key_pressed_event; 286typedef 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,
885 if (!f) 885 if (!f)
886 goto OTHER; 886 goto OTHER;
887 887
888 if (event->xkey.counter)
889 /* This event was generated by `performEditorAction'. Make
890 sure it is processed before any subsequent edits. */
891 textconv_barrier (f, event->xkey.counter);
892
888 wchar_t copy_buffer[129]; 893 wchar_t copy_buffer[129];
889 wchar_t *copy_bufptr = copy_buffer; 894 wchar_t *copy_bufptr = copy_buffer;
890 int copy_bufsiz = 128 * sizeof (wchar_t); 895 int copy_bufsiz = 128 * sizeof (wchar_t);
@@ -5178,7 +5183,10 @@ NATIVE_NAME (performEditorAction) (JNIEnv *env, jobject object,
5178 5183
5179 android_write_event (&event); 5184 android_write_event (&event);
5180 5185
5181 /* Finally, send the return key press. */ 5186 /* Finally, send the return key press. `counter' is set; this means
5187 that a text conversion barrier will be generated once the event
5188 is read, which will cause subsequent edits to wait until the
5189 edits associated with this key press complete. */
5182 5190
5183 event.xkey.type = ANDROID_KEY_PRESS; 5191 event.xkey.type = ANDROID_KEY_PRESS;
5184 event.xkey.serial = ++event_serial; 5192 event.xkey.serial = ++event_serial;
@@ -5187,6 +5195,7 @@ NATIVE_NAME (performEditorAction) (JNIEnv *env, jobject object,
5187 event.xkey.state = 0; 5195 event.xkey.state = 0;
5188 event.xkey.keycode = 66; 5196 event.xkey.keycode = 66;
5189 event.xkey.unicode_char = 0; 5197 event.xkey.unicode_char = 0;
5198 event.xkey.counter = ++edit_counter;
5190 5199
5191 android_write_event (&event); 5200 android_write_event (&event);
5192} 5201}
@@ -5234,6 +5243,7 @@ NATIVE_NAME (performContextMenuAction) (JNIEnv *env, jobject object,
5234 event.xkey.state = 0; 5243 event.xkey.state = 0;
5235 event.xkey.keycode = 66; 5244 event.xkey.keycode = 66;
5236 event.xkey.unicode_char = 0; 5245 event.xkey.unicode_char = 0;
5246 event.xkey.counter = ++edit_counter;
5237 5247
5238 android_write_event (&event); 5248 android_write_event (&event);
5239} 5249}
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
89 TEXTCONV_SET_POINT_AND_MARK, 89 TEXTCONV_SET_POINT_AND_MARK,
90 TEXTCONV_DELETE_SURROUNDING_TEXT, 90 TEXTCONV_DELETE_SURROUNDING_TEXT,
91 TEXTCONV_REQUEST_POINT_UPDATE, 91 TEXTCONV_REQUEST_POINT_UPDATE,
92 TEXTCONV_BARRIER,
92 }; 93 };
93 94
94/* Structure describing a single edit being performed by the input 95/* 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/>. */
36#include "buffer.h" 36#include "buffer.h"
37#include "syntax.h" 37#include "syntax.h"
38#include "blockinput.h" 38#include "blockinput.h"
39#include "keyboard.h"
39 40
40 41
41 42
@@ -522,7 +523,11 @@ detect_conversion_events (void)
522 523
523 FOR_EACH_FRAME (tail, frame) 524 FOR_EACH_FRAME (tail, frame)
524 { 525 {
525 if (XFRAME (frame)->conversion.actions) 526 /* See if there's a pending edit on this frame. */
527 if (XFRAME (frame)->conversion.actions
528 && ((XFRAME (frame)->conversion.actions->operation
529 != TEXTCONV_BARRIER)
530 || (kbd_fetch_ptr == kbd_store_ptr)))
526 return true; 531 return true;
527 } 532 }
528 533
@@ -740,7 +745,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t position,
740 Fset_marker_insertion_type (f->conversion.compose_region_end, 745 Fset_marker_insertion_type (f->conversion.compose_region_end,
741 Qt); 746 Qt);
742 747
743 start = position; 748 start = PT;
744 } 749 }
745 else 750 else
746 { 751 {
@@ -762,7 +767,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t position,
762 record_buffer_change (start, PT, Qnil); 767 record_buffer_change (start, PT, Qnil);
763 768
764 /* Now move point to an appropriate location. */ 769 /* Now move point to an appropriate location. */
765 if (position < 0) 770 if (position <= 0)
766 { 771 {
767 wanted = start; 772 wanted = start;
768 773
@@ -1198,6 +1203,19 @@ handle_pending_conversion_events_1 (struct frame *f,
1198 case TEXTCONV_REQUEST_POINT_UPDATE: 1203 case TEXTCONV_REQUEST_POINT_UPDATE:
1199 really_request_point_update (f); 1204 really_request_point_update (f);
1200 break; 1205 break;
1206
1207 case TEXTCONV_BARRIER:
1208 if (kbd_fetch_ptr != kbd_store_ptr)
1209 emacs_abort ();
1210
1211 /* Once a barrier is hit, synchronize F's selected window's
1212 `ephemeral_last_point' with its current point. The reason
1213 for this is because otherwise a previous keyboard event may
1214 have taken place without redisplay happening in between. */
1215
1216 if (w)
1217 w->ephemeral_last_point = window_point (w);
1218 break;
1201 } 1219 }
1202 1220
1203 /* Signal success. */ 1221 /* Signal success. */
@@ -1231,7 +1249,7 @@ handle_pending_conversion_events (void)
1231 static int inside; 1249 static int inside;
1232 specpdl_ref count; 1250 specpdl_ref count;
1233 ptrdiff_t last_point; 1251 ptrdiff_t last_point;
1234 struct window *w; 1252 struct window *w, *w1;
1235 1253
1236 handled = false; 1254 handled = false;
1237 1255
@@ -1242,8 +1260,6 @@ handle_pending_conversion_events (void)
1242 Vtext_conversion_edits = Qnil; 1260 Vtext_conversion_edits = Qnil;
1243 1261
1244 inside++; 1262 inside++;
1245 last_point = -1;
1246 w = NULL;
1247 1263
1248 count = SPECPDL_INDEX (); 1264 count = SPECPDL_INDEX ();
1249 record_unwind_protect_ptr (decrement_inside, &inside); 1265 record_unwind_protect_ptr (decrement_inside, &inside);
@@ -1251,6 +1267,8 @@ handle_pending_conversion_events (void)
1251 FOR_EACH_FRAME (tail, frame) 1267 FOR_EACH_FRAME (tail, frame)
1252 { 1268 {
1253 f = XFRAME (frame); 1269 f = XFRAME (frame);
1270 last_point = -1;
1271 w = NULL;
1254 1272
1255 /* Test if F has any outstanding conversion events. Then 1273 /* Test if F has any outstanding conversion events. Then
1256 process them in bottom to up order. */ 1274 process them in bottom to up order. */
@@ -1283,6 +1301,13 @@ handle_pending_conversion_events (void)
1283 if (!action) 1301 if (!action)
1284 break; 1302 break;
1285 1303
1304 /* If action is a barrier event and the keyboard buffer is
1305 not yet empty, break out of the loop. */
1306
1307 if (action->operation == TEXTCONV_BARRIER
1308 && kbd_store_ptr != kbd_fetch_ptr)
1309 break;
1310
1286 /* Unlink this action. */ 1311 /* Unlink this action. */
1287 next = action->next; 1312 next = action->next;
1288 f->conversion.actions = next; 1313 f->conversion.actions = next;
@@ -1515,6 +1540,29 @@ request_point_update (struct frame *f, unsigned long counter)
1515 input_pending = true; 1540 input_pending = true;
1516} 1541}
1517 1542
1543/* Request that text conversion on F pause until the keyboard buffer
1544 becomes empty.
1545
1546 Use this function to ensure that edits associated with a keyboard
1547 event complete before the text conversion edits after the barrier
1548 take place. */
1549
1550void
1551textconv_barrier (struct frame *f, unsigned long counter)
1552{
1553 struct text_conversion_action *action, **last;
1554
1555 action = xmalloc (sizeof *action);
1556 action->operation = TEXTCONV_BARRIER;
1557 action->data = Qnil;
1558 action->next = NULL;
1559 action->counter = counter;
1560 for (last = &f->conversion.actions; *last; last = &(*last)->next)
1561 ;;
1562 *last = action;
1563 input_pending = true;
1564}
1565
1518/* Return N characters of text around point in F's old selected 1566/* Return N characters of text around point in F's old selected
1519 window. 1567 window.
1520 1568
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,
139extern void delete_surrounding_text (struct frame *, ptrdiff_t, 139extern void delete_surrounding_text (struct frame *, ptrdiff_t,
140 ptrdiff_t, unsigned long); 140 ptrdiff_t, unsigned long);
141extern void request_point_update (struct frame *, unsigned long); 141extern void request_point_update (struct frame *, unsigned long);
142extern void textconv_barrier (struct frame *, unsigned long);
142extern char *get_extracted_text (struct frame *, ptrdiff_t, ptrdiff_t *, 143extern char *get_extracted_text (struct frame *, ptrdiff_t, ptrdiff_t *,
143 ptrdiff_t *, ptrdiff_t *, ptrdiff_t *, 144 ptrdiff_t *, ptrdiff_t *, ptrdiff_t *,
144 ptrdiff_t *); 145 ptrdiff_t *);