Make keyboard focus a pointer constraints necessity
Summary: This patch changes KWin's pointer constraining behavior by only allowing constraints if the surface has keyboard focus. In case the client activation state changes, it rechecks it. Test Plan: Manually with the pointer constraints test application and opening the launcher by pressing meta. Also amended autotest. Reviewers: #kwin, graesslin Reviewed By: #kwin, graesslin Subscribers: graesslin, davidedmundson, kwin Tags: #kwin Maniphest Tasks: T8923 Differential Revision: https://phabricator.kde.org/D13492
This commit is contained in:
parent
ea05ac380b
commit
0bd5eff862
3 changed files with 28 additions and 2 deletions
|
@ -224,6 +224,16 @@ void TestPointerConstraints::testConfinedPointer()
|
||||||
QCOMPARE(input()->pointer()->isConstrained(), true);
|
QCOMPARE(input()->pointer()->isConstrained(), true);
|
||||||
QVERIFY(confinedSpy2.wait());
|
QVERIFY(confinedSpy2.wait());
|
||||||
|
|
||||||
|
// deactivate the client, this should unconfine
|
||||||
|
workspace()->activateClient(nullptr);
|
||||||
|
QVERIFY(unconfinedSpy2.wait());
|
||||||
|
QCOMPARE(input()->pointer()->isConstrained(), false);
|
||||||
|
|
||||||
|
// activate it again, this confines again
|
||||||
|
workspace()->activateClient(static_cast<AbstractClient*>(input()->pointer()->window().data()));
|
||||||
|
QVERIFY(confinedSpy2.wait());
|
||||||
|
QCOMPARE(input()->pointer()->isConstrained(), true);
|
||||||
|
|
||||||
// create a second window and move it above our constrained window
|
// create a second window and move it above our constrained window
|
||||||
QScopedPointer<Surface> surface2(Test::createSurface());
|
QScopedPointer<Surface> surface2(Test::createSurface());
|
||||||
QScopedPointer<QObject> shellSurface2(Test::createShellSurface(type, surface2.data()));
|
QScopedPointer<QObject> shellSurface2(Test::createShellSurface(type, surface2.data()));
|
||||||
|
|
|
@ -544,6 +544,8 @@ void PointerInputRedirection::update()
|
||||||
);
|
);
|
||||||
m_constraintsConnection = connect(m_window->surface(), &KWayland::Server::SurfaceInterface::pointerConstraintsChanged,
|
m_constraintsConnection = connect(m_window->surface(), &KWayland::Server::SurfaceInterface::pointerConstraintsChanged,
|
||||||
this, &PointerInputRedirection::updatePointerConstraints);
|
this, &PointerInputRedirection::updatePointerConstraints);
|
||||||
|
m_constraintsActivatedConnection = connect(workspace(), &Workspace::clientActivated,
|
||||||
|
this, &PointerInputRedirection::updatePointerConstraints);
|
||||||
// check whether a pointer confinement/lock fires
|
// check whether a pointer confinement/lock fires
|
||||||
m_blockConstraint = false;
|
m_blockConstraint = false;
|
||||||
updatePointerConstraints();
|
updatePointerConstraints();
|
||||||
|
@ -588,6 +590,9 @@ void PointerInputRedirection::disconnectPointerConstraintsConnection()
|
||||||
{
|
{
|
||||||
disconnect(m_constraintsConnection);
|
disconnect(m_constraintsConnection);
|
||||||
m_constraintsConnection = QMetaObject::Connection();
|
m_constraintsConnection = QMetaObject::Connection();
|
||||||
|
|
||||||
|
disconnect(m_constraintsActivatedConnection);
|
||||||
|
m_constraintsActivatedConnection = QMetaObject::Connection();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -617,13 +622,19 @@ void PointerInputRedirection::updatePointerConstraints()
|
||||||
if (m_blockConstraint) {
|
if (m_blockConstraint) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const bool windowIsActive = m_window == workspace()->activeClient();
|
||||||
const auto cf = s->confinedPointer();
|
const auto cf = s->confinedPointer();
|
||||||
if (cf) {
|
if (cf) {
|
||||||
if (cf->isConfined()) {
|
if (cf->isConfined()) {
|
||||||
|
if (!windowIsActive) {
|
||||||
|
cf->setConfined(false);
|
||||||
|
m_confined = false;
|
||||||
|
disconnectConfinedPointerRegionConnection();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const QRegion r = getConstraintRegion(m_window.data(), cf.data());
|
const QRegion r = getConstraintRegion(m_window.data(), cf.data());
|
||||||
if (r.contains(m_pos.toPoint())) {
|
if (windowIsActive && r.contains(m_pos.toPoint())) {
|
||||||
cf->setConfined(true);
|
cf->setConfined(true);
|
||||||
m_confined = true;
|
m_confined = true;
|
||||||
m_confinedPointerRegionConnection = connect(cf.data(), &KWayland::Server::ConfinedPointerInterface::regionChanged, this,
|
m_confinedPointerRegionConnection = connect(cf.data(), &KWayland::Server::ConfinedPointerInterface::regionChanged, this,
|
||||||
|
@ -660,10 +671,14 @@ void PointerInputRedirection::updatePointerConstraints()
|
||||||
const auto lock = s->lockedPointer();
|
const auto lock = s->lockedPointer();
|
||||||
if (lock) {
|
if (lock) {
|
||||||
if (lock->isLocked()) {
|
if (lock->isLocked()) {
|
||||||
|
if (!windowIsActive) {
|
||||||
|
lock->setLocked(false);
|
||||||
|
m_locked = false;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const QRegion r = getConstraintRegion(m_window.data(), lock.data());
|
const QRegion r = getConstraintRegion(m_window.data(), lock.data());
|
||||||
if (r.contains(m_pos.toPoint())) {
|
if (windowIsActive && r.contains(m_pos.toPoint())) {
|
||||||
lock->setLocked(true);
|
lock->setLocked(true);
|
||||||
m_locked = true;
|
m_locked = true;
|
||||||
OSD::show(i18nc("notification about mouse pointer locked",
|
OSD::show(i18nc("notification about mouse pointer locked",
|
||||||
|
|
|
@ -165,6 +165,7 @@ private:
|
||||||
QMetaObject::Connection m_windowGeometryConnection;
|
QMetaObject::Connection m_windowGeometryConnection;
|
||||||
QMetaObject::Connection m_internalWindowConnection;
|
QMetaObject::Connection m_internalWindowConnection;
|
||||||
QMetaObject::Connection m_constraintsConnection;
|
QMetaObject::Connection m_constraintsConnection;
|
||||||
|
QMetaObject::Connection m_constraintsActivatedConnection;
|
||||||
QMetaObject::Connection m_confinedPointerRegionConnection;
|
QMetaObject::Connection m_confinedPointerRegionConnection;
|
||||||
QMetaObject::Connection m_decorationGeometryConnection;
|
QMetaObject::Connection m_decorationGeometryConnection;
|
||||||
bool m_confined = false;
|
bool m_confined = false;
|
||||||
|
|
Loading…
Reference in a new issue