emacs-diffs
[Top][All Lists]
Advanced

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

feature/android 46fd03a4961 1/2: Merge remote-tracking branch 'origin/ma


From: Po Lu
Subject: feature/android 46fd03a4961 1/2: Merge remote-tracking branch 'origin/master' into feature/android
Date: Mon, 17 Jul 2023 22:13:14 -0400 (EDT)

branch: feature/android
commit 46fd03a49617066fca87000378771caedfd150f3
Merge: 324d66e3901 9ad601e7d76
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Merge remote-tracking branch 'origin/master' into feature/android
---
 doc/lispref/commands.texi |  7 +++-
 etc/NEWS                  |  6 ++++
 lisp/vc/vc.el             | 17 ++-------
 src/keyboard.c            | 20 ++++++++++-
 src/termhooks.h           |  6 +++-
 src/xfns.c                |  1 +
 src/xterm.c               | 92 ++++++++++++++++++++++++++++++++++++++---------
 src/xterm.h               | 62 +++++++++++++++++++++++++++++---
 8 files changed, 172 insertions(+), 39 deletions(-)

diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index bcba3fe4026..ffb01254fc9 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -2022,11 +2022,16 @@ position.  @var{points} is a list of touch points 
containing the
 up-to-date positions of each touch point currently on the touchscreen.
 
 @cindex @code{touchscreen-end} event
-@item (touchscreen-end @var{point})
+@item (touchscreen-end @var{point} @var{canceled})
 This event is sent when @var{point} is no longer present on the
 display, because another program took the grab, or because the user
 raised the finger from the touchscreen.
 
+@var{canceled} is non-@code{nil} if the touch sequence has been
+intercepted by another program (such as the window manager), and Emacs
+should undo or avoid any editing commands that would otherwise result
+from the touch sequence.
+
 These events also have imaginary prefixes keys added by
 @code{read-key-sequence} when they originate on top of a special part
 of a frame or window.
diff --git a/etc/NEWS b/etc/NEWS
index d4d9fd37210..76b1cda9e26 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -661,6 +661,12 @@ from within a command.
 This user option names directories in which Emacs will treat all
 directory-local variables as safe.
 
++++
+** New parameter to 'touchscreen-end' events.
+CANCEL non-nil establishes that the touch sequence has been
+intercepted by programs such as window managers and should be ignored
+with Emacs.
+
 ** New variable 'inhibit-auto-fill' to temporarily prevent auto-fill.
 
 +++
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 6c3094719ed..be7fa46c28e 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1121,19 +1121,8 @@ possible values of STATE are explained in `vc-state', 
and MODEL in
 the returned list.
 
 BEWARE: this function may change the current buffer."
-  (let (new-buf res)
-    (with-current-buffer (or (buffer-base-buffer) (current-buffer))
-      (setq res
-            (vc-deduce-fileset-1 not-state-changing
-                                 allow-unregistered
-                                 state-model-only-files))
-      (setq new-buf (current-buffer)))
-    (set-buffer new-buf)
-    res))
-
-(defun vc-deduce-fileset-1 (not-state-changing
-                            allow-unregistered
-                            state-model-only-files)
+  (when (buffer-base-buffer)
+    (set-buffer (buffer-base-buffer)))
   (let (backend)
     (cond
      ((derived-mode-p 'vc-dir-mode)
@@ -1158,7 +1147,7 @@ BEWARE: this function may change the current buffer."
                                      (derived-mode-p 'diff-mode)))))
       (progn                  ;FIXME: Why not `with-current-buffer'? --Stef.
        (set-buffer vc-parent-buffer)
-       (vc-deduce-fileset-1 not-state-changing allow-unregistered 
state-model-only-files)))
+        (vc-deduce-fileset not-state-changing allow-unregistered 
state-model-only-files)))
      ((and (not buffer-file-name)
           (setq backend (vc-responsible-backend default-directory)))
       (list backend nil))
diff --git a/src/keyboard.c b/src/keyboard.c
index 78105fa9e05..bd7433e584a 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6557,7 +6557,6 @@ make_lispy_event (struct input_event *event)
       }
 
     case TOUCHSCREEN_BEGIN_EVENT:
-    case TOUCHSCREEN_END_EVENT:
       {
        Lisp_Object x, y, id, position;
        struct frame *f;
@@ -6684,6 +6683,25 @@ make_lispy_event (struct input_event *event)
                      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),
+                     event->modifiers ? Qt : Qnil);
+      }
+
     case PINCH_EVENT:
       {
        Lisp_Object x, y, position;
diff --git a/src/termhooks.h b/src/termhooks.h
index 99f27cd668e..d978819aeca 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -308,7 +308,11 @@ enum event_kind
 
      In TOUCHSCREEN_BEGIN_EVENT and TOUCHSCREEN_END_EVENT, ARG is the
      unique ID of the touchpoint, and X and Y are the frame-relative
-     positions of the touchpoint.  */
+     positions of the touchpoint.
+
+     In TOUCHSCREEN_END_EVENT, non-0 modifiers means that the
+     touchpoint has been canceled.  (See (elisp)Touchscreen
+     Events.)  */
 
   , TOUCHSCREEN_UPDATE_EVENT
   , TOUCHSCREEN_BEGIN_EVENT
diff --git a/src/xfns.c b/src/xfns.c
index 704f7a3f892..854a85f5306 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4107,6 +4107,7 @@ setup_xi_event_mask (struct frame *f)
       XISetMask (m, XI_TouchBegin);
       XISetMask (m, XI_TouchUpdate);
       XISetMask (m, XI_TouchEnd);
+      XISetMask (m, XI_TouchOwnership);
 
 #if defined HAVE_XINPUT2_4 && defined USE_GTK3
       if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4)
diff --git a/src/xterm.c b/src/xterm.c
index 75e5b07f2c0..b818609d4b5 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -5742,6 +5742,10 @@ xi_device_from_id (struct x_display_info *dpyinfo, int 
deviceid)
 
 #ifdef HAVE_XINPUT2_2
 
+/* Record a touch sequence with the identifier DETAIL from the given
+   FRAME on the specified DEVICE.  Round X and Y and record them as
+   its current position.  */
+
 static void
 xi_link_touch_point (struct xi_device_t *device,
                     int detail, double x, double y,
@@ -5751,19 +5755,28 @@ xi_link_touch_point (struct xi_device_t *device,
 
   touchpoint = xmalloc (sizeof *touchpoint);
   touchpoint->next = device->touchpoints;
-  touchpoint->x = x;
-  touchpoint->y = y;
+  touchpoint->x = lrint (x);
+  touchpoint->y = lrint (y);
   touchpoint->number = detail;
   touchpoint->frame = frame;
+  touchpoint->ownership = TOUCH_OWNERSHIP_NONE;
 
   device->touchpoints = touchpoint;
 }
 
-static bool
-xi_unlink_touch_point (int detail,
-                      struct xi_device_t *device)
+/* Free and remove the touch sequence with the identifier DETAIL.
+   DEVICE is the device in which the touch sequence should be
+   recorded.
+
+   Value is 0 if no touch sequence by that identifier exists inside
+   DEVICE, 1 if a touch sequence has been found but is not owned by
+   Emacs, and 2 otherwise.  */
+
+static int
+xi_unlink_touch_point (int detail, struct xi_device_t *device)
 {
   struct xi_touch_point_t *last, *tem;
+  enum xi_touch_ownership ownership;
 
   for (last = NULL, tem = device->touchpoints; tem;
        last = tem, tem = tem->next)
@@ -5775,12 +5788,17 @@ xi_unlink_touch_point (int detail,
          else
            last->next = tem->next;
 
+         ownership = tem->ownership;
          xfree (tem);
-         return true;
+
+         if (ownership == TOUCH_OWNERSHIP_SELF)
+           return 2;
+
+         return 1;
        }
     }
 
-  return false;
+  return 0;
 }
 
 /* Unlink all touch points associated with the frame F.
@@ -5813,6 +5831,10 @@ xi_unlink_touch_points (struct frame *f)
     }
 }
 
+/* Return the data associated with a touch sequence DETAIL recorded by
+   `xi_link_touch_point' from DEVICE, or NULL if it can't be
+   found.  */
+
 static struct xi_touch_point_t *
 xi_find_touch_point (struct xi_device_t *device, int detail)
 {
@@ -24458,12 +24480,48 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              goto XI_OTHER;
            }
 
+         case XI_TouchOwnership:
+           {
+             struct xi_device_t *device;
+             struct xi_touch_point_t *touchpoint;
+             XITouchOwnershipEvent *event;
+
+             /* All grabbing clients have decided to reject ownership
+                of this touch sequence.  */
+
+             event  = (XITouchOwnershipEvent *) xi_event;
+             device = xi_device_from_id (dpyinfo, event->deviceid);
+
+             if (!device || device->use == XIMasterPointer)
+               goto XI_OTHER;
+
+             touchpoint = xi_find_touch_point (device, event->touchid);
+
+             if (!touchpoint)
+               goto XI_OTHER;
+
+             /* As a result, Emacs should complete whatever editing
+                operations result from this touch sequence.  */
+             touchpoint->ownership = TOUCH_OWNERSHIP_SELF;
+           }
+
          case XI_TouchUpdate:
            {
              struct xi_device_t *device, *source;
              struct xi_touch_point_t *touchpoint;
              Lisp_Object arg = Qnil;
 
+             /* If flags & TouchPendingEnd, the touch sequence has
+                already ended, but some grabbing clients remain
+                undecided as to whether they will obtain ownership of
+                the touch sequence.
+
+                Wait for them to make their decision, resulting in
+                TouchOwnership and TouchEnd events being sent.  */
+
+             if (xev->flags & XITouchPendingEnd)
+               goto XI_OTHER;
+
              device = xi_device_from_id (dpyinfo, xev->deviceid);
              source = xi_device_from_id (dpyinfo, xev->sourceid);
              x_display_set_last_user_time (dpyinfo, xev->time,
@@ -24475,7 +24533,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 detached, and master pointers may also represent
                 dependent touch devices.  */
 
-             if (!device)
+             if (!device || device->use == XIMasterPointer)
                goto XI_OTHER;
 
              touchpoint = xi_find_touch_point (device, xev->detail);
@@ -24483,12 +24541,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              if (!touchpoint
                  /* Don't send this event if nothing has changed
                     either.  */
-                 || (touchpoint->x == (int) xev->event_x
-                     && touchpoint->y == (int) xev->event_y))
+                 || (touchpoint->x == lrint (xev->event_x)
+                     && touchpoint->y == lrint (xev->event_y)))
                goto XI_OTHER;
 
-             touchpoint->x = xev->event_x;
-             touchpoint->y = xev->event_y;
+             touchpoint->x = lrint (xev->event_x);
+             touchpoint->y = lrint (xev->event_y);
 
              f = x_window_to_frame (dpyinfo, xev->event);
 
@@ -24502,8 +24560,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                       touchpoint; touchpoint = touchpoint->next)
                    {
                      if (touchpoint->frame == f)
-                       arg = Fcons (list3i (lrint (touchpoint->x),
-                                            lrint (touchpoint->y),
+                       arg = Fcons (list3i (touchpoint->x, touchpoint->y,
                                             lrint (touchpoint->number)),
                                     arg);
                    }
@@ -24520,7 +24577,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
          case XI_TouchEnd:
            {
              struct xi_device_t *device, *source;
-             bool unlinked_p;
+             int state;
 
              device = xi_device_from_id (dpyinfo, xev->deviceid);
              source = xi_device_from_id (dpyinfo, xev->sourceid);
@@ -24536,9 +24593,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              if (!device || device->use == XIMasterPointer)
                goto XI_OTHER;
 
-             unlinked_p = xi_unlink_touch_point (xev->detail, device);
+             state = xi_unlink_touch_point (xev->detail, device);
 
-             if (unlinked_p)
+             if (state)
                {
                  f = x_window_to_frame (dpyinfo, xev->event);
 
@@ -24546,6 +24603,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                    {
                      inev.ie.kind = TOUCHSCREEN_END_EVENT;
                      inev.ie.timestamp = xev->time;
+                     inev.ie.modifiers = state != 2;
 
                      XSETFRAME (inev.ie.frame_or_window, f);
                      XSETINT (inev.ie.x, lrint (xev->event_x));
diff --git a/src/xterm.h b/src/xterm.h
index e7171ba072f..cb477645bfa 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -255,19 +255,71 @@ struct xi_scroll_valuator_t
 
 #ifdef HAVE_XINPUT2_2
 
+/* Enum describing the ownership of a touch point.
+
+   The input extension allows other clients to intercept touch
+   sequences destined for a client window through passively grabbing
+   for touch events on a parent window.
+
+   When a passive touch grab for an XI_TouchBegin event activates, one
+   grabbing client is designated the ``owner'' of the touch sequence
+   started by the grabbed event.  Touch events are then delivered to
+   both the grabbing client and other clients that have selected for
+   touch events on the subwindow.
+
+   The X server will not deliver TouchEnd events to clients other than
+   the owner until one grabbing client decides to take over processing
+   the touch event sequence, or no more grabbing clients remain.
+   Instead, a TouchUpdate event with the TouchPendingEnd flag is sent,
+   and the TouchEnd event is postponed until the decision is made and
+   all XI_TouchOwnership events are sent.
+
+   If the owner decides to take over processing the touch sequence, an
+   XI_TouchEnd event is delivered to all other clients receiving
+   events for the current touch sequence, who are then expected to
+   cancel or undo any actions which have taken place in reaction to
+   events from that sequence.
+
+   If the owner decides to relinquish ownership over the touch
+   sequence, the X server looks for another grabbing client, and
+   transfers touch ownership to that client instead.  Nothing changes
+   from the perspective of clients who have merely selected for events
+   from the subwindow, while an XI_TouchEnd event is delivered to the
+   old owner, and an XI_TouchOwnership event is delivered to the new
+   owner.
+
+   If all grabbing clients reject ownership over the touch sequence,
+   the X server delivers an XI_TouchOwnership event to the client that
+   has selected for touch events on the subwindow, the only client
+   that will receive events for this touch sequence from this time
+   forward.  */
+
+enum xi_touch_ownership
+  {
+    /* Emacs doesn't own this touch sequence.  */
+    TOUCH_OWNERSHIP_NONE,
+
+    /* Emacs owns this touch sequence.  */
+    TOUCH_OWNERSHIP_SELF,
+  };
+
 struct xi_touch_point_t
 {
-  /* The next touch point in this list.  */
-  struct xi_touch_point_t *next;
-
   /* The touchpoint detail.  */
   int number;
 
-  /* The last known X and Y position of the touchpoint.  */
-  double x, y;
+  /* Whether or not Emacs has ``exclusive'' access to this touch
+     point.  */
+  enum xi_touch_ownership ownership;
+
+  /* The last known rounded X and Y positions of the touchpoint.  */
+  int x, y;
 
   /* The frame associated with this touch point.  */
   struct frame *frame;
+
+  /* The next touch point in this list.  */
+  struct xi_touch_point_t *next;
 };
 
 #endif



reply via email to

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