[gtk/gtk-3-24: 1/2] wayland: Add support for gtk_surface1_titlebar_gesture()




commit 45ba6e9329798f9d24c9220d0583c1d01c2f8562
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Sep 30 22:38:03 2022 +0200

    wayland: Add support for gtk_surface1_titlebar_gesture()
    
    This adds a private GDK API that GTK calls using GDK_PRIVATE_CALL(). It
    is more or less a copy of the GdkSurface::titlebar_gesture() API, and
    achieves the same. If the backend or compositor doesn't support titlebar
    gestures, the existing path is used as a fallback.

 gdk/gdk-private.c                  |  3 +-
 gdk/gdk-private.h                  |  3 ++
 gdk/gdkinternals.h                 |  3 ++
 gdk/gdkwindow.c                    | 17 +++++++++++
 gdk/gdkwindowimpl.h                | 10 +++++++
 gdk/wayland/gdkdisplay-wayland.c   |  2 +-
 gdk/wayland/gdkwindow-wayland.c    | 60 ++++++++++++++++++++++++++++++++++++++
 gdk/wayland/protocol/gtk-shell.xml | 21 +++++++++++--
 gtk/gtkwindow.c                    | 25 ++++++++++++++++
 9 files changed, 140 insertions(+), 4 deletions(-)
---
diff --git a/gdk/gdk-private.c b/gdk/gdk-private.c
index 750edcd374..0a7438162c 100644
--- a/gdk/gdk-private.c
+++ b/gdk/gdk-private.c
@@ -22,7 +22,8 @@ gdk__private__ (void)
     gdk_get_desktop_autostart_id,
     gdk_profiler_is_running,
     gdk_profiler_start,
-    gdk_profiler_stop
+    gdk_profiler_stop,
+    gdk_window_titlebar_gesture,
   };
 
   return &table;
diff --git a/gdk/gdk-private.h b/gdk/gdk-private.h
index c71abe4634..4b616370b7 100644
--- a/gdk/gdk-private.h
+++ b/gdk/gdk-private.h
@@ -66,6 +66,9 @@ typedef struct {
   gboolean (* gdk_profiler_is_running) (void);
   void     (* gdk_profiler_start)      (int fd);
   void     (* gdk_profiler_stop)       (void);
+
+  gboolean (* gdk_window_titlebar_gesture) (GdkWindow          *window,
+                                            GdkTitlebarGesture  gesture);
 } GdkPrivateVTable;
 
 GDK_AVAILABLE_IN_ALL
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index e2c1d10c9c..468d328c22 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -557,6 +557,9 @@ void _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_win
 gboolean    _gdk_window_has_impl (GdkWindow *window);
 GdkWindow * _gdk_window_get_impl_window (GdkWindow *window);
 
+gboolean gdk_window_titlebar_gesture (GdkWindow          *window,
+                                      GdkTitlebarGesture  gesture);
+
 /*****************************
  * offscreen window routines *
  *****************************/
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 2d0ed0f963..727b0cf1f4 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -11998,3 +11998,20 @@ gdk_window_show_window_menu (GdkWindow *window,
   else
     return FALSE;
 }
+
+gboolean
+gdk_window_titlebar_gesture (GdkWindow          *window,
+                             GdkTitlebarGesture  gesture)
+{
+  GdkWindowImplClass *impl_class;
+
+  g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+  g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), FALSE);
+
+  impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
+
+  if (impl_class->titlebar_gesture)
+    return impl_class->titlebar_gesture (window, gesture);
+  else
+    return FALSE;
+}
diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h
index c72472372d..1993e12083 100644
--- a/gdk/gdkwindowimpl.h
+++ b/gdk/gdkwindowimpl.h
@@ -30,6 +30,13 @@
 
 G_BEGIN_DECLS
 
+typedef enum
+{
+  GDK_TITLEBAR_GESTURE_DOUBLE_CLICK   = 1,
+  GDK_TITLEBAR_GESTURE_RIGHT_CLICK    = 2,
+  GDK_TITLEBAR_GESTURE_MIDDLE_CLICK   = 3
+} GdkTitlebarGesture;
+
 #define GDK_TYPE_WINDOW_IMPL           (gdk_window_impl_get_type ())
 #define GDK_WINDOW_IMPL(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL, 
GdkWindowImpl))
 #define GDK_WINDOW_IMPL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL, 
GdkWindowImplClass))
@@ -315,6 +322,9 @@ struct _GdkWindowImplClass
                                                const cairo_region_t *region);
   void               (* destroy_draw_context) (GdkWindow            *window,
                                                GdkDrawingContext    *context);
+
+  gboolean (* titlebar_gesture) (GdkWindow          *window,
+                                 GdkTitlebarGesture  gesture);
 };
 
 /* Interface Functions */
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index 20f662dd21..e91490f2e5 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -84,7 +84,7 @@
 
 #define MIN_SYSTEM_BELL_DELAY_MS 20
 
-#define GTK_SHELL1_VERSION       4
+#define GTK_SHELL1_VERSION       5
 
 static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland);
 
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index 1ae4a4df87..30c0898ae6 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -4795,6 +4795,65 @@ gdk_wayland_window_show_window_menu (GdkWindow *window,
   return TRUE;
 }
 
+static gboolean
+translate_gesture (GdkTitlebarGesture         gesture,
+                   enum gtk_surface1_gesture *out_gesture)
+{
+  switch (gesture)
+    {
+    case GDK_TITLEBAR_GESTURE_DOUBLE_CLICK:
+      *out_gesture = GTK_SURFACE1_GESTURE_DOUBLE_CLICK;
+      break;
+
+    case GDK_TITLEBAR_GESTURE_RIGHT_CLICK:
+      *out_gesture = GTK_SURFACE1_GESTURE_RIGHT_CLICK;
+      break;
+
+    case GDK_TITLEBAR_GESTURE_MIDDLE_CLICK:
+      *out_gesture = GTK_SURFACE1_GESTURE_MIDDLE_CLICK;
+      break;
+
+    default:
+      g_warning ("Not handling unknown titlebar gesture %u", gesture);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static gboolean
+gdk_wayland_window_titlebar_gesture (GdkWindow          *window,
+                                     GdkTitlebarGesture  gesture)
+{
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  struct gtk_surface1 *gtk_surface = impl->display_server.gtk_surface;
+  enum gtk_surface1_gesture gtk_gesture;
+  GdkSeat *seat;
+  struct wl_seat *wl_seat;
+  uint32_t serial;
+
+  if (!gtk_surface)
+    return FALSE;
+
+  if (gtk_surface1_get_version (gtk_surface) < GTK_SURFACE1_TITLEBAR_GESTURE_SINCE_VERSION)
+    return FALSE;
+
+  if (!translate_gesture (gesture, &gtk_gesture))
+    return FALSE;
+
+  seat = gdk_display_get_default_seat (gdk_window_get_display (window));
+  wl_seat = gdk_wayland_seat_get_wl_seat (seat);
+
+  serial = _gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL);
+
+  gtk_surface1_titlebar_gesture (impl->display_server.gtk_surface,
+                                 serial,
+                                 wl_seat,
+                                 gtk_gesture);
+
+  return TRUE;
+}
+
 static void
 _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
 {
@@ -4886,6 +4945,7 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
   impl_class->show_window_menu = gdk_wayland_window_show_window_menu;
   impl_class->create_gl_context = gdk_wayland_window_create_gl_context;
   impl_class->invalidate_for_new_frame = gdk_wayland_window_invalidate_for_new_frame;
+  impl_class->titlebar_gesture = gdk_wayland_window_titlebar_gesture;
 
   signals[COMMITTED] = g_signal_new ("committed",
                                      G_TYPE_FROM_CLASS (object_class),
diff --git a/gdk/wayland/protocol/gtk-shell.xml b/gdk/wayland/protocol/gtk-shell.xml
index 1aab593c42..a8d51c65d3 100644
--- a/gdk/wayland/protocol/gtk-shell.xml
+++ b/gdk/wayland/protocol/gtk-shell.xml
@@ -1,6 +1,6 @@
 <protocol name="gtk">
 
-  <interface name="gtk_shell1" version="4">
+  <interface name="gtk_shell1" version="5">
     <description summary="gtk specific extensions">
       gtk_shell is a protocol extension providing additional features for
       clients implementing it.
@@ -35,7 +35,7 @@
     </request>
   </interface>
 
-  <interface name="gtk_surface1" version="4">
+  <interface name="gtk_surface1" version="5">
     <request name="set_dbus_properties">
       <arg name="application_id" type="string" allow-null="true"/>
       <arg name="app_menu_path" type="string" allow-null="true"/>
@@ -85,6 +85,23 @@
 
     <!-- Version 4 additions -->
     <request name="release" type="destructor" since="4"/>
+
+    <!-- Version 5 additions -->
+    <enum name="gesture" since="5">
+      <entry name="double_click" value="1"/>
+      <entry name="right_click" value="2"/>
+      <entry name="middle_click" value="3"/>
+    </enum>
+
+    <enum name="error" since="5">
+      <entry name="invalid_gesture" value="0"/>
+    </enum>
+
+    <request name="titlebar_gesture" since="5">
+      <arg name="serial" type="uint"/>
+      <arg name="seat" type="object" interface="wl_seat"/>
+      <arg name="gesture" type="uint" enum="gesture"/>
+    </request>
   </interface>
 
 </protocol>
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 8df1c8e861..5478e893eb 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -1383,10 +1383,34 @@ gtk_window_titlebar_action (GtkWindow      *window,
                             guint           button,
                             gint            n_press)
 {
+  GdkTitlebarGesture gesture = 0;
+  GdkWindow *gdk_window;
   GtkSettings *settings;
   gchar *action = NULL;
   gboolean retval = TRUE;
 
+  switch (button)
+    {
+    case GDK_BUTTON_PRIMARY:
+      if (n_press == 2)
+        gesture = GDK_TITLEBAR_GESTURE_DOUBLE_CLICK;
+      break;
+    case GDK_BUTTON_MIDDLE:
+      gesture = GDK_TITLEBAR_GESTURE_MIDDLE_CLICK;
+      break;
+    case GDK_BUTTON_SECONDARY:
+      gesture = GDK_TITLEBAR_GESTURE_RIGHT_CLICK;
+      break;
+    }
+
+  gdk_window = _gtk_widget_get_window (GTK_WIDGET (window));
+  if (gesture &&
+      GDK_PRIVATE_CALL (gdk_window_titlebar_gesture (gdk_window, gesture)))
+    {
+      retval = TRUE;
+      goto out;
+    }
+
   settings = gtk_widget_get_settings (GTK_WIDGET (window));
   switch (button)
     {
@@ -1432,6 +1456,7 @@ gtk_window_titlebar_action (GtkWindow      *window,
 
   g_free (action);
 
+out:
   return retval;
 }
 


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