Improve lock screen interaction for pointer in InputRedirection
InputRedirection connects to lockStateChanged to udate the current pointer window. This way we can ensure that the current pointer surface gets reset as soon as the screen locks (c.f. the expect fail in the autotest) and also that it restores to the surface under the mouse once the screen is unlocked. The relevant code was not yet lock screen aware and performed an early exit. Part of the code was fine, e.g. findToplevel is lock screen aware. So this change adjusts the methods for updating the internal window and decoration to be lock screen aware, that is they get reset. With that updatePointerWindow is also lock screen aware. Thus the LockScreenFilter can also use updatePointerWindow just like the normal handling and does not need to reimplement parts of it. As it now relies on other code being correct it has an additional check to verify that the current pointer surface is a surface which is allowed to get events. If it isn't the events are not forwarded. Reviewed-By: Bhushan Shah
This commit is contained in:
parent
142e826191
commit
16a33f662b
2 changed files with 41 additions and 32 deletions
|
@ -300,16 +300,13 @@ void LockScreenTest::testPointer()
|
|||
|
||||
LOCK
|
||||
|
||||
QEXPECT_FAIL("", "Adding the lock screen window should send left event", Continue);
|
||||
QVERIFY(leftSpy.wait(100));
|
||||
QEXPECT_FAIL("", "Adding the lock screen window should send left event", Continue);
|
||||
QCOMPARE(leftSpy.count(), 1);
|
||||
|
||||
// simulate moving out in and out again
|
||||
MOTION(c->geometry().center());
|
||||
MOTION(c->geometry().bottomRight() + QPoint(100, 100));
|
||||
MOTION(c->geometry().bottomRight() + QPoint(100, 100));
|
||||
QEXPECT_FAIL("", "Adding the lock screen window should send left event", Continue);
|
||||
QVERIFY(!leftSpy.wait(100));
|
||||
QCOMPARE(leftSpy.count(), 1);
|
||||
QCOMPARE(enteredSpy.count(), 1);
|
||||
|
@ -319,16 +316,14 @@ void LockScreenTest::testPointer()
|
|||
// and unlock
|
||||
UNLOCK
|
||||
|
||||
QEXPECT_FAIL("", "Focus doesn't move back on surface removal", Continue);
|
||||
QVERIFY(enteredSpy.wait(100));
|
||||
QEXPECT_FAIL("", "Focus doesn't move back on surface removal", Continue);
|
||||
QCOMPARE(enteredSpy.count(), 2);
|
||||
// move on the window
|
||||
MOTION(c->geometry().center() + QPoint(100, 100));
|
||||
QVERIFY(leftSpy.wait());
|
||||
MOTION(c->geometry().center());
|
||||
QEXPECT_FAIL("", "Focus doesn't move back on surface removal", Continue);
|
||||
QVERIFY(!enteredSpy.wait(100));
|
||||
QCOMPARE(enteredSpy.count(), 2);
|
||||
QVERIFY(enteredSpy.wait());
|
||||
QCOMPARE(enteredSpy.count(), 3);
|
||||
}
|
||||
|
||||
void LockScreenTest::testPointerButton()
|
||||
|
|
62
input.cpp
62
input.cpp
|
@ -49,6 +49,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <QTemporaryFile>
|
||||
// KDE
|
||||
#include <kkeyserver.h>
|
||||
//screenlocker
|
||||
#include <KScreenLocker/KsldApp>
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||
// system
|
||||
|
@ -352,19 +355,16 @@ public:
|
|||
auto seat = waylandServer()->seat();
|
||||
seat->setTimestamp(event->timestamp());
|
||||
if (event->type() == QEvent::MouseMove) {
|
||||
Toplevel *t = input()->findToplevel(event->screenPos().toPoint());
|
||||
if (t && t->surface()) {
|
||||
seat->setFocusedPointerSurface(t->surface(), t->inputTransformation());
|
||||
} else {
|
||||
seat->setFocusedPointerSurface(nullptr);
|
||||
if (event->buttons() == Qt::NoButton) {
|
||||
// update pointer window only if no button is pressed
|
||||
input()->updatePointerWindow();
|
||||
}
|
||||
if (pointerSurfaceAllowed()) {
|
||||
seat->setPointerPos(event->screenPos().toPoint());
|
||||
}
|
||||
seat->setPointerPos(event->screenPos().toPoint());
|
||||
} else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) {
|
||||
if (KWayland::Server::SurfaceInterface *s = seat->focusedPointerSurface()) {
|
||||
Toplevel *t = waylandServer()->findClient(s);
|
||||
if (t->isLockScreen() || t->isInputMethod()) {
|
||||
event->type() == QEvent::MouseButtonPress ? seat->pointerButtonPressed(nativeButton) : seat->pointerButtonReleased(nativeButton);
|
||||
}
|
||||
if (pointerSurfaceAllowed()) {
|
||||
event->type() == QEvent::MouseButtonPress ? seat->pointerButtonPressed(nativeButton) : seat->pointerButtonReleased(nativeButton);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -374,13 +374,10 @@ public:
|
|||
return false;
|
||||
}
|
||||
auto seat = waylandServer()->seat();
|
||||
if (KWayland::Server::SurfaceInterface *s = seat->focusedPointerSurface()) {
|
||||
Toplevel *t = waylandServer()->findClient(s);
|
||||
if (t->isLockScreen() || t->isInputMethod()) {
|
||||
seat->setTimestamp(event->timestamp());
|
||||
const Qt::Orientation orientation = event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal;
|
||||
seat->pointerAxis(orientation, orientation == Qt::Horizontal ? event->angleDelta().x() : event->angleDelta().y());
|
||||
}
|
||||
if (pointerSurfaceAllowed()) {
|
||||
seat->setTimestamp(event->timestamp());
|
||||
const Qt::Orientation orientation = event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal;
|
||||
seat->pointerAxis(orientation, orientation == Qt::Horizontal ? event->angleDelta().x() : event->angleDelta().y());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -425,6 +422,16 @@ public:
|
|||
}
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
bool pointerSurfaceAllowed() const {
|
||||
if (KWayland::Server::SurfaceInterface *s = waylandServer()->seat()->focusedPointerSurface()) {
|
||||
if (Toplevel *t = waylandServer()->findClient(s)) {
|
||||
return t->isLockScreen() || t->isInputMethod();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class EffectsFilter : public InputEventFilter {
|
||||
|
@ -878,6 +885,8 @@ void InputRedirection::setupWorkspace()
|
|||
}
|
||||
);
|
||||
connect(workspace(), &Workspace::configChanged, this, &InputRedirection::reconfigure);
|
||||
|
||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updatePointerWindow);
|
||||
}
|
||||
setupInputFilters();
|
||||
}
|
||||
|
@ -1034,9 +1043,6 @@ void InputRedirection::setupLibInputWithScreens()
|
|||
|
||||
void InputRedirection::updatePointerWindow()
|
||||
{
|
||||
if (waylandServer() && waylandServer()->isScreenLocked()) {
|
||||
return;
|
||||
}
|
||||
// TODO: handle pointer grab aka popups
|
||||
Toplevel *t = findToplevel(m_globalPointer.toPoint());
|
||||
updatePointerInternalWindow();
|
||||
|
@ -1090,6 +1096,7 @@ void InputRedirection::updatePointerWindow()
|
|||
void InputRedirection::updatePointerDecoration(Toplevel *t)
|
||||
{
|
||||
const auto oldDeco = m_pointerDecoration;
|
||||
bool needsReset = waylandServer() && waylandServer()->isScreenLocked();
|
||||
if (AbstractClient *c = dynamic_cast<AbstractClient*>(t)) {
|
||||
// check whether it's on a Decoration
|
||||
if (c->decoratedClient()) {
|
||||
|
@ -1097,12 +1104,15 @@ void InputRedirection::updatePointerDecoration(Toplevel *t)
|
|||
if (!clientRect.contains(m_globalPointer.toPoint())) {
|
||||
m_pointerDecoration = c->decoratedClient();
|
||||
} else {
|
||||
m_pointerDecoration.clear();
|
||||
needsReset = true;
|
||||
}
|
||||
} else {
|
||||
m_pointerDecoration.clear();
|
||||
needsReset = true;
|
||||
}
|
||||
} else {
|
||||
needsReset = true;
|
||||
}
|
||||
if (needsReset) {
|
||||
m_pointerDecoration.clear();
|
||||
}
|
||||
|
||||
|
@ -1128,6 +1138,7 @@ void InputRedirection::updatePointerInternalWindow()
|
|||
const auto oldInternalWindow = m_pointerInternalWindow;
|
||||
if (waylandServer()) {
|
||||
bool found = false;
|
||||
bool needsReset = waylandServer()->isScreenLocked();
|
||||
const auto &internalClients = waylandServer()->internalClients();
|
||||
const bool change = m_pointerInternalWindow.isNull() || !(m_pointerInternalWindow->flags().testFlag(Qt::Popup) && m_pointerInternalWindow->isVisible());
|
||||
if (!internalClients.isEmpty() && change) {
|
||||
|
@ -1146,9 +1157,12 @@ void InputRedirection::updatePointerInternalWindow()
|
|||
}
|
||||
} while (it != internalClients.begin());
|
||||
if (!found) {
|
||||
m_pointerInternalWindow.clear();
|
||||
needsReset = true;
|
||||
}
|
||||
}
|
||||
if (needsReset) {
|
||||
m_pointerInternalWindow.clear();
|
||||
}
|
||||
}
|
||||
if (oldInternalWindow != m_pointerInternalWindow) {
|
||||
// changed
|
||||
|
|
Loading…
Reference in a new issue