aboutsummaryrefslogtreecommitdiffstats
path: root/src/textconv.c
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/textconv.c
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/textconv.c')
-rw-r--r--src/textconv.c60
1 files changed, 54 insertions, 6 deletions
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