From dcc4b8c31318e785270d636fe19486aef9ccae17 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 29 Sep 2015 23:43:59 +0200 Subject: [PATCH] wm/layouter/decorator: propagate window controls --- repos/gems/src/app/decorator/window.h | 12 +++++----- repos/gems/src/app/decorator/window_element.h | 8 +++---- .../src/app/floating_window_layouter/main.cc | 23 +++++++++++++++++-- repos/gems/src/server/wm/nitpicker.h | 22 ++++++++++++++++++ repos/gems/src/server/wm/window_registry.h | 13 +++++++++++ 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/repos/gems/src/app/decorator/window.h b/repos/gems/src/app/decorator/window.h index 806ef8ebf..278897cf5 100644 --- a/repos/gems/src/app/decorator/window.h +++ b/repos/gems/src/app/decorator/window.h @@ -78,9 +78,9 @@ class Decorator::Window : public Window_base { Element::BOTTOM_LEFT, _animator, _base_color }, { Element::BOTTOM_RIGHT, _animator, _base_color }, { Element::CLOSER, _animator, _base_color }, - { Element::MAXIMIZE, _animator, _base_color }, - { Element::MINIMIZE, _animator, _base_color }, - { Element::UNMAXIMIZE, _animator, _base_color } }; + { Element::MAXIMIZER, _animator, _base_color }, + { Element::MINIMIZER, _animator, _base_color }, + { Element::UNMAXIMIZER, _animator, _base_color } }; Element &element(Element::Type type) { @@ -290,9 +290,9 @@ class Decorator::Window : public Window_base { switch (window_control.type()) { case Control::TYPE_CLOSER: return element(Element::CLOSER).color(); - case Control::TYPE_MAXIMIZER: return element(Element::MAXIMIZE).color(); - case Control::TYPE_MINIMIZER: return element(Element::MINIMIZE).color(); - case Control::TYPE_UNMAXIMIZER: return element(Element::UNMAXIMIZE).color(); + case Control::TYPE_MAXIMIZER: return element(Element::MAXIMIZER).color(); + case Control::TYPE_MINIMIZER: return element(Element::MINIMIZER).color(); + case Control::TYPE_UNMAXIMIZER: return element(Element::UNMAXIMIZER).color(); case Control::TYPE_TITLE: return element(Element::TITLE).color(); case Control::TYPE_UNDEFINED: break; }; diff --git a/repos/gems/src/app/decorator/window_element.h b/repos/gems/src/app/decorator/window_element.h index 132b0ce35..20fa52b90 100644 --- a/repos/gems/src/app/decorator/window_element.h +++ b/repos/gems/src/app/decorator/window_element.h @@ -33,7 +33,7 @@ class Decorator::Window_element : public Animator::Item enum Type { TITLE, LEFT, RIGHT, TOP, BOTTOM, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, - CLOSER, MAXIMIZE, MINIMIZE, UNMAXIMIZE, UNDEFINED }; + CLOSER, MAXIMIZER, MINIMIZER, UNMAXIMIZER, UNDEFINED }; private: @@ -130,9 +130,9 @@ class Decorator::Window_element : public Animator::Item case BOTTOM_LEFT: return "bottom_left"; case BOTTOM_RIGHT: return "bottom_right"; case CLOSER: return "closer"; - case MINIMIZE: return "minimize"; - case MAXIMIZE: return "maximize"; - case UNMAXIMIZE: return "unmaximize"; + case MINIMIZER: return "minimizer"; + case MAXIMIZER: return "maximizer"; + case UNMAXIMIZER: return "unmaximizer"; } return ""; } diff --git a/repos/gems/src/app/floating_window_layouter/main.cc b/repos/gems/src/app/floating_window_layouter/main.cc index d3a457a1b..d84e0cc8c 100644 --- a/repos/gems/src/app/floating_window_layouter/main.cc +++ b/repos/gems/src/app/floating_window_layouter/main.cc @@ -75,7 +75,8 @@ class Floating_window_layouter::Window : public List::Element struct Element { enum Type { UNDEFINED, TITLE, LEFT, RIGHT, TOP, BOTTOM, - TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT }; + TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, + CLOSER, MAXIMIZER, MINIMIZER }; Type type; @@ -92,6 +93,9 @@ class Floating_window_layouter::Window : public List::Element case TOP_RIGHT: return "top_right"; case BOTTOM_LEFT: return "bottom_left"; case BOTTOM_RIGHT: return "bottom_right"; + case CLOSER: return "closer"; + case MAXIMIZER: return "maximizer"; + case MINIMIZER: return "minimizer"; } return ""; } @@ -131,6 +135,8 @@ class Floating_window_layouter::Window : public List::Element */ bool _is_hidden = false; + bool _is_resizeable = false; + /* * Number of times the window has been topped. This value is used by * the decorator to detect the need for bringing the window to the @@ -167,6 +173,8 @@ class Floating_window_layouter::Window : public List::Element void is_hidden(bool is_hidden) { _is_hidden = is_hidden; } + void is_resizeable(bool is_resizeable) { _is_resizeable = is_resizeable; } + bool label_matches(Label const &label) const { return label == _label; } /** @@ -251,6 +259,11 @@ class Floating_window_layouter::Window : public List::Element if (_has_alpha) xml.attribute("has_alpha", "yes"); + + if (_is_resizeable) { + xml.attribute("maximizer", "yes"); + xml.attribute("closer", "yes"); + } }); } @@ -458,6 +471,8 @@ void Floating_window_layouter::Main::import_window_list(Xml_node window_list_xml && node.attribute("has_alpha").has_value("yes")); win->is_hidden(node.has_attribute("hidden") && node.attribute("hidden").has_value("yes")); + win->is_resizeable(node.has_attribute("resizeable") + && node.attribute("resizeable").has_value("yes")); } } catch (...) { } } @@ -536,7 +551,11 @@ element_from_hover_model(Genode::Xml_node hover_window_xml) if (top_sizer) return Type::TOP; if (bottom_sizer) return Type::BOTTOM; - if (hover_window_xml.has_sub_node("title")) return Type::TITLE; + if (hover_window_xml.has_sub_node("title")) return Type::TITLE; + if (hover_window_xml.has_sub_node("closer")) return Type::CLOSER; + if (hover_window_xml.has_sub_node("maximizer")) return Type::MAXIMIZER; + if (hover_window_xml.has_sub_node("minimizer")) return Type::MINIMIZER; + return Type::UNDEFINED; } diff --git a/repos/gems/src/server/wm/nitpicker.h b/repos/gems/src/server/wm/nitpicker.h index b85c49ede..aefe56ab3 100644 --- a/repos/gems/src/server/wm/nitpicker.h +++ b/repos/gems/src/server/wm/nitpicker.h @@ -229,6 +229,8 @@ class Wm::Nitpicker::Top_level_view : public View, */ Rect _content_geometry; + bool _resizeable = false; + Title _window_title; Session_label _session_label; @@ -268,6 +270,7 @@ class Wm::Nitpicker::Top_level_view : public View, _window_registry.title(_win_id, _window_title.string()); _window_registry.label(_win_id, _session_label); _window_registry.has_alpha(_win_id, View::has_alpha()); + _window_registry.resizeable(_win_id, _resizeable); } _window_registry.size(_win_id, geometry.area()); @@ -319,6 +322,14 @@ class Wm::Nitpicker::Top_level_view : public View, } void is_hidden(bool is_hidden) { _window_registry.is_hidden(_win_id, is_hidden); } + + void resizeable(bool resizeable) + { + _resizeable = resizeable; + + if (_win_id.valid()) + _window_registry.resizeable(_win_id, resizeable); + } }; @@ -580,6 +591,8 @@ class Wm::Nitpicker::Session_component : public Rpc_object, Top_level_view *view = new (_top_level_view_alloc) Top_level_view(_session, _session_label, _has_alpha, _window_registry); + view->resizeable(_mode_sigh.valid()); + _top_level_views.insert(view); return *view; } @@ -905,6 +918,15 @@ class Wm::Nitpicker::Session_component : public Rpc_object, void mode_sigh(Genode::Signal_context_capability sigh) override { _mode_sigh = sigh; + + /* + * We consider a window as resizable if the client shows interest + * in mode-change notifications. + */ + bool const resizeable = _mode_sigh.valid(); + + for (Top_level_view *v = _top_level_views.first(); v; v = v->next()) + v->resizeable(resizeable); } void buffer(Framebuffer::Mode mode, bool has_alpha) override diff --git a/repos/gems/src/server/wm/window_registry.h b/repos/gems/src/server/wm/window_registry.h index fbc04a15a..298dfc836 100644 --- a/repos/gems/src/server/wm/window_registry.h +++ b/repos/gems/src/server/wm/window_registry.h @@ -68,6 +68,8 @@ class Wm::Window_registry enum Is_hidden { IS_HIDDEN, IS_NOT_HIDDEN }; + enum Resizeable { RESIZEABLE, NOT_RESIZEABLE }; + private: Id const _id; @@ -82,6 +84,8 @@ class Wm::Window_registry Is_hidden _is_hidden = IS_NOT_HIDDEN; + Resizeable _resizeable = NOT_RESIZEABLE; + friend class Window_registry; Window(Id id) : _id(id) { } @@ -98,6 +102,7 @@ class Wm::Window_registry void attr(Area size) { _size = size; } void attr(Has_alpha has_alpha) { _has_alpha = has_alpha; } void attr(Is_hidden is_hidden) { _is_hidden = is_hidden; } + void attr(Resizeable resizeable) { _resizeable = resizeable; } void generate_window_list_entry_xml(Xml_generator &xml) const { @@ -113,6 +118,9 @@ class Wm::Window_registry if (_is_hidden == IS_HIDDEN) xml.attribute("hidden", "yes"); + + if (_resizeable == RESIZEABLE) + xml.attribute("resizeable", "yes"); }); } }; @@ -217,6 +225,11 @@ class Wm::Window_registry { _set_attr(id, is_hidden ? Window::IS_HIDDEN : Window::IS_NOT_HIDDEN); } + + void resizeable(Id id, bool resizeable) + { + _set_attr(id, resizeable ? Window::RESIZEABLE : Window::NOT_RESIZEABLE); + } }; #endif /* _WINDOW_REGISTRY_H_ */