Commit Graph

12 Commits

Author SHA1 Message Date
John Lindgren
6d197eef94 util: let wlr_box_closest_point() be within 1/65536 of right/bottom edge
Limiting the position to (x + width - 1, y + height - 1) created a 1px
"dead zone" at monitor edges, noticeable with high-resolution mice with
motion deltas of <1px.

See: https://github.com/swaywm/sway/issues/8110

Using (x + width - 1/65536, y + height - 1/65536) instead should make
the "dead zone" small enough to be unobservable, while the value 1/65536
is still large enough to avoid rounding to zero (due to loss of
significant digits) in simple floating-point calculations.

This does expose a client-side bug in Qt layer-shell applications,
noticeable in right/bottom panels which do not accept positions beyond
(x + width - 1, x + height - 1) as valid - thus driving the cursor
to the bottom/right of the screen to click on the panel does not work.
I don't have a good workaround for this, and probably it needs to be
fixed in Qt itself.

Fixes: 3fc66d4525
("util: fix non-linear behavior of wlr_box_closest_point()")
2024-06-25 11:09:33 -04:00
John Lindgren
3fc66d4525 util: fix non-linear behavior of wlr_box_closest_point()
Per comments in util/box.h, the width and height of a wlr_box are
exclusive; that is, for a 100x100 box at (0,0), the point (99,99) is
inside it while the point (100,100) is outside it.

Thus mathematically, there exists no single closest point to the
bottom-right corner of the box while remaining inside it. You can
construct an infinite series approaching the limit, such as {(99,99),
(99.9,99.9), (99.99,99.99)...}, but since the intervals are half-open,
there is no "last" point.

wlr_box_closest_point() must therefore define an arbitrary "closest"
point. For points below and to the right of the box, the current
implementation returns (box.x + width - 1, box.y + height - 1). Let's
continue to do this.

However, the current implementation is non-linear: with the example
100x100 box, it will return an input point of (99.9,99.9) unchanged, but
for an input point (100.1,100.1) the returned point will jump back to
(99.0,99.0).

In practice, this non-linearity results in strange behaviors when
driving the mouse cursor to a screen corner. On a 1920x1080 display for
example, driving the cursor quickly to the bottom-left corner results in
a position of exactly (0,1079). Continuing to slowly nudge the cursor
downward results in the position jumping between (0,1079) and other,
fractional coordinates such as (0,1079.88).

The fractional coordinates expose some client/toolkit-side bugs (which,
to be clear, should be fixed on the client side), but IMHO the wlroots
behavior is also inconsistent and wrong -- when I drive the mouse cursor
into the corner of the screen, it should come to a stop at a fixed
position, not jitter around.
2024-03-28 12:51:53 +00:00
Kirill Primak
dc6402d153 util/box: transform empty boxes' origins
Not a huge fan of this, but changing this behavior would be a breaking change
to a stable API.

Fixes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3650
2023-05-24 08:55:15 +00:00
Kirill Primak
5f4a35290d util/box: always treat NULL boxes as empty 2023-05-23 21:08:22 +03:00
Kirill Primak
5d67bbde86 util/box: simplify empty box case in wlr_box_intersection() 2023-05-23 21:02:18 +03:00
Alexander Orzechowski
d495fb8c04 wlr_{box, fbox}_equal: Consider empty boxes NULL 2023-05-23 17:57:16 +00:00
Alexander Orzechowski
acaf57dcca wlr_{box, fbox}_equal: Handle NULL 2023-05-23 17:57:16 +00:00
Alexander Orzechowski
1d08ef234e util/box: Introduce wlr_fbox_equal 2022-08-15 06:14:59 -04:00
Alexander Orzechowski
9f3bd64a33 util/box: Introduce wlr_box_equal 2022-08-15 06:14:28 -04:00
Simon Ser
fdc22449d6 util/box: introduce wlr_fbox_empty
Same as wlr_box_empty, but for wlr_fbox.
2021-09-22 10:45:39 -06:00
Kirill Primak
664307f968 util/box: introduce wlr_fbox_transform()
A floating-point version of wlr_box_transform().
2021-08-24 10:36:06 +02:00
Simon Zeni
e192d87731 move wlr_box from /types to /util 2021-07-06 21:43:17 +02:00