[gtk/wip/matthiasc/popup4] surface: Add gdk_surface_show_with_auto_dismissal
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/popup4] surface: Add gdk_surface_show_with_auto_dismissal
- Date: Mon, 22 Apr 2019 21:40:39 +0000 (UTC)
commit f5c0e3f16376d84673985de86e969dca335ad85f
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Apr 22 21:31:33 2019 +0000
surface: Add gdk_surface_show_with_auto_dismissal
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.
gdk/gdksurface.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-
gdk/gdksurface.h | 4 ++++
gdk/gdksurfaceprivate.h | 1 +
3 files changed, 68 insertions(+), 1 deletion(-)
---
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 75fc2778dc..35306bed6a 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -1750,7 +1750,10 @@ gdk_surface_show_internal (GdkSurface *surface, gboolean raise)
gdk_surface_raise_internal (surface);
if (!was_mapped)
- gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_WITHDRAWN, 0);
+ {
+ gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_WITHDRAWN, 0);
+ surface->auto_dismissal = FALSE;
+ }
did_show = _gdk_surface_update_viewable (surface);
@@ -4171,10 +4174,48 @@ gdk_synthesize_surface_state (GdkSurface *surface,
gdk_surface_set_state (surface, (surface->state | set_flags) & ~unset_flags);
}
+static gboolean
+check_auto_dismissal (GdkEvent *event)
+{
+ GdkDisplay *display;
+ GdkDevice *device;
+ GdkSurface *grab_surface;
+
+ switch ((guint) gdk_event_get_event_type (event))
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ 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->auto_dismissal)
+ {
+ gdk_surface_hide (grab_surface);
+ return TRUE;
+ }
+ }
+ break;
+ default:;
+ }
+
+ return FALSE;
+}
+
gboolean
gdk_surface_handle_event (GdkEvent *event)
{
gboolean handled = FALSE;
+
+ if (check_auto_dismissal (event))
+ return TRUE;
+
if (gdk_event_get_event_type (event) == GDK_CONFIGURE)
{
g_signal_emit (gdk_event_get_surface (event), signals[SIZE_CHANGED], 0,
@@ -4188,3 +4229,24 @@ gdk_surface_handle_event (GdkEvent *event)
return handled;
}
+
+static void
+grab_prepare_func (GdkSeat *seat,
+ GdkSurface *surface,
+ gpointer data)
+{
+ gdk_surface_show (surface);
+ surface->auto_dismissal = TRUE;
+}
+
+void
+gdk_surface_show_with_auto_dismissal (GdkSurface *surface,
+ GdkSeat *seat)
+{
+ gdk_seat_grab (seat,
+ surface,
+ GDK_SEAT_CAPABILITY_ALL,
+ TRUE,
+ NULL, NULL,
+ grab_prepare_func, NULL);
+}
diff --git a/gdk/gdksurface.h b/gdk/gdksurface.h
index 938c59ba17..956870d040 100644
--- a/gdk/gdksurface.h
+++ b/gdk/gdksurface.h
@@ -443,6 +443,10 @@ 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_show_with_auto_dismissal (GdkSurface *surface,
+ GdkSeat *seat);
+
GDK_AVAILABLE_IN_ALL
void gdk_surface_move (GdkSurface *surface,
gint x,
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index 25319c6b38..b03cc5ccd1 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 auto_dismissal : 1;
guint update_and_descendants_freeze_count;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]