From 08bb689ae7b22c38edd9188c5a1ed05a680030ef Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 27 Nov 2018 14:04:20 +0100 Subject: [PATCH] window layouter: bring unknown windows to front This patch improves the handing of new appearing windows for which only a wildcard assignment - but no exact assignment - rule exists. In the prior version, an interactively raised window would stay in front of such a window, which is unintuitive. The new version applies the to-front mechanism to unknown new windows. For known new windows (with an exact assignment rule) their original stacking position is preserved. --- repos/gems/src/app/window_layouter/assign.h | 14 +++++++++- .../src/app/window_layouter/assign_list.h | 8 ++++++ repos/gems/src/app/window_layouter/main.cc | 28 ++++++++++++++----- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/repos/gems/src/app/window_layouter/assign.h b/repos/gems/src/app/window_layouter/assign.h index c70c02eb2..5160f3b07 100644 --- a/repos/gems/src/app/window_layouter/assign.h +++ b/repos/gems/src/app/window_layouter/assign.h @@ -148,7 +148,7 @@ class Window_layouter::Assign : public List_model::Element Target::Name target_name() const { return _target_name; } /** - * Generate nodes of windows captured via wildcard + * Used to generate nodes of windows captured via wildcard */ template void for_each_wildcard_member(FN const &fn) const @@ -160,6 +160,18 @@ class Window_layouter::Assign : public List_model::Element _members.for_each([&] (Assign::Member const &member) { fn(member); }); } + /** + * Used to bring wildcard-matching windows to front + */ + template + void for_each_wildcard_member(FN const &fn) + { + if (_label.valid()) + return; + + _members.for_each([&] (Assign::Member &member) { fn(member); }); + } + bool floating() const { return _pos_defined; } bool wildcard() const { return !_label.valid(); } diff --git a/repos/gems/src/app/window_layouter/assign_list.h b/repos/gems/src/app/window_layouter/assign_list.h index 63fa84bba..4bc28af45 100644 --- a/repos/gems/src/app/window_layouter/assign_list.h +++ b/repos/gems/src/app/window_layouter/assign_list.h @@ -90,6 +90,14 @@ class Window_layouter::Assign_list : Noncopyable fn(assign, member); }); }); } + template + void for_each_wildcard_assigned_window(FN const &fn) + { + _assignments.for_each([&] (Assign &assign) { + assign.for_each_wildcard_member([&] (Assign::Member &member) { + fn(member.window); }); }); + } + /** * Return true if any window is assigned via a wildcard * diff --git a/repos/gems/src/app/window_layouter/main.cc b/repos/gems/src/app/window_layouter/main.cc index 6474c9c1b..700f0ef11 100644 --- a/repos/gems/src/app/window_layouter/main.cc +++ b/repos/gems/src/app/window_layouter/main.cc @@ -64,6 +64,22 @@ struct Window_layouter::Main : Operations, Target_list _target_list { _heap }; + /** + * Bring window to front, return true if the stacking order changed + */ + bool _to_front(Window &window) + { + bool stacking_order_changed = false; + + if (window.to_front_cnt() != _to_front_cnt) { + _to_front_cnt++; + window.to_front_cnt(_to_front_cnt); + stacking_order_changed = true; + }; + + return stacking_order_changed; + } + void _update_window_layout() { _window_list.dissolve_windows_from_assignments(); @@ -95,6 +111,10 @@ struct Window_layouter::Main : Operations, }); }); + /* bring new windows that solely match a wildcard assignment to the front */ + _assign_list.for_each_wildcard_assigned_window([&] (Window &window) { + _to_front(window); }); + _gen_window_layout(); if (_assign_list.matching_wildcards()) @@ -147,13 +167,7 @@ struct Window_layouter::Main : Operations, bool stacking_order_changed = false; _window_list.with_window(id, [&] (Window &window) { - - if (window.to_front_cnt() != _to_front_cnt) { - _to_front_cnt++; - window.to_front_cnt(_to_front_cnt); - stacking_order_changed = true; - }; - }); + stacking_order_changed = _to_front(window); }); if (stacking_order_changed) _gen_rules();