gui_session.h: distinguish child-view creation

This patch replaces the optional parent argument of the create_view
RPC function by a dedicated create_child_view RPC function. This
is a preparatory step of removing the notion of an invalid handle
as a special case.

Issue #5242
This commit is contained in:
Norman Feske 2024-06-10 16:03:40 +02:00 committed by Christian Helmuth
parent 83ddc41d63
commit 1c148c7984
14 changed files with 126 additions and 88 deletions

View File

@ -117,8 +117,11 @@ struct Gui::Session_component : Rpc_object<Gui::Session>
Input::Session_capability input_session() override {
return _input_component.cap(); }
View_handle create_view(View_handle parent) override {
return _connection.create_view(parent); }
View_handle create_view() override {
return _connection.create_view(); }
View_handle create_child_view(View_handle parent) override {
return _connection.create_child_view(parent); }
void destroy_view(View_handle view) override {
_connection.destroy_view(view); }

View File

@ -121,8 +121,11 @@ struct Sandboxed_runtime::Gui_session : Session_object<Gui::Session>
Input::Session_capability input_session() override {
return _input_component.cap(); }
View_handle create_view(View_handle parent) override {
return _connection.create_view(parent); }
View_handle create_view() override {
return _connection.create_view(); }
View_handle create_child_view(View_handle parent) override {
return _connection.create_child_view(parent); }
void destroy_view(View_handle view) override {
_connection.destroy_view(view); }

View File

@ -345,9 +345,16 @@ class Gui_fader::Gui_session_component
return _gui.input_session();
}
View_handle create_view(View_handle parent) override
View_handle create_view() override
{
_view_handle = _gui.create_view(parent);
_view_handle = _gui.create_view();
_update_view_visibility();
return _view_handle;
}
View_handle create_child_view(View_handle parent) override
{
_view_handle = _gui.create_child_view(parent);
_update_view_visibility();
return _view_handle;
}

View File

@ -357,9 +357,14 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object<Gui::Session>,
return _dummy_input_component_cap;
}
View_handle create_view(View_handle parent) override
View_handle create_view() override
{
return _gui_session.create_view(parent);
return _gui_session.create_view();
}
View_handle create_child_view(View_handle parent) override
{
return _gui_session.create_child_view(parent);
}
void destroy_view(View_handle view) override

View File

@ -60,9 +60,14 @@ class Wm::Direct_gui_session : public Genode::Rpc_object<Gui::Session>
return _session.input_session();
}
View_handle create_view(View_handle parent) override
View_handle create_view() override
{
return _session.create_view(parent);
return _session.create_view();
}
View_handle create_child_view(View_handle parent) override
{
return _session.create_child_view(parent);
}
void destroy_view(View_handle view) override

View File

@ -437,7 +437,7 @@ class Wm::Gui::Child_view : public View, private List<Child_view>::Element
if (!parent_handle.valid())
return;
_real_handle = _real_gui.create_view(parent_handle);
_real_handle = _real_gui.create_child_view(parent_handle);
_real_gui.release_view_handle(parent_handle);
@ -658,35 +658,27 @@ class Wm::Gui::Session_component : public Rpc_object<Gui::Session>,
_input_session.submit(Input::Absolute_motion { pos.x, pos.y });
}
View &_create_view_object(View_handle parent_handle)
View &_create_view_object()
{
/*
* Create child view
*/
if (parent_handle.valid()) {
Top_level_view *view = new (_top_level_view_alloc)
Top_level_view(_session, _session_label, _has_alpha,
_window_registry, *this);
Weak_ptr<View> parent_ptr = _view_handle_registry.lookup(parent_handle);
view->resizeable(_mode_sigh.valid());
Child_view *view = new (_child_view_alloc)
Child_view(_session, _session_label, _has_alpha, parent_ptr);
_top_level_views.insert(view);
return *view;
}
_child_views.insert(view);
return *view;
}
View &_create_child_view_object(View_handle parent_handle)
{
Weak_ptr<View> parent_ptr = _view_handle_registry.lookup(parent_handle);
/*
* Create top-level view
*/
else {
Top_level_view *view = new (_top_level_view_alloc)
Top_level_view(_session, _session_label, _has_alpha,
_window_registry, *this);
Child_view *view = new (_child_view_alloc)
Child_view(_session, _session_label, _has_alpha, parent_ptr);
view->resizeable(_mode_sigh.valid());
_top_level_views.insert(view);
return *view;
}
_child_views.insert(view);
return *view;
}
void _destroy_top_level_view(Top_level_view &view)
@ -939,10 +931,17 @@ class Wm::Gui::Session_component : public Rpc_object<Gui::Session>,
return _input_session_cap;
}
View_handle create_view(View_handle parent) override
View_handle create_view() override
{
View &view = _create_view_object();
_env.ep().manage(view);
return _view_handle_registry.alloc(view);
}
View_handle create_child_view(View_handle parent) override
{
try {
View &view = _create_view_object(parent);
View &view = _create_child_view_object(parent);
_env.ep().manage(view);
return _view_handle_registry.alloc(view);
}

View File

@ -62,7 +62,9 @@ struct Wm::Layouter_gui_session : Genode::Rpc_object<Gui::Session>
return _input_session_cap;
}
View_handle create_view(View_handle) override { return View_handle(); }
View_handle create_view() override { return View_handle(); }
View_handle create_child_view(View_handle) override { return View_handle(); }
void destroy_view(View_handle) override { }

View File

@ -47,8 +47,11 @@ class Gui::Session_client : public Rpc_client<Session>
Input::Session_capability input_session() override {
return call<Rpc_input_session>(); }
View_handle create_view(View_handle parent = View_handle()) override {
return call<Rpc_create_view>(parent); }
View_handle create_view() override {
return call<Rpc_create_view>(); }
View_handle create_child_view(View_handle parent) override {
return call<Rpc_create_child_view>(parent); }
void destroy_view(View_handle view) override {
call<Rpc_destroy_view>(view); }

View File

@ -196,7 +196,15 @@ struct Gui::Session : Genode::Session
virtual Input::Session_capability input_session() = 0;
/**
* Create a new view at the buffer
* Create a new top-level view at the buffer
*
* \throw Invalid_handle
* \return handle for new view
*/
virtual View_handle create_view() = 0;
/**
* Create a new child view at the buffer
*
* \param parent parent view
*
@ -205,10 +213,8 @@ struct Gui::Session : Genode::Session
*
* The 'parent' argument allows the client to use the location of an
* existing view as the coordinate origin for the to-be-created view.
* If an invalid handle is specified (default), the view will be a
* top-level view.
*/
virtual View_handle create_view(View_handle parent = View_handle()) = 0;
virtual View_handle create_child_view(View_handle parent) = 0;
/**
* Destroy view
@ -307,6 +313,8 @@ struct Gui::Session : Genode::Session
GENODE_RPC(Rpc_framebuffer_session, Framebuffer::Session_capability, framebuffer_session);
GENODE_RPC(Rpc_input_session, Input::Session_capability, input_session);
GENODE_RPC_THROW(Rpc_create_view, View_handle, create_view,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps));
GENODE_RPC_THROW(Rpc_create_child_view, View_handle, create_child_view,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps, Invalid_handle), View_handle);
GENODE_RPC(Rpc_destroy_view, void, destroy_view, View_handle);
GENODE_RPC_THROW(Rpc_view_handle, View_handle, view_handle,
@ -323,8 +331,8 @@ struct Gui::Session : Genode::Session
Framebuffer::Mode, bool);
GENODE_RPC_INTERFACE(Rpc_framebuffer_session, Rpc_input_session,
Rpc_create_view, Rpc_destroy_view, Rpc_view_handle,
Rpc_view_capability, Rpc_release_view_handle,
Rpc_create_view, Rpc_create_child_view, Rpc_destroy_view,
Rpc_view_handle, Rpc_view_capability, Rpc_release_view_handle,
Rpc_command_dataspace, Rpc_execute, Rpc_mode,
Rpc_mode_sigh, Rpc_buffer, Rpc_focus);
};

View File

@ -231,50 +231,49 @@ void Gui_session::submit_input_event(Input::Event e)
}
Gui_session::View_handle Gui_session::create_view(View_handle parent_handle)
void Gui_session::_adopt_new_view(View &view)
{
View *view = nullptr;
_view_stack.title(view, "");
view.apply_origin_policy(_pointer_origin);
/*
* Create child view
*/
if (parent_handle.valid()) {
_view_list.insert(&view);
_env.ep().manage(view);
}
try {
Locked_ptr<View> parent(_view_handle_registry.lookup(parent_handle));
if (!parent.valid())
return View_handle();
view = new (_view_alloc)
View(*this, _texture, { .transparent = false, .background = false }, &(*parent));
Gui_session::View_handle Gui_session::create_view()
{
View &view = *new (_view_alloc)
View(*this, _texture, { .transparent = false, .background = false }, nullptr);
parent->add_child(*view);
}
catch (View_handle_registry::Lookup_failed) { return View_handle(); }
catch (View_handle_registry::Out_of_memory) { throw Out_of_ram(); }
}
_adopt_new_view(view);
/*
* Create top-level view
*/
else {
try {
view = new (_view_alloc)
View(*this, _texture, { .transparent = false, .background = false }, nullptr);
}
catch (Allocator::Out_of_memory) { throw Out_of_ram(); }
}
return _view_handle_registry.alloc(view);
}
_view_stack.title(*view, "");
view->apply_origin_policy(_pointer_origin);
_view_list.insert(view);
_env.ep().manage(*view);
Gui_session::View_handle Gui_session::create_child_view(View_handle const parent_handle)
{
View *parent_view_ptr = nullptr;
try {
return _view_handle_registry.alloc(*view);
Locked_ptr<View> parent(_view_handle_registry.lookup(parent_handle));
if (parent.valid())
parent_view_ptr = &(*parent);
}
catch (View_handle_registry::Out_of_memory) { throw Out_of_ram(); }
catch (View_handle_registry::Lookup_failed) { }
if (!parent_view_ptr)
return View_handle();
View &view = *new (_view_alloc)
View(*this, _texture, { .transparent = false, .background = false }, parent_view_ptr);
parent_view_ptr->add_child(view);
_adopt_new_view(view);
return _view_handle_registry.alloc(view);
}

View File

@ -154,6 +154,8 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
void _destroy_view(View &);
void _adopt_new_view(View &);
public:
Gui_session(Env &env,
@ -346,7 +348,9 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
Input::Session_capability input_session() override {
return _input_session_cap; }
View_handle create_view(View_handle parent_handle) override;
View_handle create_view() override;
View_handle create_child_view(View_handle parent_handle) override;
void destroy_view(View_handle handle) override;

View File

@ -36,13 +36,13 @@ class Test::View
using View_handle = Gui::Session::View_handle;
Gui::Session_client &_gui;
View_handle const _handle = _gui.create_view(View_handle{});
Gui::Rect const _rect;
Gui::Connection &_gui;
View_handle const _handle = _gui.create_view();
Gui::Rect const _rect;
public:
View(Gui::Session_client &gui, Gui::Rect rect) : _gui(gui), _rect(rect)
View(Gui::Connection &gui, Gui::Rect rect) : _gui(gui), _rect(rect)
{
using Command = Gui::Session::Command;

View File

@ -115,7 +115,7 @@ struct Test::Child_view : View
[&] /* create_fn */ {
using View_handle = Gui::Session::View_handle;
View_handle const parent_handle = gui.view_handle(parent.view_cap());
View_handle const handle = gui.create_view(parent_handle);
View_handle const handle = gui.create_child_view(parent_handle);
gui.release_view_handle(parent_handle);
return handle;
}

View File

@ -38,13 +38,13 @@ class Test::View
using View_handle = Gui::Session::View_handle;
Gui::Session_client &_gui;
View_handle const _handle = _gui.create_view(View_handle{});
Gui::Rect const _rect;
Gui::Connection &_gui;
View_handle const _handle = _gui.create_view();
Gui::Rect const _rect;
public:
View(Gui::Session_client &gui, Gui::Rect rect) : _gui(gui), _rect(rect)
View(Gui::Connection &gui, Gui::Rect rect) : _gui(gui), _rect(rect)
{
using Command = Gui::Session::Command;