[libdazzle/libdazzle-3-30] app-window: use GtkEventControllerMotion for motion tracking
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdazzle/libdazzle-3-30] app-window: use GtkEventControllerMotion for motion tracking
- Date: Tue, 25 Sep 2018 23:26:33 +0000 (UTC)
commit 58f1731ec3056b6bdb7f23f1ca7296fab4d67b23
Author: Christian Hergert <chergert redhat com>
Date: Tue Sep 25 16:13:42 2018 -0700
app-window: use GtkEventControllerMotion for motion tracking
Instead of relying on the eventbox for motion events, we can use the new
GtkEventControllerMotion that landed in gtk 3.24. Doing so helps ensure
that we can get event delivery during the capture phase which is useful
to make this handle more corner cases.
src/app/dzl-application-window.c | 71 +++++++++++++---------------------------
1 file changed, 23 insertions(+), 48 deletions(-)
---
diff --git a/src/app/dzl-application-window.c b/src/app/dzl-application-window.c
index b435943..7a9e164 100644
--- a/src/app/dzl-application-window.c
+++ b/src/app/dzl-application-window.c
@@ -48,10 +48,10 @@ typedef struct
{
GtkStack *titlebar_container;
GtkRevealer *titlebar_revealer;
- GtkEventBox *event_box;
GtkOverlay *overlay;
- gulong motion_notify_handler;
+ GtkEventController *motion_controller;
+ gulong motion_controller_handler;
guint fullscreen_source;
guint fullscreen_reveal_source;
@@ -128,20 +128,17 @@ revealer_set_reveal_child_now (GtkRevealer *revealer,
gtk_revealer_set_transition_type (revealer, GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN);
}
-static gboolean
-dzl_application_window_event_box_motion (DzlApplicationWindow *self,
- GdkEventMotion *motion,
- GtkEventBox *event_box)
+static void
+dzl_application_window_motion_cb (DzlApplicationWindow *self,
+ gdouble x,
+ gdouble y,
+ GtkEventControllerMotion *controller)
{
DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
- GtkWidget *widget = NULL;
GtkWidget *focus;
- gint x = 0;
- gint y = 0;
g_assert (DZL_IS_APPLICATION_WINDOW (self));
- g_assert (motion != NULL);
- g_assert (GTK_IS_EVENT_BOX (event_box));
+ g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (controller));
/*
* If we are focused in the revealer, ignore this. We will have already
@@ -150,28 +147,17 @@ dzl_application_window_event_box_motion (DzlApplicationWindow *self,
focus = gtk_window_get_focus (GTK_WINDOW (self));
if (focus != NULL &&
dzl_gtk_widget_is_ancestor_or_relative (focus, GTK_WIDGET (priv->titlebar_revealer)))
- return GDK_EVENT_PROPAGATE;
-
- /* The widget is stored in GdkWindow user_data */
- gdk_window_get_user_data (motion->window, (gpointer *)&widget);
- if (widget == NULL)
- return GDK_EVENT_PROPAGATE;
+ return;
/* If the headerbar is underneath the pointer or we are within a
* small distance of the edge of the window (and monitor), ensure
* that the titlebar is displayed and queue our next dismissal.
*/
- if (dzl_gtk_widget_is_ancestor_or_relative (widget, GTK_WIDGET (priv->titlebar_revealer)) ||
- gtk_widget_translate_coordinates (widget, GTK_WIDGET (self), motion->x, motion->y, &x, &y))
+ if (y <= SHOW_HEADER_WITHIN_DISTANCE)
{
- if (y < SHOW_HEADER_WITHIN_DISTANCE)
- {
- gtk_revealer_set_reveal_child (priv->titlebar_revealer, TRUE);
- dzl_application_window_queue_dismissal (self);
- }
+ gtk_revealer_set_reveal_child (priv->titlebar_revealer, TRUE);
+ dzl_application_window_queue_dismissal (self);
}
-
- return GDK_EVENT_PROPAGATE;
}
static gboolean
@@ -205,7 +191,7 @@ dzl_application_window_complete_fullscreen (DzlApplicationWindow *self)
if (priv->fullscreen)
{
/* Only listen for motion notify events while in fullscreen mode. */
- g_signal_handler_unblock (priv->event_box, priv->motion_notify_handler);
+ gtk_event_controller_set_propagation_phase (priv->motion_controller, GTK_PHASE_CAPTURE);
if (titlebar && gtk_widget_is_ancestor (titlebar, GTK_WIDGET (priv->titlebar_container)))
{
@@ -219,7 +205,7 @@ dzl_application_window_complete_fullscreen (DzlApplicationWindow *self)
else
{
/* Motion events are no longer needed */
- g_signal_handler_block (priv->event_box, priv->motion_notify_handler);
+ gtk_event_controller_set_propagation_phase (priv->motion_controller, GTK_PHASE_NONE);
if (gtk_widget_is_ancestor (titlebar, GTK_WIDGET (priv->titlebar_revealer)))
{
@@ -330,7 +316,7 @@ dzl_application_window_add (GtkContainer *container,
g_assert (DZL_IS_APPLICATION_WINDOW (self));
g_assert (GTK_IS_WIDGET (widget));
- gtk_container_add (GTK_CONTAINER (priv->event_box), widget);
+ gtk_container_add (GTK_CONTAINER (priv->overlay), widget);
}
static gboolean
@@ -363,12 +349,10 @@ dzl_application_window_destroy (GtkWidget *widget)
g_assert (DZL_IS_APPLICATION_WINDOW (self));
- if (priv->event_box != NULL)
- dzl_clear_signal_handler (priv->event_box, &priv->motion_notify_handler);
+ g_clear_object (&priv->motion_controller);
g_clear_pointer ((GtkWidget **)&priv->titlebar_container, gtk_widget_destroy);
g_clear_pointer ((GtkWidget **)&priv->titlebar_revealer, gtk_widget_destroy);
- g_clear_pointer ((GtkWidget **)&priv->event_box, gtk_widget_destroy);
g_clear_pointer ((GtkWidget **)&priv->overlay, gtk_widget_destroy);
dzl_clear_source (&priv->fullscreen_source);
@@ -475,6 +459,7 @@ dzl_application_window_init (DzlApplicationWindow *self)
priv->overlay = g_object_new (GTK_TYPE_OVERLAY,
"visible", TRUE,
NULL);
+ gtk_widget_set_events (GTK_WIDGET (priv->overlay), GDK_POINTER_MOTION_MASK);
g_signal_connect (priv->overlay,
"destroy",
G_CALLBACK (gtk_widget_destroyed),
@@ -482,23 +467,13 @@ dzl_application_window_init (DzlApplicationWindow *self)
GTK_CONTAINER_CLASS (dzl_application_window_parent_class)->add (GTK_CONTAINER (self),
GTK_WIDGET (priv->overlay));
- priv->event_box = g_object_new (GTK_TYPE_EVENT_BOX,
- "above-child", FALSE,
- "visible", TRUE,
- "visible-window", TRUE,
- NULL);
- gtk_widget_set_events (GTK_WIDGET (priv->event_box), GDK_POINTER_MOTION_MASK);
- g_signal_connect (priv->event_box,
- "destroy",
- G_CALLBACK (gtk_widget_destroyed),
- &priv->event_box);
- priv->motion_notify_handler =
- g_signal_connect_swapped (priv->event_box,
- "motion-notify-event",
- G_CALLBACK (dzl_application_window_event_box_motion),
+ priv->motion_controller = gtk_event_controller_motion_new (GTK_WIDGET (priv->overlay));
+ priv->motion_controller_handler =
+ g_signal_connect_swapped (priv->motion_controller,
+ "motion",
+ G_CALLBACK (dzl_application_window_motion_cb),
self);
- g_signal_handler_block (priv->event_box, priv->motion_notify_handler);
- gtk_container_add (GTK_CONTAINER (priv->overlay), GTK_WIDGET (priv->event_box));
+ gtk_event_controller_set_propagation_phase (priv->motion_controller, GTK_PHASE_NONE);
priv->titlebar_revealer = g_object_new (GTK_TYPE_REVEALER,
"valign", GTK_ALIGN_START,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]