Ensure size is valid after maximising

In X11 when a window is maximised if the client is unable to fufill the
space provided we centre align the window.

With the new floating point geometry behaviour of centreing changes.
Instead of a 1 pixel gap at the top, we get a 0.5 pixel gap either side.
When we get into the codepath to "fix" the window in `closeHeight` we
only move the top, giving us an invalid buffer size.

We don't really want to change the logic here; on xwayland with the
scaling opt-out path it's feasible for a floating sized logical size to
still be representable. This code rounds to the native unit after all
the logic has taken effect.
This commit is contained in:
David Edmundson 2022-07-25 17:06:03 +01:00 committed by Vlad Zahorodnii
parent c61515cd8d
commit 2073415f91
4 changed files with 15 additions and 0 deletions

View file

@ -27,4 +27,8 @@ QSizeF Xcb::fromXNative(const QSize &value)
return value;
}
QRectF Xcb::nativeFloor(const QRectF &value)
{
return value;
}
}

View file

@ -646,5 +646,11 @@ qreal nativeFloor(qreal value)
return std::floor(value / kwinApp()->xwaylandScale()) * kwinApp()->xwaylandScale();
}
QRectF nativeFloor(const QRectF &value)
{
return QRectF(nativeFloor(value.left()), nativeFloor(value.top()),
nativeFloor(value.width()), nativeFloor(value.height()));
}
} // namespace Xcb
} // namespace KWin

View file

@ -47,6 +47,7 @@ QSizeF KWIN_EXPORT fromXNative(const QSize &value);
* i.e floor(a/scale) * scale
*/
qreal KWIN_EXPORT nativeFloor(qreal value);
QRectF KWIN_EXPORT nativeFloor(const QRectF &value);
// forward declaration of methods
static void defineCursor(xcb_window_t window, xcb_cursor_t cursor);

View file

@ -4536,6 +4536,10 @@ void X11Window::changeMaximize(bool horizontal, bool vertical, bool adjust)
}
r.moveTopLeft(rules()->checkPosition(r.topLeft()));
}
// The above code tries to center align the window followed by setting top and bottom
// it's possible that we no longer have a valid size
r = Xcb::nativeFloor(r);
moveResize(r);
if (options->electricBorderMaximize() && r.top() == clientArea.top()) {
updateQuickTileMode(QuickTileFlag::Maximize);