Re: KRect and KRectF proposal
Akseli Lahtinen <[email protected]> Sat, 28 Mar 2026 19:36:52 +0200
| Newsgroups | gmane.comp.kde.devel.general |
|---|---|
| Message-ID | <12860287.O9o76ZdvQC@desktop> |
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