From 08d28e9b94a996ace929ce1dde5fa43e449f0e17 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sat, 4 Oct 2014 18:50:06 +0200 Subject: [PATCH] nitpicker: add 'session_control' RPC function The new 'session_control' function can be used to perform operations on the global view stack that span one or multiple sessions, e.g., bringing all views of specific sessions to the front, or hiding them. --- repos/os/include/nitpicker_session/client.h | 3 ++ .../nitpicker_session/nitpicker_session.h | 21 +++++++- repos/os/src/server/nitpicker/main.cc | 15 ++++++ repos/os/src/server/nitpicker/session.h | 20 ++++++++ repos/os/src/server/nitpicker/view_stack.cc | 2 + repos/os/src/server/nitpicker/view_stack.h | 51 +++++++++++++++++++ 6 files changed, 111 insertions(+), 1 deletion(-) diff --git a/repos/os/include/nitpicker_session/client.h b/repos/os/include/nitpicker_session/client.h index f569be68a..7b4f02fb9 100644 --- a/repos/os/include/nitpicker_session/client.h +++ b/repos/os/include/nitpicker_session/client.h @@ -83,6 +83,9 @@ class Nitpicker::Session_client : public Genode::Rpc_client void focus(Nitpicker::Session_capability session) override { call(session); } + void session_control(Label selector, Session_control operation) override { + call(selector, operation); } + /** * Enqueue command to command buffer * diff --git a/repos/os/include/nitpicker_session/nitpicker_session.h b/repos/os/include/nitpicker_session/nitpicker_session.h index 23f99f9c6..1d095fc63 100644 --- a/repos/os/include/nitpicker_session/nitpicker_session.h +++ b/repos/os/include/nitpicker_session/nitpicker_session.h @@ -279,6 +279,23 @@ struct Nitpicker::Session : Genode::Session */ virtual void focus(Genode::Capability focused) = 0; + typedef Genode::String<160> Label; + + enum Session_control { SESSION_CONTROL_HIDE, SESSION_CONTROL_SHOW, + SESSION_CONTROL_TO_FRONT }; + + /** + * Perform control operation on one or multiple sessions + * + * The 'label' is used to select the sessions, on which the 'operation' is + * performed. Nitpicker creates a selector string by concatenating the + * caller's session label with the supplied 'label' argument. A session is + * selected if its label starts with the selector string. Thereby, the + * operation is limited to the caller session or any child session of the + * caller. + */ + virtual void session_control(Label label, Session_control operation) { } + /** * Return number of bytes needed for virtual framebuffer of specified size */ @@ -311,6 +328,7 @@ struct Nitpicker::Session : Genode::Session GENODE_RPC(Rpc_mode, Framebuffer::Mode, mode); GENODE_RPC(Rpc_mode_sigh, void, mode_sigh, Genode::Signal_context_capability); GENODE_RPC(Rpc_focus, void, focus, Genode::Capability); + GENODE_RPC(Rpc_session_control, void, session_control, Label, Session_control); GENODE_RPC_THROW(Rpc_buffer, void, buffer, GENODE_TYPE_LIST(Out_of_metadata), Framebuffer::Mode, bool); @@ -332,8 +350,9 @@ struct Nitpicker::Session : Genode::Session Type_tuple - > > > > > > > > > > > > Rpc_functions; + > > > > > > > > > > > > > Rpc_functions; }; #endif /* _INCLUDE__NITPICKER_SESSION__NITPICKER_SESSION_H_ */ diff --git a/repos/os/src/server/nitpicker/main.cc b/repos/os/src/server/nitpicker/main.cc index 3a9f7a32d..e50bbc5f5 100644 --- a/repos/os/src/server/nitpicker/main.cc +++ b/repos/os/src/server/nitpicker/main.cc @@ -921,6 +921,21 @@ class Nitpicker::Session_component : public Genode::Rpc_object, report_focus(_focus_reporter, session); } + void session_control(Label suffix, Session_control control) override + { + char selector[Label::size()]; + + Genode::snprintf(selector, sizeof(selector), "%s%s%s", + label().string(), + suffix.length() ? " -> " : "", suffix.string()); + + switch (control) { + case SESSION_CONTROL_HIDE: _view_stack.visible(selector, false); break; + case SESSION_CONTROL_SHOW: _view_stack.visible(selector, true); break; + case SESSION_CONTROL_TO_FRONT: _view_stack.to_front(selector); break; + } + } + /******************************* ** Buffer_provider interface ** diff --git a/repos/os/src/server/nitpicker/session.h b/repos/os/src/server/nitpicker/session.h index bc3bb037e..4a901cb75 100644 --- a/repos/os/src/server/nitpicker/session.h +++ b/repos/os/src/server/nitpicker/session.h @@ -39,6 +39,7 @@ class Session : public Session_list::Element Domain_registry::Entry const *_domain; Texture_base const *_texture = { 0 }; bool _uses_alpha = { false }; + bool _visible = true; View *_background = 0; unsigned char const *_input_mask = { 0 }; @@ -59,6 +60,21 @@ class Session : public Session_list::Element Genode::Session_label const &label() const { return _label; } + /** + * Return true if session label starts with specified 'selector' + */ + bool matches_session_label(char const *selector) const + { + /* + * Append label separator to match selectors with a trailing + * separator. + */ + char label[Genode::Session_label::MAX_LEN + 4]; + Genode::snprintf(label, sizeof(label), "%s ->", _label.string()); + return Genode::strcmp(label, selector, + Genode::strlen(selector)) == 0; + } + bool xray_opaque() const { return _domain && _domain->xray_opaque(); } bool xray_no() const { return _domain && _domain->xray_no(); } @@ -67,6 +83,10 @@ class Session : public Session_list::Element unsigned layer() const { return _domain ? _domain->layer() : ~0UL; } + bool visible() const { return _visible; } + + void visible(bool visible) { _visible = visible; } + Domain_registry::Entry::Name domain_name() const { return _domain ? _domain->name() : Domain_registry::Entry::Name(); diff --git a/repos/os/src/server/nitpicker/view_stack.cc b/repos/os/src/server/nitpicker/view_stack.cc index ecbb259fb..33f022eb8 100644 --- a/repos/os/src/server/nitpicker/view_stack.cc +++ b/repos/os/src/server/nitpicker/view_stack.cc @@ -34,6 +34,8 @@ VIEW *View_stack::_next_view(VIEW &view) const /* check if we hit the bottom of the view stack */ if (!next_view) return 0; + if (!next_view->session().visible()) continue; + if (!next_view->background()) return next_view; if (is_default_background(*next_view) || next_view == active_background) diff --git a/repos/os/src/server/nitpicker/view_stack.h b/repos/os/src/server/nitpicker/view_stack.h index 9db3ac73d..f8dde55b8 100644 --- a/repos/os/src/server/nitpicker/view_stack.h +++ b/repos/os/src/server/nitpicker/view_stack.h @@ -264,6 +264,57 @@ class View_stack } void sort_views_by_layer(); + + /** + * Set visibility of views that match the specified label selector + */ + void visible(char const *selector, bool visible) + { + for (View *v = _first_view(); v; v = v->view_stack_next()) { + + if (!v->session().matches_session_label(selector)) + continue; + + /* mark view geometry as to be redrawn */ + refresh(_outline(*v)); + + /* let the view stack omit the views of the session */ + v->session().visible(visible); + } + } + + /** + * Bring views that match the specified label selector to the front + */ + void to_front(char const *selector) + { + /* + * Move all views that match the selector to the front while + * maintaining their ordering. + */ + View *at = nullptr; + for (View *v = _first_view(); v; v = v->view_stack_next()) { + + if (!v->session().matches_session_label(selector)) + continue; + + /* + * Move view to behind the previous view that we moved to + * front. If 'v' is the first view that matches the selector, + * move it to the front ('at' argument of 'insert' is 0). + */ + _views.remove(v); + _views.insert(v, at); + + at = v; + + /* mark view geometry as to be redrawn */ + refresh(_outline(*v)); + } + + /* reestablish domain layering */ + sort_views_by_layer(); + } }; #endif