[gtk+/popovers: 12/26] popover: listen harder on the widget being pointed to
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/popovers: 12/26] popover: listen harder on the widget being pointed to
- Date: Wed, 25 Dec 2013 00:32:00 +0000 (UTC)
commit 87fe82e3bcd409510740092ef904eec000e93531
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 | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 92 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 0a9d83d..b9340c7 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;
guint has_pointing_to : 1;
guint preferred_position : 2;
guint final_position : 2;
@@ -67,6 +69,8 @@ struct _GtkPopoverPrivate
};
static void gtk_popover_update_position (GtkPopover *popover);
+static void gtk_popover_update_relative_to (GtkPopover *popover,
+ GtkWidget *relative_to);
G_DEFINE_TYPE_WITH_PRIVATE (GtkPopover, gtk_popover, GTK_TYPE_BIN)
@@ -135,6 +139,10 @@ static void
gtk_popover_finalize (GObject *object)
{
GtkPopover *popover = GTK_POPOVER (object);
+ GtkPopoverPrivate *priv = popover->priv;
+
+ if (priv->widget)
+ gtk_popover_update_relative_to (popover, NULL);
G_OBJECT_CLASS (gtk_popover_parent_class)->finalize (object);
}
@@ -149,7 +157,9 @@ gtk_popover_dispose (GObject *object)
gtk_window_remove_popover (priv->window, GTK_WIDGET (object));
priv->window = NULL;
- priv->widget = NULL;
+
+ if (priv->widget)
+ gtk_popover_update_relative_to (popover, NULL);
G_OBJECT_CLASS (gtk_popover_parent_class)->dispose (object);
}
@@ -815,6 +825,59 @@ _gtk_popover_update_context_parent (GtkPopover *popover)
}
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;
+
+ g_object_ref (popover);
+
+ if (priv->window)
+ gtk_window_remove_popover (priv->window, GTK_WIDGET (popover));
+
+ if (new_window)
+ {
+ gtk_window_add_popover (new_window, GTK_WIDGET (popover));
+ g_object_unref (popover);
+ }
+ else
+ g_object_force_floating (G_OBJECT (popover));
+
+ priv->window = new_window;
+
+ if (new_window)
+ gtk_popover_update_position (popover);
+
+ _gtk_popover_update_context_parent (popover);
+
+ if (gtk_widget_is_visible (GTK_WIDGET (popover)))
+ gtk_widget_queue_resize (GTK_WIDGET (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)
+{
+ gtk_popover_update_position (popover);
+}
+
+static void
gtk_popover_update_relative_to (GtkPopover *popover,
GtkWidget *relative_to)
{
@@ -831,12 +894,37 @@ gtk_popover_update_relative_to (GtkPopover *popover,
priv->window = NULL;
}
+ if (priv->widget)
+ {
+ if (g_signal_handler_is_connected (priv->widget, priv->hierarchy_changed_id))
+ g_signal_handler_disconnect (priv->widget, priv->hierarchy_changed_id);
+ if (g_signal_handler_is_connected (priv->widget, priv->size_allocate_id))
+ g_signal_handler_disconnect (priv->widget, priv->size_allocate_id);
+ if (g_signal_handler_is_connected (priv->widget, priv->unmap_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]