Commit 2a1f9e44 authored by Henri Chain's avatar Henri Chain 🛰 Committed by Nate Graham
Browse files

[libtaskmanager/x11] Fix transient windows bug

The logic for handling the active window when it is a transient, added in
!509, had
a bug (fixed in 67003f74).

This reworks the implementation and actually makes the original feature work
(a signal also wasn't properly handled).

BUG: 438222
FIXED-IN: 5.22.1


(cherry picked from commit 7573ae03)
parent 924bdf5e
......@@ -56,8 +56,12 @@ public:
~Private();
QVector<WId> windows;
QMultiHash<WId, WId> transients;
// key=transient child, value=leader
QHash<WId, WId> transients;
// key=leader, values=transient children
QMultiHash<WId, WId> transientsDemandingAttention;
QHash<WId, KWindowInfo *> windowInfoCache;
QHash<WId, AppData> appDataCache;
QHash<WId, QRect> delegateGeometries;
......@@ -172,6 +176,12 @@ void XWindowTasksModel::Private::init()
// Update IsActive for previously- and newly-active windows.
QObject::connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged, q, [this](WId window) {
const WId oldActiveWindow = activeWindow;
const auto leader = transients.value(window, XCB_WINDOW_NONE);
if (leader != XCB_WINDOW_NONE) {
window = leader;
}
activeWindow = window;
lastActivated[activeWindow] = QTime::currentTime();
......@@ -216,8 +226,8 @@ void XWindowTasksModel::Private::addWindow(WId window)
const WId leader = info.transientFor();
// Handle transient.
if (leader > 0 && leader != window && leader != QX11Info::appRootWindow() && !transients.values().contains(window) && windows.contains(leader)) {
transients.insert(leader, window);
if (leader > 0 && leader != window && leader != QX11Info::appRootWindow() && !transients.contains(window) && windows.contains(leader)) {
transients.insert(window, leader);
// Update demands attention state for leader.
if (info.hasState(NET::DemandsAttention) && windows.contains(leader)) {
......@@ -255,10 +265,8 @@ void XWindowTasksModel::Private::removeWindow(WId window)
q->endRemoveRows();
} else { // Could be a transient.
// Removing a transient might change the demands attention state of the leader.
WId leader = transients.key(window, XCB_WINDOW_NONE);
if (leader != XCB_WINDOW_NONE) {
transients.remove(leader, window);
leader = transientsDemandingAttention.key(window, XCB_WINDOW_NONE);
if (transients.remove(window)) {
const WId leader = transientsDemandingAttention.key(window, XCB_WINDOW_NONE);
if (leader != XCB_WINDOW_NONE) {
transientsDemandingAttention.remove(leader, window);
......@@ -316,7 +324,6 @@ void XWindowTasksModel::Private::windowChanged(WId window, NET::Properties prope
{
if (transients.contains(window)) {
transientChanged(window, properties, properties2);
return;
}
......@@ -629,15 +636,7 @@ QVariant XWindowTasksModel::data(const QModelIndex &index, int role) const
} else if (role == IsWindow) {
return true;
} else if (role == IsActive) {
if (window == d->activeWindow) {
return true;
}
for (const WId transient : d->transients.values(window)) {
if (transient == d->activeWindow) {
return true;
}
}
return false;
return (window == d->activeWindow);
} else if (role == IsClosable) {
return d->windowInfo(window)->actionSupported(NET::ActionClose);
} else if (role == IsMovable) {
......@@ -729,10 +728,10 @@ void XWindowTasksModel::requestActivate(const QModelIndex &index)
// dialog and trying to bring the window forward by clicking on it in a tasks widget
// TODO: do we need to check all the transients for shaded?"
} else if (!d->transients.isEmpty()) {
foreach (const WId transient, d->transients) {
const auto transients = d->transients.keys(window);
for (const auto transient : qAsConst(transients)) {
KWindowInfo info(transient, NET::WMState, NET::WM2TransientFor);
if (info.valid(true) && info.hasState(NET::Shaded) && info.transientFor() == window) {
if (info.valid(true) && info.hasState(NET::Shaded)) {
window = transient;
break;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment