From c74a4fbbe2ed5fe4f63e6f7171bf56f9e644a1dc Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 3 Jun 2015 11:20:58 +0200 Subject: [PATCH] wm: decouple decorator and layouter from wm --- repos/gems/run/wm.run | 47 ++- .../src/app/floating_window_layouter/main.cc | 8 +- .../gems/src/server/wm/decorator_nitpicker.h | 88 ++---- repos/gems/src/server/wm/decorator_slave.h | 128 -------- repos/gems/src/server/wm/last_motion.h | 22 ++ repos/gems/src/server/wm/layouter_nitpicker.h | 93 ++++++ repos/gems/src/server/wm/main.cc | 141 ++------- repos/gems/src/server/wm/nitpicker.h | 298 ++++++++++++------ .../src/server/wm/window_layouter_slave.h | 137 -------- repos/gems/src/server/wm/window_registry.h | 11 +- 10 files changed, 422 insertions(+), 551 deletions(-) delete mode 100644 repos/gems/src/server/wm/decorator_slave.h create mode 100644 repos/gems/src/server/wm/last_motion.h create mode 100644 repos/gems/src/server/wm/layouter_nitpicker.h delete mode 100644 repos/gems/src/server/wm/window_layouter_slave.h diff --git a/repos/gems/run/wm.run b/repos/gems/run/wm.run index 69f1974995..afcb094b06 100644 --- a/repos/gems/run/wm.run +++ b/repos/gems/run/wm.run @@ -125,12 +125,53 @@ append config { + + + + + + + + + + + + + + + + + - - + + + + + + + + - + + + + + + + + + + + + + + + + + + + diff --git a/repos/gems/src/app/floating_window_layouter/main.cc b/repos/gems/src/app/floating_window_layouter/main.cc index 589a372205..c0e6a0953b 100644 --- a/repos/gems/src/app/floating_window_layouter/main.cc +++ b/repos/gems/src/app/floating_window_layouter/main.cc @@ -16,7 +16,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -307,7 +308,6 @@ struct Floating_window_layouter::Main Attached_rom_dataspace hover { "hover" }; - /** * Install handler for responding to user input */ @@ -316,7 +316,9 @@ struct Floating_window_layouter::Main Signal_dispatcher
input_dispatcher = { sig_rec, *this, &Main::handle_input }; - Input::Connection input; + Nitpicker::Connection nitpicker; + + Input::Session_client input { nitpicker.input_session() }; Attached_dataspace input_ds { input.dataspace() }; diff --git a/repos/gems/src/server/wm/decorator_nitpicker.h b/repos/gems/src/server/wm/decorator_nitpicker.h index 45b4977209..f917254392 100644 --- a/repos/gems/src/server/wm/decorator_nitpicker.h +++ b/repos/gems/src/server/wm/decorator_nitpicker.h @@ -1,5 +1,5 @@ /* - * \brief Local nitpicker service provided to decorator + * \brief Nitpicker service provided to decorator * \author Norman Feske * \date 2014-02-14 */ @@ -16,8 +16,10 @@ /* Genode includes */ #include +#include #include #include +#include #include #include #include @@ -25,6 +27,7 @@ /* local includes */ #include +#include namespace Wm { class Main; using Genode::size_t; @@ -37,6 +40,7 @@ namespace Wm { class Main; using Genode::Attached_dataspace; using Genode::Attached_ram_dataspace; using Genode::Signal_rpc_member; + using Genode::Reporter; } @@ -163,7 +167,9 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object Attached_dataspace _nitpicker_input_ds { _nitpicker_input.dataspace() }; - Local_reporter &_pointer_reporter; + Reporter &_pointer_reporter; + + Last_motion &_last_motion; Input::Session_component &_window_layouter_input; @@ -186,12 +192,14 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object */ Decorator_nitpicker_session(Ram_session_capability ram, Entrypoint &ep, Allocator &md_alloc, - Local_reporter &pointer_reporter, + Reporter &pointer_reporter, + Last_motion &last_motion, Input::Session_component &window_layouter_input, Decorator_content_callback &content_callback) : _ram(ram), _pointer_reporter(pointer_reporter), + _last_motion(last_motion), _window_layouter_input(window_layouter_input), _content_callback(content_callback), _ep(ep), _md_alloc(md_alloc) @@ -215,7 +223,10 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object Input::Event const &ev = events[i]; if (ev.type() == Input::Event::MOTION) { - Local_reporter::Xml_generator xml(_pointer_reporter, [&] () + + _last_motion = LAST_MOTION_DECORATOR; + + Reporter::Xml_generator xml(_pointer_reporter, [&] () { xml.attribute("xpos", ev.ax()); xml.attribute("ypos", ev.ay()); @@ -224,10 +235,19 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object if (ev.type() == Input::Event::LEAVE) { - Local_reporter::Xml_generator xml(_pointer_reporter, [&] () - { - /* report empty pointer model */ - }); + /* + * Invalidate pointer as reported to the decorator if the + * pointer moved from a window decoration to a position + * with no window known to the window manager. If the last + * motion referred to one of the regular client session, + * this is not needed because the respective session will + * update the pointer model with the entered position + * already. + */ + if (_last_motion == LAST_MOTION_DECORATOR) { + Reporter::Xml_generator xml(_pointer_reporter, [&] () + { }); + } } _window_layouter_input.submit(ev); @@ -418,56 +438,4 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object void focus(Genode::Capability) { } }; - -struct Wm::Decorator_nitpicker_service : Genode::Service, Genode::Noncopyable -{ - private: - - Entrypoint &_ep; - Allocator &_md_alloc; - Ram_session_capability _ram; - Local_reporter &_pointer_reporter; - Input::Session_component &_window_layouter_input; - Decorator_content_callback &_content_callback; - - - public: - - Decorator_nitpicker_service(Entrypoint &ep, Allocator &md_alloc, - Ram_session_capability ram, - Local_reporter &pointer_reporter, - Input::Session_component &window_layouter_input, - Decorator_content_callback &content_callback) - : - Service("Nitpicker"), - _ep(ep), _md_alloc(md_alloc), - _ram(ram), _pointer_reporter(pointer_reporter), - _window_layouter_input(window_layouter_input), - _content_callback(content_callback) - { } - - Genode::Session_capability - session(const char *, Genode::Affinity const &) override - { - Decorator_nitpicker_session *s = new (_md_alloc) - Decorator_nitpicker_session(_ram, _ep, _md_alloc, - _pointer_reporter, - _window_layouter_input, - _content_callback); - - return _ep.manage(*s); - } - - void upgrade(Genode::Session_capability session, const char *args) override - { - typedef typename Object_pool::Guard Object_guard; - Object_guard np_session(_ep.rpc_ep().lookup_and_lock(session)); - - if (np_session) - np_session->upgrade(args); - } - - void close(Genode::Session_capability) { } -}; - #endif /* _DECORATOR_NITPICKER_H_ */ diff --git a/repos/gems/src/server/wm/decorator_slave.h b/repos/gems/src/server/wm/decorator_slave.h deleted file mode 100644 index f8dbb55902..0000000000 --- a/repos/gems/src/server/wm/decorator_slave.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * \brief Slave for drawing window decorations - * \author Norman Feske - * \date 2014-02-14 - */ - -/* - * Copyright (C) 2014 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _DECORATOR_SLAVE_H_ -#define _DECORATOR_SLAVE_H_ - -namespace Wm { - - class Decorator_slave; - - using Genode::Rom_session_capability; - using Genode::Capability; -} - - -class Wm::Decorator_slave -{ - private: - - Genode::Ram_session &_ram; - - class Policy : public Genode::Slave_policy - { - private: - - Genode::Service &_nitpicker_service; - - Single_session_service _window_layout_rom_service; - Single_session_service _pointer_rom_service; - Single_session_service _hover_report_service; - - protected: - - char const **_permitted_services() const - { - static char const *permitted_services[] = { - "CAP", "LOG", "SIGNAL", "RM", 0 }; - - return permitted_services; - }; - - public: - - Policy(Genode::Rpc_entrypoint &entrypoint, - Genode::Ram_session &ram, - Genode::Service &nitpicker_service, - Rom_session_capability window_layout_rom, - Rom_session_capability pointer_rom, - Genode::Capability hover_report) - : - Slave_policy("decorator", entrypoint, &ram), - _nitpicker_service(nitpicker_service), - _window_layout_rom_service("ROM", window_layout_rom), - _pointer_rom_service("ROM", pointer_rom), - _hover_report_service("Report", hover_report) - - { } - - Genode::Service *resolve_session_request(const char *service_name, - const char *args) override - { - using Genode::strcmp; - - if (strcmp(service_name, "Nitpicker") == 0) - return &_nitpicker_service; - - char label[128]; - Arg_string::find_arg(args, "label").string(label, sizeof(label), ""); - - if (strcmp(service_name, "ROM") == 0) { - - if (strcmp(label, "decorator -> window_layout") == 0) - return &_window_layout_rom_service; - - if (strcmp(label, "decorator -> pointer") == 0) - return &_pointer_rom_service; - } - - if (strcmp(service_name, "Report") == 0) { - - if (strcmp(label, "decorator -> hover") == 0) - return &_hover_report_service; - } - - return Genode::Slave_policy::resolve_session_request(service_name, args); - } - }; - - Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t); - Genode::Rpc_entrypoint _ep; - Policy _policy; - Genode::size_t const _quota = 4*1024*1024; - Genode::Slave _slave; - - public: - - /** - * Constructor - * - * \param ram RAM session for paying nitpicker sessions created - * by the decorator - */ - Decorator_slave(Genode::Cap_session &cap, - Genode::Service &nitpicker_service, - Genode::Ram_session &ram, - Rom_session_capability window_layout_rom, - Rom_session_capability pointer_rom, - Genode::Capability hover_report) - : - _ram(ram), - _ep(&cap, _ep_stack_size, "decorator"), - _policy(_ep, ram, nitpicker_service, window_layout_rom, - pointer_rom, hover_report), - _slave(_ep, _policy, _quota) - { } -}; - -#endif /* _DECORATOR_SLAVE_H_ */ diff --git a/repos/gems/src/server/wm/last_motion.h b/repos/gems/src/server/wm/last_motion.h new file mode 100644 index 0000000000..337cdb6fa1 --- /dev/null +++ b/repos/gems/src/server/wm/last_motion.h @@ -0,0 +1,22 @@ +/* + * \brief Type of client that receive the last motion event + * \author Norman Feske + * \date 2014-06-10 + */ + +/* + * Copyright (C) 2014 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _LAST_MOTION_H_ +#define _LAST_MOTION_H_ + +namespace Wm { + + enum Last_motion { LAST_MOTION_NITPICKER, LAST_MOTION_DECORATOR }; +} + +#endif /* _LAST_MOTION_H_ */ diff --git a/repos/gems/src/server/wm/layouter_nitpicker.h b/repos/gems/src/server/wm/layouter_nitpicker.h new file mode 100644 index 0000000000..7a6268183d --- /dev/null +++ b/repos/gems/src/server/wm/layouter_nitpicker.h @@ -0,0 +1,93 @@ +/* + * \brief Nitpicker service provided to layouter + * \author Norman Feske + * \date 2015-06-06 + */ + +/* + * Copyright (C) 2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _LAYOUTER_NITPICKER_H_ +#define _LAYOUTER_NITPICKER_H_ + +/* Genode includes */ +#include +#include + +namespace Wm { using Server::Entrypoint; } + + +namespace Wm { + struct Layouter_nitpicker_session; + struct Layouter_nitpicker_service; +} + + +struct Wm::Layouter_nitpicker_session : Genode::Rpc_object +{ + typedef Nitpicker::View_capability View_capability; + typedef Nitpicker::Session::View_handle View_handle; + + Input::Session_capability input_session_cap; + + Attached_ram_dataspace command_ds; + + Layouter_nitpicker_session(Genode::Ram_session &ram, + Input::Session_capability input_session_cap) + : + input_session_cap(input_session_cap), + command_ds(&ram, 4096) + { } + + + /********************************* + ** Nitpicker session interface ** + *********************************/ + + Framebuffer::Session_capability framebuffer_session() override + { + return Framebuffer::Session_capability(); + } + + Input::Session_capability input_session() override + { + return input_session_cap; + } + + View_handle create_view(View_handle) override { return View_handle(); } + + void destroy_view(View_handle) override { } + + View_handle view_handle(View_capability, View_handle) override + { + return View_handle(); + } + + View_capability view_capability(View_handle) override + { + return View_capability(); + } + + void release_view_handle(View_handle) override { } + + Genode::Dataspace_capability command_dataspace() override + { + return command_ds.cap(); + } + + void execute() override { } + + Framebuffer::Mode mode() override { return Framebuffer::Mode(); } + + void mode_sigh(Genode::Signal_context_capability) override { } + + void buffer(Framebuffer::Mode, bool) override { } + + void focus(Genode::Capability) { } +}; + +#endif /* _LAYOUTER_NITPICKER_H_ */ diff --git a/repos/gems/src/server/wm/main.cc b/repos/gems/src/server/wm/main.cc index 2401921917..e4e9c331bf 100644 --- a/repos/gems/src/server/wm/main.cc +++ b/repos/gems/src/server/wm/main.cc @@ -16,19 +16,11 @@ #include #include #include -#include +#include #include #include -/* gems includes */ -#include -#include -#include - /* local includes */ -#include -#include -#include #include namespace Wm { @@ -40,6 +32,7 @@ namespace Wm { using Genode::Rom_session_client; using Genode::Rom_connection; using Genode::Xml_node; + using Genode::Attached_rom_dataspace; } @@ -49,127 +42,34 @@ struct Wm::Main Genode::Cap_connection cap; - char const *report_rom_config = - " " - " " - " " - " " - " " - " " - " " - " "; + /* currently focused window, reported by the layouter */ + Attached_rom_dataspace focus_rom { "focus" }; - Report_rom_slave report_rom_slave = { cap, *env()->ram_session(), report_rom_config }; + /* resize requests, issued by the layouter */ + Attached_rom_dataspace resize_request_rom { "resize_request" }; - Rom_session_capability window_list_rom = report_rom_slave.rom_session("window_list"); - Rom_session_capability window_layout_rom = report_rom_slave.rom_session("window_layout"); - Rom_session_capability pointer_rom = report_rom_slave.rom_session("pointer"); - Rom_session_capability hover_rom = report_rom_slave.rom_session("hover"); + /* pointer position to be consumed by the layouter */ + Reporter pointer_reporter = { "pointer" }; - Rom_session_client focus_rom { report_rom_slave.rom_session("focus") }; - Rom_session_client resize_request_rom { report_rom_slave.rom_session("resize_request") }; - - /* pointer position reported by nitpicker */ - Capability pointer_report = report_rom_slave.report_session("pointer"); - Local_reporter pointer_reporter = { "pointer", pointer_report }; - - /* hovered element reported by decorator */ - Capability hover_report = report_rom_slave.report_session("hover"); - - Capability window_list_report = report_rom_slave.report_session("window_list"); - Local_reporter window_list_reporter = { "window_list", window_list_report }; - - Capability window_layout_report = report_rom_slave.report_session("window_layout"); - Capability resize_request_report = report_rom_slave.report_session("resize_request"); - Capability focus_report = report_rom_slave.report_session("focus"); - - Input::Session_component window_layouter_input; - - /* handler that forwards clicks into unfocused windows to the layouter */ - struct Click_handler : Nitpicker::Click_handler - { - Input::Session_component &window_layouter_input; - Local_reporter &pointer_reporter; - - void _submit_button_event(Input::Event::Type type, Nitpicker::Point pos) - { - window_layouter_input.submit(Input::Event(type, Input::BTN_LEFT, - pos.x(), pos.y(), 0, 0)); - } - - void handle_enter(Nitpicker::Point pos) override - { - Local_reporter::Xml_generator xml(pointer_reporter, [&] () - { - xml.attribute("xpos", pos.x()); - xml.attribute("ypos", pos.y()); - }); - } - - void handle_click(Nitpicker::Point pos) override - { - /* - * Propagate clicked-at position to decorator such that it can - * update its hover model. - */ - Local_reporter::Xml_generator xml(pointer_reporter, [&] () - { - xml.attribute("xpos", pos.x()); - xml.attribute("ypos", pos.y()); - }); - - /* - * Supply artificial mouse click to the decorator's input session - * (which is routed to the layouter). - */ - _submit_button_event(Input::Event::PRESS, pos); - _submit_button_event(Input::Event::RELEASE, pos); - } - - Click_handler(Input::Session_component &window_layouter_input, - Local_reporter &pointer_reporter) - : - window_layouter_input(window_layouter_input), - pointer_reporter(pointer_reporter) - { } - - } click_handler { window_layouter_input, pointer_reporter }; + /* list of present windows, to be consumed by the layouter */ + Reporter window_list_reporter = { "window_list" }; Window_registry window_registry { *env()->heap(), window_list_reporter }; Nitpicker::Root nitpicker_root { ep, window_registry, *env()->heap(), env()->ram_session_cap(), - click_handler }; - - Decorator_nitpicker_service decorator_nitpicker_service { - ep, *env()->heap(), env()->ram_session_cap(), pointer_reporter, - window_layouter_input, nitpicker_root }; - - Window_layouter_slave window_layouter_slave = { - cap, *env()->ram_session(), window_list_rom, hover_rom, - ep.manage(window_layouter_input), window_layout_report, - resize_request_report, focus_report }; - - Decorator_slave decorator_slave = { - cap, decorator_nitpicker_service, *env()->ram_session(), - window_layout_rom, pointer_rom, hover_report }; - - Genode::Lazy_volatile_object focus_ds; + pointer_reporter }; Nitpicker::Connection focus_nitpicker_session; void handle_focus_update(unsigned) { try { - if (!focus_ds.is_constructed() || focus_rom.update() == false) { - if (focus_ds.is_constructed()) - focus_ds->invalidate(); - focus_ds.construct(focus_rom.dataspace()); - } + focus_rom.update(); unsigned long win_id = 0; - Xml_node(focus_ds->local_addr()).sub_node("window") + Xml_node(focus_rom.local_addr()).sub_node("window") .attribute("id").value(&win_id); if (win_id) { @@ -186,21 +86,15 @@ struct Wm::Main Genode::Signal_rpc_member
focus_dispatcher = { ep, *this, &Main::handle_focus_update }; - Genode::Lazy_volatile_object resize_request_ds; - void handle_resize_request_update(unsigned) { try { - if (!resize_request_ds.is_constructed() || resize_request_rom.update() == false) { - if (resize_request_ds.is_constructed()) - resize_request_ds->invalidate(); - resize_request_ds.construct(resize_request_rom.dataspace()); - } + resize_request_rom.update(); char const * const node_type = "window"; Xml_node window = - Xml_node(resize_request_ds->local_addr()).sub_node(node_type); + Xml_node(resize_request_rom.local_addr()).sub_node(node_type); for (;;) { unsigned long win_id = 0, width = 0, height = 0; @@ -225,10 +119,11 @@ struct Wm::Main Main(Server::Entrypoint &ep) : ep(ep) { - window_layouter_input.event_queue().enabled(true); + pointer_reporter.enabled(true); /* initially report an empty window list */ - Local_reporter::Xml_generator xml(window_list_reporter, [&] () { }); + window_list_reporter.enabled(true); + Genode::Reporter::Xml_generator xml(window_list_reporter, [&] () { }); focus_rom.sigh(focus_dispatcher); resize_request_rom.sigh(resize_request_dispatcher); diff --git a/repos/gems/src/server/wm/nitpicker.h b/repos/gems/src/server/wm/nitpicker.h index db3e2d59f3..c92c4d35d9 100644 --- a/repos/gems/src/server/wm/nitpicker.h +++ b/repos/gems/src/server/wm/nitpicker.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -29,6 +31,8 @@ /* local includes */ #include +#include +#include namespace Wm { @@ -46,6 +50,8 @@ namespace Wm { using Genode::Attached_ram_dataspace; using Genode::Signal_context_capability; using Genode::Signal_transmitter; + using Genode::Reporter; + using Genode::Capability; } namespace Wm { namespace Nitpicker { @@ -57,7 +63,6 @@ namespace Wm { namespace Nitpicker { class View; class Top_level_view; class Child_view; - class Direct_view; class Session_component; class Root; @@ -391,37 +396,8 @@ class Wm::Nitpicker::Child_view : public View, }; -class Wm::Nitpicker::Direct_view : public View -{ - public: - - Direct_view(Nitpicker::Session_client &real_nitpicker, - Session_label const &session_label, - bool const direct) - : - View(real_nitpicker, session_label) - { - if (!direct) - return; - - typedef Nitpicker::Session::Command Command; - _real_handle = _real_nitpicker.create_view(); - _real_nitpicker.enqueue(_real_handle, - Rect(Point(0, 0), Area(0, 0))); - _real_nitpicker.enqueue(_real_handle); - _real_nitpicker.execute(); - } - - bool belongs_to_win_id(Window_registry::Id id) const override { return false; } - - void _propagate_view_geometry() override { } - - Point input_anchor_position() const override { return Point(); } -}; - - -class Wm::Nitpicker::Session_component : public Genode::Rpc_object, - public List::Element +class Wm::Nitpicker::Session_component : public Rpc_object, + public List::Element { private: @@ -431,7 +407,6 @@ class Wm::Nitpicker::Session_component : public Genode::Rpc_object, Ram_session_client _ram; Nitpicker::Connection _session { _session_label.string() }; - Direct_view _direct_view; Window_registry &_window_registry; Entrypoint &_ep; Tslab _top_level_view_alloc; @@ -570,20 +545,6 @@ class Wm::Nitpicker::Session_component : public Genode::Rpc_object, View &_create_view_object(View_handle parent_handle) { - /* - * If the session operates in direct mode, we subordinate all - * top-level views of the session to the 'direct_parent' pseudo - * view, which is located at the screen origin. - */ - if (!parent_handle.valid() && _direct_view.real_handle().valid()) { - - Child_view *view = new (_child_view_alloc) - Child_view(_session, _session_label, _direct_view.weak_ptr()); - - _child_views.insert(view); - return *view; - } - /* * Create child view */ @@ -709,12 +670,10 @@ class Wm::Nitpicker::Session_component : public Genode::Rpc_object, Entrypoint &ep, Allocator &session_alloc, Session_label const &session_label, - bool const direct, Click_handler &click_handler) : _session_label(session_label), _ram(ram), - _direct_view(_session, session_label, direct), _window_registry(window_registry), _ep(ep), _top_level_view_alloc(&session_alloc), @@ -923,60 +882,94 @@ class Wm::Nitpicker::Session_component : public Genode::Rpc_object, }; -class Wm::Nitpicker::Root : public Genode::Root_component, +class Wm::Nitpicker::Root : public Genode::Rpc_object >, public Decorator_content_callback { private: Entrypoint &_ep; + Allocator &_md_alloc; + Ram_session_capability _ram; enum { STACK_SIZE = 1024*sizeof(long) }; + Reporter &_pointer_reporter; + + Last_motion _last_motion = LAST_MOTION_DECORATOR; + Window_registry &_window_registry; - Click_handler &_click_handler; + Input::Session_component _window_layouter_input; + Input::Session_capability _window_layouter_input_cap { + _ep.manage(_window_layouter_input) }; + + /* handler that forwards clicks into unfocused windows to the layouter */ + struct Click_handler : Nitpicker::Click_handler + { + Input::Session_component &window_layouter_input; + Reporter &pointer_reporter; + Last_motion &last_motion; + + void _submit_button_event(Input::Event::Type type, Nitpicker::Point pos) + { + window_layouter_input.submit(Input::Event(type, Input::BTN_LEFT, + pos.x(), pos.y(), 0, 0)); + } + + void handle_enter(Nitpicker::Point pos) override + { + last_motion = LAST_MOTION_NITPICKER; + + Reporter::Xml_generator xml(pointer_reporter, [&] () + { + xml.attribute("xpos", pos.x()); + xml.attribute("ypos", pos.y()); + }); + } + + void handle_click(Nitpicker::Point pos) override + { + /* + * Propagate clicked-at position to decorator such that it can + * update its hover model. + */ + Reporter::Xml_generator xml(pointer_reporter, [&] () + { + xml.attribute("xpos", pos.x()); + xml.attribute("ypos", pos.y()); + }); + + /* + * Supply artificial mouse click to the decorator's input session + * (which is routed to the layouter). + */ + _submit_button_event(Input::Event::PRESS, pos); + _submit_button_event(Input::Event::RELEASE, pos); + } + + Click_handler(Input::Session_component &window_layouter_input, + Reporter &pointer_reporter, + Last_motion &last_motion) + : + window_layouter_input(window_layouter_input), + pointer_reporter(pointer_reporter), + last_motion(last_motion) + { } + + } _click_handler { _window_layouter_input, _pointer_reporter, + _last_motion }; + + /** + * List of regular sessions + */ List _sessions; - protected: + Layouter_nitpicker_session *_layouter_session = nullptr; - Session_component *_create_session(const char *args) override - { - bool direct = false; - - Session_label session_label(args); - - /* - * Determine session policy - */ - try { - Genode::Xml_node policy = Genode::Session_policy(session_label); - direct = policy.attribute("direct").has_value("yes"); - } - catch (...) { } - - Session_component *session = new (md_alloc()) - Session_component(_ram, _window_registry, - _ep, *md_alloc(), session_label, direct, - _click_handler); - - _sessions.insert(session); - - return session; - } - - void _destroy_session(Session_component *session) override - { - _sessions.remove(session); - Root_component::_destroy_session(session); - } - - void _upgrade_session(Session_component *s, const char *args) override - { - s->upgrade(args); - } + Decorator_nitpicker_session *_decorator_session = nullptr; public: @@ -986,16 +979,136 @@ class Wm::Nitpicker::Root : public Genode::Root_component, Root(Entrypoint &ep, Window_registry &window_registry, Allocator &md_alloc, Ram_session_capability ram, - Click_handler &click_handler) + Reporter &pointer_reporter) : - Root_component(&ep.rpc_ep(), &md_alloc), - _ep(ep), _ram(ram), _window_registry(window_registry), - _click_handler(click_handler) + _ep(ep), _md_alloc(md_alloc), _ram(ram), + _pointer_reporter(pointer_reporter), + _window_registry(window_registry) { + _window_layouter_input.event_queue().enabled(true); + Genode::env()->parent()->announce(_ep.manage(*this)); } + /******************** + ** Root interface ** + ********************/ + + Genode::Session_capability session(Session_args const &args, + Affinity const &affinity) override + { + Genode::Session_label session_label(args.string()); + + enum Role { ROLE_DECORATOR, ROLE_LAYOUTER, ROLE_REGULAR }; + Role role = ROLE_REGULAR; + + /* + * Determine session policy + */ + try { + Genode::Xml_node policy = Genode::Session_policy(session_label); + + char const *role_attr = "role"; + if (policy.has_attribute(role_attr)) { + + if (policy.attribute(role_attr).has_value("layouter")) + role = ROLE_LAYOUTER; + + if (policy.attribute(role_attr).has_value("decorator")) + role = ROLE_DECORATOR; + } + } + catch (...) { } + + switch (role) { + + case ROLE_REGULAR: + { + auto session = new (_md_alloc) + Session_component(_ram, _window_registry, + _ep, _md_alloc, session_label, + _click_handler); + _sessions.insert(session); + return _ep.manage(*session); + } + + case ROLE_DECORATOR: + { + _decorator_session = new (_md_alloc) + Decorator_nitpicker_session(_ram, _ep, _md_alloc, + _pointer_reporter, + _last_motion, + _window_layouter_input, + *this); + return _ep.manage(*_decorator_session); + } + + case ROLE_LAYOUTER: + { + _layouter_session = new (_md_alloc) + Layouter_nitpicker_session(*Genode::env()->ram_session(), + _window_layouter_input_cap); + + return _ep.manage(*_layouter_session); + } + } + + return Session_capability(); + } + + void upgrade(Genode::Session_capability session_cap, Upgrade_args const &args) override + { + if (!args.is_valid_string()) throw Root::Invalid_args(); + + Rpc_object_base *session = _ep.rpc_ep().lookup_and_lock(session_cap); + + if (!session) { + PDBG("session lookup failed"); + return; + } + + Session_component *regular_session = + dynamic_cast(session); + + if (regular_session) + regular_session->upgrade(args.string()); + + Decorator_nitpicker_session *decorator_session = + dynamic_cast(session); + + if (decorator_session) + decorator_session->upgrade(args.string()); + + session->release(); + } + + void close(Genode::Session_capability session_cap) override + { + Rpc_object_base *session = _ep.rpc_ep().lookup_and_lock(session_cap); + + Session_component *regular_session = dynamic_cast(session); + if (regular_session) { + _sessions.remove(regular_session); + _ep.dissolve(*regular_session); + Genode::destroy(_md_alloc, regular_session); + return; + } + + if (session == _decorator_session) { + _ep.dissolve(*_decorator_session); + Genode::destroy(_md_alloc, _decorator_session); + _decorator_session = nullptr; + } + + if (session == _layouter_session) { + _ep.dissolve(*_layouter_session); + Genode::destroy(_md_alloc, _layouter_session); + _layouter_session = nullptr; + } + } + + /****************************************** ** Decorator_content_callback interface ** ******************************************/ @@ -1024,8 +1137,9 @@ class Wm::Nitpicker::Root : public Genode::Root_component, /* * Try to create physical views for its child views. */ - for (Session_component *s = _sessions.first(); s; s = s->next()) + for (Session_component *s = _sessions.first(); s; s = s->next()) { s->try_to_init_real_child_views(); + } /* * Apply the stacking order to the child views that belong to the diff --git a/repos/gems/src/server/wm/window_layouter_slave.h b/repos/gems/src/server/wm/window_layouter_slave.h deleted file mode 100644 index 63de576a34..0000000000 --- a/repos/gems/src/server/wm/window_layouter_slave.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * \brief Slave for managing the window layout - * \author Norman Feske - * \date 2014-02-14 - */ - -/* - * Copyright (C) 2014 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _WINDOW_LAYOUTER_SLAVE_H_ -#define _WINDOW_LAYOUTER_SLAVE_H_ - -namespace Wm { - - class Window_layouter_slave; - - using Genode::Rom_session_capability; - using Genode::Capability; -} - - -class Wm::Window_layouter_slave -{ - private: - - Genode::Ram_session &_ram; - - class Policy : public Genode::Slave_policy - { - private: - - Single_session_service _window_list_rom_service; - Single_session_service _hover_rom_service; - Single_session_service _input_service; - Single_session_service _window_layout_report_service; - Single_session_service _resize_request_report_service; - Single_session_service _focus_report_service; - - protected: - - char const **_permitted_services() const - { - static char const *permitted_services[] = { - "CAP", "LOG", "SIGNAL", "RM", "Timer", 0 }; - - return permitted_services; - }; - - public: - - Policy(Genode::Rpc_entrypoint &entrypoint, - Genode::Ram_session &ram, - Rom_session_capability window_list_rom, - Rom_session_capability hover_rom, - Input::Session_capability input, - Capability window_layout_report, - Capability resize_request_report, - Capability focus_report) - : - Slave_policy("floating_window_layouter", entrypoint, &ram), - _window_list_rom_service("ROM", window_list_rom), - _hover_rom_service("ROM", hover_rom), - _input_service("Input", input), - _window_layout_report_service("Report", window_layout_report), - _resize_request_report_service("Report", resize_request_report), - _focus_report_service("Report", focus_report) - { } - - Genode::Service *resolve_session_request(const char *service_name, - const char *args) override - { - using Genode::strcmp; - - char label[128]; - Arg_string::find_arg(args, "label").string(label, sizeof(label), ""); - - if (strcmp(service_name, "ROM") == 0) { - - if (strcmp(label, "floating_window_layouter -> window_list") == 0) - return &_window_list_rom_service; - - if (strcmp(label, "floating_window_layouter -> hover") == 0) - return &_hover_rom_service; - } - - if (strcmp(service_name, "Report") == 0) { - - if (strcmp(label, "floating_window_layouter -> window_layout") == 0) - return &_window_layout_report_service; - - if (strcmp(label, "floating_window_layouter -> resize_request") == 0) - return &_resize_request_report_service; - - if (strcmp(label, "floating_window_layouter -> focus") == 0) - return &_focus_report_service; - } - - if (strcmp(service_name, "Input") == 0) - return &_input_service; - - return Genode::Slave_policy::resolve_session_request(service_name, args); - } - }; - - Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t); - Genode::Rpc_entrypoint _ep; - Policy _policy; - Genode::size_t const _quota = 1*1024*1024; - Genode::Slave _slave; - - public: - - /** - * Constructor - */ - Window_layouter_slave(Genode::Cap_session &cap, - Genode::Ram_session &ram, - Rom_session_capability window_list_rom, - Rom_session_capability hover_rom, - Input::Session_capability input, - Capability window_layout_report, - Capability resize_request_report, - Capability focus_report) - : - _ram(ram), - _ep(&cap, _ep_stack_size, "floating_window_layouter"), - _policy(_ep, ram, window_list_rom, hover_rom, input, - window_layout_report, resize_request_report, focus_report), - _slave(_ep, _policy, _quota) - { } -}; - -#endif /* _WINDOW_LAYOUTER_SLAVE_H_ */ diff --git a/repos/gems/src/server/wm/window_registry.h b/repos/gems/src/server/wm/window_registry.h index 23d0c9ffcd..c25fc70b38 100644 --- a/repos/gems/src/server/wm/window_registry.h +++ b/repos/gems/src/server/wm/window_registry.h @@ -17,9 +17,9 @@ /* Genode includes */ #include #include -#include #include #include +#include /* gems includes */ #include @@ -31,6 +31,7 @@ namespace Wm { using Genode::Allocator; using Genode::List; using Genode::Xml_generator; + using Genode::Reporter; typedef Genode::Surface_base::Area Area; typedef Genode::Surface_base::Point Point; @@ -96,8 +97,8 @@ class Wm::Window_registry private: - Allocator &_alloc; - Local_reporter &_window_list_reporter; + Allocator &_alloc; + Reporter &_window_list_reporter; enum { MAX_WINDOWS = 1024 }; @@ -116,7 +117,7 @@ class Wm::Window_registry void _report_updated_window_list_model() const { - Local_reporter::Xml_generator xml(_window_list_reporter, [&] () + Reporter::Xml_generator xml(_window_list_reporter, [&] () { for (Window const *w = _windows.first(); w; w = w->next()) w->generate_window_list_entry_xml(xml); @@ -140,7 +141,7 @@ class Wm::Window_registry public: - Window_registry(Allocator &alloc, Local_reporter &window_list_reporter) + Window_registry(Allocator &alloc, Reporter &window_list_reporter) : _alloc(alloc), _window_list_reporter(window_list_reporter) {