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)
{