diff --git a/src/platforms/wayland/display.cpp b/src/platforms/wayland/display.cpp index 8d6c3d07395..eb70f9bbe3e 100644 --- a/src/platforms/wayland/display.cpp +++ b/src/platforms/wayland/display.cpp @@ -369,7 +369,9 @@ void mir::graphics::wayland::Display::pointer_motion(wl_pointer* pointer, uint32 { { std::lock_guard lock{sink_mutex}; - pointer_pos = geom::PointF{wl_fixed_to_double(x), wl_fixed_to_double(y)} + geom::DisplacementF{pointer_displacement}; + auto const descaled_x = pointer_scale * wl_fixed_to_double(x); + auto const descaled_y = pointer_scale * wl_fixed_to_double(y); + pointer_pos = geom::PointF{descaled_x, descaled_y} + pointer_displacement; pointer_time = std::chrono::milliseconds{time}; } diff --git a/src/platforms/wayland/displayclient.cpp b/src/platforms/wayland/displayclient.cpp index 7fcce539777..cb2e0cc74f7 100644 --- a/src/platforms/wayland/displayclient.cpp +++ b/src/platforms/wayland/displayclient.cpp @@ -719,7 +719,9 @@ void mgw::DisplayClient::pointer_enter( { if (surface == out.second->surface) { - pointer_displacement = out.second->dcout.top_left - geometry::Point{}; + // Pointer events are displaced and scaled according to the surface + pointer_displacement = geom::DisplacementF{out.second->dcout.top_left - geometry::Point{}}; + pointer_scale = out.second->host_scale; break; } } diff --git a/src/platforms/wayland/displayclient.h b/src/platforms/wayland/displayclient.h index f95c955d2f0..ca73bb3dd6b 100644 --- a/src/platforms/wayland/displayclient.h +++ b/src/platforms/wayland/displayclient.h @@ -159,8 +159,9 @@ class DisplayClient xkb_keymap* keyboard_map_ = nullptr; xkb_state* keyboard_state_ = nullptr; bool fake_pointer_frame = false; - geometry::Displacement pointer_displacement; // Position of current output + geometry::DisplacementF pointer_displacement; // Position of current output geometry::Displacement touch_displacement; // Position of current output + float pointer_scale{1.0f}; std::unique_ptr registry;