diff --git a/repos/gems/src/app/decorator/texture_by_id.cc b/repos/gems/src/app/decorator/texture_by_id.cc index d8aeb5561..4ebedcb10 100644 --- a/repos/gems/src/app/decorator/texture_by_id.cc +++ b/repos/gems/src/app/decorator/texture_by_id.cc @@ -1,5 +1,5 @@ /* - * \brief Accessor for the default font + * \brief Accessor for textures * \author Norman Feske * \date 2015-09-16 */ diff --git a/repos/gems/src/app/decorator/window.cc b/repos/gems/src/app/decorator/window.cc index e06a23915..099a32ebd 100644 --- a/repos/gems/src/app/decorator/window.cc +++ b/repos/gems/src/app/decorator/window.cc @@ -205,7 +205,35 @@ static bool attribute_has_value(Genode::Xml_node node, bool Decorator::Window::update(Genode::Xml_node window_node) { - bool updated = Window_base::update(window_node); + bool updated = false; + + /* + * Detect the need to bring the window to the top of the global + * view stack. + */ + unsigned const topped_cnt = attribute(window_node, "topped", 0UL); + if (topped_cnt != _topped_cnt) { + + _global_to_front = true; + _topped_cnt = topped_cnt; + _nitpicker_stacking_up_to_date = false; + + updated |= true; + } + + /* + * Detect geometry changes + */ + Rect new_geometry = rect_attribute(window_node); + if (new_geometry.p1() != geometry().p1() + || new_geometry.p2() != geometry().p2()) { + + geometry(new_geometry); + + _nitpicker_views_up_to_date = false; + + updated |= true; + } _focused = attribute_has_value(window_node, "focused", "yes"); _has_alpha = attribute_has_value(window_node, "has_alpha", "yes"); diff --git a/repos/gems/src/app/decorator/window.h b/repos/gems/src/app/decorator/window.h index 278897cf5..3874237cd 100644 --- a/repos/gems/src/app/decorator/window.h +++ b/repos/gems/src/app/decorator/window.h @@ -29,6 +29,82 @@ class Decorator::Window : public Window_base { private: + Nitpicker::Session_client &_nitpicker; + + /* + * Flag indicating that the current window position has been propagated + * to the window's corresponding nitpicker views. + */ + bool _nitpicker_views_up_to_date = false; + + /* + * Flag indicating that the stacking position of the window within the + * window stack has changed. The new stacking position must be + * propagated to nitpicker. + */ + bool _nitpicker_stacking_up_to_date = false; + + Nitpicker::Session::View_handle _neighbor; + + struct Nitpicker_view + { + Nitpicker::Session_client &_nitpicker; + Nitpicker::Session::View_handle _handle { _nitpicker.create_view() }; + + typedef Nitpicker::Session::Command Command; + + Nitpicker_view(Nitpicker::Session_client &nitpicker, unsigned id = 0) + : + _nitpicker(nitpicker) + { + /* + * We supply the window ID as label for the anchor view. + */ + if (id) { + char buf[128]; + Genode::snprintf(buf, sizeof(buf), "%d", id); + + _nitpicker.enqueue(_handle, buf); + } + } + + ~Nitpicker_view() + { + _nitpicker.destroy_view(_handle); + } + + Nitpicker::Session::View_handle handle() const { return _handle; } + + void stack(Nitpicker::Session::View_handle neighbor) + { + _nitpicker.enqueue(_handle, neighbor); + } + + void place(Rect rect) + { + _nitpicker.enqueue(_handle, rect); + Point offset = Point(0, 0) - rect.p1(); + _nitpicker.enqueue(_handle, offset); + } + }; + + Nitpicker_view _bottom_view { _nitpicker }, + _right_view { _nitpicker }, + _left_view { _nitpicker }, + _top_view { _nitpicker }; + + Nitpicker_view _content_view { _nitpicker, id() }; + + static Border _init_border() { + return Border(_border_size + _title_height, + _border_size, _border_size, _border_size); } + + Border const _border { _init_border() }; + + bool _global_to_front = false; + + unsigned _topped_cnt = 0; + Window_title _title; bool _focused = false; @@ -41,9 +117,6 @@ class Decorator::Window : public Window_base static unsigned const _border_size = 4; static unsigned const _title_height = 16; - static Border _border() { - return Border(_border_size + _title_height, - _border_size, _border_size, _border_size); } Color _bright = { 255, 255, 255, 64 }; Color _dark = { 0, 0, 0, 127 }; @@ -54,7 +127,6 @@ class Decorator::Window : public Window_base Area const _icon_size { 16, 16 }; - /* * Intensity of the title-bar radient in percent. A value of 0 produces * no gradient. A value of 100 creates a gradient from white over @@ -329,10 +401,78 @@ class Decorator::Window : public Window_base Window(unsigned id, Nitpicker::Session_client &nitpicker, Animator &animator, Config const &config) : - Window_base(id, nitpicker, _border()), + Window_base(id), + _nitpicker(nitpicker), _animator(animator), _config(config) { } + void stack(Nitpicker::Session::View_handle neighbor) override + { + _neighbor = neighbor; + _nitpicker_stacking_up_to_date = false; + } + + Nitpicker::Session::View_handle frontmost_view() const override + { + return _bottom_view.handle(); + } + + Rect outer_geometry() const override + { + return Rect(geometry().p1() - Point(_border.left, _border.top), + geometry().p2() + Point(_border.right, _border.bottom)); + } + + void border_rects(Rect *top, Rect *left, Rect *right, Rect *bottom) const + { + outer_geometry().cut(geometry(), top, left, right, bottom); + } + + bool is_in_front_of(Window_base const &neighbor) const override + { + return _neighbor == neighbor.frontmost_view(); + } + + void update_nitpicker_views() override + { + if (!_nitpicker_views_up_to_date) { + + /* update view positions */ + Rect top, left, right, bottom; + border_rects(&top, &left, &right, &bottom); + + _content_view.place(geometry()); + _top_view .place(top); + _left_view .place(left); + _right_view .place(right); + _bottom_view .place(bottom); + + _nitpicker_views_up_to_date = true; + } + + if (!_nitpicker_stacking_up_to_date) { + + /* + * Bring the view to the global top of the view stack if the + * 'topped' counter changed. Otherwise, we refer to a + * session-local neighbor for the restacking operation. + */ + Nitpicker::Session::View_handle neighbor = _neighbor; + if (_global_to_front) { + neighbor = Nitpicker::Session::View_handle(); + _global_to_front = false; + } + + _content_view.stack(neighbor); + _top_view.stack(_content_view.handle()); + _left_view.stack(_top_view.handle()); + _right_view.stack(_left_view.handle()); + _bottom_view.stack(_right_view.handle()); + + _nitpicker_stacking_up_to_date = true; + } + } + void adapt_to_changed_config() { _base_color = _config.base_color(_title); diff --git a/repos/os/include/decorator/window.h b/repos/os/include/decorator/window.h index 8cde0001e..4b941c703 100644 --- a/repos/os/include/decorator/window.h +++ b/repos/os/include/decorator/window.h @@ -85,11 +85,8 @@ class Decorator::Window_base : public Window_list::Element virtual void draw_behind(Canvas_base &, Window_base const &, Rect) const = 0; }; - private: - Nitpicker::Session_client &_nitpicker; - /* * Geometry of content */ @@ -100,114 +97,22 @@ class Decorator::Window_base : public Window_list::Element */ unsigned const _id; - /* - * Flag indicating that the current window position has been propagated - * to the window's corresponding nitpicker views. - */ - bool _nitpicker_views_up_to_date = false; - - /* - * Flag indicating that the stacking position of the window within the - * window stack has changed. The new stacking position must be - * propagated to nitpicker. - */ - bool _nitpicker_stacking_up_to_date = false; - - unsigned _topped_cnt = 0; - - bool _global_to_front = false; - - Nitpicker::Session::View_handle _neighbor; - - Border const _border; - - struct Nitpicker_view - { - Nitpicker::Session_client &_nitpicker; - Nitpicker::Session::View_handle _handle { _nitpicker.create_view() }; - - typedef Nitpicker::Session::Command Command; - - Nitpicker_view(Nitpicker::Session_client &nitpicker, unsigned id = 0) - : - _nitpicker(nitpicker) - { - /* - * We supply the window ID as label for the anchor view. - */ - if (id) { - char buf[128]; - Genode::snprintf(buf, sizeof(buf), "%d", id); - - _nitpicker.enqueue(_handle, buf); - } - } - - ~Nitpicker_view() - { - _nitpicker.destroy_view(_handle); - } - - Nitpicker::Session::View_handle handle() const { return _handle; } - - void stack(Nitpicker::Session::View_handle neighbor) - { - _nitpicker.enqueue(_handle, neighbor); - } - - void place(Rect rect) - { - _nitpicker.enqueue(_handle, rect); - Point offset = Point(0, 0) - rect.p1(); - _nitpicker.enqueue(_handle, offset); - } - }; - - Nitpicker_view _bottom_view, _right_view, _left_view, _top_view; - Nitpicker_view _content_view; - public: - Window_base(unsigned id, Nitpicker::Session_client &nitpicker, - Border border) - : - _nitpicker(nitpicker), _id(id), _border(border), - _bottom_view(nitpicker), - _right_view(nitpicker), - _left_view(nitpicker), - _top_view(nitpicker), - _content_view(nitpicker, _id) - { } - - void stack(Nitpicker::Session::View_handle neighbor) - { - _neighbor = neighbor; - _nitpicker_stacking_up_to_date = false; - } - - Nitpicker::Session::View_handle frontmost_view() const - { - return _bottom_view.handle(); - } - - Rect outer_geometry() const - { - return Rect(_geometry.p1() - Point(_border.left, _border.top), - _geometry.p2() + Point(_border.right, _border.bottom)); - } - - void border_rects(Rect *top, Rect *left, Rect *right, Rect *bottom) const - { - outer_geometry().cut(_geometry, top, left, right, bottom); - } + Window_base(unsigned id) : _id(id) { } unsigned long id() const { return _id; } Rect geometry() const { return _geometry; } - bool is_in_front_of(Window_base const &neighbor) const - { - return _neighbor == neighbor.frontmost_view(); - } + void geometry(Rect geometry) { _geometry = geometry; } + + virtual Rect outer_geometry() const = 0; + + virtual void stack(Nitpicker::Session::View_handle neighbor) = 0; + + virtual Nitpicker::Session::View_handle frontmost_view() const = 0; + + virtual bool is_in_front_of(Window_base const &neighbor) const = 0; /** * Draw window elements @@ -227,79 +132,9 @@ class Decorator::Window_base : public Window_list::Element * decorations haven't been redrawn already. If we updated the * nitpicker views at this point, we would reveal not-yet-drawn pixels. */ - virtual bool update(Xml_node window_node) - { - bool result = false; + virtual bool update(Xml_node window_node) = 0; - /* - * Detect the need to bring the window to the top of the global - * view stack. - */ - unsigned const topped_cnt = attribute(window_node, "topped", 0UL); - if (topped_cnt != _topped_cnt) { - - _global_to_front = true; - _topped_cnt = topped_cnt; - _nitpicker_stacking_up_to_date = false; - - result = true; - } - - /* - * Detect geometry changes - */ - Rect new_geometry = rect_attribute(window_node); - if (new_geometry.p1() != _geometry.p1() - || new_geometry.p2() != _geometry.p2()) { - - _geometry = new_geometry; - - _nitpicker_views_up_to_date = false; - - result = true; - } - return result; - } - - virtual void update_nitpicker_views() - { - if (!_nitpicker_views_up_to_date) { - - /* update view positions */ - Rect top, left, right, bottom; - border_rects(&top, &left, &right, &bottom); - - _content_view.place(_geometry); - _top_view .place(top); - _left_view .place(left); - _right_view .place(right); - _bottom_view .place(bottom); - - _nitpicker_views_up_to_date = true; - } - - if (!_nitpicker_stacking_up_to_date) { - - /* - * Bring the view to the global top of the view stack if the - * 'topped' counter changed. Otherwise, we refer to a - * session-local neighbor for the restacking operation. - */ - Nitpicker::Session::View_handle neighbor = _neighbor; - if (_global_to_front) { - neighbor = Nitpicker::Session::View_handle(); - _global_to_front = false; - } - - _content_view.stack(neighbor); - _top_view.stack(_content_view.handle()); - _left_view.stack(_top_view.handle()); - _right_view.stack(_left_view.handle()); - _bottom_view.stack(_right_view.handle()); - - _nitpicker_stacking_up_to_date = true; - } - } + virtual void update_nitpicker_views() { } /** * Report information about element at specified position