[epiphany] Add touchpad gesture



commit 1bb0557344b1fb467353f660d83fb6a870673e30
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Fri Jan 11 12:19:53 2019 +0100

    Add touchpad gesture
    
    Add 3-finger swipe gesture to navigate back and forward
    
    Fixes: https://gitlab.gnome.org/GNOME/epiphany/issues/435

 src/ephy-touchpad-gesture-controller.c | 205 +++++++++++++++++++++++++++++++++
 src/ephy-touchpad-gesture-controller.h |  35 ++++++
 src/ephy-window.c                      |   4 +
 src/meson.build                        |   1 +
 4 files changed, 245 insertions(+)
---
diff --git a/src/ephy-touchpad-gesture-controller.c b/src/ephy-touchpad-gesture-controller.c
new file mode 100644
index 000000000..e7068fbf7
--- /dev/null
+++ b/src/ephy-touchpad-gesture-controller.c
@@ -0,0 +1,205 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2019 Jan-Michael Brummer
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ephy-embed.h"
+#include "ephy-touchpad-gesture-controller.h"
+#include "ephy-prefs.h"
+#include "ephy-settings.h"
+#include "ephy-window.h"
+
+#include <math.h>
+#include <gtk/gtk.h>
+
+#define NUM_SEQUENCES 2
+
+typedef enum {
+  TOUCHPAD_DIRECTION_UNKNOWN = 0,
+  TOUCHPAD_DIRECTION_RIGHT,
+  TOUCHPAD_DIRECTION_LEFT,
+  TOUCHPAD_DIRECTION_DOWN,
+  TOUCHPAD_DIRECTION_UP,
+} TouchpadDirection;
+
+struct _EphyTouchpadGestureController {
+  GObject parent_instance;
+
+  GtkGesture *gesture;
+  EphyWindow *window;
+
+  TouchpadDirection direction;
+};
+
+enum {
+  PROP_0,
+  PROP_WINDOW,
+  LAST_PROP
+};
+
+static GParamSpec *obj_properties[LAST_PROP];
+
+G_DEFINE_TYPE (EphyTouchpadGestureController, ephy_touchpad_gesture_controller, G_TYPE_OBJECT)
+
+static void
+ephy_touchpad_gesture_controller_set_property (GObject      *object,
+                                               guint         prop_id,
+                                               const GValue *value,
+                                               GParamSpec   *pspec)
+{
+  EphyTouchpadGestureController *self = EPHY_TOUCHPAD_GESTURE_CONTROLLER (object);
+
+  switch (prop_id) {
+    case PROP_WINDOW:
+      self->window = g_value_get_object (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+ephy_touchpad_gesture_controller_get_property (GObject    *object,
+                                               guint       prop_id,
+                                               GValue     *value,
+                                               GParamSpec *pspec)
+{
+  EphyTouchpadGestureController *self = EPHY_TOUCHPAD_GESTURE_CONTROLLER (object);
+
+  switch (prop_id) {
+    case PROP_WINDOW:
+      g_value_set_object (value, self->window);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+ephy_touchpad_gesture_controller_pan (GtkGesturePan  *gesture,
+                                      GtkPanDirection direction,
+                                      gdouble         offset,
+                                      gpointer        user_data)
+{
+  EphyTouchpadGestureController *self = EPHY_TOUCHPAD_GESTURE_CONTROLLER (user_data);
+
+  if (direction == GTK_PAN_DIRECTION_LEFT)
+    self->direction = TOUCHPAD_DIRECTION_LEFT;
+  else if (direction == GTK_PAN_DIRECTION_RIGHT)
+    self->direction = TOUCHPAD_DIRECTION_RIGHT;
+}
+
+static void
+ephy_touchpad_gesture_controller_drag_end (GtkGestureDrag *drag,
+                                           gdouble         x,
+                                           gdouble         y,
+                                           gpointer        user_data)
+{
+  EphyTouchpadGestureController *self = EPHY_TOUCHPAD_GESTURE_CONTROLLER (user_data);
+  GActionGroup *action_group_toolbar = gtk_widget_get_action_group (GTK_WIDGET (self->window), "toolbar");
+  GAction *action;
+
+  if (self->direction == TOUCHPAD_DIRECTION_RIGHT) {
+    /* Nav forward */
+    action = g_action_map_lookup_action (G_ACTION_MAP (action_group_toolbar), "navigation-forward");
+    g_action_activate (action, NULL);
+  } else if (self->direction == TOUCHPAD_DIRECTION_LEFT) {
+    /* Nav back */
+    action = g_action_map_lookup_action (G_ACTION_MAP (action_group_toolbar), "navigation-back");
+    g_action_activate (action, NULL);
+  }
+
+  self->direction = TOUCHPAD_DIRECTION_UNKNOWN;
+}
+
+
+static void
+ephy_touchpad_gesture_controller_init (EphyTouchpadGestureController *self)
+{
+}
+
+static void
+ephy_touchpad_gesture_controller_dispose (GObject *object)
+{
+  EphyTouchpadGestureController *self = EPHY_TOUCHPAD_GESTURE_CONTROLLER (object);
+
+  if (self->gesture != NULL) {
+    g_signal_handlers_disconnect_by_func (self->gesture,
+                                          G_CALLBACK (ephy_touchpad_gesture_controller_pan),
+                                          self);
+    g_signal_handlers_disconnect_by_func (self->gesture,
+                                          G_CALLBACK (ephy_touchpad_gesture_controller_drag_end),
+                                          self);
+  }
+
+  g_clear_object (&self->gesture);
+
+  G_OBJECT_CLASS (ephy_touchpad_gesture_controller_parent_class)->dispose (object);
+}
+
+static void
+ephy_touchpad_gesture_controller_constructed (GObject *object)
+{
+  EphyTouchpadGestureController *self = EPHY_TOUCHPAD_GESTURE_CONTROLLER (object);
+
+  gtk_widget_add_events (GTK_WIDGET (self->window), GDK_TOUCHPAD_GESTURE_MASK);
+  self->direction = TOUCHPAD_DIRECTION_UNKNOWN;
+  self->gesture = g_object_new (GTK_TYPE_GESTURE_PAN,
+                                "widget", GTK_WIDGET (self->window),
+                                "orientation", GTK_ORIENTATION_HORIZONTAL,
+                                "n-points", 3,
+                                NULL);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (self->gesture),
+                                              GTK_PHASE_CAPTURE);
+  g_signal_connect_object (self->gesture, "pan", G_CALLBACK (ephy_touchpad_gesture_controller_pan), self, 0);
+  g_signal_connect_object (self->gesture, "drag-end", G_CALLBACK 
(ephy_touchpad_gesture_controller_drag_end), self, 0);
+}
+
+static void
+ephy_touchpad_gesture_controller_class_init (EphyTouchpadGestureControllerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = ephy_touchpad_gesture_controller_dispose;
+  object_class->constructed = ephy_touchpad_gesture_controller_constructed;
+
+  /* class creation */
+  object_class->set_property = ephy_touchpad_gesture_controller_set_property;
+  object_class->get_property = ephy_touchpad_gesture_controller_get_property;
+
+  obj_properties[PROP_WINDOW] =
+    g_param_spec_object ("window",
+                         "window",
+                         "window",
+                         EPHY_TYPE_WINDOW,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (object_class, LAST_PROP, obj_properties);
+}
+
+EphyTouchpadGestureController *
+ephy_touchpad_gesture_controller_new (EphyWindow *window)
+{
+  return g_object_new (EPHY_TYPE_TOUCHPAD_GESTURE_CONTROLLER,
+                       "window", window,
+                       NULL);
+}
diff --git a/src/ephy-touchpad-gesture-controller.h b/src/ephy-touchpad-gesture-controller.h
new file mode 100644
index 000000000..c35636c0d
--- /dev/null
+++ b/src/ephy-touchpad-gesture-controller.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2019 Jan-Michael Brummer
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "ephy-window.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_TOUCHPAD_GESTURE_CONTROLLER (ephy_touchpad_gesture_controller_get_type ())
+
+G_DECLARE_FINAL_TYPE (EphyTouchpadGestureController, ephy_touchpad_gesture_controller, EPHY, 
TOUCHPAD_GESTURE_CONTROLLER, GObject);
+
+EphyTouchpadGestureController *ephy_touchpad_gesture_controller_new (EphyWindow *window);
+
+G_END_DECLS
diff --git a/src/ephy-window.c b/src/ephy-window.c
index b88327bb0..7c0774b37 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -49,6 +49,7 @@
 #include "ephy-shell.h"
 #include "ephy-title-box.h"
 #include "ephy-title-widget.h"
+#include "ephy-touchpad-gesture-controller.h"
 #include "ephy-type-builtins.h"
 #include "ephy-web-app-utils.h"
 #include "ephy-web-view.h"
@@ -154,6 +155,7 @@ struct _EphyWindow {
   EphyLocationController *location_controller;
   guint modified_forms_timeout_id;
   EphyMouseGestureController *mouse_gesture_controller;
+  EphyTouchpadGestureController *touchpad_gesture_controller;
 
   gboolean show_fullscreen_header_bar;
 
@@ -2958,6 +2960,7 @@ ephy_window_dispose (GObject *object)
     g_clear_object (&window->bookmarks_manager);
     g_clear_object (&window->hit_test_result);
     g_clear_object (&window->mouse_gesture_controller);
+    g_clear_object (&window->touchpad_gesture_controller);
 
     g_clear_handle_id (&window->modified_forms_timeout_id, g_source_remove);
 
@@ -3500,6 +3503,7 @@ ephy_window_constructed (GObject *object)
   }
 
   window->mouse_gesture_controller = ephy_mouse_gesture_controller_new (window);
+  window->touchpad_gesture_controller = ephy_touchpad_gesture_controller_new (window);
 
   ephy_window_set_chrome (window, chrome);
 }
diff --git a/src/meson.build b/src/meson.build
index c346172ef..bcb56dac7 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -38,6 +38,7 @@ libephymain_sources = [
   'ephy-session.c',
   'ephy-shell.c',
   'ephy-suggestion-model.c',
+  'ephy-touchpad-gesture-controller.c',
   'ephy-window.c',
   'passwords-dialog.c',
   'popup-commands.c',


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