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
This commit is contained in:
parent
e38ecfcbcf
commit
2694839099
4 changed files with 52 additions and 5 deletions
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue