diff --git a/js/ui/main.js b/js/ui/main.js index 155cdb299..603f48522 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -136,6 +136,7 @@ function start() { // Set up stage hierarchy to group all UI actors under one container. uiGroup = new Clutter.Group(); + St.set_ui_root(global.stage, uiGroup); global.window_group.reparent(uiGroup); global.overlay_group.reparent(uiGroup); global.stage.add_actor(uiGroup); diff --git a/src/st/st-widget.c b/src/st/st-widget.c index 45b3f8db9..fe5d1b0c5 100644 --- a/src/st/st-widget.c +++ b/src/st/st-widget.c @@ -2222,3 +2222,71 @@ on_can_focus_notify (GObject *gobject, atk_object_notify_state_change (ATK_OBJECT (data), ATK_STATE_FOCUSABLE, can_focus); } + +static GQuark +st_ui_root_quark (void) +{ + static GQuark value = 0; + if (G_UNLIKELY (value == 0)) + value = g_quark_from_static_string ("st-ui-root"); + return value; +} + +static void +st_ui_root_destroyed (ClutterActor *actor, + ClutterStage *stage) +{ + st_set_ui_root (stage, NULL); + g_signal_handlers_disconnect_by_func (actor, st_ui_root_destroyed, stage); +} + +/** + * st_get_ui_root: + * @stage: a #ClutterStage + * @container: (allow-none): the new UI root + * + * Sets a #ClutterContainer to be the parent of all UI in the program. + * This container is used when St needs to add new content outside the + * widget hierarchy, for example, when it shows a tooltip over a widget. + */ +void +st_set_ui_root (ClutterStage *stage, + ClutterContainer *container) +{ + ClutterContainer *previous; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + g_return_if_fail (CLUTTER_IS_CONTAINER (container)); + + previous = st_get_ui_root (stage); + if (previous) + g_signal_handlers_disconnect_by_func (container, st_ui_root_destroyed, stage); + + if (container) + { + g_signal_connect (container, "destroy", G_CALLBACK (st_ui_root_destroyed), stage); + g_object_set_qdata_full (G_OBJECT (stage), st_ui_root_quark (), g_object_ref (container), g_object_unref); + } +} + +/** + * st_get_ui_root: + * @stage: a #ClutterStage + * + * Returns: (transfer none): the container which should be the parent of all user interface, + * which can be set with st_set_ui_root(). If not set, returns @stage + */ +ClutterContainer * +st_get_ui_root (ClutterStage *stage) +{ + ClutterContainer *root; + + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); + + root = g_object_get_qdata (G_OBJECT (stage), st_ui_root_quark ()); + + if (root != NULL) + return root; + else + return CLUTTER_CONTAINER (stage); +} diff --git a/src/st/st-widget.h b/src/st/st-widget.h index 7f5efec7a..d38eb6893 100644 --- a/src/st/st-widget.h +++ b/src/st/st-widget.h @@ -162,6 +162,10 @@ char *st_describe_actor (ClutterActor *actor); void st_set_slow_down_factor (gfloat factor); gfloat st_get_slow_down_factor (void); +void st_set_ui_root (ClutterStage *stage, + ClutterContainer *container); +ClutterContainer *st_get_ui_root (ClutterStage *stage); + G_END_DECLS #endif /* __ST_WIDGET_H__ */