Bug 459733 - Kwin applies integer scaling instead of fractional when calculating output boundaries for wl_surface enter and leave events
Summary: Kwin applies integer scaling instead of fractional when calculating output bo...
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: wayland-generic (other bugs)
Version First Reported In: 5.25.5
Platform: Arch Linux Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-09-27 10:38 UTC by Mark Bolhuis
Modified: 2022-09-27 13:20 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed/Implemented In: 5.26
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Bolhuis 2022-09-27 10:38:48 UTC
SUMMARY
A wl_surface will receive enter and leave events based on a region that is the output's physical resolution divided by the integer scaling factor, not the fractional scaling factor.
For example, for a fractional scale of 1.25 the wl_output scale used is 2, which means that for an output of 2560x1440 physical pixels the region that triggers surface enter and leave events is 1280x720, anchored at the top left.
Instead the bounds should be calculated based on the physical size divided by the fractional scale.

STEPS TO REPRODUCE
1. Configure a 2560x1440 physical pixel output to use 125% fractional scaling.
2. Create a small window (idealy less than 
3. Log wl_surface.{enter,leave} events of the window
4. Place the window at the top left corner of the output
5. Drag the window down, or horizontally and observe surface events

OBSERVED RESULT
Once the the entire surface is past 1280 logical pixels in the x axis or 720 in the y the surface receives a leave event.

EXPECTED RESULT
The surface should receive a leave event once it fully passes 2048 logical pixels in the x and 1152 in the y.

NOTES
The bug applies equally for different output resolutions and fractional scaling factors, not just the example values I've used above. The bug does not appear when outputs use integer scaling.

SOFTWARE/OS VERSIONS
Linux: Arch
KDE Plasma Version: 5.25.5
KDE Frameworks Version: 5.98.0
Qt Version: 5.15.6
NVIDIA Driver: 515.76
Wayland Version: 1.21
Comment 1 Vlad Zahorodnii 2022-09-27 10:42:12 UTC
Wayland has no native fractional scaling support atm, fractional scaling is faked by ceil()ing the scale factor, i.e. kwin would tell clients to use 200% scale factor instead of 125%.

To be implemented, see also https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/143
Comment 2 Mark Bolhuis 2022-09-27 10:46:00 UTC
That is not the issue at all.
I am aware that Wayland has no native fractional scaling, this is an issue with KWin's implementation of the next-highest-integer-scale-and down-sample workaround.

This is an issue unique to Kwin, it doesn't appear in wlroots or mutter, both of which calculate the bounds correctly.
Comment 3 Vlad Zahorodnii 2022-09-27 10:55:05 UTC
Oh, I see
Comment 4 Bug Janitor Service 2022-09-27 11:00:29 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/3006
Comment 5 Vlad Zahorodnii 2022-09-27 12:24:16 UTC
Git commit f343f3fb80284a8e402b39924c789b629806ac62 by Vlad Zahorodnii.
Committed on 27/09/2022 at 12:07.
Pushed by vladz into branch 'master'.

wayland: Use true logical geometry in Display::outputsIntersecting()

Display::outputsIntersecting() computes the logical geometry using the
oriented mode size and the scale factor, but OutputInterface's scale
factor is ceil()ed up, so the resulting logical geometry can be incorrect.

M  +1    -2    src/wayland/display.cpp

https://invent.kde.org/plasma/kwin/commit/f343f3fb80284a8e402b39924c789b629806ac62
Comment 6 Vlad Zahorodnii 2022-09-27 12:31:23 UTC
Git commit 25466f9546dc9a2752708f4b1216088f1f0b7ef3 by Vlad Zahorodnii.
Committed on 27/09/2022 at 12:31.
Pushed by vladz into branch 'Plasma/5.26'.

wayland: Use true logical geometry in Display::outputsIntersecting()

Display::outputsIntersecting() computes the logical geometry using the
oriented mode size and the scale factor, but OutputInterface's scale
factor is ceil()ed up, so the resulting logical geometry can be incorrect.


(cherry picked from commit f343f3fb80284a8e402b39924c789b629806ac62)

M  +1    -2    src/wayland/display.cpp

https://invent.kde.org/plasma/kwin/commit/25466f9546dc9a2752708f4b1216088f1f0b7ef3