[gtk+/popovers: 12/17] popover: listen harder on the widget being pointed to



commit 57261e32e32ce87ab4a23f273e8b581d86ad08f1
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Nov 13 10:47:13 2013 +0100

    popover: listen harder on the widget being pointed to
    
    Hierarchy, size allocation and widget visibility are now listened
    to in order to update the popover state accordingly.

 gtk/gtkpopover.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 69 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 2323fd7..05db5c2 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -56,10 +56,12 @@ enum {
 
 struct _GtkPopoverPrivate
 {
-  GdkDevice *device;
   GtkWidget *widget;
   GtkWindow *window;
   cairo_rectangle_int_t pointing_to;
+  guint hierarchy_changed_id;
+  guint size_allocate_id;
+  guint unmap_id;
   gint win_x;
   gint win_y;
   guint has_pointing_to    : 1;
@@ -847,6 +849,48 @@ gtk_popover_class_init (GtkPopoverClass *klass)
 }
 
 static void
+_gtk_popover_parent_hierarchy_changed (GtkWidget  *widget,
+                                       GtkWidget  *previous_toplevel,
+                                       GtkPopover *popover)
+{
+  GtkPopoverPrivate *priv;
+  GtkWindow *new_window;
+
+  priv = popover->priv;
+  new_window = GTK_WINDOW (gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW));
+
+  if (priv->window == new_window)
+    return;
+
+  if (priv->window)
+    gtk_window_remove_popover (priv->window, GTK_WIDGET (popover));
+
+  if (new_window)
+    gtk_window_add_popover (new_window, GTK_WIDGET (popover));
+
+  priv->window = new_window;
+
+  if (gtk_widget_is_visible (GTK_WIDGET (popover)))
+    gtk_popover_update_position (popover);
+}
+
+static void
+_gtk_popover_parent_unmap (GtkWidget *widget,
+                           GtkPopover *popover)
+{
+  gtk_widget_unmap (GTK_WIDGET (popover));
+}
+
+static void
+_gtk_popover_parent_size_allocate (GtkWidget     *widget,
+                                   GtkAllocation *allocation,
+                                   GtkPopover    *popover)
+{
+  if (gtk_widget_is_visible (GTK_WIDGET (popover)))
+    gtk_popover_update_position (popover);
+}
+
+static void
 gtk_popover_update_relative_to (GtkPopover *popover,
                                 GtkWidget  *relative_to)
 {
@@ -863,12 +907,34 @@ gtk_popover_update_relative_to (GtkPopover *popover,
       priv->window = NULL;
     }
 
+  if (priv->widget)
+    {
+      g_signal_handler_disconnect (priv->widget, priv->hierarchy_changed_id);
+      g_signal_handler_disconnect (priv->widget, priv->size_allocate_id);
+      g_signal_handler_disconnect (priv->widget, priv->unmap_id);
+    }
+
   priv->widget = relative_to;
   g_object_notify (G_OBJECT (popover), "relative-to");
 
   if (priv->widget)
-    priv->window =
-      GTK_WINDOW (gtk_widget_get_ancestor (priv->widget, GTK_TYPE_WINDOW));
+    {
+      priv->window =
+        GTK_WINDOW (gtk_widget_get_ancestor (priv->widget, GTK_TYPE_WINDOW));
+
+      priv->hierarchy_changed_id =
+        g_signal_connect (priv->widget, "hierarchy-changed",
+                          G_CALLBACK (_gtk_popover_parent_hierarchy_changed),
+                          popover);
+      priv->size_allocate_id =
+        g_signal_connect (priv->widget, "size-allocate",
+                          G_CALLBACK (_gtk_popover_parent_size_allocate),
+                          popover);
+      priv->unmap_id =
+        g_signal_connect (priv->widget, "unmap",
+                          G_CALLBACK (_gtk_popover_parent_unmap),
+                          popover);
+    }
 
   if (priv->window)
     gtk_window_add_popover (priv->window, GTK_WIDGET (popover));


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