emacs-diffs
[Top][All Lists]
Advanced

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

master 337005af0b: Add pinch event support to xwidgets


From: Po Lu
Subject: master 337005af0b: Add pinch event support to xwidgets
Date: Thu, 30 Dec 2021 21:10:06 -0500 (EST)

branch: master
commit 337005af0bf21244cabdc0b2a2c11d0095ecd0fa
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Add pinch event support to xwidgets
    
    * src/xterm.c (handle_one_xevent): Pass through pinch events to
    xwidgets and provide root coordinates when translating motion
    events.
    * src/xwidget.c (xwidget_motion_notify): Use provided root
    window coordinates.
    (xwidget_pinch): New function.
    * src/xwidget.h (xwidget_motion_notify): Update prototype.
    (xwidget_pinch): New function prototype.
---
 src/xterm.c   | 27 ++++++++++++++++++---
 src/xwidget.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/xwidget.h |  9 ++++++-
 3 files changed, 106 insertions(+), 7 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index afac07e7ff..d3d85a9e0d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10268,7 +10268,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                                                && xv_total_y == 0.0));
                  else
                    xwidget_motion_notify (xv, xev->event_x, xev->event_y,
-                                          state, xev->time);
+                                          xev->root_x, xev->root_y, state,
+                                          xev->time);
 
                  goto XI_OTHER;
                }
@@ -11112,6 +11113,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              if (!device || !device->master_p)
                goto XI_OTHER;
 
+#ifdef HAVE_XWIDGETS
+             struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
+
+             if (xvw)
+               {
+                 *finish = X_EVENT_DROP;
+                 xwidget_pinch (xvw, pev);
+                 goto XI_OTHER;
+               }
+#endif
+
              any = x_any_window_to_frame (dpyinfo, pev->event);
              if (any)
                {
@@ -11133,8 +11145,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              goto XI_OTHER;
            }
          case XI_GesturePinchEnd:
-           *finish = X_EVENT_DROP;
-           goto XI_OTHER;
+           {
+#if defined HAVE_XWIDGETS && HAVE_USABLE_XI_GESTURE_PINCH_EVENT
+             XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
+             struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
+
+             if (xvw)
+               xwidget_pinch (xvw, pev);
+#endif
+             *finish = X_EVENT_DROP;
+             goto XI_OTHER;
+           }
 #endif
          default:
            goto XI_OTHER;
diff --git a/src/xwidget.c b/src/xwidget.c
index 05997bb9d5..4f14152833 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -1162,7 +1162,9 @@ xwidget_button (struct xwidget_view *view,
 #ifdef HAVE_XINPUT2
 void
 xwidget_motion_notify (struct xwidget_view *view,
-                      double x, double y, uint state, Time time)
+                      double x, double y,
+                      double root_x, double root_y,
+                      uint state, Time time)
 {
   GdkEvent *xg_event;
   GtkWidget *target;
@@ -1190,8 +1192,8 @@ xwidget_motion_notify (struct xwidget_view *view,
   xg_event->any.window = gtk_widget_get_window (target);
   xg_event->motion.x = target_x;
   xg_event->motion.y = target_y;
-  xg_event->motion.x_root = lrint (x);
-  xg_event->motion.y_root = lrint (y);
+  xg_event->motion.x_root = root_x;
+  xg_event->motion.y_root = root_y;
   xg_event->motion.time = time;
   xg_event->motion.state = state;
   xg_event->motion.device = find_suitable_pointer (view->frame);
@@ -1248,6 +1250,70 @@ xwidget_scroll (struct xwidget_view *view, double x, 
double y,
   gtk_main_do_event (xg_event);
   gdk_event_free (xg_event);
 }
+
+#ifdef HAVE_USABLE_XI_GESTURE_PINCH_EVENT
+void
+xwidget_pinch (struct xwidget_view *view, XIGesturePinchEvent *xev)
+{
+#if GTK_CHECK_VERSION (3, 18, 0)
+  GdkEvent *xg_event;
+  GtkWidget *target;
+  struct xwidget *model = XXWIDGET (view->model);
+  int target_x, target_y;
+  double x = xev->event_x;
+  double y = xev->event_y;
+
+  if (NILP (model->buffer))
+    return;
+
+  record_osr_embedder (view);
+
+  target = find_widget_at_pos (model->widgetwindow_osr,
+                              lrint (x + view->clip_left),
+                              lrint (y + view->clip_top),
+                              &target_x, &target_y);
+
+  if (!target)
+    {
+      target_x = lrint (x);
+      target_y = lrint (y);
+      target = model->widget_osr;
+    }
+
+  xg_event = gdk_event_new (GDK_TOUCHPAD_PINCH);
+  xg_event->any.window = gtk_widget_get_window (target);
+  xg_event->touchpad_pinch.x = target_x;
+  xg_event->touchpad_pinch.y = target_y;
+  xg_event->touchpad_pinch.dx = xev->delta_x;
+  xg_event->touchpad_pinch.dy = xev->delta_y;
+  xg_event->touchpad_pinch.angle_delta = xev->delta_angle;
+  xg_event->touchpad_pinch.scale = xev->scale;
+  xg_event->touchpad_pinch.x_root = xev->root_x;
+  xg_event->touchpad_pinch.y_root = xev->root_y;
+  xg_event->touchpad_pinch.state = xev->mods.effective;
+  xg_event->touchpad_pinch.n_fingers = 2;
+
+  switch (xev->evtype)
+    {
+    case XI_GesturePinchBegin:
+      xg_event->touchpad_pinch.phase = GDK_TOUCHPAD_GESTURE_PHASE_BEGIN;
+      break;
+    case XI_GesturePinchUpdate:
+      xg_event->touchpad_pinch.phase = GDK_TOUCHPAD_GESTURE_PHASE_UPDATE;
+      break;
+    case XI_GesturePinchEnd:
+      xg_event->touchpad_pinch.phase = GDK_TOUCHPAD_GESTURE_PHASE_END;
+      break;
+    }
+
+  gdk_event_set_device (xg_event, find_suitable_pointer (view->frame));
+
+  g_object_ref (xg_event->any.window);
+  gtk_main_do_event (xg_event);
+  gdk_event_free (xg_event);
+#endif
+}
+#endif
 #endif
 
 #ifdef HAVE_XINPUT2
@@ -2180,6 +2246,11 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
          XISetMask (m, XI_ButtonRelease);
          XISetMask (m, XI_Enter);
          XISetMask (m, XI_Leave);
+#ifdef XI_GesturePinchBegin
+         XISetMask (m, XI_GesturePinchBegin);
+         XISetMask (m, XI_GesturePinchUpdate);
+         XISetMask (m, XI_GesturePinchEnd);
+#endif
          XISelectEvents (xv->dpy, xv->wdesc, &mask, 1);
        }
 #endif
diff --git a/src/xwidget.h b/src/xwidget.h
index ab60b9ed34..0c6ed1a381 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -43,6 +43,10 @@ struct window;
 #import "nsxwidget.h"
 #endif
 
+#ifdef HAVE_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
+
 struct xwidget
 {
   union vectorlike_header header;
@@ -210,9 +214,12 @@ extern void xwidget_motion_or_crossing (struct 
xwidget_view *,
                                        const XEvent *);
 #ifdef HAVE_XINPUT2
 extern void xwidget_motion_notify (struct xwidget_view *, double,
-                                  double, uint, Time);
+                                  double, double, double, uint, Time);
 extern void xwidget_scroll (struct xwidget_view *, double, double,
                             double, double, uint, Time, bool);
+#ifdef HAVE_USABLE_XI_GESTURE_PINCH_EVENT
+extern void xwidget_pinch (struct xwidget_view *, XIGesturePinchEvent *);
+#endif
 #endif
 #endif
 #else



reply via email to

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