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
This commit is contained in:
Carlos Garnacho 2015-06-15 14:05:00 +02:00
parent 3955d93e9d
commit 76dc8aced5
4 changed files with 62 additions and 5 deletions

View File

@ -1699,7 +1699,7 @@ _gtk_popover_parent_hierarchy_changed (GtkWidget *widget,
_gtk_window_remove_popover (priv->window, GTK_WIDGET (popover)); _gtk_window_remove_popover (priv->window, GTK_WIDGET (popover));
if (new_window) 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; priv->window = new_window;
@ -1970,7 +1970,7 @@ gtk_popover_update_relative_to (GtkPopover *popover,
} }
if (priv->window) 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) if (relative_to)
scrollable = GTK_SCROLLABLE (gtk_widget_get_ancestor (priv->widget, GTK_TYPE_SCROLLABLE)); scrollable = GTK_SCROLLABLE (gtk_widget_get_ancestor (priv->widget, GTK_TYPE_SCROLLABLE));

View File

@ -309,7 +309,7 @@ _gtk_text_handle_ensure_widget (GtkTextHandle *handle,
priv->windows[pos].widget = g_object_ref_sink (widget); priv->windows[pos].widget = g_object_ref_sink (widget);
window = gtk_widget_get_ancestor (priv->parent, GTK_TYPE_WINDOW); 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_style_context_set_parent (gtk_widget_get_style_context (widget),
gtk_widget_get_style_context (priv->parent)); gtk_widget_get_style_context (priv->parent));

View File

@ -132,6 +132,7 @@ typedef struct _GtkWindowPopover GtkWindowPopover;
struct _GtkWindowPopover struct _GtkWindowPopover
{ {
GtkWidget *widget; GtkWidget *widget;
GtkWidget *parent;
GdkWindow *window; GdkWindow *window;
GtkPositionType pos; GtkPositionType pos;
cairo_rectangle_int_t rect; cairo_rectangle_int_t rect;
@ -11810,7 +11811,8 @@ _gtk_window_get_shadow_width (GtkWindow *window,
void void
_gtk_window_add_popover (GtkWindow *window, _gtk_window_add_popover (GtkWindow *window,
GtkWidget *popover) GtkWidget *popover,
GtkWidget *parent)
{ {
GtkWindowPrivate *priv; GtkWindowPrivate *priv;
GtkWindowPopover *data; 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_WINDOW (window));
g_return_if_fail (GTK_IS_WIDGET (popover)); 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_get_parent (popover) == NULL);
g_return_if_fail (gtk_widget_is_ancestor (parent, GTK_WIDGET (window)));
priv = window->priv; priv = window->priv;
@ -11827,6 +11831,7 @@ _gtk_window_add_popover (GtkWindow *window,
data = g_new0 (GtkWindowPopover, 1); data = g_new0 (GtkWindowPopover, 1);
data->widget = popover; data->widget = popover;
data->parent = parent;
priv->popovers = g_list_prepend (priv->popovers, data); priv->popovers = g_list_prepend (priv->popovers, data);
if (gtk_widget_get_realized (GTK_WIDGET (window))) if (gtk_widget_get_realized (GTK_WIDGET (window)))
@ -11943,6 +11948,52 @@ _gtk_window_get_popover_position (GtkWindow *window,
*rect = data->rect; *rect = data->rect;
} }
/*<private>
* _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;
}
/*<private>
* _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 GtkWidget *inspector_window = NULL;
static void set_warn_again (gboolean warn); static void set_warn_again (gboolean warn);

View File

@ -104,7 +104,8 @@ void _gtk_window_set_window_group (GtkWindow *window,
/* Popovers */ /* Popovers */
void _gtk_window_add_popover (GtkWindow *window, void _gtk_window_add_popover (GtkWindow *window,
GtkWidget *popover); GtkWidget *popover,
GtkWidget *popover_parent);
void _gtk_window_remove_popover (GtkWindow *window, void _gtk_window_remove_popover (GtkWindow *window,
GtkWidget *popover); GtkWidget *popover);
void _gtk_window_set_popover_position (GtkWindow *window, void _gtk_window_set_popover_position (GtkWindow *window,
@ -116,6 +117,11 @@ void _gtk_window_get_popover_position (GtkWindow *window,
GtkPositionType *pos, GtkPositionType *pos,
cairo_rectangle_int_t *rect); 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, GdkPixbuf *gtk_window_get_icon_for_size (GtkWindow *window,
gint size); gint size);