KRect and KRectF proposal
Akseli Lahtinen
akselmo at akselmo.dev
Sat Mar 28 17:36:52 GMT 2026
On Friday 27 March 2026 20:03:01 Eastern European Standard Time Vlad Zahorodnii wrote:
> Hi,
>
> After hitting a number of issues with `QRect` and `QRectF` in KWin, we
> started a work on new rect helper counterparts that have fewer
> unexpected pitfalls. There are a number of issues with `QRect` and
> `QRectF`, for example some of them:
>
> * `QRect::right()` and `QRect::bottom()` are off by one. One could argue
> that it's a well-known thing. But it's easy to miss it during a code
> review (maybe the author actually intended to have bottom() or right()
> off by 1, or maybe they were unaware that those edges are off by 1). It
> also leads to indirect side-effects, for example center() can return a
> value that makes no sense with an empty `QRect`;
> * `QRectF::toRect()` has a smart rounding policy that is unsuitable for
> HiDPI on Wayland. People tend to use `toRect()` thinking that it does
> the right thing, but unfortunately, it just cannot be used if you want
> to render something properly with HiDPI;
> * There are just some API bugs in `QRect`, e.g. the assert in
> `rect.moveCenter(center); Q_ASSERT(rect.center() == center);` can trip.
> (Just in case, we attempted to fix it upstream, but it turned out to be
> more challenging than expected so it got stuck);
> * etc
>
> The rect helpers in kwin address a bunch of issues that we had
> encountered with `QRect` and `QRectF`. However, they also go slightly
> further and add some new useful APIs. Some key things about the new rect
> types:
>
> - `Rect::right()` and `Rect::bottom()` represent the true right and
> bottom edges, respectively. In other words, `x() + width()` and `y() +
> height()`;
> - `RectF::contains()` does not consider the right and bottom edges
> inside the rectangle. Current `QRectF::contains()` can lead to issues
> with input handling;
> - `RectF::toRect()` rounds the coordinates of top, left, right, and
> bottom edges;
> - `RectF::rounded()`, `RectF::roundedIn()`, `RectF::roundedOut()` for
> various rounding strategies. `rounded()` can be used for general
> geometry, `roundedOut()` for repaints, `roundedIn()` for things like the
> opaque region, etc;
> - Less confusing names for growing and shrinking rects, i.e.
> `Rect::grownBy()` and `Rect::shrunkBy()`;
> - `Rect::horizontalCenter()` and `Rect::verticalCenter()` +
> `Rect::moveHorizontalCenter()` and `Rect::moveVerticalCenter()`,
> respectively;
> - `Rect::scaled()` and `RectF::scaled()` for scaling rectangles. It is
> pretty common when working with HiDPI.
>
> We had interoperability between `QRect`/`QRectF` and `KRect`/`KRectF`
> back in our mind. The idea is that you should be able to swap out
> `QRect`/`QRectF` for `KRect`/`KRectF` in your code with minimal changes.
> You don't have to rewrite the project to use `KRect` or `KRectF`, you
> should be able to combine them with existing code that uses `QRect` +
> `QRectF` and gradually migrate to the new types.
>
> Our long term hope is that Qt developers would see what KDE does with
> `KRect` and `KRectF` and consider either fixing `QRect` and `QRectF` or
> incorporating them as is to Qt. Right now, if we go with our list of
> issues, we will likely be turned around with the reason that `QRect` and
> `QRectF` have been working like this since the beginning and there is a
> lot of software that can be broken, which is a really fair argument!
> Still, it won't make the issues go away...
>
> In 6.6, kwin (except some effects) has been ported away from `QRect` and
> `QRectF` with a considerable success. kdecoration is the next candidate
> to switch away from those two.
>
> The new rect helpers can be found at
> https://invent.kde.org/plasma/kwin/-/blob/master/src/core/rect.h?ref_type=heads.
>
> I would like to propose adding a new library, e.g. kprimitivetypes, that
> would host `KRect` and `KRectF`. There is a slight challenge with KF
> though. It will be nice if KConfig and maybe other tier 1 libraries are
> able use `KRect(F)`. In order to achieve that, the new library will need
> to live either outside of KF or perhaps there could be tier 0 in KF?
>
> Thoughts?
>
> Regards,
> Vlad
>
I'd love to use this in Breeze and the Union widget styling eventually.
A lot of weird offset bugs happen because of QRect being weird. So yes,
I'm all for KRect. :)
Best regards,
- Akseli
More information about the kde-devel
mailing list