From f70c745ac04d6648ab0e9af59e480e6d43d77b4c Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sat, 30 Oct 2021 17:04:21 +0300 Subject: [PATCH] Fix placement of windows on disconnected outputs If an output is disconnected, the Workspace will update the Toplevel.output property for all windows that are on that output, then it will call AbstractClient::checkWorkspacePosition() to fix window position. That may result in some windows partially sticking outside visible area because AbstractClient::checkWorkspacePosition() has no idea what output the window was. This change addresses that problem by delaying updating the Toplevel.output property so AbstractClient::checkWorkspacePosition() could pick better window placement. --- src/abstract_client.cpp | 11 ++++++++--- src/workspace.cpp | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/abstract_client.cpp b/src/abstract_client.cpp index fda6f94dd9..7a86ad2e09 100644 --- a/src/abstract_client.cpp +++ b/src/abstract_client.cpp @@ -3389,13 +3389,18 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, QRect oldClientGe // edge will move when a new strut is placed on the edge. QRect oldScreenArea; QRect screenArea; - if( workspace()->inUpdateClientArea()) { + if (workspace()->inUpdateClientArea()) { + // check if the window is on an about to be destroyed output + AbstractOutput *newOutput = output(); + if (!kwinApp()->platform()->enabledOutputs().contains(newOutput)) { + newOutput = kwinApp()->platform()->outputAt(newGeom.center()); + } // we need to find the screen area as it was before the change oldScreenArea = workspace()->previousScreenSizes().value(output()); if (oldScreenArea.isNull()) { - oldScreenArea = output()->geometry(); + oldScreenArea = newOutput->geometry(); } - screenArea = output()->geometry(); + screenArea = newOutput->geometry(); newGeom.translate(screenArea.topLeft() - oldScreenArea.topLeft()); } else { oldScreenArea = workspace()->clientArea(ScreenArea, kwinApp()->platform()->outputAt(oldGeometry.center()), oldDesktop); diff --git a/src/workspace.cpp b/src/workspace.cpp index 1bc7964f7a..532a009c7e 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -1214,15 +1214,15 @@ void Workspace::slotOutputDisabled(AbstractOutput *output) m_activeOutput = kwinApp()->platform()->outputAt(output->geometry().center()); } + disconnect(output, &AbstractOutput::geometryChanged, this, &Workspace::desktopResized); + desktopResized(); + const auto stack = xStackingOrder(); for (Toplevel *toplevel : stack) { if (toplevel->output() == output) { toplevel->setOutput(kwinApp()->platform()->outputAt(toplevel->frameGeometry().center())); } } - - disconnect(output, &AbstractOutput::geometryChanged, this, &Workspace::desktopResized); - desktopResized(); } void Workspace::slotDesktopAdded(VirtualDesktop *desktop)