Add check for lock screen in InputRedirection::updateKeyboardWindow
Instead of only making the active client the focused keyboard surface, the method now also performs the lock screen security restriction. Also just like udatePointerWindow the method becomes public, so that it can be used from the LockScreenEventFilter and is connected for lock state changes. This means as soon as the screen locks the current focused keyboard surface will get a leave event and get an enter event once the screen unlocks. The auto test is adjusted to verify these new conditions. Reviewed-By: Bhushan Shah
This commit is contained in:
parent
16a33f662b
commit
a311f9bfda
3 changed files with 50 additions and 36 deletions
|
@ -434,13 +434,15 @@ void LockScreenTest::testKeyboard()
|
||||||
QCOMPARE(keyChangedSpy.at(1).at(2).value<quint32>(), quint32(2));
|
QCOMPARE(keyChangedSpy.at(1).at(2).value<quint32>(), quint32(2));
|
||||||
|
|
||||||
LOCK
|
LOCK
|
||||||
|
QVERIFY(leftSpy.wait());
|
||||||
KEYPRESS(KEY_B);
|
KEYPRESS(KEY_B);
|
||||||
KEYRELEASE(KEY_B);
|
KEYRELEASE(KEY_B);
|
||||||
QVERIFY(leftSpy.wait());
|
|
||||||
QCOMPARE(leftSpy.count(), 1);
|
QCOMPARE(leftSpy.count(), 1);
|
||||||
QCOMPARE(keyChangedSpy.count(), 2);
|
QCOMPARE(keyChangedSpy.count(), 2);
|
||||||
|
|
||||||
UNLOCK
|
UNLOCK
|
||||||
|
QVERIFY(enteredSpy.wait());
|
||||||
|
QCOMPARE(enteredSpy.count(), 2);
|
||||||
KEYPRESS(KEY_C);
|
KEYPRESS(KEY_C);
|
||||||
QVERIFY(keyChangedSpy.wait());
|
QVERIFY(keyChangedSpy.wait());
|
||||||
QCOMPARE(keyChangedSpy.count(), 3);
|
QCOMPARE(keyChangedSpy.count(), 3);
|
||||||
|
|
79
input.cpp
79
input.cpp
|
@ -385,31 +385,12 @@ public:
|
||||||
if (!waylandServer()->isScreenLocked()) {
|
if (!waylandServer()->isScreenLocked()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const ToplevelList &stacking = Workspace::self()->stackingOrder();
|
input()->updateKeyboardWindow();
|
||||||
auto seat = waylandServer()->seat();
|
if (!keyboardSurfaceAllowed()) {
|
||||||
seat->setTimestamp(event->timestamp());
|
// don't pass event to seat
|
||||||
Toplevel *found = nullptr;
|
return true;
|
||||||
if (!stacking.isEmpty()) {
|
|
||||||
auto it = stacking.end();
|
|
||||||
do {
|
|
||||||
--it;
|
|
||||||
Toplevel *t = (*it);
|
|
||||||
if (t->isDeleted()) {
|
|
||||||
// a deleted window doesn't get mouse events
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!t->isLockScreen()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!t->readyForPainting()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
found = t;
|
|
||||||
break;
|
|
||||||
} while (it != stacking.begin());
|
|
||||||
}
|
}
|
||||||
// if we reach this point it's time to unset
|
auto seat = waylandServer()->seat();
|
||||||
seat->setFocusedKeyboardSurface(found ? found->surface() : nullptr);
|
|
||||||
switch (event->type()) {
|
switch (event->type()) {
|
||||||
case QEvent::KeyPress:
|
case QEvent::KeyPress:
|
||||||
seat->keyPressed(event->nativeScanCode());
|
seat->keyPressed(event->nativeScanCode());
|
||||||
|
@ -423,8 +404,8 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool pointerSurfaceAllowed() const {
|
bool surfaceAllowed(KWayland::Server::SurfaceInterface *(KWayland::Server::SeatInterface::*method)() const) const {
|
||||||
if (KWayland::Server::SurfaceInterface *s = waylandServer()->seat()->focusedPointerSurface()) {
|
if (KWayland::Server::SurfaceInterface *s = (waylandServer()->seat()->*method)()) {
|
||||||
if (Toplevel *t = waylandServer()->findClient(s)) {
|
if (Toplevel *t = waylandServer()->findClient(s)) {
|
||||||
return t->isLockScreen() || t->isInputMethod();
|
return t->isLockScreen() || t->isInputMethod();
|
||||||
}
|
}
|
||||||
|
@ -432,6 +413,12 @@ private:
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool pointerSurfaceAllowed() const {
|
||||||
|
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedPointerSurface);
|
||||||
|
}
|
||||||
|
bool keyboardSurfaceAllowed() const {
|
||||||
|
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedKeyboardSurface);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class EffectsFilter : public InputEventFilter {
|
class EffectsFilter : public InputEventFilter {
|
||||||
|
@ -707,10 +694,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto seat = waylandServer()->seat();
|
auto seat = waylandServer()->seat();
|
||||||
if (workspace()->activeClient() &&
|
input()->updateKeyboardWindow();
|
||||||
(seat->focusedKeyboardSurface() != workspace()->activeClient()->surface())) {
|
|
||||||
seat->setFocusedKeyboardSurface(workspace()->activeClient()->surface());
|
|
||||||
}
|
|
||||||
seat->setTimestamp(event->timestamp());
|
seat->setTimestamp(event->timestamp());
|
||||||
switch (event->type()) {
|
switch (event->type()) {
|
||||||
case QEvent::KeyPress:
|
case QEvent::KeyPress:
|
||||||
|
@ -887,6 +871,7 @@ void InputRedirection::setupWorkspace()
|
||||||
connect(workspace(), &Workspace::configChanged, this, &InputRedirection::reconfigure);
|
connect(workspace(), &Workspace::configChanged, this, &InputRedirection::reconfigure);
|
||||||
|
|
||||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updatePointerWindow);
|
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updatePointerWindow);
|
||||||
|
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updateKeyboardWindow);
|
||||||
}
|
}
|
||||||
setupInputFilters();
|
setupInputFilters();
|
||||||
}
|
}
|
||||||
|
@ -1300,11 +1285,37 @@ void InputRedirection::updateKeyboardWindow()
|
||||||
}
|
}
|
||||||
if (auto seat = findSeat()) {
|
if (auto seat = findSeat()) {
|
||||||
// TODO: this needs better integration
|
// TODO: this needs better integration
|
||||||
Toplevel *t = workspace()->activeClient();
|
Toplevel *found = nullptr;
|
||||||
if (t && t->surface()) {
|
if (waylandServer()->isScreenLocked()) {
|
||||||
if (t->surface() != seat->focusedKeyboardSurface()) {
|
const ToplevelList &stacking = Workspace::self()->stackingOrder();
|
||||||
seat->setFocusedKeyboardSurface(t->surface());
|
if (!stacking.isEmpty()) {
|
||||||
|
auto it = stacking.end();
|
||||||
|
do {
|
||||||
|
--it;
|
||||||
|
Toplevel *t = (*it);
|
||||||
|
if (t->isDeleted()) {
|
||||||
|
// a deleted window doesn't get mouse events
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!t->isLockScreen()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!t->readyForPainting()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
found = t;
|
||||||
|
break;
|
||||||
|
} while (it != stacking.begin());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
found = workspace()->activeClient();
|
||||||
|
}
|
||||||
|
if (found && found->surface()) {
|
||||||
|
if (found->surface() != seat->focusedKeyboardSurface()) {
|
||||||
|
seat->setFocusedKeyboardSurface(found->surface());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
seat->setFocusedKeyboardSurface(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
input.h
3
input.h
|
@ -155,6 +155,8 @@ public:
|
||||||
qint32 touchId(quint32 internalId);
|
qint32 touchId(quint32 internalId);
|
||||||
void removeTouchId(quint32 internalId);
|
void removeTouchId(quint32 internalId);
|
||||||
|
|
||||||
|
void updateKeyboardWindow();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void updatePointerWindow();
|
void updatePointerWindow();
|
||||||
|
|
||||||
|
@ -213,7 +215,6 @@ private:
|
||||||
void pointerInternalWindowVisibilityChanged(bool visible);
|
void pointerInternalWindowVisibilityChanged(bool visible);
|
||||||
void installCursorFromDecoration();
|
void installCursorFromDecoration();
|
||||||
bool areButtonsPressed() const;
|
bool areButtonsPressed() const;
|
||||||
void updateKeyboardWindow();
|
|
||||||
void setupWorkspace();
|
void setupWorkspace();
|
||||||
void reconfigure();
|
void reconfigure();
|
||||||
void setupInputFilters();
|
void setupInputFilters();
|
||||||
|
|
Loading…
Reference in a new issue