emacs-diffs
[Top][All Lists]
Advanced

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

master 101bbd1392: Add support for pinch gestures to the XI2 build


From: Po Lu
Subject: master 101bbd1392: Add support for pinch gestures to the XI2 build
Date: Sun, 26 Dec 2021 00:55:30 -0500 (EST)

branch: master
commit 101bbd1392077e26e904c70fead7f7d7dce595f7
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Add support for pinch gestures to the XI2 build
    
    * doc/lispref/commands.texi (Misc Events): Document new event
    type `pinch'.
    * etc/NEWS: Announce new event `pinch'.
    * etc/PROBLEMS: Document problems with mismatched libXi
    versions.
    * lisp/face-remap.el (text-scale--pinch-start-scale): New
    variable.
    (text-scale-pinch): New command.
    * src/keyboard.c (make_lispy_event): Handle PINCH_EVENTs.
    (syms_of_keyboard): New symbol `pinch'.
    * src/termhooks.h (enum event_kind): New enum `PINCH_EVENT'.
    * src/xfns.c (setup_xi_event_mask): Add pinch events to event
    mask if available.
    * src/xterm.c (handle_one_xevent): Handle pinch events.
---
 doc/lispref/commands.texi | 21 +++++++++++++++++++++
 etc/NEWS                  |  8 ++++++++
 etc/PROBLEMS              | 12 ++++++++++++
 lisp/face-remap.el        | 24 ++++++++++++++++++++++++
 src/keyboard.c            | 21 +++++++++++++++++++++
 src/termhooks.h           | 15 +++++++++++++++
 src/xfns.c                |  8 ++++++++
 src/xterm.c               | 33 +++++++++++++++++++++++++++++++++
 8 files changed, 142 insertions(+)

diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 9a396f57ef..ccb9752841 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -2085,6 +2085,27 @@ portable code, use the variables 
@code{mouse-wheel-up-event} and
 @code{mouse-wheel-down-event} defined in @file{mwheel.el} to determine
 what event types to expect for the mouse wheel.
 
+@cindex @code{pinch} event
+@item (pinch @var{position} @var{dx} @var{dy} @var{scale} @var{angle})
+This kind of event is generated by the user performing a ``pinch''
+gesture with two fingers on a touchpad.  @var{position} is a mouse
+position list (@pxref{Click Events}) detailing the position of the
+mouse cursor when the event occured, @var{dx} is the distance between
+the horizontal positions of the fingers since the last event in the
+same sequence, @var{dy} is the vertical movement of the fingers since
+the last event in the same sequence, @var{scale} is the division of
+the current distance between the fingers and the distance at the start
+of the sequence, and @var{angle} is the delta in degrees between the
+angles of the fingers in this event and the fingers in the last event
+of the same sequence.
+
+All arguments after @var{position} are floating point numbers.
+
+This event is usually sent as part of a sequence, which begins with
+the user placing two fingers on the touchpad and ends with the user
+removing those fingers.  @var{dx}, @var{dy}, and @var{angle} will be
+@code{0.0} in the first event sent after a sequence begins.
+
 @cindex @code{drag-n-drop} event
 @item (drag-n-drop @var{position} @var{files})
 This kind of event is generated when a group of files is
diff --git a/etc/NEWS b/etc/NEWS
index 39fbd8f6b7..aea6a46c1d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -312,6 +312,9 @@ effectively dragged.
 Customize this option to limit the number of entries in the menu
 "Edit->Paste from Kill Menu".  The default is 60.
 
+---
+** Performing a pinch gesture on a touchpad now increases the text scale.
+
 ** show-paren-mode
 
 +++
@@ -885,6 +888,11 @@ This allows setting a minimum display width for a region 
of text.
 This event is sent whenever the user's finger moves off the mouse
 wheel on some mice, or when the user's finger moves off the touchpad.
 
++++
+** New event type 'pinch'.
+This event is sent when a user peforms a two-finger pinch gesture on a
+touchpad.
+
 ** Keymaps and key definitions
 
 +++
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 230313d224..07ae98885d 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -1681,6 +1681,18 @@ This happens on the proprietary X server ASTEC-X when 
the number of
 monitors is changed after the server has started.  A workaround is to
 restart the X server after the monitor configuration has been changed.
 
+*** Touchpad gestures don't work and emit warning messages.
+
+When pinching or swiping on your touchpad, you might see a warning
+message that looks like:
+
+  XInputWireToCookie: Unknown generic event. type 28
+
+This happens when your XInput headers support XInput 2.4, but the
+actual version of libXi installed does not.  The solution is to
+upgrade your libXi binaries to libXi 1.8.0 or later, to correspond
+with your XInput headers.
+
 * Runtime problems on character terminals
 
 *** With X forwarding, mouse highlighting can make Emacs slow.
diff --git a/lisp/face-remap.el b/lisp/face-remap.el
index 50302b9682..8507f7e8e3 100644
--- a/lisp/face-remap.el
+++ b/lisp/face-remap.el
@@ -390,6 +390,30 @@ a top-level keymap, `text-scale-increase' or
                (lambda () (interactive) (text-scale-adjust (abs inc))))))
          map))))) ;; )
 
+(defvar-local text-scale--pinch-start-scale 0
+  "The text scale at the start of a pinch sequence.")
+
+;;;###autoload (define-key global-map [pinch] 'text-scale-pinch)
+;;;###autoload
+(defun text-scale-pinch (event)
+  "Adjust the height of the default face by the scale in EVENT."
+  (interactive "e")
+  (let ((window (posn-window (nth 1 event)))
+        (scale (nth 4 event))
+        (dx (nth 2 event))
+        (dy (nth 3 event))
+        (angle (nth 5 event)))
+    (with-selected-window window
+      (when (and (zerop dx)
+                 (zerop dy)
+                 (zerop angle)
+                 (equal scale 1.0))
+        (setq text-scale--pinch-start-scale
+              (if text-scale-mode text-scale-mode-amount 0)))
+      (text-scale-set
+       (+ text-scale--pinch-start-scale
+          (round (log scale text-scale-mode-step)))))))
+
 
 ;; ----------------------------------------------------------------
 ;; buffer-face-mode
diff --git a/src/keyboard.c b/src/keyboard.c
index 821a1b576b..5453811406 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4466,6 +4466,7 @@ static Lisp_Object func_key_syms;
 static Lisp_Object mouse_syms;
 static Lisp_Object wheel_syms;
 static Lisp_Object drag_n_drop_syms;
+static Lisp_Object pinch_syms;
 
 /* This is a list of keysym codes for special "accent" characters.
    It parallels lispy_accent_keys.  */
@@ -6032,6 +6033,22 @@ make_lispy_event (struct input_event *event)
                      Fcons (id, position));
       }
 
+    case PINCH_EVENT:
+      {
+       Lisp_Object x, y, position;
+       struct frame *f = XFRAME (event->frame_or_window);
+
+       x = event->x;
+       y = event->y;
+
+       position = make_lispy_position (f, x, y, event->timestamp);
+
+       return Fcons (modify_event_symbol (0, event->modifiers, Qpinch,
+                                          Qnil, (const char *[]) {"pinch"},
+                                          &pinch_syms, 1),
+                     Fcons (position, event->arg));
+      }
+
     case TOUCHSCREEN_UPDATE_EVENT:
       {
        Lisp_Object x, y, id, position, tem, it, evt;
@@ -11970,6 +11987,9 @@ syms_of_keyboard (void)
   drag_n_drop_syms = Qnil;
   staticpro (&drag_n_drop_syms);
 
+  pinch_syms = Qnil;
+  staticpro (&pinch_syms);
+
   unread_switch_frame = Qnil;
   staticpro (&unread_switch_frame);
 
@@ -12309,6 +12329,7 @@ See also `pre-command-hook'.  */);
   DEFSYM (Qtouchscreen_begin, "touchscreen-begin");
   DEFSYM (Qtouchscreen_end, "touchscreen-end");
   DEFSYM (Qtouchscreen_update, "touchscreen-update");
+  DEFSYM (Qpinch, "pinch");
   Fset (Qecho_area_clear_hook, Qnil);
 
   DEFVAR_LISP ("lucid-menu-bar-dirty-flag", Vlucid_menu_bar_dirty_flag,
diff --git a/src/termhooks.h b/src/termhooks.h
index 9f22187b84..1c89a4d306 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -293,6 +293,21 @@ enum event_kind
   , TOUCHSCREEN_UPDATE_EVENT
   , TOUCHSCREEN_BEGIN_EVENT
   , TOUCHSCREEN_END_EVENT
+
+  /* In a PINCH_EVENT, X and Y are the position of the pointer
+     relative to the top-left corner of the frame, and arg is a list
+     of (DX DY SCALE ANGLE), in which:
+
+       - DX and DY are the difference between the positions of the
+         fingers comprising the current gesture and the last such
+         gesture in the same sequence.
+       - SCALE is the division of the current distance between the
+         fingers and the distance at the start of the gesture.
+       - DELTA-ANGLE is the delta between the angle of the current
+         event and the last event in the same sequence, in degrees.  A
+         positive delta represents a change clockwise, and a negative
+         delta represents a change counter-clockwise.  */
+  , PINCH_EVENT
 };
 
 /* Bit width of an enum event_kind tag at the start of structs and unions.  */
diff --git a/src/xfns.c b/src/xfns.c
index 126e837b43..2b134716bd 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2961,6 +2961,14 @@ setup_xi_event_mask (struct frame *f)
       XISetMask (m, XI_TouchBegin);
       XISetMask (m, XI_TouchUpdate);
       XISetMask (m, XI_TouchEnd);
+#ifdef XI_GesturePinchBegin
+      if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4)
+       {
+         XISetMask (m, XI_GesturePinchBegin);
+         XISetMask (m, XI_GesturePinchUpdate);
+         XISetMask (m, XI_GesturePinchEnd);
+       }
+#endif
     }
 #endif
   XISelectEvents (FRAME_X_DISPLAY (f),
diff --git a/src/xterm.c b/src/xterm.c
index 6be7e2e9f9..12c14e5e4f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -11044,6 +11044,39 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
              goto XI_OTHER;
            }
+#endif
+#ifdef XI_GesturePinchBegin
+         case XI_GesturePinchBegin:
+         case XI_GesturePinchUpdate:
+           {
+             XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
+             struct xi_device_t *device = xi_device_from_id (dpyinfo, 
pev->deviceid);
+
+             if (!device || !device->master_p)
+               goto XI_OTHER;
+
+             any = x_any_window_to_frame (dpyinfo, pev->event);
+             if (any)
+               {
+                 inev.ie.kind = PINCH_EVENT;
+                 inev.ie.modifiers = x_x_to_emacs_modifiers 
(FRAME_DISPLAY_INFO (any),
+                                                             
pev->mods.effective);
+                 XSETINT (inev.ie.x, lrint (pev->event_x));
+                 XSETINT (inev.ie.y, lrint (pev->event_y));
+                 XSETFRAME (inev.ie.frame_or_window, any);
+                 inev.ie.arg = list4 (make_float (pev->delta_x),
+                                      make_float (pev->delta_y),
+                                      make_float (pev->scale),
+                                      make_float (pev->delta_angle));
+               }
+             /* Once again GTK seems to crash when confronted by
+                events it doesn't understand.  */
+             *finish = X_EVENT_DROP;
+             goto XI_OTHER;
+           }
+         case XI_GesturePinchEnd:
+           *finish = X_EVENT_DROP;
+           goto XI_OTHER;
 #endif
          default:
            goto XI_OTHER;



reply via email to

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