From 4145417f6748264dae27eac28cb53bd13ae18af5 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 27 Nov 2018 11:25:56 +0100 Subject: [PATCH] window_layouter: improve window-resize handling This patch solves an off-by-one problem in the window-size calculation, which resulted in sporadic artificial resize requests. In Sculpt, this glitch caused flickering artifacts in VirtualBox windows caused by superfluous guest desktop-resize handling. Furthermore, the patch introduces the dropping of resize requests with unchanged content. --- repos/gems/src/app/window_layouter/main.cc | 17 +++----- repos/gems/src/app/window_layouter/window.h | 47 ++++++++++++++++++--- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/repos/gems/src/app/window_layouter/main.cc b/repos/gems/src/app/window_layouter/main.cc index 9cc35274e..6474c9c1b 100644 --- a/repos/gems/src/app/window_layouter/main.cc +++ b/repos/gems/src/app/window_layouter/main.cc @@ -362,26 +362,19 @@ void Window_layouter::Main::_gen_resize_request() { bool resize_needed = false; _window_list.for_each_window([&] (Window const &window) { - if (window.client_size() != window.requested_size()) + if (window.resize_request_needed()) resize_needed = true; }); if (!resize_needed) return; _resize_request_reporter.generate([&] (Xml_generator &xml) { - _window_list.for_each_window([&] (Window const &window) { + window.gen_resize_request(xml); }); }); - Area const requested_size = window.requested_size(); - if (requested_size != window.client_size()) { - xml.node("window", [&] () { - xml.attribute("id", window.id().value); - xml.attribute("width", requested_size.w()); - xml.attribute("height", requested_size.h()); - }); - } - }); - }); + /* prevent superfluous resize requests for the same size */ + _window_list.for_each_window([&] (Window &window) { + window.resize_request_updated(); }); } diff --git a/repos/gems/src/app/window_layouter/window.h b/repos/gems/src/app/window_layouter/window.h index 890d339c4..2d6c574fc 100644 --- a/repos/gems/src/app/window_layouter/window.h +++ b/repos/gems/src/app/window_layouter/window.h @@ -96,6 +96,14 @@ class Window_layouter::Window : public List_model::Element */ Area _requested_size; + /** + * Most recent resize request propagated to the window manager + * + * Initially, no resize request must be generated because the + * '_requested_size' corresponds to the window size. + */ + Area _reported_resize_request = _requested_size; + /** * Window may be partially transparent */ @@ -236,10 +244,10 @@ class Window_layouter::Window : public List_model::Element return _drag_geometry; /* resize window */ - if (_drag_left_border) x1 = x2 - _client_size.w(); - if (_drag_right_border) x2 = x1 + _client_size.w(); - if (_drag_top_border) y1 = y2 - _client_size.h(); - if (_drag_bottom_border) y2 = y1 + _client_size.h(); + if (_drag_left_border) x1 = x2 - _client_size.w() + 1; + if (_drag_right_border) x2 = x1 + _client_size.w() - 1; + if (_drag_top_border) y1 = y2 - _client_size.h() + 1; + if (_drag_bottom_border) y2 = y1 + _client_size.h() - 1; return Rect(Point(x1, y1), Point(x2, y2)); } @@ -304,7 +312,35 @@ class Window_layouter::Window : public List_model::Element xml.attribute("maximized", true); } - Area requested_size() const { return _requested_size; } + /** + * Return true if a request request to the window manager is due + */ + bool resize_request_needed() const + { + /* a resize request for the current size is already in flight */ + if (_requested_size == _reported_resize_request) + return false; + + return (_requested_size != _client_size); + } + + /** + * Mark the currently requested size as processed so that no further + * resize requests for the same size are generated + */ + void resize_request_updated() { _reported_resize_request = _requested_size; } + + void gen_resize_request(Xml_generator &xml) const + { + if (_requested_size == _client_size) + return; + + xml.node("window", [&] () { + xml.attribute("id", _id.value); + xml.attribute("width", _requested_size.w()); + xml.attribute("height", _requested_size.h()); + }); + } void generate(Xml_generator &xml) const { @@ -372,6 +408,7 @@ class Window_layouter::Window : public List_model::Element _drag_top_border = false; _drag_bottom_border = false; _requested_size = effective_inner_geometry().area(); + } void to_front_cnt(unsigned to_front_cnt) { _to_front_cnt = to_front_cnt; }