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.
This commit is contained in:
Norman Feske 2018-11-27 14:04:20 +01:00 committed by Christian Helmuth
parent 4145417f67
commit 08bb689ae7
3 changed files with 42 additions and 8 deletions

View File

@ -148,7 +148,7 @@ class Window_layouter::Assign : public List_model<Assign>::Element
Target::Name target_name() const { return _target_name; }
/**
* Generate <assign> nodes of windows captured via wildcard
* Used to generate <assign> nodes of windows captured via wildcard
*/
template <typename FN>
void for_each_wildcard_member(FN const &fn) const
@ -160,6 +160,18 @@ class Window_layouter::Assign : public List_model<Assign>::Element
_members.for_each([&] (Assign::Member const &member) { fn(member); });
}
/**
* Used to bring wildcard-matching windows to front
*/
template <typename FN>
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(); }

View File

@ -90,6 +90,14 @@ class Window_layouter::Assign_list : Noncopyable
fn(assign, member); }); });
}
template <typename FN>
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
*

View File

@ -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();