From bf6727b38418303b0c85ad07d0c371dff8141f72 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sat, 16 Mar 2024 14:08:03 +0200 Subject: [PATCH] Fix the titlebar visibility check for small windows Consider a window with the size of 50x100 and the titlebar height of 36px. The maximum number of visible titlebar pixels is 1800, but the titleBarRect() function reports 3600 instead, which is completely wrong. Since the reported number of required visible pixels is wrong, the window geometry constraining logic is mistriggered and it's possible to move the window only by 1px. --- src/window.cpp | 20 +++++++++----------- src/window.h | 2 +- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/window.cpp b/src/window.cpp index 15af89c317..8da20fe333 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1460,7 +1460,7 @@ void Window::updateInteractiveMoveResize(const QPointF &global) } } -QRectF Window::titleBarRect(const QRectF &rect, bool &transposed, int &requiredPixels) const +QRectF Window::titleBarRect(const QRectF &rect, bool &transposed) const { QRectF titleRect = rect; titleRect.moveTopLeft(QPointF(0, 0)); @@ -1481,10 +1481,6 @@ QRectF Window::titleBarRect(const QRectF &rect, bool &transposed, int &requiredP transposed = true; break; } - // When doing a restricted move we must always keep 100px of the titlebar - // visible to allow the user to be able to move it again. - requiredPixels = std::min(100 * (transposed ? titleRect.width() : titleRect.height()), - rect.width() * rect.height()); return titleRect; } @@ -1558,13 +1554,14 @@ QRectF Window::nextInteractiveResizeGeometry(const QPointF &global) const availableArea -= rect; } bool transposed = false; - int requiredPixels; - QRectF bTitleRect = titleBarRect(nextMoveResizeGeom, transposed, requiredPixels); + QRectF bTitleRect = titleBarRect(nextMoveResizeGeom, transposed); int lastVisiblePixels = -1; QRectF lastTry = nextMoveResizeGeom; bool titleFailed = false; for (;;) { const QRect titleRect = bTitleRect.translated(nextMoveResizeGeom.topLeft()).toRect(); + const int requiredPixels = std::min(100 * (transposed ? titleRect.width() : titleRect.height()), titleRect.width() * titleRect.height()); + int visiblePixels = 0; int realVisiblePixels = 0; for (const QRect &rect : availableArea) { @@ -1683,14 +1680,15 @@ QRectF Window::nextInteractiveMoveGeometry(const QPointF &global) const availableArea -= rect; // Strut areas } bool transposed = false; - int requiredPixels; - QRectF bTitleRect = titleBarRect(nextMoveResizeGeom, transposed, requiredPixels); + QRectF bTitleRect = titleBarRect(nextMoveResizeGeom, transposed); for (;;) { QRectF currentTry = nextMoveResizeGeom; - const QRectF titleRect(bTitleRect.translated(currentTry.topLeft())); + const QRect titleRect = bTitleRect.translated(currentTry.topLeft()).toRect(); + const int requiredPixels = std::min(100 * (transposed ? titleRect.width() : titleRect.height()), titleRect.width() * titleRect.height()); + int visiblePixels = 0; for (const QRect &rect : availableArea) { - const QRect r = rect & titleRect.toRect(); + const QRect r = rect & titleRect; if ((transposed && r.width() == titleRect.width()) || // Only the full size regions... (!transposed && r.height() == titleRect.height())) { // ...prevents long slim areas visiblePixels += r.width() * r.height(); diff --git a/src/window.h b/src/window.h index ed62695394..de92482553 100644 --- a/src/window.h +++ b/src/window.h @@ -1682,7 +1682,7 @@ protected: * Default implementation does nothing. */ virtual void doInteractiveResizeSync(const QRectF &rect); - QRectF titleBarRect(const QRectF &rect, bool &transposed, int &requiredPixels) const; + QRectF titleBarRect(const QRectF &rect, bool &transposed) const; QRectF nextInteractiveMoveGeometry(const QPointF &global) const; QRectF nextInteractiveResizeGeometry(const QPointF &global) const; void dontInteractiveMoveResize();