summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-08-02 01:14:08 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-08-02 01:14:08 +0000
commit2a528df977654fa84d637ff84f529400d7cba1d8 (patch)
tree47cd5889f4a68c5c21c8c261ac5fe063afbcc634
parent84684bd56e48e7263790622249b725931e479b5e (diff)
parent23e79d2eb2bc9aa4b630ab2dee4b38a8fc70af5c (diff)
downloadgtk+-2a528df977654fa84d637ff84f529400d7cba1d8.tar.gz
Merge branch 'titlebar-gesture' into 'master'
Delegate titlebar action to the compositor if possible See merge request GNOME/gtk!3797
-rw-r--r--gdk/gdktoplevel.c18
-rw-r--r--gdk/gdktoplevel.h11
-rw-r--r--gdk/gdktoplevelprivate.h2
-rw-r--r--gdk/wayland/gdkdisplay-wayland.c2
-rw-r--r--gdk/wayland/gdksurface-wayland.c67
-rw-r--r--gdk/wayland/protocol/gtk-shell.xml21
-rw-r--r--gtk/gtkwindowhandle.c52
7 files changed, 160 insertions, 13 deletions
diff --git a/gdk/gdktoplevel.c b/gdk/gdktoplevel.c
index d50a88675d..f020d81765 100644
--- a/gdk/gdktoplevel.c
+++ b/gdk/gdktoplevel.c
@@ -79,6 +79,13 @@ gdk_toplevel_default_show_window_menu (GdkToplevel *toplevel,
}
static gboolean
+gdk_toplevel_default_titlebar_gesture (GdkToplevel *toplevel,
+ GdkTitlebarGesture gesture)
+{
+ return FALSE;
+}
+
+static gboolean
gdk_toplevel_default_supports_edge_constraints (GdkToplevel *toplevel)
{
return FALSE;
@@ -114,6 +121,7 @@ gdk_toplevel_default_init (GdkToplevelInterface *iface)
iface->supports_edge_constraints = gdk_toplevel_default_supports_edge_constraints;
iface->inhibit_system_shortcuts = gdk_toplevel_default_inhibit_system_shortcuts;
iface->restore_system_shortcuts = gdk_toplevel_default_restore_system_shortcuts;
+ iface->titlebar_gesture = gdk_toplevel_default_titlebar_gesture;
/**
* GdkToplevel:state: (attributes org.gtk.Property.get=gdk_toplevel_get_state)
@@ -716,3 +724,13 @@ gdk_toplevel_begin_move (GdkToplevel *toplevel,
x, y,
timestamp);
}
+
+gboolean
+gdk_toplevel_titlebar_gesture (GdkToplevel *toplevel,
+ GdkTitlebarGesture gesture)
+{
+ g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
+
+ return GDK_TOPLEVEL_GET_IFACE (toplevel)->titlebar_gesture (toplevel,
+ gesture);
+}
diff --git a/gdk/gdktoplevel.h b/gdk/gdktoplevel.h
index 1d3f9c627d..68613a9024 100644
--- a/gdk/gdktoplevel.h
+++ b/gdk/gdktoplevel.h
@@ -115,6 +115,13 @@ typedef enum
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 15
} GdkToplevelState;
+typedef enum
+{
+ GDK_TITLEBAR_GESTURE_DOUBLE_CLICK = 1,
+ GDK_TITLEBAR_GESTURE_RIGHT_CLICK = 2,
+ GDK_TITLEBAR_GESTURE_MIDDLE_CLICK = 3
+} GdkTitlebarGesture;
+
#define GDK_TYPE_TOPLEVEL (gdk_toplevel_get_type ())
@@ -196,6 +203,10 @@ void gdk_toplevel_begin_move (GdkToplevel *toplevel,
double y,
guint32 timestamp);
+GDK_AVAILABLE_IN_4_4
+gboolean gdk_toplevel_titlebar_gesture (GdkToplevel *toplevel,
+ GdkTitlebarGesture gesture);
+
G_END_DECLS
#endif /* __GDK_TOPLEVEL_H__ */
diff --git a/gdk/gdktoplevelprivate.h b/gdk/gdktoplevelprivate.h
index 52dcdca0ad..2d1f0122f3 100644
--- a/gdk/gdktoplevelprivate.h
+++ b/gdk/gdktoplevelprivate.h
@@ -38,6 +38,8 @@ struct _GdkToplevelInterface
double x,
double y,
guint32 timestamp);
+ gboolean (* titlebar_gesture) (GdkToplevel *toplevel,
+ GdkTitlebarGesture gesture);
};
typedef enum
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index 0312411e0c..ad033076b4 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -87,7 +87,7 @@
#define MIN_SYSTEM_BELL_DELAY_MS 20
-#define GTK_SHELL1_VERSION 4
+#define GTK_SHELL1_VERSION 5
#define OUTPUT_VERSION_WITH_DONE 2
#define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3
#define XDG_ACTIVATION_VERSION 1
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 5689241c7d..84ec54a335 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -4191,6 +4191,65 @@ gdk_wayland_surface_show_window_menu (GdkSurface *surface,
}
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_surface_titlebar_gesture (GdkSurface *surface,
+ GdkTitlebarGesture gesture)
+{
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+ 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 (surface->display);
+ wl_seat = gdk_wayland_seat_get_wl_seat (seat);
+
+ serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (seat), NULL);
+
+ gtk_surface1_titlebar_gesture (impl->display_server.gtk_surface,
+ serial,
+ wl_seat,
+ gtk_gesture);
+
+ return TRUE;
+}
+
+static gboolean
gdk_wayland_surface_supports_edge_constraints (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
@@ -4988,6 +5047,13 @@ gdk_wayland_toplevel_show_window_menu (GdkToplevel *toplevel,
}
static gboolean
+gdk_wayland_toplevel_titlebar_gesture (GdkToplevel *toplevel,
+ GdkTitlebarGesture gesture)
+{
+ return gdk_wayland_surface_titlebar_gesture (GDK_SURFACE (toplevel), gesture);
+}
+
+static gboolean
gdk_wayland_toplevel_supports_edge_constraints (GdkToplevel *toplevel)
{
return gdk_wayland_surface_supports_edge_constraints (GDK_SURFACE (toplevel));
@@ -5065,6 +5131,7 @@ gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface)
iface->lower = gdk_wayland_toplevel_lower;
iface->focus = gdk_wayland_toplevel_focus;
iface->show_window_menu = gdk_wayland_toplevel_show_window_menu;
+ iface->titlebar_gesture = gdk_wayland_toplevel_titlebar_gesture;
iface->supports_edge_constraints = gdk_wayland_toplevel_supports_edge_constraints;
iface->inhibit_system_shortcuts = gdk_wayland_toplevel_inhibit_system_shortcuts;
iface->restore_system_shortcuts = gdk_wayland_toplevel_restore_system_shortcuts;
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/gtkwindowhandle.c b/gtk/gtkwindowhandle.c
index 1cf9067405..b1494043f2 100644
--- a/gtk/gtkwindowhandle.c
+++ b/gtk/gtkwindowhandle.c
@@ -266,26 +266,24 @@ do_popup (GtkWindowHandle *self,
}
static gboolean
-perform_titlebar_action (GtkWindowHandle *self,
- GdkEvent *event,
- guint button,
- int n_press)
+perform_titlebar_action_fallback (GtkWindowHandle *self,
+ GdkEvent *event,
+ GdkTitlebarGesture gesture)
{
GtkSettings *settings;
char *action = NULL;
gboolean retval = TRUE;
settings = gtk_widget_get_settings (GTK_WIDGET (self));
- switch (button)
+ switch (gesture)
{
- case GDK_BUTTON_PRIMARY:
- if (n_press == 2)
- g_object_get (settings, "gtk-titlebar-double-click", &action, NULL);
+ case GDK_TITLEBAR_GESTURE_DOUBLE_CLICK:
+ g_object_get (settings, "gtk-titlebar-double-click", &action, NULL);
break;
- case GDK_BUTTON_MIDDLE:
+ case GDK_TITLEBAR_GESTURE_MIDDLE_CLICK:
g_object_get (settings, "gtk-titlebar-middle-click", &action, NULL);
break;
- case GDK_BUTTON_SECONDARY:
+ case GDK_TITLEBAR_GESTURE_RIGHT_CLICK:
g_object_get (settings, "gtk-titlebar-right-click", &action, NULL);
break;
default:
@@ -320,6 +318,40 @@ perform_titlebar_action (GtkWindowHandle *self,
return retval;
}
+static gboolean
+perform_titlebar_action (GtkWindowHandle *self,
+ GdkEvent *event,
+ guint button,
+ int n_press)
+{
+ GdkSurface *surface =
+ gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (self)));
+ GdkTitlebarGesture gesture;
+
+ switch (button)
+ {
+ case GDK_BUTTON_PRIMARY:
+ if (n_press == 2)
+ gesture = GDK_TITLEBAR_GESTURE_DOUBLE_CLICK;
+ else
+ return FALSE;
+ break;
+ case GDK_BUTTON_MIDDLE:
+ gesture = GDK_TITLEBAR_GESTURE_MIDDLE_CLICK;
+ break;
+ case GDK_BUTTON_SECONDARY:
+ gesture = GDK_TITLEBAR_GESTURE_RIGHT_CLICK;
+ break;
+ default:
+ break;
+ }
+
+ if (gdk_toplevel_titlebar_gesture (GDK_TOPLEVEL (surface), gesture))
+ return TRUE;
+
+ return perform_titlebar_action_fallback (self, event, gesture);
+}
+
static void
click_gesture_pressed_cb (GtkGestureClick *gesture,
int n_press,