[wayland] Add some restrictions for lockscreen
When screen is locked, - No window other then screenlocker or inputmethods gets rendered - Only screenlocker gets keyboard events - Only screenlocker and inputmethods get mouse events Things that are not secured/tested are : - Touch events - Global shortcuts for screenlocker - Fallback/emergency screen not yet working REVIEW: 126015
This commit is contained in:
parent
450bbaafdc
commit
e5518dffe2
2 changed files with 99 additions and 7 deletions
|
@ -703,13 +703,21 @@ void Compositor::performCompositing()
|
|||
return;
|
||||
}
|
||||
|
||||
// skip windows that are not yet ready for being painted
|
||||
// skip windows that are not yet ready for being painted and if screen is locked skip windows that are
|
||||
// neither lockscreen nor inputmethod windows
|
||||
// TODO ?
|
||||
// this cannot be used so carelessly - needs protections against broken clients, the window
|
||||
// should not get focus before it's displayed, handle unredirected windows properly and so on.
|
||||
foreach (Toplevel *t, windows)
|
||||
if (!t->readyForPainting())
|
||||
foreach (Toplevel *t, windows) {
|
||||
if (!t->readyForPainting()) {
|
||||
windows.removeAll(t);
|
||||
}
|
||||
if (waylandServer() && waylandServer()->isScreenLocked()) {
|
||||
if(!t->isLockScreen() && !t->isInputMethod()) {
|
||||
windows.removeAll(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QRegion repaints = repaints_region;
|
||||
// clear all repaints, so that post-pass can add repaints for the next repaint
|
||||
|
|
92
input.cpp
92
input.cpp
|
@ -507,6 +507,9 @@ void InputRedirection::setupLibInputWithScreens()
|
|||
|
||||
void InputRedirection::updatePointerWindow()
|
||||
{
|
||||
if (waylandServer() && waylandServer()->isScreenLocked()) {
|
||||
return;
|
||||
}
|
||||
// TODO: handle pointer grab aka popups
|
||||
Toplevel *t = findToplevel(m_globalPointer.toPoint());
|
||||
updatePointerInternalWindow();
|
||||
|
@ -695,6 +698,17 @@ void InputRedirection::processPointerMotion(const QPointF &pos, uint32_t time)
|
|||
if (!workspace()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (waylandServer()->isScreenLocked()) {
|
||||
Toplevel *t = findToplevel(pos.toPoint());
|
||||
if (auto seat = findSeat()) {
|
||||
seat->setFocusedPointerSurface(t->surface(), t->pos());
|
||||
seat->setTimestamp(time);
|
||||
seat->setPointerPos(pos);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// first update to new mouse position
|
||||
// const QPointF oldPos = m_globalPointer;
|
||||
updatePointerPosition(pos);
|
||||
|
@ -734,6 +748,21 @@ void InputRedirection::processPointerButton(uint32_t button, InputRedirection::P
|
|||
|
||||
QMouseEvent event(buttonStateToEvent(state), m_globalPointer.toPoint(), m_globalPointer.toPoint(),
|
||||
buttonToQtMouseButton(button), qtButtonStates(), keyboardModifiers());
|
||||
|
||||
if (waylandServer()->isScreenLocked()) {
|
||||
if (auto seat = findSeat()) {
|
||||
KWayland::Server::SurfaceInterface *s = seat->focusedPointerSurface();
|
||||
if (s) {
|
||||
Toplevel *t = waylandServer()->findClient(s);
|
||||
if (t->isLockScreen() || t->isInputMethod()) {
|
||||
seat->setTimestamp(time);
|
||||
state == PointerButtonPressed ? seat->pointerButtonPressed(button) : seat->pointerButtonReleased(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// check whether an effect has a mouse grab
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(&event)) {
|
||||
// an effect grabbed the pointer, we do not forward the event to surfaces
|
||||
|
@ -806,7 +835,23 @@ void InputRedirection::processPointerAxis(InputRedirection::PointerAxis axis, qr
|
|||
if (delta == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
emit pointerAxisChanged(axis, delta);
|
||||
|
||||
if (waylandServer()->isScreenLocked()) {
|
||||
if (auto seat = findSeat()) {
|
||||
KWayland::Server::SurfaceInterface *s = seat->focusedPointerSurface();
|
||||
if (s) {
|
||||
Toplevel *t = waylandServer()->findClient(s);
|
||||
if (t->isLockScreen() || t->isInputMethod()) {
|
||||
seat->setTimestamp(time);
|
||||
seat->pointerAxis(axis == InputRedirection::PointerAxisHorizontal ? Qt::Horizontal : Qt::Vertical, delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_xkb->modifiers() != Qt::NoModifier) {
|
||||
PointerAxisDirection direction = PointerAxisUp;
|
||||
if (axis == PointerAxisHorizontal) {
|
||||
|
@ -894,6 +939,37 @@ void InputRedirection::processKeyboardKey(uint32_t key, InputRedirection::Keyboa
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (waylandServer()->isScreenLocked()) {
|
||||
const ToplevelList &stacking = Workspace::self()->stackingOrder();
|
||||
if (stacking.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (auto seat = findSeat()) {
|
||||
seat->setFocusedKeyboardSurface(t->surface());
|
||||
seat->setTimestamp(time);
|
||||
state == InputRedirection::KeyboardKeyPressed ? seat->keyPressed(key) : seat->keyReleased(key);
|
||||
}
|
||||
return;
|
||||
} while (it != stacking.begin());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: pass to internal parts of KWin
|
||||
#ifdef KWIN_BUILD_TABBOX
|
||||
if (TabBox::TabBox::self() && TabBox::TabBox::self()->isGrabbed()) {
|
||||
|
@ -1119,11 +1195,14 @@ Toplevel *InputRedirection::findToplevel(const QPoint &pos)
|
|||
if (!Workspace::self()) {
|
||||
return nullptr;
|
||||
}
|
||||
const bool isScreenLocked = waylandServer() && waylandServer()->isScreenLocked();
|
||||
// TODO: check whether the unmanaged wants input events at all
|
||||
const UnmanagedList &unmanaged = Workspace::self()->unmanagedList();
|
||||
foreach (Unmanaged *u, unmanaged) {
|
||||
if (u->geometry().contains(pos) && acceptsInput(u, pos)) {
|
||||
return u;
|
||||
if (!isScreenLocked) {
|
||||
const UnmanagedList &unmanaged = Workspace::self()->unmanagedList();
|
||||
foreach (Unmanaged *u, unmanaged) {
|
||||
if (u->geometry().contains(pos) && acceptsInput(u, pos)) {
|
||||
return u;
|
||||
}
|
||||
}
|
||||
}
|
||||
const ToplevelList &stacking = Workspace::self()->stackingOrder();
|
||||
|
@ -1146,6 +1225,11 @@ Toplevel *InputRedirection::findToplevel(const QPoint &pos)
|
|||
if (!t->readyForPainting()) {
|
||||
continue;
|
||||
}
|
||||
if (isScreenLocked) {
|
||||
if (!t->isLockScreen() && !t->isInputMethod()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (t->geometry().contains(pos) && acceptsInput(t, pos)) {
|
||||
return t;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue