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; } 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> template <typename FN>
void for_each_wildcard_member(FN const &fn) const 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); }); _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 floating() const { return _pos_defined; }
bool wildcard() const { return !_label.valid(); } bool wildcard() const { return !_label.valid(); }

View File

@ -90,6 +90,14 @@ class Window_layouter::Assign_list : Noncopyable
fn(assign, member); }); }); 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 * 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 }; 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() void _update_window_layout()
{ {
_window_list.dissolve_windows_from_assignments(); _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(); _gen_window_layout();
if (_assign_list.matching_wildcards()) if (_assign_list.matching_wildcards())
@ -147,13 +167,7 @@ struct Window_layouter::Main : Operations,
bool stacking_order_changed = false; bool stacking_order_changed = false;
_window_list.with_window(id, [&] (Window &window) { _window_list.with_window(id, [&] (Window &window) {
stacking_order_changed = _to_front(window); });
if (window.to_front_cnt() != _to_front_cnt) {
_to_front_cnt++;
window.to_front_cnt(_to_front_cnt);
stacking_order_changed = true;
};
});
if (stacking_order_changed) if (stacking_order_changed)
_gen_rules(); _gen_rules();