x11window: round border size to integral XNative units

Both frameSize and clientSize are rounded to integral XNative units.
So their difference must also be rounded to integral XNative units.
Otherwise we get cycles of rounding that can cause growing window sizes.

BUG: 481460
wilder/Plasma/6.2
Yifan Zhu 2 years ago
parent 5c16cdd4ed
commit 111657ad04
  1. 5
      src/utils/xcbutils.cpp
  2. 7
      src/utils/xcbutils.h
  3. 22
      src/x11window.cpp

@ -644,6 +644,11 @@ QSizeF fromXNative(const QSize &s)
return QSizeF(fromXNative(s.width()), fromXNative(s.height()));
}
qreal nativeRound(qreal value)
{
return fromXNative(toXNative(value));
}
static qreal nativeFloor(qreal value)
{
return std::floor(value * kwinApp()->xwaylandScale()) / kwinApp()->xwaylandScale();

@ -46,6 +46,13 @@ qreal KWIN_EXPORT fromXNative(int value);
QRectF KWIN_EXPORT fromXNative(const QRect &value);
QSizeF KWIN_EXPORT fromXNative(const QSize &value);
/**
* Rounds a given value using the scale as a base
*
* Equivalent to fromXNative(toXNative(value))
*/
qreal KWIN_EXPORT nativeRound(qreal value);
/** Floors a given value to using the scale as a base
* Use when flooring to ints from Xwayland
* i.e floor(a/scale) * scale

@ -2807,8 +2807,8 @@ QPointF X11Window::framePosToClientPos(const QPointF &point) const
qreal y = point.y();
if (isDecorated()) {
x += borderLeft();
y += borderTop();
x += Xcb::nativeRound(borderLeft());
y += Xcb::nativeRound(borderTop());
} else {
x -= m_clientFrameExtents.left();
y -= m_clientFrameExtents.top();
@ -2823,8 +2823,8 @@ QPointF X11Window::clientPosToFramePos(const QPointF &point) const
qreal y = point.y();
if (isDecorated()) {
x -= borderLeft();
y -= borderTop();
x -= Xcb::nativeRound(borderLeft());
y -= Xcb::nativeRound(borderTop());
} else {
x += m_clientFrameExtents.left();
y += m_clientFrameExtents.top();
@ -2839,8 +2839,11 @@ QSizeF X11Window::frameSizeToClientSize(const QSizeF &size) const
qreal height = size.height();
if (isDecorated()) {
width -= borderLeft() + borderRight();
height -= borderTop() + borderBottom();
// Both frameSize and clientSize are rounded to integral XNative units
// So their difference must also be rounded to integral XNative units
// Otherwise we get cycles of rounding that can cause growing window sizes
width -= Xcb::nativeRound(borderLeft()) + Xcb::nativeRound(borderRight());
height -= Xcb::nativeRound(borderTop()) + Xcb::nativeRound(borderBottom());
} else {
width += m_clientFrameExtents.left() + m_clientFrameExtents.right();
height += m_clientFrameExtents.top() + m_clientFrameExtents.bottom();
@ -2855,8 +2858,11 @@ QSizeF X11Window::clientSizeToFrameSize(const QSizeF &size) const
qreal height = size.height();
if (isDecorated()) {
width += borderLeft() + borderRight();
height += borderTop() + borderBottom();
// Both frameSize and clientSize are rounded to integral XNative units
// So their difference must also be rounded to integral XNative units
// Otherwise we get cycles of rounding that can cause growing window sizes
width += Xcb::nativeRound(borderLeft()) + Xcb::nativeRound(borderRight());
height += Xcb::nativeRound(borderTop()) + Xcb::nativeRound(borderBottom());
} else {
width -= m_clientFrameExtents.left() + m_clientFrameExtents.right();
height -= m_clientFrameExtents.top() + m_clientFrameExtents.bottom();

Loading…
Cancel
Save