wm: hide child views if top-level view vanishes

This patch handles the corner case of switching virtual desktops while
child views are visible. Examples of such child views are tool tips,
pull-down menus, or the graph of the top-view utility. The switch to
another virtual desktop would implicitely turn the child views into
top-level views of the root nitpicker GUI server until switching back
to the original virtual desktop.

The patch implements the expected behavior of hiding all child views
that belong to a disappearing top-level view.
This commit is contained in:
Norman Feske 2022-04-07 16:54:57 +02:00 committed by Christian Helmuth
parent d21464399f
commit 78d7a08618
2 changed files with 31 additions and 0 deletions

View File

@ -54,6 +54,8 @@ struct Wm::Decorator_content_callback : Interface
virtual Gui::View_capability content_view(Window_registry::Id win_id) = 0;
virtual void update_content_child_views(Window_registry::Id win_id) = 0;
virtual void hide_content_child_views(Window_registry::Id win_id) = 0;
};
@ -369,6 +371,9 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object<Gui::Session>,
Gui::Rect rect(Gui::Point(0, 0), Gui::Area(0, 0));
_gui_session.enqueue<Gui::Session::Command::Geometry>(view, rect);
_gui_session.execute();
Window_registry::Id win_id = _content_registry.lookup(view);
_content_callback.hide_content_child_views(win_id);
}
_gui_session.destroy_view(view);

View File

@ -451,6 +451,15 @@ class Wm::Gui::Child_view : public View, private List<Child_view>::Element
{
_apply_view_config();
}
void hide()
{
if (!_real_handle.valid())
return;
_real_gui.destroy_view(_real_handle);
_real_handle = { };
}
};
@ -829,6 +838,13 @@ class Wm::Gui::Session_component : public Rpc_object<Gui::Session>,
v->update_child_stacking();
}
void hide_content_child_views(Window_registry::Id id)
{
for (Child_view *v = _child_views.first(); v; v = v->next())
if (v->belongs_to_win_id(id))
v->hide();
}
void content_geometry(Window_registry::Id id, Rect rect)
{
for (Top_level_view *v = _top_level_views.first(); v; v = v->next()) {
@ -1419,6 +1435,16 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Session> >,
s->update_stacking_order_of_children(id);
}
void hide_content_child_views(Window_registry::Id id) override
{
/*
* Destroy physical views for the child views belonging to the
* specified id.
*/
for (Session_component *s = _sessions.first(); s; s = s->next())
s->hide_content_child_views(id);
}
void content_geometry(Window_registry::Id id, Rect rect) override
{
for (Session_component *s = _sessions.first(); s; s = s->next())