mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
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.
This commit is contained in:
parent
5af830c0de
commit
08d28e9b94
@ -83,6 +83,9 @@ class Nitpicker::Session_client : public Genode::Rpc_client<Session>
|
||||
void focus(Nitpicker::Session_capability session) override {
|
||||
call<Rpc_focus>(session); }
|
||||
|
||||
void session_control(Label selector, Session_control operation) override {
|
||||
call<Rpc_session_control>(selector, operation); }
|
||||
|
||||
/**
|
||||
* Enqueue command to command buffer
|
||||
*
|
||||
|
@ -279,6 +279,23 @@ struct Nitpicker::Session : Genode::Session
|
||||
*/
|
||||
virtual void focus(Genode::Capability<Session> 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<Session>);
|
||||
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_mode_sigh,
|
||||
Type_tuple<Rpc_buffer,
|
||||
Type_tuple<Rpc_focus,
|
||||
Type_tuple<Rpc_session_control,
|
||||
Genode::Meta::Empty>
|
||||
> > > > > > > > > > > > Rpc_functions;
|
||||
> > > > > > > > > > > > > Rpc_functions;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_SESSION__NITPICKER_SESSION_H_ */
|
||||
|
@ -921,6 +921,21 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||
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 **
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user