diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-08-02 01:14:08 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-08-02 01:14:08 +0000 |
commit | 2a528df977654fa84d637ff84f529400d7cba1d8 (patch) | |
tree | 47cd5889f4a68c5c21c8c261ac5fe063afbcc634 | |
parent | 84684bd56e48e7263790622249b725931e479b5e (diff) | |
parent | 23e79d2eb2bc9aa4b630ab2dee4b38a8fc70af5c (diff) | |
download | gtk+-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.c | 18 | ||||
-rw-r--r-- | gdk/gdktoplevel.h | 11 | ||||
-rw-r--r-- | gdk/gdktoplevelprivate.h | 2 | ||||
-rw-r--r-- | gdk/wayland/gdkdisplay-wayland.c | 2 | ||||
-rw-r--r-- | gdk/wayland/gdksurface-wayland.c | 67 | ||||
-rw-r--r-- | gdk/wayland/protocol/gtk-shell.xml | 21 | ||||
-rw-r--r-- | gtk/gtkwindowhandle.c | 52 |
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, >k_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, |