summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2021-12-26 13:47:23 +0800
committerPo Lu <luangruo@yahoo.com>2021-12-26 13:55:05 +0800
commit101bbd1392077e26e904c70fead7f7d7dce595f7 (patch)
tree1947fe12c50d8d53588b55329618ba1a1009c1db
parent4e2058aec33db5097edd17da8fe08bea373fd8bc (diff)
downloademacs-101bbd1392077e26e904c70fead7f7d7dce595f7.tar.gz
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.
-rw-r--r--doc/lispref/commands.texi21
-rw-r--r--etc/NEWS8
-rw-r--r--etc/PROBLEMS12
-rw-r--r--lisp/face-remap.el24
-rw-r--r--src/keyboard.c21
-rw-r--r--src/termhooks.h15
-rw-r--r--src/xfns.c8
-rw-r--r--src/xterm.c33
8 files changed, 142 insertions, 0 deletions
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 9a396f57ef0..ccb97528418 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 39fbd8f6b77..aea6a46c1d3 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 230313d2247..07ae98885d5 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 50302b9682c..8507f7e8e36 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 821a1b576be..54538114065 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 9f22187b841..1c89a4d306f 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 126e837b43c..2b134716bd7 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 6be7e2e9f95..12c14e5e4f1 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -11045,6 +11045,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;
}