Compute correct boundaries in checkWorkspacePosition

Summary:
When a client sets a strut, checkWorkspacePosition will be called to
bump clients that touch corresponding screen edge.

In order to do that, checkWorkspacePosition needs to calculate client
boundaries before and after the restricted move area was changed. As it
turns out, if the client reserves space "between" screens, calculated
boundaries can be incorrect, which may lead to some funky results, e.g.
shrunken clients.

For example, let's say that there is a dual-monitor setup. If a client
reserves some amount of space at the right border of the left screen,
then clients on the right monitor will have rightMax which is equal to
the x coordinate of screenArea.

To fix that, this change ensures that only restricted areas belonging
to the same screen as the client are taken into account when computing
the boundaries.

BUG: 404837
BUG: 406573

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D20987
This commit is contained in:
Vlad Zagorodniy 2019-05-03 16:36:18 +03:00
parent 0aa288bfae
commit 67b2746ecd

View file

@ -1141,14 +1141,9 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, int oldDesktop, Q
// Old and new maximums have different starting values so windows on the screen // Old and new maximums have different starting values so windows on the screen
// edge will move when a new strut is placed on the edge. // edge will move when a new strut is placed on the edge.
QRect oldScreenArea; QRect oldScreenArea;
QRect oldGeomTall;
QRect oldGeomWide;
const auto displaySize = screens()->displaySize();
if( workspace()->inUpdateClientArea()) { if( workspace()->inUpdateClientArea()) {
// we need to find the screen area as it was before the change // we need to find the screen area as it was before the change
oldScreenArea = QRect( 0, 0, workspace()->oldDisplayWidth(), workspace()->oldDisplayHeight()); oldScreenArea = QRect( 0, 0, workspace()->oldDisplayWidth(), workspace()->oldDisplayHeight());
oldGeomTall = QRect(oldGeometry.x(), 0, oldGeometry.width(), workspace()->oldDisplayHeight()); // Full screen height
oldGeomWide = QRect(0, oldGeometry.y(), workspace()->oldDisplayWidth(), oldGeometry.height()); // Full screen width
int distance = INT_MAX; int distance = INT_MAX;
foreach(const QRect &r, workspace()->previousScreenSizes()) { foreach(const QRect &r, workspace()->previousScreenSizes()) {
int d = r.contains( oldGeometry.center()) ? 0 : ( r.center() - oldGeometry.center()).manhattanLength(); int d = r.contains( oldGeometry.center()) ? 0 : ( r.center() - oldGeometry.center()).manhattanLength();
@ -1159,9 +1154,9 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, int oldDesktop, Q
} }
} else { } else {
oldScreenArea = workspace()->clientArea(ScreenArea, oldGeometry.center(), oldDesktop); oldScreenArea = workspace()->clientArea(ScreenArea, oldGeometry.center(), oldDesktop);
oldGeomTall = QRect(oldGeometry.x(), 0, oldGeometry.width(), displaySize.height()); // Full screen height
oldGeomWide = QRect(0, oldGeometry.y(), displaySize.width(), oldGeometry.height()); // Full screen width
} }
const QRect oldGeomTall = QRect(oldGeometry.x(), oldScreenArea.y(), oldGeometry.width(), oldScreenArea.height()); // Full screen height
const QRect oldGeomWide = QRect(oldScreenArea.x(), oldGeometry.y(), oldScreenArea.width(), oldGeometry.height()); // Full screen width
int oldTopMax = oldScreenArea.y(); int oldTopMax = oldScreenArea.y();
int oldRightMax = oldScreenArea.x() + oldScreenArea.width(); int oldRightMax = oldScreenArea.x() + oldScreenArea.width();
int oldBottomMax = oldScreenArea.y() + oldScreenArea.height(); int oldBottomMax = oldScreenArea.y() + oldScreenArea.height();
@ -1173,8 +1168,8 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, int oldDesktop, Q
int leftMax = screenArea.x(); int leftMax = screenArea.x();
QRect newGeom = geometryRestore(); // geometry(); QRect newGeom = geometryRestore(); // geometry();
QRect newClientGeom = newGeom.adjusted(border[Left], border[Top], -border[Right], -border[Bottom]); QRect newClientGeom = newGeom.adjusted(border[Left], border[Top], -border[Right], -border[Bottom]);
const QRect newGeomTall = QRect(newGeom.x(), 0, newGeom.width(), displaySize.height()); // Full screen height const QRect newGeomTall = QRect(newGeom.x(), screenArea.y(), newGeom.width(), screenArea.height()); // Full screen height
const QRect newGeomWide = QRect(0, newGeom.y(), displaySize.width(), newGeom.height()); // Full screen width const QRect newGeomWide = QRect(screenArea.x(), newGeom.y(), screenArea.width(), newGeom.height()); // Full screen width
// Get the max strut point for each side where the window is (E.g. Highest point for // Get the max strut point for each side where the window is (E.g. Highest point for
// the bottom struts bounded by the window's left and right sides). // the bottom struts bounded by the window's left and right sides).