[gtk/wip/matthiasc/popup5: 168/234] surface: Add an autohide property
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/popup5: 168/234] surface: Add an autohide property
- Date: Mon, 27 May 2019 13:36:14 +0000 (UTC)
commit 5557b85728ad5c4c91965654c3b2bed38d5a68dd
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Apr 22 21:31:33 2019 +0000
surface: Add an autohide property
This api is meant to mimic xdg-popover.grab - we
show the surface, and dismiss it when we get events
on other surfaces. For foreign surfaces, the compositor
handles that for us; for our own, we check outselves
before delivering events to GTK.
docs/reference/gdk/gdk4-sections.txt | 1 +
gdk/gdksurface.c | 88 +++++++++++++++++++++++++++++++++++-
gdk/gdksurface.h | 4 +-
gdk/gdksurfaceprivate.h | 1 +
4 files changed, 91 insertions(+), 3 deletions(-)
---
diff --git a/docs/reference/gdk/gdk4-sections.txt b/docs/reference/gdk/gdk4-sections.txt
index e3fa979d66..6338ab03cc 100644
--- a/docs/reference/gdk/gdk4-sections.txt
+++ b/docs/reference/gdk/gdk4-sections.txt
@@ -186,6 +186,7 @@ gdk_surface_get_surface_type
gdk_surface_get_display
gdk_surface_show
gdk_surface_show_unraised
+gdk_surface_show_with_auto_dismissal
gdk_surface_hide
gdk_surface_is_destroyed
gdk_surface_is_visible
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index e681cfa6c8..4463c3ee0e 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -85,6 +85,7 @@ enum {
PROP_FRAME_CLOCK,
PROP_STATE,
PROP_MAPPED,
+ PROP_AUTOHIDE,
LAST_PROP
};
@@ -498,6 +499,13 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ properties[PROP_AUTOHIDE] =
+ g_param_spec_boolean ("autohide",
+ P_("Autohide"),
+ P_("Whether to dismiss the surface on outside clicks"),
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, LAST_PROP, properties);
/**
@@ -670,6 +678,10 @@ gdk_surface_set_property (GObject *object,
gdk_surface_set_frame_clock (surface, GDK_FRAME_CLOCK (g_value_get_object (value)));
break;
+ case PROP_AUTOHIDE:
+ surface->autohide = g_value_get_boolean (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -706,6 +718,10 @@ gdk_surface_get_property (GObject *object,
g_value_set_boolean (value, GDK_SURFACE_IS_MAPPED (surface));
break;
+ case PROP_AUTOHIDE:
+ g_value_set_boolean (value, surface->autohide);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -791,8 +807,10 @@ gdk_surface_new_temp (GdkDisplay *display,
* gdk_surface_new_popup: (constructor)
* @display: the display to create the surface on
* @parent: the parent surface to attach the surface to
+ * @autohide: whether to hide the surface on outside clicks
*
* Create a new popup surface.
+ *
* The surface will be attached to @parent and can
* be positioned relative to it using
* gdk_surface_move_to_rect().
@@ -801,7 +819,8 @@ gdk_surface_new_temp (GdkDisplay *display,
*/
GdkSurface *
gdk_surface_new_popup (GdkDisplay *display,
- GdkSurface *parent)
+ GdkSurface *parent,
+ gboolean autohide)
{
GdkSurface *surface;
@@ -811,6 +830,8 @@ gdk_surface_new_popup (GdkDisplay *display,
surface = gdk_surface_new (display, GDK_SURFACE_POPUP,
parent, 0, 0, 100, 100);
+ surface->autohide = autohide;
+
return surface;
}
@@ -1884,6 +1905,13 @@ gdk_surface_restack (GdkSurface *surface,
GDK_SURFACE_GET_CLASS (surface)->restack_toplevel (surface, sibling, above);
}
+static void
+grab_prepare_func (GdkSeat *seat,
+ GdkSurface *surface,
+ gpointer data)
+{
+ gdk_surface_show_internal (surface, TRUE);
+}
/**
* gdk_surface_show:
@@ -1902,7 +1930,19 @@ gdk_surface_restack (GdkSurface *surface,
void
gdk_surface_show (GdkSurface *surface)
{
- gdk_surface_show_internal (surface, TRUE);
+ if (surface->autohide)
+ {
+ gdk_seat_grab (gdk_display_get_default_seat (surface->display),
+ surface,
+ GDK_SEAT_CAPABILITY_ALL,
+ TRUE,
+ NULL, NULL,
+ grab_prepare_func, NULL);
+ }
+ else
+ {
+ gdk_surface_show_internal (surface, TRUE);
+ }
}
/**
@@ -4178,10 +4218,54 @@ gdk_synthesize_surface_state (GdkSurface *surface,
gdk_surface_set_state (surface, (surface->state | set_flags) & ~unset_flags);
}
+static gboolean
+check_autohide (GdkEvent *event)
+{
+ GdkDisplay *display;
+ GdkDevice *device;
+ GdkSurface *grab_surface;
+
+ switch ((guint) gdk_event_get_event_type (event))
+ {
+ case GDK_BUTTON_PRESS:
+#if 0
+ // FIXME: we need to ignore the release that is paired
+ // with the press starting the grab - due to implicit
+ // grabs, it will be delivered to the same place as the
+ // press, and will cause the auto dismissal to be triggered.
+ case GDK_BUTTON_RELEASE:
+#endif
+ case GDK_TOUCH_BEGIN:
+ case GDK_TOUCH_END:
+ case GDK_TOUCH_CANCEL:
+ case GDK_TOUCHPAD_SWIPE:
+ case GDK_TOUCHPAD_PINCH:
+ display = gdk_event_get_display (event);
+ device = gdk_event_get_device (event);
+ if (gdk_device_grab_info (display, device, &grab_surface, NULL))
+ {
+ if (grab_surface != gdk_event_get_surface (event) &&
+ grab_surface->autohide)
+ {
+ gdk_surface_hide (grab_surface);
+ return TRUE;
+ }
+ }
+ break;
+ default:;
+ }
+
+ return FALSE;
+}
+
gboolean
gdk_surface_handle_event (GdkEvent *event)
{
gboolean handled = FALSE;
+
+ if (check_autohide (event))
+ return TRUE;
+
if (gdk_event_get_event_type (event) == GDK_CONFIGURE)
{
g_signal_emit (gdk_event_get_surface (event), signals[SIZE_CHANGED], 0,
diff --git a/gdk/gdksurface.h b/gdk/gdksurface.h
index 938c59ba17..99f920c5f4 100644
--- a/gdk/gdksurface.h
+++ b/gdk/gdksurface.h
@@ -426,7 +426,8 @@ GdkSurface * gdk_surface_new_temp (GdkDisplay *display,
const GdkRectangle *position);
GDK_AVAILABLE_IN_ALL
GdkSurface * gdk_surface_new_popup (GdkDisplay *display,
- GdkSurface *parent);
+ GdkSurface *parent,
+ gboolean autohide);
GDK_AVAILABLE_IN_ALL
void gdk_surface_destroy (GdkSurface *surface);
@@ -443,6 +444,7 @@ GDK_AVAILABLE_IN_ALL
void gdk_surface_hide (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gdk_surface_show_unraised (GdkSurface *surface);
+
GDK_AVAILABLE_IN_ALL
void gdk_surface_move (GdkSurface *surface,
gint x,
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index 25319c6b38..c7933fe0f2 100644
--- a/gdk/gdksurfaceprivate.h
+++ b/gdk/gdksurfaceprivate.h
@@ -69,6 +69,7 @@ struct _GdkSurface
guint viewable : 1; /* mapped and all parents mapped */
guint in_update : 1;
guint frame_clock_events_paused : 1;
+ guint autohide : 1;
guint update_and_descendants_freeze_count;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]