diff --git a/repos/os/src/server/nitpicker/domain_registry.h b/repos/os/src/server/nitpicker/domain_registry.h index 9321a20d1f..45420d09b1 100644 --- a/repos/os/src/server/nitpicker/domain_registry.h +++ b/repos/os/src/server/nitpicker/domain_registry.h @@ -28,16 +28,26 @@ class Domain_registry typedef Genode::String<64> Name; typedef Genode::Color Color; + /** + * Behaviour of the views of the domain when X-ray is activated + */ + enum Xray { + XRAY_NO, /* views are not subjected to X-ray mode */ + XRAY_FRAME, /* views are tinted and framed */ + XRAY_OPAQUE, /* views are replaced by opaque domain color */ + }; + private: Name _name; Color _color; + Xray _xray; friend class Domain_registry; - Entry(Name const &name, Color color) + Entry(Name const &name, Color color, Xray xray) : - _name(name), _color(color) + _name(name), _color(color), _xray(xray) { } public: @@ -45,8 +55,30 @@ class Domain_registry bool has_name(Name const &name) const { return name == _name; } Color color() const { return _color; } + + bool xray_opaque() const { return _xray == XRAY_OPAQUE; } + bool xray_no() const { return _xray == XRAY_NO; } }; + static Entry::Xray _xray(Genode::Xml_node domain) + { + char const * const attr_name = "xray"; + + Entry::Xray const default_xray = Entry::XRAY_FRAME; + + if (!domain.has_attribute(attr_name)) + return default_xray; + + Genode::Xml_node::Attribute const attr = domain.attribute(attr_name); + + if (attr.has_value("no")) return Entry::XRAY_NO; + if (attr.has_value("frame")) return Entry::XRAY_FRAME; + if (attr.has_value("opaque")) return Entry::XRAY_OPAQUE; + + PWRN("invalid value of xray attribute"); + return default_xray; + } + void _insert(Genode::Xml_node domain) { char buf[sizeof(Entry::Name)]; @@ -69,9 +101,9 @@ class Domain_registry return; } - Entry::Color const color = domain.attribute_value("color", Entry::Color()); + Entry::Color const color = domain.attribute_value("color", WHITE); - _entries.insert(new (_alloc) Entry(name, color)); + _entries.insert(new (_alloc) Entry(name, color, _xray(domain))); } private: diff --git a/repos/os/src/server/nitpicker/session.h b/repos/os/src/server/nitpicker/session.h index 8dff028d58..bd266068eb 100644 --- a/repos/os/src/server/nitpicker/session.h +++ b/repos/os/src/server/nitpicker/session.h @@ -66,6 +66,9 @@ class Session : public Session_list::Element Genode::Session_label const &label() const { return _label; } + bool xray_opaque() const { return _domain ? _domain->xray_opaque() : false; } + bool xray_no() const { return _domain ? _domain->xray_no() : false; } + Texture_base const *texture() const { return _texture; } void texture(Texture_base const *texture, bool uses_alpha) diff --git a/repos/os/src/server/nitpicker/view.cc b/repos/os/src/server/nitpicker/view.cc index 4c6ce768da..dd63e8f1cc 100644 --- a/repos/os/src/server/nitpicker/view.cc +++ b/repos/os/src/server/nitpicker/view.cc @@ -73,22 +73,44 @@ void View::frame(Canvas_base &canvas, Mode const &mode) const /* do not draw frame in flat mode */ if (mode.flat()) return; - draw_frame(canvas, abs_geometry(), _session.color(), frame_size(mode)); + Rect const geometry = abs_geometry(); + + if (_session.xray_no()) + return; + + if (_session.xray_opaque()) { + Point frame_offset(frame_size(mode), frame_size(mode)); + Rect rect(geometry.p1() - frame_offset, geometry.p2() + frame_offset); + canvas.draw_box(rect, _session.color()); + return; + } + + draw_frame(canvas, geometry, _session.color(), frame_size(mode)); } -void View::draw(Canvas_base &canvas, Mode const &mode) const +/** + * Return texture painter mode depending on nitpicker state and session policy + */ +static Texture_painter::Mode +texture_painter_mode(Mode const &mode, Session const &session) { - bool const is_focused = _session.has_same_domain(mode.focused_session()); - - Color const frame_color = _session.color(); + bool const is_focused = session.has_same_domain(mode.focused_session()); /* * Use dimming in x-ray and kill mode, but do not dim the focused view in * x-ray mode. */ - Texture_painter::Mode const op = mode.flat() || (mode.xray() && is_focused) - ? Texture_painter::SOLID : Texture_painter::MIXED; + if (mode.flat() || (session.xray_no()) || (mode.xray() && is_focused)) + return Texture_painter::SOLID; + + return Texture_painter::MIXED; +} + + +void View::draw(Canvas_base &canvas, Mode const &mode) const +{ + Texture_painter::Mode const op = texture_painter_mode(mode, _session); Rect const view_rect = abs_geometry(); @@ -113,9 +135,8 @@ void View::draw(Canvas_base &canvas, Mode const &mode) const } } - /* allow alpha blending only in flat mode */ - bool allow_alpha = mode.flat(); + bool allow_alpha = mode.flat() || _session.xray_no(); /* draw view content */ Color const mix_color = mode.kill() ? KILL_COLOR @@ -123,16 +144,22 @@ void View::draw(Canvas_base &canvas, Mode const &mode) const _session.color().g >> 1, _session.color().b >> 1); - if (_session.texture()) { - canvas.draw_texture(_buffer_off + view_rect.p1(), *_session.texture(), - op, mix_color, allow_alpha); + if (mode.xray() && _session.xray_opaque()) { + canvas.draw_box(view_rect, _session.color()); + } else { - canvas.draw_box(view_rect, BLACK); + if (_session.texture()) { + canvas.draw_texture(_buffer_off + view_rect.p1(), *_session.texture(), + op, mix_color, allow_alpha); + } else { + canvas.draw_box(view_rect, BLACK); + } } - if (mode.flat()) return; + if (mode.flat() || _session.xray_opaque() || _session.xray_no()) return; /* draw label */ + Color const frame_color = _session.color(); draw_label(canvas, _label_rect.p1(), _session.label().string(), WHITE, _title, frame_color); } diff --git a/repos/os/src/server/nitpicker/view.h b/repos/os/src/server/nitpicker/view.h index 55a48a0c87..841fbae906 100644 --- a/repos/os/src/server/nitpicker/view.h +++ b/repos/os/src/server/nitpicker/view.h @@ -164,6 +164,9 @@ class View : public Same_buffer_list_elem, */ virtual int frame_size(Mode const &mode) const { + if (_session.xray_opaque()) return 1; + if (_session.xray_no()) return 0; + return mode.is_focused(_session) ? 5 : 3; }