emacs-diffs
[Top][All Lists]
Advanced

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

feature/android 5ff31bf36cf 2/2: Update Android port


From: Po Lu
Subject: feature/android 5ff31bf36cf 2/2: Update Android port
Date: Mon, 17 Jul 2023 22:13:15 -0400 (EDT)

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

    Update Android port
    
    * doc/lispref/commands.texi (Touchscreen Events): Describe
    treatment of canceled touch sequences during touch event
    translation.
    * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Update JNI
    prototypes.
    * java/org/gnu/emacs/EmacsWindow.java (motionEvent): Set
    cancelation flag in events sent where appropriate.
    * lisp/touch-screen.el (touch-screen-handle-point-update):
    Improve treatment of horizontal scrolling near window edges.
    (touch-screen-handle-touch): Don't handle point up if the touch
    sequence has been canceled.
    * src/android.c (sendTouchDown, sendTouchUp, sendTouchMove): New
    argument `flags'.
    * src/androidgui.h (enum android_touch_event_flags): New enum.
    (struct android_touch_event): New field `flags'.
    * src/androidterm.c (handle_one_android_event): Report
    cancelation in TOUCHSCREEN_END_EVENTs.
    * src/keyboard.c (make_lispy_event): Fix botched merge.
---
 doc/lispref/commands.texi           |  23 ++++----
 java/org/gnu/emacs/EmacsNative.java |   9 ++--
 java/org/gnu/emacs/EmacsWindow.java |  19 ++++---
 lisp/touch-screen.el                |  27 ++++++++--
 src/android.c                       |  12 +++--
 src/androidgui.h                    |  10 ++++
 src/androidterm.c                   |   5 ++
 src/keyboard.c                      | 103 +++++++++++++++++++++++++-----------
 8 files changed, 152 insertions(+), 56 deletions(-)

diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index ffb01254fc9..55fecdce2d7 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -2061,9 +2061,11 @@ keymaps that are active at the location of the
 of a single @code{down-mouse-1} event, with subsequent
 @code{touchscreen-update} events translated to mouse motion events
 (@pxref{Motion Events}), and a final @code{touchscreen-end} event
-translated to a @code{mouse-1} or @code{drag-mouse-1} event.  This is
-referred to ``simple translation'', and produces a simple
-correspondence between touchpoint motion and mouse motion.
+translated to a @code{mouse-1} or @code{drag-mouse-1} event (unless
+the @code{touchscreen-end} event indicates that the touch sequence has
+been intercepted by another program.)  This is referred to ``simple
+translation'', and produces a simple correspondence between touchpoint
+motion and mouse motion.
 
 @cindex @code{ignored-mouse-command}, a symbol property
 However, some commands bound to
@@ -2078,13 +2080,14 @@ takes place: here, Emacs processes touch screen gestures
 (@pxref{Touchscreens,,, emacs, The GNU Emacs Manual}) first, and
 finally attempts to translate touch screen events into mouse events if
 no gesture was detected prior to a closing @code{touchscreen-end}
-event and a command is bound to @code{mouse-1} at the location of that
-event.  Before generating the @code{mouse-1} event, point is also set
-to the location of the @code{touchscreen-end} event, and the window
-containing the position of that event is selected, as a compromise for
-packages which assume @code{mouse-drag-region} has already set point
-to the location of any mouse click and selected the window where it
-took place.
+event (with its @var{canceled} parameter @code{nil}, as with simple
+translation) and a command is bound to @code{mouse-1} at the location
+of that event.  Before generating the @code{mouse-1} event, point is
+also set to the location of the @code{touchscreen-end} event, and the
+window containing the position of that event is selected, as a
+compromise for packages which assume @code{mouse-drag-region} has
+already set point to the location of any mouse click and selected the
+window where it took place.
 
 To prevent unwanted @code{mouse-1} events arriving after a mouse menu
 is dismissed (@pxref{Mouse Menus}), Emacs also avoids simple
diff --git a/java/org/gnu/emacs/EmacsNative.java 
b/java/org/gnu/emacs/EmacsNative.java
index 1331539879a..d4d502ede5a 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -142,15 +142,18 @@ public final class EmacsNative
 
   /* Send an ANDROID_TOUCH_DOWN event.  */
   public static native long sendTouchDown (short window, int x, int y,
-                                          long time, int pointerID);
+                                          long time, int pointerID,
+                                          int flags);
 
   /* Send an ANDROID_TOUCH_UP event.  */
   public static native long sendTouchUp (short window, int x, int y,
-                                        long time, int pointerID);
+                                        long time, int pointerID,
+                                        int flags);
 
   /* Send an ANDROID_TOUCH_MOVE event.  */
   public static native long sendTouchMove (short window, int x, int y,
-                                          long time, int pointerID);
+                                          long time, int pointerID,
+                                          int flags);
 
   /* Send an ANDROID_WHEEL event.  */
   public static native long sendWheel (short window, int x, int y,
diff --git a/java/org/gnu/emacs/EmacsWindow.java 
b/java/org/gnu/emacs/EmacsWindow.java
index 0e96a8382d0..8118479319e 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -1025,23 +1025,30 @@ public final class EmacsWindow extends EmacsHandleObject
            /* Touch down event.  */
            EmacsNative.sendTouchDown (this.handle, coordinate.x,
                                       coordinate.y, time,
-                                      coordinate.id);
+                                      coordinate.id, 0);
            break;
 
          case MotionEvent.ACTION_UP:
          case MotionEvent.ACTION_POINTER_UP:
+           /* Touch up event.  */
+           EmacsNative.sendTouchUp (this.handle, coordinate.x,
+                                    coordinate.y, time,
+                                    coordinate.id, 0);
+           break;
+
          case MotionEvent.ACTION_CANCEL:
-           /* Touch up event.  Android documentation says ACTION_CANCEL
-              should be treated as more or less equivalent to ACTION_UP,
-              so that is what is done here.  */
+           /* Touch sequence cancellation event.  */
            EmacsNative.sendTouchUp (this.handle, coordinate.x,
-                                    coordinate.y, time, coordinate.id);
+                                    coordinate.y, time,
+                                    coordinate.id,
+                                    1 /* ANDROID_TOUCH_SEQUENCE_CANCELED */);
            break;
 
          case MotionEvent.ACTION_MOVE:
            /* Pointer motion event.  */
            EmacsNative.sendTouchMove (this.handle, coordinate.x,
-                                      coordinate.y, time, coordinate.id);
+                                      coordinate.y, time,
+                                      coordinate.id, 0);
            break;
          }
       }
diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el
index 1ef66d0043f..8f10bc3e794 100644
--- a/lisp/touch-screen.el
+++ b/lisp/touch-screen.el
@@ -548,11 +548,26 @@ then move point to the position of POINT."
                   ;; WINDOW.
                   (relative-xy
                    (touch-screen-relative-xy posn window))
+                  (col (and (eq (posn-area posn) 'text-area)
+                            (car (posn-col-row posn
+                                               (posn-window posn)))))
+                  ;; Don't start horizontal scrolling if the touch
+                  ;; point originated within two columns of the window
+                  ;; edges, as systems like Android use those two
+                  ;; columns to implement gesture navigation.
+                  (diff-x-eligible
+                   (and col (> (car col) 2)
+                        (< (car col) (- (window-width window) 2))))
                   (diff-x (- (car last-posn) (car relative-xy)))
                   (diff-y (- (cdr last-posn) (cdr relative-xy))))
-             ;; Decide whether or not to start scrolling.
-             (when (or (> diff-y 10) (> diff-x 10)
-                       (< diff-y -10) (< diff-x -10))
+             ;; Decide whether or not to start scrolling.  Make the
+             ;; hscrolling threshold slightly larger than the vertical
+             ;; scrolling threshold, to compensate better for
+             ;; Android-style gesture navigation.
+             (when (or (> diff-y 10) (and diff-x-eligible
+                                          (> diff-x 20))
+                       (< diff-y -10) (and diff-x-eligible
+                                           (< diff-x -20)))
                (setcar (nthcdr 3 touch-screen-current-tool)
                        'scroll)
                (setcar (nthcdr 2 touch-screen-current-tool)
@@ -852,7 +867,11 @@ the place of EVENT within the key sequence being 
translated, or
           (cancel-timer touch-screen-current-timer)
           (setq touch-screen-current-timer nil))
         (unwind-protect
-            (touch-screen-handle-point-up (cadr event) prefix)
+            ;; Don't perform any actions associated with releasing the
+            ;; tool if the touch sequence was intercepted by another
+            ;; program.
+            (unless (caddr event)
+              (touch-screen-handle-point-up (cadr event) prefix))
           ;; Make sure the tool list is cleared even if
           ;; `touch-screen-handle-point-up' throws.
           (setq touch-screen-current-tool nil)))
diff --git a/src/android.c b/src/android.c
index 90288737c77..f2e5e75d35e 100644
--- a/src/android.c
+++ b/src/android.c
@@ -2870,7 +2870,8 @@ NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject 
object,
 JNIEXPORT jlong JNICALL
 NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
                             jshort window, jint x, jint y,
-                            jlong time, jint pointer_id)
+                            jlong time, jint pointer_id,
+                            jint flags)
 {
   JNI_STACK_ALIGNMENT_PROLOGUE;
 
@@ -2883,6 +2884,7 @@ NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
   event.touch.y = y;
   event.touch.time = time;
   event.touch.pointer_id = pointer_id;
+  event.touch.flags = flags;
 
   android_write_event (&event);
   return event_serial;
@@ -2891,7 +2893,8 @@ NATIVE_NAME (sendTouchDown) (JNIEnv *env, jobject object,
 JNIEXPORT jlong JNICALL
 NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
                           jshort window, jint x, jint y,
-                          jlong time, jint pointer_id)
+                          jlong time, jint pointer_id,
+                          jint flags)
 {
   JNI_STACK_ALIGNMENT_PROLOGUE;
 
@@ -2904,6 +2907,7 @@ NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
   event.touch.y = y;
   event.touch.time = time;
   event.touch.pointer_id = pointer_id;
+  event.touch.flags = flags;
 
   android_write_event (&event);
   return event_serial;
@@ -2912,7 +2916,8 @@ NATIVE_NAME (sendTouchUp) (JNIEnv *env, jobject object,
 JNIEXPORT jlong JNICALL
 NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
                             jshort window, jint x, jint y,
-                            jlong time, jint pointer_id)
+                            jlong time, jint pointer_id,
+                            jint flags)
 {
   JNI_STACK_ALIGNMENT_PROLOGUE;
 
@@ -2925,6 +2930,7 @@ NATIVE_NAME (sendTouchMove) (JNIEnv *env, jobject object,
   event.touch.y = y;
   event.touch.time = time;
   event.touch.pointer_id = pointer_id;
+  event.touch.flags = flags;
 
   android_write_event (&event);
   return event_serial;
diff --git a/src/androidgui.h b/src/androidgui.h
index 9e604cdcb8c..265ec29b678 100644
--- a/src/androidgui.h
+++ b/src/androidgui.h
@@ -365,6 +365,13 @@ struct android_expose_event
   int width, height;
 };
 
+enum android_touch_event_flags
+  {
+    /* This touch sequence has been intercepted by the WM (probably
+       for back gesture navigation or some such.)  */
+    ANDROID_TOUCH_SEQUENCE_CANCELED = 1,
+  };
+
 struct android_touch_event
 {
   /* Type of the event.  */
@@ -384,6 +391,9 @@ struct android_touch_event
 
   /* Index of the pointer being tracked.  */
   unsigned int pointer_id;
+
+  /* Flags associated with this event.  */
+  int flags;
 };
 
 struct android_wheel_event
diff --git a/src/androidterm.c b/src/androidterm.c
index 27800a61864..bcb6cd6db45 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -1511,6 +1511,11 @@ handle_one_android_event (struct android_display_info 
*dpyinfo,
              inev.ie.kind = TOUCHSCREEN_END_EVENT;
              inev.ie.timestamp = event->touch.time;
 
+             /* Report whether the sequence has been canceled.  */
+
+             if (event->touch.flags & ANDROID_TOUCH_SEQUENCE_CANCELED)
+               inev.ie.modifiers = 1;
+
              XSETFRAME (inev.ie.frame_or_window, any);
              XSETINT (inev.ie.x, event->touch.x);
              XSETINT (inev.ie.y, event->touch.y);
diff --git a/src/keyboard.c b/src/keyboard.c
index bd7433e584a..73c4e3f2593 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6560,11 +6560,10 @@ make_lispy_event (struct input_event *event)
       {
        Lisp_Object x, y, id, position;
        struct frame *f;
+#ifdef HAVE_WINDOW_SYSTEM
        int tab_bar_item;
        bool close;
-#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
-       int column, row, dummy;
-#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
+#endif /* HAVE_WINDOW_SYSTEM */
 
        f = XFRAME (event->frame_or_window);
        id = event->arg;
@@ -6572,16 +6571,82 @@ make_lispy_event (struct input_event *event)
        y = event->y;
 
 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
-       if (event->kind == TOUCHSCREEN_BEGIN_EVENT
-           && coords_in_menu_bar_window (f, XFIXNUM (x), XFIXNUM (y)))
+       if (coords_in_menu_bar_window (f, XFIXNUM (x), XFIXNUM (y)))
          {
            /* If the tap began in the menu bar window, then save the
               id.  */
            menu_bar_touch_id = id;
            return Qnil;
          }
-       else if (event->kind == TOUCHSCREEN_END_EVENT
-                && EQ (menu_bar_touch_id, id))
+#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
+
+       position = make_lispy_position (f, x, y, event->timestamp);
+
+#ifdef HAVE_WINDOW_SYSTEM
+
+       /* Now check if POSITION lies on the tab bar.  If so, look up
+          the corresponding tab bar item's propertized string as the
+          OBJECT.  */
+
+       if (coords_in_tab_bar_window (f, XFIXNUM (event->x),
+                                     XFIXNUM (event->y))
+           /* `get_tab_bar_item_kbd' returns 0 if the item was
+              previously highlighted, 1 otherwise, and -1 if there is
+              no tab bar item.  */
+           && get_tab_bar_item_kbd (f, XFIXNUM (event->x),
+                                    XFIXNUM (event->y), &tab_bar_item,
+                                    &close) >= 0)
+         {
+           /* First, obtain the propertized string.  */
+           x = Fcopy_sequence (AREF (f->tab_bar_items,
+                                     (tab_bar_item
+                                      + TAB_BAR_ITEM_CAPTION)));
+
+           /* Next, add the key binding.  */
+           AUTO_LIST2 (y, Qmenu_item, list3 (AREF (f->tab_bar_items,
+                                                   (tab_bar_item
+                                                    + TAB_BAR_ITEM_KEY)),
+                                             AREF (f->tab_bar_items,
+                                                   (tab_bar_item
+                                                    + TAB_BAR_ITEM_BINDING)),
+                                             close ? Qt : Qnil));
+
+           /* And add the new properties to the propertized string.  */
+           Fadd_text_properties (make_fixnum (0),
+                                 make_fixnum (SCHARS (x)),
+                                 y, x);
+
+           /* Set the position to 0.  */
+           x = Fcons (x, make_fixnum (0));
+
+           /* Finally, add the OBJECT.  */
+           position = nconc2 (position, Fcons (x, Qnil));
+         }
+
+#endif /* HAVE_WINDOW_SYSTEM */
+
+       return list2 (Qtouchscreen_begin,
+                     Fcons (id, position));
+      }
+
+    case TOUCHSCREEN_END_EVENT:
+      {
+       Lisp_Object x, y, id, position;
+       struct frame *f = XFRAME (event->frame_or_window);
+#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
+       int column, row, dummy;
+#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
+#ifdef HAVE_WINDOW_SYSTEM
+       int tab_bar_item;
+       bool close;
+#endif /* HAVE_WINDOW_SYSTEM */
+
+       id = event->arg;
+       x = event->x;
+       y = event->y;
+
+#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
+       if (EQ (menu_bar_touch_id, id))
          {
            /* This touch should activate the menu bar.  Generate the
               menu bar event.  */
@@ -6631,8 +6696,6 @@ make_lispy_event (struct input_event *event)
          }
 #endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
 
-       position = make_lispy_position (f, x, y, event->timestamp);
-
 #ifdef HAVE_WINDOW_SYSTEM
 
        /* Now check if POSITION lies on the tab bar.  If so, look up
@@ -6676,29 +6739,9 @@ make_lispy_event (struct input_event *event)
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
-       return list2 (((event->kind
-                       == TOUCHSCREEN_BEGIN_EVENT)
-                      ? Qtouchscreen_begin
-                      : Qtouchscreen_end),
-                     Fcons (id, position));
-      }
-
-    case TOUCHSCREEN_END_EVENT:
-      {
-       Lisp_Object x, y, id, position;
-       struct frame *f = XFRAME (event->frame_or_window);
-
-       id = event->arg;
-       x = event->x;
-       y = event->y;
-
        position = make_lispy_position (f, x, y, event->timestamp);
 
-       return list3 (((event->kind
-                       == TOUCHSCREEN_BEGIN_EVENT)
-                      ? Qtouchscreen_begin
-                      : Qtouchscreen_end),
-                     Fcons (id, position),
+       return list3 (Qtouchscreen_end, Fcons (id, position),
                      event->modifiers ? Qt : Qnil);
       }
 



reply via email to

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