window: Fix potential freeze during resize
The loop in `Window::handleInteractiveMoveResize` "bruteforces" the value for `nextMoveResizeGeom` such that the area of `nextMoveResizeGeom` contains at least `requiredPixels`. In each loop iteration, one or more attributes (left, right, top, bottom) of `nextMoveResizeGeom` are selected to be moved +/-1.0 towards the value of `currentMoveResizeGeom`. The loop terminates if either the area of `nextMoveResizeGeom` is large enough or `nextMoveResizeGeom == currentMoveResizeGeom`. The problem is that the variables compared and adjusted here are floating point variables, and their difference may not be a whole number. Using +/-1.0 adjustments can make the loop oscillate indefinitely around the target value. This commit ensures loop termination by using `qFuzzyCompare` to compare floating point values and correctly handles the cases where adjustments smaller than 1.0 are needed to reach the target value.
This commit is contained in:
parent
0efb8d01db
commit
b095f51035
1 changed files with 8 additions and 8 deletions
|
@ -1994,10 +1994,10 @@ void Window::handleInteractiveMoveResize(int x, int y, int x_root, int y_root)
|
|||
// precedence. The opposing edge has no impact on visiblePixels and only one of
|
||||
// the adjacent can alter at a time, ie. it's enough to ignore adjacent edges
|
||||
// if the title edge altered
|
||||
bool leftChanged = currentMoveResizeGeom.left() != currentTry.left();
|
||||
bool rightChanged = currentMoveResizeGeom.right() != currentTry.right();
|
||||
bool topChanged = currentMoveResizeGeom.top() != currentTry.top();
|
||||
bool btmChanged = currentMoveResizeGeom.bottom() != currentTry.bottom();
|
||||
bool leftChanged = !qFuzzyCompare(currentMoveResizeGeom.left(), currentTry.left());
|
||||
bool rightChanged = !qFuzzyCompare(currentMoveResizeGeom.right(), currentTry.right());
|
||||
bool topChanged = !qFuzzyCompare(currentMoveResizeGeom.top(), currentTry.top());
|
||||
bool btmChanged = !qFuzzyCompare(currentMoveResizeGeom.bottom(), currentTry.bottom());
|
||||
auto fixChangedState = [titleFailed](bool &major, bool &counter, bool &ad1, bool &ad2) {
|
||||
counter = false;
|
||||
if (titleFailed) {
|
||||
|
@ -2023,13 +2023,13 @@ void Window::handleInteractiveMoveResize(int x, int y, int x_root, int y_root)
|
|||
break;
|
||||
}
|
||||
if (topChanged) {
|
||||
currentTry.setTop(currentTry.y() + sign(currentMoveResizeGeom.y() - currentTry.y()));
|
||||
currentTry.setTop(currentTry.y() + qBound(-1.0, currentMoveResizeGeom.y() - currentTry.y(), 1.0));
|
||||
} else if (leftChanged) {
|
||||
currentTry.setLeft(currentTry.x() + sign(currentMoveResizeGeom.x() - currentTry.x()));
|
||||
currentTry.setLeft(currentTry.x() + qBound(-1.0, currentMoveResizeGeom.x() - currentTry.x(), 1.0));
|
||||
} else if (btmChanged) {
|
||||
currentTry.setBottom(currentTry.bottom() + sign(currentMoveResizeGeom.bottom() - currentTry.bottom()));
|
||||
currentTry.setBottom(currentTry.bottom() + qBound(-1.0, currentMoveResizeGeom.bottom() - currentTry.bottom(), 1.0));
|
||||
} else if (rightChanged) {
|
||||
currentTry.setRight(currentTry.right() + sign(currentMoveResizeGeom.right() - currentTry.right()));
|
||||
currentTry.setRight(currentTry.right() + qBound(-1.0, currentMoveResizeGeom.right() - currentTry.right(), 1.0));
|
||||
} else {
|
||||
break; // no position changed - that's certainly not good
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue