From e5aeb674c04755f7fdeffd6d93237f68723f107d Mon Sep 17 00:00:00 2001 From: David Redondo Date: Thu, 18 Aug 2022 10:05:00 +0200 Subject: [PATCH] Floor coordinates to check if a point is inside a region More correct since QRegion models half open intervals (like QRect) and toPoint rounds the coordinates. Fixes an issue where one could escape a pointer confinement by just moving the mouse. --- src/input.cpp | 4 +++- src/pointer_input.cpp | 13 ++++++++++--- src/wayland/surface_interface.cpp | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/input.cpp b/src/input.cpp index 5651e6e49c..6eb8cf44e0 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -70,6 +70,8 @@ #include +#include + namespace KWin { @@ -3440,7 +3442,7 @@ void InputDeviceHandler::updateDecoration() Decoration::DecoratedClientImpl *decoration = nullptr; auto hover = m_hover.window.data(); if (hover && hover->decoratedClient()) { - if (!hover->clientGeometry().toRect().contains(position().toPoint())) { + if (!hover->clientGeometry().toRect().contains(QPoint(std::floor(position().x()), std::floor(position().y())))) { // input device above decoration decoration = hover->decoratedClient(); } diff --git a/src/pointer_input.cpp b/src/pointer_input.cpp index 12d26bbaf5..3bc3a5f441 100644 --- a/src/pointer_input.cpp +++ b/src/pointer_input.cpp @@ -45,6 +45,8 @@ #include +#include + namespace KWin { @@ -770,18 +772,23 @@ QPointF PointerInputRedirection::applyPointerConfinement(const QPointF &pos) con return pos; } + auto floorPoint = [](const QPointF &point) { + return QPoint(std::floor(point.x()), std::floor(point.y())); + }; + const QRegion confinementRegion = getConstraintRegion(focus(), cf); - if (confinementRegion.contains(pos.toPoint())) { + if (confinementRegion.contains(floorPoint(pos))) { return pos; } QPointF p = pos; // allow either x or y to pass p = QPointF(m_pos.x(), pos.y()); - if (confinementRegion.contains(p.toPoint())) { + + if (confinementRegion.contains(floorPoint(p))) { return p; } p = QPointF(pos.x(), m_pos.y()); - if (confinementRegion.contains(p.toPoint())) { + if (confinementRegion.contains(floorPoint(p))) { return p; } diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index f3869f7c05..8d884cfee7 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -772,7 +772,7 @@ bool SurfaceInterfacePrivate::contains(const QPointF &position) const bool SurfaceInterfacePrivate::inputContains(const QPointF &position) const { - return contains(position) && inputRegion.contains(position.toPoint()); + return contains(position) && inputRegion.contains(QPoint(std::floor(position.x()), std::floor(position.y()))); } QRegion SurfaceInterface::damage() const