slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
17.48k stars 599 forks source link

Shape-aware hit testing #5754

Open Enyium opened 2 months ago

Enyium commented 2 months ago

This code draws a circle:

export component Demo {
    Rectangle {
        width: 70px;
        height: self.width;
        border-radius: self.width / 2;
        border-width: 5px;
        clip: true; // Makes no difference. Would erroneously exclude border area anyways.

        states [
            regular when !touch-area.has-hover : {
                border-color: gray;
                background: red;
            }

            hovered when touch-area.has-hover : {
                border-color: gray.darker(80%);
                background: red.darker(80%);
            }
        ]

        touch-area := TouchArea { }
    }
}

When hovered, its colors get darker. The problem is that hovering outside of the rounded corners, but within the enclosing rectangle is treated as hovering the circle, even though it is fully transparent in those areas.

With SVG in the browser, those areas not belonging to the shape are excluded from object hits when hit testing, as this example shows.

For layered Win32 windows, Windows treats only fully transparent pixels of the window as hit test misses:

Hit testing of a layered window is based on the shape and transparency of the window. This means that the areas of the window [...] whose alpha value is zero will let the mouse messages through.

It would be great if Slint could also do shape-aware hit testing like this.

ogoffart commented 2 months ago

Thanks for filling a bug. It is true that the input code currently doesn't follow the radius clipping.

Enyium commented 2 months ago

My comment may have insinuated that a Rectangle with background: transparent should interpret mouse messages over the background area as hit test misses. But this may not necessarily be what's desirable. Depending, among other things, on your future plans regarding alpha masks for all kinds of objects, you may only want to treat mouse messages over the rounded-corner areas as hit test misses, even if the background is transparent. This would have to be decided and defined.