forked from AuroraMiddleware/gtk
widget: Add GtkWidgetClass:root and :unroot functions
They get added whenever a widget gets added into a hierarchy with a root widget.
This commit is contained in:
parent
aeda099f47
commit
4ca1f7e29f
@ -602,6 +602,8 @@ static void gtk_widget_real_move_focus (GtkWidget
|
||||
GtkDirectionType direction);
|
||||
static gboolean gtk_widget_real_keynav_failed (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
static void gtk_widget_root (GtkWidget *widget);
|
||||
static void gtk_widget_unroot (GtkWidget *widget);
|
||||
#ifdef G_ENABLE_CONSISTENCY_CHECKS
|
||||
static void gtk_widget_verify_invariants (GtkWidget *widget);
|
||||
static void gtk_widget_push_verify_invariants (GtkWidget *widget);
|
||||
@ -853,6 +855,18 @@ gtk_widget_real_grab_notify (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_real_root (GtkWidget *widget)
|
||||
{
|
||||
gtk_widget_forall (widget, (GtkCallback) gtk_widget_root, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_real_unroot (GtkWidget *widget)
|
||||
{
|
||||
gtk_widget_forall (widget, (GtkCallback) gtk_widget_unroot, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
{
|
||||
@ -899,6 +913,8 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
klass->unmap = gtk_widget_real_unmap;
|
||||
klass->realize = gtk_widget_real_realize;
|
||||
klass->unrealize = gtk_widget_real_unrealize;
|
||||
klass->root = gtk_widget_real_root;
|
||||
klass->unroot = gtk_widget_real_unroot;
|
||||
klass->size_allocate = gtk_widget_real_size_allocate;
|
||||
klass->get_request_mode = gtk_widget_real_get_request_mode;
|
||||
klass->measure = gtk_widget_real_measure;
|
||||
@ -2868,6 +2884,9 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
|
||||
gtk_css_node_set_visible (priv->cssnode, priv->visible);
|
||||
/* need to set correct type here, and only class has the correct type here */
|
||||
gtk_css_node_set_widget_type (priv->cssnode, G_TYPE_FROM_CLASS (g_class));
|
||||
|
||||
if (g_type_is_a (G_TYPE_FROM_CLASS (g_class), GTK_TYPE_ROOT))
|
||||
priv->root = (GtkRoot *) widget;
|
||||
}
|
||||
|
||||
|
||||
@ -2995,6 +3014,42 @@ gtk_widget_new (GType type,
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_root (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
/* roots are rooted by default */
|
||||
if (GTK_IS_ROOT (widget))
|
||||
return;
|
||||
|
||||
g_assert (priv->root == NULL);
|
||||
g_assert (!priv->realized);
|
||||
g_assert (priv->parent);
|
||||
g_assert (priv->parent->priv->root);
|
||||
|
||||
priv->root = priv->parent->priv->root;
|
||||
|
||||
GTK_WIDGET_GET_CLASS (widget)->root (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
|
||||
/* roots are rooted by default and cannot be unrooted */
|
||||
if (GTK_IS_ROOT (widget))
|
||||
return;
|
||||
|
||||
g_assert (priv->root);
|
||||
g_assert (!priv->realized);
|
||||
|
||||
GTK_WIDGET_GET_CLASS (widget)->unroot (widget);
|
||||
|
||||
priv->root = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_unparent:
|
||||
* @widget: a #GtkWidget
|
||||
@ -3046,6 +3101,9 @@ gtk_widget_unparent (GtkWidget *widget)
|
||||
if (_gtk_widget_get_realized (widget))
|
||||
gtk_widget_unrealize (widget);
|
||||
|
||||
if (priv->root)
|
||||
gtk_widget_unroot (widget);
|
||||
|
||||
/* If we are unanchoring the child, we save around the toplevel
|
||||
* to emit hierarchy changed
|
||||
*/
|
||||
@ -3103,10 +3161,9 @@ gtk_widget_unparent (GtkWidget *widget)
|
||||
gtk_list_list_model_item_removed (old_parent->priv->children_observer, old_prev_sibling);
|
||||
|
||||
if (toplevel)
|
||||
{
|
||||
_gtk_widget_propagate_hierarchy_changed (widget, toplevel);
|
||||
g_object_unref (toplevel);
|
||||
}
|
||||
_gtk_widget_propagate_hierarchy_changed (widget, toplevel);
|
||||
|
||||
g_clear_object (&toplevel);
|
||||
|
||||
/* Now that the parent pointer is nullified and the hierarchy-changed
|
||||
* already passed, go ahead and unset the parent window, if we are unparenting
|
||||
@ -6591,7 +6648,11 @@ gtk_widget_reposition_after (GtkWidget *widget,
|
||||
}
|
||||
|
||||
if (priv->parent->priv->anchored && prev_parent == NULL)
|
||||
_gtk_widget_propagate_hierarchy_changed (widget, NULL);
|
||||
{
|
||||
_gtk_widget_propagate_hierarchy_changed (widget, NULL);
|
||||
}
|
||||
if (parent->priv->root && priv->root == NULL)
|
||||
gtk_widget_root (widget);
|
||||
|
||||
if (prev_parent == NULL)
|
||||
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_PARENT]);
|
||||
|
@ -152,6 +152,9 @@ struct _GtkWidget
|
||||
* widget is destroyed, which means that gtk_widget_unrealize() has
|
||||
* been called or the widget has been unmapped (that is, it is going
|
||||
* to be hidden).
|
||||
* @root: Called when the widget gets added to a #GtkRoot widget.
|
||||
* @unroot: Called when the widget is about to be removed from its
|
||||
* #GtkRoot widget.
|
||||
* @size_allocate: Signal emitted to get the widget allocation.
|
||||
* @state_flags_changed: Signal emitted when the widget state changes,
|
||||
* see gtk_widget_get_state_flags().
|
||||
@ -247,6 +250,8 @@ struct _GtkWidgetClass
|
||||
void (* unmap) (GtkWidget *widget);
|
||||
void (* realize) (GtkWidget *widget);
|
||||
void (* unrealize) (GtkWidget *widget);
|
||||
void (* root) (GtkWidget *widget);
|
||||
void (* unroot) (GtkWidget *widget);
|
||||
void (* size_allocate) (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
|
@ -124,6 +124,11 @@ struct _GtkWidgetPrivate
|
||||
*/
|
||||
gchar *name;
|
||||
|
||||
/* The root this widget belongs to or %NULL if widget is not
|
||||
* rooted or is a #GtkRoot itself.
|
||||
*/
|
||||
GtkRoot *root;
|
||||
|
||||
/* The list of attached windows to this widget.
|
||||
* We keep a list in order to call reset_style to all of them,
|
||||
* recursively.
|
||||
|
Loading…
Reference in New Issue
Block a user