KRect and KRectF proposal

Vlad Zahorodnii vlad.zahorodnii at kde.org
Tue Mar 31 08:08:33 BST 2026


Hi,

On 3/31/26 2:25 AM, Albert Astals Cid wrote:
> El divendres, 27 de març del 2026, a les 19:03:01 (Hora d’estiu d’Europa
> central), Vlad Zahorodnii va escriure:
>> 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=he
>> ads.
>>
>> 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?
> I don't have enough domain knowledge to comment on whether QRectF is wrong or
> what you are suggesting is wrong BUT...
>
> I don't think this class should be named KRect/KRectF.
>
> Most/All of the KFoo are QFoo but with more features. So one can just replace
> QFoo with KFoo if you need the new features and it will work and if you have a
> KFoo and you don't use the extra feagures you can replace it with a QFoo and
> it will all work.
>
> Here KRectF is NOT a QRectF drop in replacement.
>
> I don't have a good naming suggestion though, KGeometryRect? KPrimitiveRect?

Names like KGeometryRect or KPrimitiveRect are really long. There is 
also a question of people being more accustomed to the term "rect."

To be honest, I'm not sure that we have to be so strict here that 
KSomething can only exist if QSomething exists and it inherits from 
QSomething. For example, with KProcess, KComboBox and so on (to be fair, 
those are the only two examples that I'm aware of), it just makes sense 
that they inherit from the corresponding Qt counterparts. They only want 
to add a few things. Re-implementing the corresponding functionality 
from scratch would be kind of bonkers. KF doesn't follow that rule 
consistently either, e.g. KCursor doesn't inherit from QCursor and it 
provides an API that doesn't look like QCursor at all. Another example 
is KMessageBox and QMessageBox. In the rect case, the base Qt 
counterpart has just too many issues that inheriting is not an option 
and I personally don't think it'll be worth it to move away from a 
pretty convenient name such as "KRect".

Regards,
Vlad



More information about the kde-devel mailing list