Make FocusChain ignore closed windows

At the moment, the FocusChain has Q_ASSERT()s to prevent inserting closed
windows back into the focus chain. It makes sense on paper. But, there
are code paths that could still hypothetically call FocusChain::update(),
they are harmless except the logic in the FocusChain.

So instead this change makes the FocusChain ignore closed windows, i.e.
take a more defensive approach. There are a few reasons why it's
worthwhile doing: the first is that it would prevent inserting closed
windows back into the focus chain in release builds and potentially even
back into the stack, debugging such crashes is absolutely no fun; the
second is that it would be preferred to avoid sprinkling random
isDeleted() checks in the Window code here and there and thus making
the code harder to follow.
This commit is contained in:
Vlad Zahorodnii 2024-06-18 18:04:18 +03:00
parent 03eb688818
commit 6a2bc79dae

View file

@ -116,7 +116,9 @@ void FocusChain::updateWindowInChain(Window *window, FocusChain::Change change,
void FocusChain::insertWindowIntoChain(Window *window, Chain &chain)
{
Q_ASSERT(!window->isDeleted());
if (window->isDeleted()) {
return;
}
if (chain.contains(window)) {
return;
}
@ -131,7 +133,9 @@ void FocusChain::insertWindowIntoChain(Window *window, Chain &chain)
void FocusChain::moveAfterWindow(Window *window, Window *reference)
{
Q_ASSERT(!window->isDeleted());
if (window->isDeleted()) {
return;
}
if (!window->wantsTabFocus()) {
return;
}
@ -149,7 +153,9 @@ void FocusChain::moveAfterWindow(Window *window, Window *reference)
void FocusChain::moveAfterWindowInChain(Window *window, Window *reference, Chain &chain)
{
Q_ASSERT(!window->isDeleted());
if (window->isDeleted()) {
return;
}
if (!chain.contains(reference)) {
return;
}
@ -214,14 +220,18 @@ Window *FocusChain::nextForDesktop(Window *reference, VirtualDesktop *desktop) c
void FocusChain::makeFirstInChain(Window *window, Chain &chain)
{
Q_ASSERT(!window->isDeleted());
if (window->isDeleted()) {
return;
}
chain.removeAll(window);
chain.append(window);
}
void FocusChain::makeLastInChain(Window *window, Chain &chain)
{
Q_ASSERT(!window->isDeleted());
if (window->isDeleted()) {
return;
}
chain.removeAll(window);
chain.prepend(window);
}