[libgd/wip/ernestask/gtk4: 1/5] notification: use an event controller for motion events



commit da03ee62e6eec29675dfc2a177d2c1f83773da7e
Author: Ernestas Kulik <ernestask gnome org>
Date:   Sun Mar 11 10:08:53 2018 +0200

    notification: use an event controller for motion events
    
    This allows us to drop the GdkWindow stuff.

 libgd/gd-notification.c |  174 +++++++++++++---------------------------------
 1 files changed, 49 insertions(+), 125 deletions(-)
---
diff --git a/libgd/gd-notification.c b/libgd/gd-notification.c
index 1697e8d..06330c1 100644
--- a/libgd/gd-notification.c
+++ b/libgd/gd-notification.c
@@ -65,6 +65,8 @@ struct _GdNotificationPrivate {
 
   gint timeout;
   guint timeout_source_id;
+
+  GtkEventController *motion_controller;
 };
 
 enum {
@@ -97,6 +99,47 @@ static void     gd_notification_close_button_clicked_cb        (GtkWidget
 G_DEFINE_TYPE(GdNotification, gd_notification, GTK_TYPE_BIN);
 
 static void
+unqueue_autohide (GdNotification *notification)
+{
+  GdNotificationPrivate *priv = notification->priv;
+
+  if (priv->timeout_source_id)
+    {
+      g_source_remove (priv->timeout_source_id);
+      priv->timeout_source_id = 0;
+    }
+}
+
+static void
+queue_autohide (GdNotification *notification)
+{
+  GdNotificationPrivate *priv = notification->priv;
+
+  if (priv->timeout_source_id == 0 &&
+      priv->timeout != -1)
+    priv->timeout_source_id =
+      g_timeout_add (priv->timeout * 1000, gd_notification_timeout_cb, notification);
+}
+
+static void
+on_enter (GtkEventControllerMotion *controller,
+          gdouble                   x,
+          gdouble                   y,
+          gpointer                  user_data)
+{
+  unqueue_autohide (user_data);
+}
+
+static void
+on_leave (GtkEventControllerMotion *controller,
+          gdouble                   x,
+          gdouble                   y,
+          gpointer                  user_data)
+{
+  queue_autohide (user_data);
+}
+
+static void
 gd_notification_init (GdNotification *notification)
 {
   GtkStyleContext *context;
@@ -109,7 +152,7 @@ gd_notification_init (GdNotification *notification)
   gtk_widget_set_halign (GTK_WIDGET (notification), GTK_ALIGN_CENTER);
   gtk_widget_set_valign (GTK_WIDGET (notification), GTK_ALIGN_START);
 
-  gtk_widget_set_has_window (GTK_WIDGET (notification), TRUE);
+  gtk_widget_set_has_window (GTK_WIDGET (notification), FALSE);
 
   priv = notification->priv =
     G_TYPE_INSTANCE_GET_PRIVATE (notification,
@@ -130,6 +173,11 @@ gd_notification_init (GdNotification *notification)
                     notification);
 
   priv->timeout_source_id = 0;
+
+  priv->motion_controller = gtk_event_controller_motion_new (GTK_WIDGET (notification));
+
+  g_signal_connect (priv->motion_controller, "enter", G_CALLBACK (on_enter), notification);
+  g_signal_connect (priv->motion_controller, "leave", G_CALLBACK (on_leave), notification);
 }
 
 static void
@@ -173,71 +221,6 @@ gd_notification_destroy (GtkWidget *widget)
   GTK_WIDGET_CLASS (gd_notification_parent_class)->destroy (widget);
 }
 
-static void
-gd_notification_realize (GtkWidget *widget)
-{
-  GdNotification *notification = GD_NOTIFICATION (widget);
-  GdNotificationPrivate *priv = notification->priv;
-  GtkBin *bin = GTK_BIN (widget);
-  GtkAllocation allocation;
-  GtkWidget *child;
-  GdkWindow *window;
-  GdkWindowAttr attributes;
-  gint attributes_mask;
-
-  gtk_widget_set_realized (widget, TRUE);
-
-  gtk_widget_get_allocation (widget, &allocation);
-
-  attributes.x = allocation.x;
-  attributes.y = allocation.y;
-  attributes.width = allocation.width;
-  attributes.height = allocation.height;
-  attributes.window_type = GDK_WINDOW_CHILD;
-  attributes.wclass = GDK_INPUT_OUTPUT;
-  attributes.visual = gtk_widget_get_visual (widget);
-
-  attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK;
-
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
-
-  window = gdk_window_new (gtk_widget_get_parent_window (widget),
-                           &attributes, attributes_mask);
-  gtk_widget_set_window (widget, window);
-  gtk_widget_register_window (widget, window);
-
-  attributes.x = 0;
-  attributes.y = attributes.height + priv->animate_y;
-  attributes.event_mask = gtk_widget_get_events (widget) |
-                          GDK_EXPOSURE_MASK |
-                          GDK_VISIBILITY_NOTIFY_MASK |
-                          GDK_ENTER_NOTIFY_MASK |
-                          GDK_LEAVE_NOTIFY_MASK;
-
-  priv->bin_window = gdk_window_new (window, &attributes, attributes_mask);
-  gtk_widget_register_window (widget, priv->bin_window);
-
-  child = gtk_bin_get_child (bin);
-  if (child)
-    gtk_widget_set_parent_window (child, priv->bin_window);
-  gtk_widget_set_parent_window (priv->close_button, priv->bin_window);
-
-  gdk_window_show (priv->bin_window);
-}
-
-static void
-gd_notification_unrealize (GtkWidget *widget)
-{
-  GdNotification *notification = GD_NOTIFICATION (widget);
-  GdNotificationPrivate *priv = notification->priv;
-
-  gtk_widget_unregister_window (widget, priv->bin_window);
-  gdk_window_destroy (priv->bin_window);
-  priv->bin_window = NULL;
-
-  GTK_WIDGET_CLASS (gd_notification_parent_class)->unrealize (widget);
-}
-
 static int
 animation_target (GdNotification *notification)
 {
@@ -385,29 +368,6 @@ gd_notification_forall (GtkContainer *container,
     (* callback) (priv->close_button, callback_data);
 }
 
-static void
-unqueue_autohide (GdNotification *notification)
-{
-  GdNotificationPrivate *priv = notification->priv;
-
-  if (priv->timeout_source_id)
-    {
-      g_source_remove (priv->timeout_source_id);
-      priv->timeout_source_id = 0;
-    }
-}
-
-static void
-queue_autohide (GdNotification *notification)
-{
-  GdNotificationPrivate *priv = notification->priv;
-
-  if (priv->timeout_source_id == 0 &&
-      priv->timeout != -1)
-    priv->timeout_source_id =
-      g_timeout_add (priv->timeout * 1000, gd_notification_timeout_cb, notification);
-}
-
 static gboolean
 gd_notification_visibility_notify_event (GtkWidget          *widget,
                                           GdkEventVisibility  *event)
@@ -429,38 +389,6 @@ gd_notification_visibility_notify_event (GtkWidget          *widget,
   return FALSE;
 }
 
-static gboolean
-gd_notification_enter_notify (GtkWidget        *widget,
-                              GdkEventCrossing *event)
-{
-  GdNotification *notification = GD_NOTIFICATION (widget);
-  GdNotificationPrivate *priv = notification->priv;
-
-  if ((event->window == priv->bin_window) &&
-      (event->detail != GDK_NOTIFY_INFERIOR))
-    {
-      unqueue_autohide (notification);
-    }
-
-  return FALSE;
-}
-
-static gboolean
-gd_notification_leave_notify (GtkWidget        *widget,
-                              GdkEventCrossing *event)
-{
-  GdNotification *notification = GD_NOTIFICATION (widget);
-  GdNotificationPrivate *priv = notification->priv;
-
-  if ((event->window == priv->bin_window) &&
-      (event->detail != GDK_NOTIFY_INFERIOR))
-    {
-      queue_autohide (notification);
-    }
-
-  return FALSE;
-}
-
 static void
 gd_notification_class_init (GdNotificationClass *klass)
 {
@@ -477,11 +405,7 @@ gd_notification_class_init (GdNotificationClass *klass)
   widget_class->destroy = gd_notification_destroy;
   widget_class->measure = gd_notification_measure;
   widget_class->size_allocate = gd_notification_size_allocate;
-  widget_class->realize = gd_notification_realize;
-  widget_class->unrealize = gd_notification_unrealize;
   widget_class->visibility_notify_event = gd_notification_visibility_notify_event;
-  widget_class->enter_notify_event = gd_notification_enter_notify;
-  widget_class->leave_notify_event = gd_notification_leave_notify;
 
   container_class->add = gd_notification_add;
   container_class->forall = gd_notification_forall;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]