Remove pointer constraint on resource unbind

Summary:
A client might delete its pointer lock/confinement object. This is supposed to
directly remove the pointer lock/confinement in KWin, but did not explicitly
until now.

BUG: 388885

Test Plan:
Tested manually with Neverball, Nexuiz and the new pointer constraints test
application. The pointer constraints autotest is also appended.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: davidedmundson, graesslin, kwin

Tags: #kwin

Maniphest Tasks: T8923

Differential Revision: https://phabricator.kde.org/D13466
icc-effect-5.14.5
Roman Gilg 2018-06-11 22:45:09 +02:00
parent e38ecfcbcf
commit 2694839099
4 changed files with 52 additions and 5 deletions

View File

@ -37,6 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Client/shm_pool.h>
#include <KWayland/Client/surface.h>
#include <KWayland/Server/seat_interface.h>
#include <KWayland/Server/surface_interface.h>
#include <linux/input.h>
@ -246,6 +247,24 @@ void TestPointerConstraints::testConfinedPointer()
QVERIFY(confinedSpy2.wait());
QCOMPARE(input()->pointer()->isConstrained(), true);
// delete pointer confine
confinedPointer.reset(nullptr);
Test::flushWaylandConnection();
QSignalSpy constraintsChangedSpy(input()->pointer()->window()->surface(), &KWayland::Server::SurfaceInterface::pointerConstraintsChanged);
QVERIFY(constraintsChangedSpy.isValid());
QVERIFY(constraintsChangedSpy.wait());
// should be unconfined
QCOMPARE(input()->pointer()->isConstrained(), false);
// confine again
confinedPointer.reset(Test::waylandPointerConstraints()->confinePointer(surface.data(), pointer.data(), nullptr, PointerConstraints::LifeTime::Persistent));
QSignalSpy confinedSpy3(confinedPointer.data(), &ConfinedPointer::confined);
QVERIFY(confinedSpy3.isValid());
QVERIFY(confinedSpy3.wait());
QCOMPARE(input()->pointer()->isConstrained(), true);
// and now unmap
shellSurface.reset();
surface.reset();
@ -302,6 +321,29 @@ void TestPointerConstraints::testLockedPointer()
// moving cursor should be allowed again
KWin::Cursor::setPos(c->geometry().center() + QPoint(1, 1));
QCOMPARE(KWin::Cursor::pos(), c->geometry().center() + QPoint(1, 1));
lockedPointer.reset(Test::waylandPointerConstraints()->lockPointer(surface.data(), pointer.data(), nullptr, PointerConstraints::LifeTime::Persistent));
QSignalSpy lockedSpy2(lockedPointer.data(), &LockedPointer::locked);
QVERIFY(lockedSpy2.isValid());
QVERIFY(lockedSpy2.wait());
// try to move the pointer
QCOMPARE(input()->pointer()->isConstrained(), true);
KWin::Cursor::setPos(c->geometry().center());
QCOMPARE(KWin::Cursor::pos(), c->geometry().center() + QPoint(1, 1));
// delete pointer lock
lockedPointer.reset(nullptr);
Test::flushWaylandConnection();
QSignalSpy constraintsChangedSpy(input()->pointer()->window()->surface(), &KWayland::Server::SurfaceInterface::pointerConstraintsChanged);
QVERIFY(constraintsChangedSpy.isValid());
QVERIFY(constraintsChangedSpy.wait());
// moving cursor should be allowed again
QCOMPARE(input()->pointer()->isConstrained(), false);
KWin::Cursor::setPos(c->geometry().center());
QCOMPARE(KWin::Cursor::pos(), c->geometry().center());
}
void TestPointerConstraints::testBreakConstrainedPointer_data()

View File

@ -1340,7 +1340,7 @@ public:
if (event->buttons() == Qt::NoButton) {
// update pointer window only if no button is pressed
input()->pointer()->update();
input()->pointer()->enablePointerConstraints();
input()->pointer()->updatePointerConstraints();
}
seat->setPointerPos(event->globalPos());
MouseEvent *e = static_cast<MouseEvent*>(event);

View File

@ -542,10 +542,10 @@ void PointerInputRedirection::update()
}
);
m_constraintsConnection = connect(m_window->surface(), &KWayland::Server::SurfaceInterface::pointerConstraintsChanged,
this, &PointerInputRedirection::enablePointerConstraints);
this, &PointerInputRedirection::updatePointerConstraints);
// check whether a pointer confinement/lock fires
m_blockConstraint = false;
enablePointerConstraints();
updatePointerConstraints();
} else {
m_window.clear();
warpXcbOnSurfaceLeft(nullptr);
@ -598,7 +598,7 @@ static QRegion getConstraintRegion(Toplevel *t, T *constraint)
return intersected.translated(t->pos() + t->clientPos());
}
void PointerInputRedirection::enablePointerConstraints()
void PointerInputRedirection::updatePointerConstraints()
{
if (m_window.isNull()) {
return;
@ -653,6 +653,7 @@ void PointerInputRedirection::enablePointerConstraints()
return;
}
} else {
m_confined = false;
disconnectConfinedPointerRegionConnection();
}
const auto lock = s->lockedPointer();
@ -669,6 +670,8 @@ void PointerInputRedirection::enablePointerConstraints()
QStringLiteral("preferences-desktop-mouse"), 5000);
// TODO: connect to region change - is it needed at all? If the pointer is locked it's always in the region
}
} else {
m_locked = false;
}
}

View File

@ -84,8 +84,10 @@ public:
void setWindowSelectionCursor(const QByteArray &shape);
void removeWindowSelectionCursor();
void enablePointerConstraints();
void updatePointerConstraints();
void breakPointerConstraints();
/* This is only used for ESC pressing */
void blockPointerConstraints() {
m_blockConstraint = true;
}