From 13648d196a494658e76bf85b081858b0346aacb8 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Wed, 1 Oct 2025 13:15:23 +0200 Subject: [PATCH] protocols/seat: force down rounding of coords at the surface edge (#11890) ref https://github.com/hyprwm/Hyprland/discussions/11665 --- src/protocols/core/Seat.cpp | 27 +++++++++++++++++++++++++-- src/protocols/core/Seat.hpp | 2 ++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp index 7e1ff53b..74e5615e 100644 --- a/src/protocols/core/Seat.cpp +++ b/src/protocols/core/Seat.cpp @@ -10,6 +10,8 @@ #include +constexpr const float WL_FIXED_EPSILON = 1.F / 256.F; + CWLTouchResource::CWLTouchResource(SP resource_, SP owner_) : m_owner(owner_), m_resource(resource_) { if UNLIKELY (!good()) return; @@ -169,7 +171,9 @@ void CWLPointerResource::sendEnter(SP surface, const Vector2 m_currentSurface = surface; m_listeners.destroySurface = surface->m_events.destroy.listen([this] { sendLeave(); }); - m_resource->sendEnter(g_pSeatManager->nextSerial(m_owner.lock()), surface->getResource().get(), wl_fixed_from_double(local.x), wl_fixed_from_double(local.y)); + const auto fixedLocal = fixPosWithWlFixed(local); + + m_resource->sendEnter(g_pSeatManager->nextSerial(m_owner.lock()), surface->getResource().get(), wl_fixed_from_double(fixedLocal.x), wl_fixed_from_double(fixedLocal.y)); } void CWLPointerResource::sendLeave() { @@ -201,7 +205,9 @@ void CWLPointerResource::sendMotion(uint32_t timeMs, const Vector2D& local) { if (!(PROTO::seat->m_currentCaps & eHIDCapabilityType::HID_INPUT_CAPABILITY_POINTER)) return; - m_resource->sendMotion(timeMs, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y)); + const auto fixedLocal = fixPosWithWlFixed(local); + + m_resource->sendMotion(timeMs, wl_fixed_from_double(fixedLocal.x), wl_fixed_from_double(fixedLocal.y)); } void CWLPointerResource::sendButton(uint32_t timeMs, uint32_t button, wl_pointer_button_state state) { @@ -297,6 +303,23 @@ void CWLPointerResource::sendAxisRelativeDirection(wl_pointer_axis axis, wl_poin m_resource->sendAxisRelativeDirection(axis, direction); } +Vector2D CWLPointerResource::fixPosWithWlFixed(const Vector2D& pos) { + if (!m_currentSurface) + return pos; + + Vector2D newPos = pos; + + // When our cursor pos is right at the edge, wl_fixed will round it up, + // instead of down, meaning 10.999999 -> 11 instead of 10 + 255/256 + // if we are within that epsilon, move the coord a bit down to account for that. + if (std::abs(newPos.x - m_currentSurface->m_current.size.x) < WL_FIXED_EPSILON) + newPos.x = m_currentSurface->m_current.size.x - WL_FIXED_EPSILON * 2; + if (std::abs(newPos.y - m_currentSurface->m_current.size.y) < WL_FIXED_EPSILON) + newPos.y = m_currentSurface->m_current.size.y - WL_FIXED_EPSILON * 2; + + return newPos; +} + CWLKeyboardResource::CWLKeyboardResource(SP resource_, SP owner_) : m_owner(owner_), m_resource(resource_) { if UNLIKELY (!good()) return; diff --git a/src/protocols/core/Seat.hpp b/src/protocols/core/Seat.hpp index 29399a27..c30bbd71 100644 --- a/src/protocols/core/Seat.hpp +++ b/src/protocols/core/Seat.hpp @@ -98,6 +98,8 @@ class CWLPointerResource { std::vector m_pressedButtons; + Vector2D fixPosWithWlFixed(const Vector2D& pos); + struct { CHyprSignalListener destroySurface; } m_listeners;