From: Po Lu Date: Sun, 12 Mar 2023 11:36:09 +0000 (+0800) Subject: Update Android port X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=776f1ca3e3551b98569ab7daa58cd6921048881e;p=emacs.git Update Android port * src/android.c (android_check_if_event): * src/androidgui.h: New function. * src/androidterm.c (android_event_is_for_frame): New function. (android_reset_conversion): Free and unqueue all text conversion events for the given frame. --- diff --git a/src/android.c b/src/android.c index e4f9dd0ffbe..a2c239736a7 100644 --- a/src/android.c +++ b/src/android.c @@ -601,6 +601,40 @@ android_next_event (union android_event *event_return) pthread_mutex_unlock (&event_queue.mutex); } +bool +android_check_if_event (union android_event *event_return, + bool (*predicate) (union android_event *, + void *), + void *arg) +{ + struct android_event_container *container; + + pthread_mutex_lock (&event_queue.mutex); + + /* Loop over each event. */ + container = event_queue.events.last; + for (; container != &event_queue.events; container = container->last) + { + /* See if the predicate matches. */ + if ((*predicate) (&container->event, arg)) + { + /* Copy out the event and return true. */ + *event_return = container->event; + --event_queue.num_events; + + /* Unlink container. */ + container->last->next = container->next; + container->next->last = container->last; + free (container); + pthread_mutex_unlock (&event_queue.mutex); + return true; + } + } + + pthread_mutex_unlock (&event_queue.mutex); + return false; +} + void android_write_event (union android_event *event) { diff --git a/src/androidgui.h b/src/androidgui.h index 0e311b629c6..ddd8e9fcf72 100644 --- a/src/androidgui.h +++ b/src/androidgui.h @@ -524,6 +524,10 @@ enum android_ic_mode extern int android_pending (void); extern void android_next_event (union android_event *); +extern bool android_check_if_event (union android_event *, + bool (*) (union android_event *, + void *), + void *); extern android_window android_create_window (android_window, int, int, int, int, diff --git a/src/androidterm.c b/src/androidterm.c index ed375ef53fe..72d81744128 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -5474,6 +5474,19 @@ android_update_selection (struct frame *f, struct window *w) } } +/* Return whether or not EVENT is an input method event destined for + the frame (struct frame *) ARG. */ + +static bool +android_event_is_for_frame (union android_event *event, void *arg) +{ + struct frame *f; + + f = arg; + return (event->type == ANDROID_INPUT_METHOD + && event->ime.window == FRAME_ANDROID_WINDOW (f)); +} + /* Notice that the input method connection to F should be reset as a result of a change to its contents. */ @@ -5484,6 +5497,7 @@ android_reset_conversion (struct frame *f) struct window *w; struct buffer *buffer; Lisp_Object style; + union android_event event; /* Reset the input method. @@ -5507,6 +5521,27 @@ android_reset_conversion (struct frame *f) else mode = ANDROID_IC_MODE_TEXT; + /* Remove any existing input method events that apply to FRAME from + the event queue. + + There's a small window between this and the call to + android_reset_ic between which more events can be generated. */ + + while (android_check_if_event (&event, android_event_is_for_frame, f)) + { + switch (event.ime.operation) + { + case ANDROID_IME_COMMIT_TEXT: + case ANDROID_IME_FINISH_COMPOSING_TEXT: + case ANDROID_IME_SET_COMPOSING_TEXT: + xfree (event.ime.text); + break; + + default: + break; + } + } + android_reset_ic (FRAME_ANDROID_WINDOW (f), mode); /* Clear extracted text flags. Since the IM has been reinitialised,