From 76dc8aced5517b409e2cc7897e1d49a20a0c8ade Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 15 Jun 2015 14:05:00 +0200 Subject: [PATCH] window: Add concept of popover "parent" This will be the widget that the popover relates to (::pointing-to in GtkPopover, ::parent in GtkTextHandle). Additional API to check the popover/parent relationship between widgets has been added, which will be useful wherever this is necessary in a generic manner. https://bugzilla.gnome.org/show_bug.cgi?id=750993 --- gtk/gtkpopover.c | 4 ++-- gtk/gtktexthandle.c | 2 +- gtk/gtkwindow.c | 53 +++++++++++++++++++++++++++++++++++++++++- gtk/gtkwindowprivate.h | 8 ++++++- 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c index da4e1c1d3e..e2e7942eae 100644 --- a/gtk/gtkpopover.c +++ b/gtk/gtkpopover.c @@ -1699,7 +1699,7 @@ _gtk_popover_parent_hierarchy_changed (GtkWidget *widget, _gtk_window_remove_popover (priv->window, GTK_WIDGET (popover)); if (new_window) - _gtk_window_add_popover (new_window, GTK_WIDGET (popover)); + _gtk_window_add_popover (new_window, GTK_WIDGET (popover), priv->widget); priv->window = new_window; @@ -1970,7 +1970,7 @@ gtk_popover_update_relative_to (GtkPopover *popover, } if (priv->window) - _gtk_window_add_popover (priv->window, GTK_WIDGET (popover)); + _gtk_window_add_popover (priv->window, GTK_WIDGET (popover), priv->widget); if (relative_to) scrollable = GTK_SCROLLABLE (gtk_widget_get_ancestor (priv->widget, GTK_TYPE_SCROLLABLE)); diff --git a/gtk/gtktexthandle.c b/gtk/gtktexthandle.c index 977de041b2..47de7efe5f 100644 --- a/gtk/gtktexthandle.c +++ b/gtk/gtktexthandle.c @@ -309,7 +309,7 @@ _gtk_text_handle_ensure_widget (GtkTextHandle *handle, priv->windows[pos].widget = g_object_ref_sink (widget); window = gtk_widget_get_ancestor (priv->parent, GTK_TYPE_WINDOW); - _gtk_window_add_popover (GTK_WINDOW (window), widget); + _gtk_window_add_popover (GTK_WINDOW (window), widget, priv->parent); gtk_style_context_set_parent (gtk_widget_get_style_context (widget), gtk_widget_get_style_context (priv->parent)); diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 7f6f3e3a2e..555d9d760f 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -132,6 +132,7 @@ typedef struct _GtkWindowPopover GtkWindowPopover; struct _GtkWindowPopover { GtkWidget *widget; + GtkWidget *parent; GdkWindow *window; GtkPositionType pos; cairo_rectangle_int_t rect; @@ -11810,7 +11811,8 @@ _gtk_window_get_shadow_width (GtkWindow *window, void _gtk_window_add_popover (GtkWindow *window, - GtkWidget *popover) + GtkWidget *popover, + GtkWidget *parent) { GtkWindowPrivate *priv; GtkWindowPopover *data; @@ -11818,7 +11820,9 @@ _gtk_window_add_popover (GtkWindow *window, g_return_if_fail (GTK_IS_WINDOW (window)); g_return_if_fail (GTK_IS_WIDGET (popover)); + g_return_if_fail (GTK_IS_WIDGET (parent)); g_return_if_fail (gtk_widget_get_parent (popover) == NULL); + g_return_if_fail (gtk_widget_is_ancestor (parent, GTK_WIDGET (window))); priv = window->priv; @@ -11827,6 +11831,7 @@ _gtk_window_add_popover (GtkWindow *window, data = g_new0 (GtkWindowPopover, 1); data->widget = popover; + data->parent = parent; priv->popovers = g_list_prepend (priv->popovers, data); if (gtk_widget_get_realized (GTK_WIDGET (window))) @@ -11943,6 +11948,52 @@ _gtk_window_get_popover_position (GtkWindow *window, *rect = data->rect; } +/* + * _gtk_window_get_popover_parent: + * @window: A #GtkWindow + * @popover: A popover #GtkWidget + * + * Returns the conceptual parent of this popover, the real + * parent will always be @window. + * + * Returns: The conceptual parent widget, or %NULL. + **/ +GtkWidget * +_gtk_window_get_popover_parent (GtkWindow *window, + GtkWidget *popover) +{ + GtkWindowPopover *data; + + g_return_if_fail (GTK_IS_WINDOW (window)); + g_return_if_fail (GTK_IS_WIDGET (popover)); + + data = _gtk_window_has_popover (window, popover); + + if (data && data->parent) + return data->parent; + + return NULL; +} + +/* + * _gtk_window_is_popover_widget: + * @window: A #GtkWindow + * @possible_popover: A possible popover of @window + * + * Returns #TRUE if @possible_popover is a popover of @window. + * + * Returns: Whether the widget is a popover of @window + **/ +gboolean +_gtk_window_is_popover_widget (GtkWindow *window, + GtkWidget *possible_popover) +{ + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); + g_return_val_if_fail (GTK_IS_WIDGET (possible_popover), FALSE); + + return _gtk_window_has_popover (window, possible_popover) != NULL; +} + static GtkWidget *inspector_window = NULL; static void set_warn_again (gboolean warn); diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h index f6b3747701..a8236b0c9f 100644 --- a/gtk/gtkwindowprivate.h +++ b/gtk/gtkwindowprivate.h @@ -104,7 +104,8 @@ void _gtk_window_set_window_group (GtkWindow *window, /* Popovers */ void _gtk_window_add_popover (GtkWindow *window, - GtkWidget *popover); + GtkWidget *popover, + GtkWidget *popover_parent); void _gtk_window_remove_popover (GtkWindow *window, GtkWidget *popover); void _gtk_window_set_popover_position (GtkWindow *window, @@ -116,6 +117,11 @@ void _gtk_window_get_popover_position (GtkWindow *window, GtkPositionType *pos, cairo_rectangle_int_t *rect); +GtkWidget * _gtk_window_get_popover_parent (GtkWindow *window, + GtkWidget *popover); +gboolean _gtk_window_is_popover_widget (GtkWindow *window, + GtkWidget *popover); + GdkPixbuf *gtk_window_get_icon_for_size (GtkWindow *window, gint size);