Commit e5aeb674 authored by David Redondo's avatar David Redondo 🏎
Browse files

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.
parent 6bf53c87
Pipeline #220097 passed with stage
in 14 minutes and 38 seconds
......@@ -70,6 +70,8 @@
#include <xkbcommon/xkbcommon.h>
#include <cmath>
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();
}
......
......@@ -45,6 +45,8 @@
#include <linux/input.h>
#include <cmath>
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;
}
......
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment