Improve Workspace::outputAt()
Workspace::outputAt() casts vectors to four rectangle corners and uses the shortest one to decide which output is the closest to the given point. This works poorly on dual monitor setups where on the left side you have a monitor with landscape orientation and one with portrait orientation on the right hand side. In that case, outputAt() will prefer the left monitor even though the right monitor is the closest one if you cast a perpendicular from the given point to the right monitor. In order to improve the handling of that case, this change makes Workspace::outputAt() compute the closest point to the output geometry rectangle and use the squared distance as the score.
This commit is contained in:
parent
cbd50a1e08
commit
a9ad59b32a
2 changed files with 8 additions and 9 deletions
|
@ -1520,7 +1520,7 @@ void PointerInputTest::testConfineToScreenGeometry_data()
|
|||
QTest::newRow("move right - top screen") << QPoint(1920, 512) << QPoint(2660, 512) << QPoint(2660, 512);
|
||||
QTest::newRow("move bottom-right - top screen") << QPoint(1920, 512) << QPoint(2660, 1124) << QPoint(2660, 1023);
|
||||
QTest::newRow("move bottom - top screen") << QPoint(1920, 512) << QPoint(1920, 1124) << QPoint(1920, 1124);
|
||||
QTest::newRow("move bottom-left - top screen") << QPoint(1920, 512) << QPoint(1180, 1124) << QPoint(1180, 1023);
|
||||
QTest::newRow("move bottom-left - top screen") << QPoint(1920, 512) << QPoint(1180, 1124) << QPoint(1280, 1124);
|
||||
QTest::newRow("move left - top screen") << QPoint(1920, 512) << QPoint(1180, 512) << QPoint(1180, 512);
|
||||
|
||||
QTest::newRow("move top-left - right screen") << QPoint(3200, 512) << QPoint(2460, -100) << QPoint(2460, 0);
|
||||
|
|
|
@ -1231,14 +1231,13 @@ Output *Workspace::outputAt(const QPointF &pos) const
|
|||
qreal minDistance;
|
||||
|
||||
for (Output *output : std::as_const(m_outputs)) {
|
||||
const QRect &geo = output->geometry();
|
||||
if (geo.contains(pos.toPoint())) {
|
||||
return output;
|
||||
}
|
||||
qreal distance = QPointF(geo.topLeft() - pos).manhattanLength();
|
||||
distance = std::min(distance, QPointF(geo.topRight() - pos).manhattanLength());
|
||||
distance = std::min(distance, QPointF(geo.bottomRight() - pos).manhattanLength());
|
||||
distance = std::min(distance, QPointF(geo.bottomLeft() - pos).manhattanLength());
|
||||
const QRectF geo = output->geometry();
|
||||
|
||||
const QPointF closestPoint(std::clamp(pos.x(), geo.x(), geo.x() + geo.width() - 1),
|
||||
std::clamp(pos.y(), geo.y(), geo.y() + geo.height() - 1));
|
||||
|
||||
const QPointF ray = closestPoint - pos;
|
||||
const qreal distance = ray.x() * ray.x() + ray.y() * ray.y();
|
||||
if (!bestOutput || distance < minDistance) {
|
||||
minDistance = distance;
|
||||
bestOutput = output;
|
||||
|
|
Loading…
Reference in a new issue