Add always-visible Plasma unlock prompt
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQml
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import org.kde.plasma.components as PlasmaComponents3
|
||||
import org.kde.plasma.workspace.components as PW
|
||||
import org.kde.plasma.private.keyboardindicator as KeyboardIndicator
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kscreenlocker as ScreenLocker
|
||||
|
||||
import org.kde.plasma.private.sessions
|
||||
import org.kde.breeze.components
|
||||
|
||||
Item {
|
||||
id: lockScreenUi
|
||||
|
||||
// If we're using software rendering, draw outlines instead of shadows
|
||||
// See https://bugs.kde.org/show_bug.cgi?id=398317
|
||||
readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software
|
||||
|
||||
function handleMessage(msg) {
|
||||
if (!root.notification) {
|
||||
root.notification += msg;
|
||||
} else if (root.notification.includes(msg)) {
|
||||
root.notificationRepeated();
|
||||
} else {
|
||||
root.notification += "\n" + msg
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
|
||||
|
||||
Connections {
|
||||
target: authenticator
|
||||
function onFailed(kind) {
|
||||
if (kind != 0) { // if this is coming from the noninteractive authenticators
|
||||
return;
|
||||
}
|
||||
const msg = i18ndc("plasma_shell_org.kde.plasma.desktop", "@info:status", "Unlocking failed");
|
||||
lockScreenUi.handleMessage(msg);
|
||||
graceLockTimer.restart();
|
||||
notificationRemoveTimer.restart();
|
||||
rejectPasswordAnimation.start();
|
||||
}
|
||||
|
||||
function onSucceeded() {
|
||||
if (authenticator.hadPrompt) {
|
||||
Qt.quit();
|
||||
} else {
|
||||
mainStack.replace(null, Qt.resolvedUrl("NoPasswordUnlock.qml"),
|
||||
{
|
||||
userListModel: users
|
||||
},
|
||||
StackView.Immediate,
|
||||
);
|
||||
mainStack.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
function onInfoMessageChanged() {
|
||||
lockScreenUi.handleMessage(authenticator.infoMessage);
|
||||
}
|
||||
|
||||
function onErrorMessageChanged() {
|
||||
lockScreenUi.handleMessage(authenticator.errorMessage);
|
||||
}
|
||||
|
||||
function onPromptChanged(msg) {
|
||||
lockScreenUi.handleMessage(authenticator.prompt);
|
||||
}
|
||||
function onPromptForSecretChanged(msg) {
|
||||
mainBlock.showPassword = false;
|
||||
mainBlock.mainPasswordBox.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
SessionManagement {
|
||||
id: sessionManagement
|
||||
}
|
||||
|
||||
KeyboardIndicator.KeyState {
|
||||
id: capsLockState
|
||||
key: Qt.Key_CapsLock
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: sessionManagement
|
||||
function onAboutToSuspend() {
|
||||
root.clearPassword();
|
||||
}
|
||||
}
|
||||
|
||||
RejectPasswordAnimation {
|
||||
id: rejectPasswordAnimation
|
||||
target: mainBlock
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: lockScreenRoot
|
||||
|
||||
property bool uiVisible: false
|
||||
property bool seenPositionChange: false
|
||||
property bool blockUI: containsMouse && (mainStack.depth > 1 || mainBlock.mainPasswordBox.text.length > 0 || inputPanel.keyboardActive)
|
||||
|
||||
x: parent.x
|
||||
y: parent.y
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
hoverEnabled: true
|
||||
cursorShape: uiVisible ? Qt.ArrowCursor : Qt.BlankCursor
|
||||
drag.filterChildren: true
|
||||
onPressed: uiVisible = true;
|
||||
onPositionChanged: {
|
||||
uiVisible = seenPositionChange;
|
||||
seenPositionChange = true;
|
||||
}
|
||||
onUiVisibleChanged: {
|
||||
if (uiVisible) {
|
||||
Window.window.requestActivate();
|
||||
}
|
||||
|
||||
if (blockUI) {
|
||||
fadeoutTimer.running = false;
|
||||
} else if (uiVisible) {
|
||||
fadeoutTimer.restart();
|
||||
}
|
||||
authenticator.startAuthenticating();
|
||||
}
|
||||
onBlockUIChanged: {
|
||||
if (blockUI) {
|
||||
fadeoutTimer.running = false;
|
||||
uiVisible = true;
|
||||
} else {
|
||||
fadeoutTimer.restart();
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
uiVisible = false;
|
||||
}
|
||||
Keys.onEscapePressed: {
|
||||
// If the escape key is pressed, kscreenlocker will turn off the screen.
|
||||
// We do not want to show the password prompt in this case.
|
||||
if (uiVisible) {
|
||||
uiVisible = false;
|
||||
if (inputPanel.keyboardActive) {
|
||||
inputPanel.showHide();
|
||||
}
|
||||
root.clearPassword();
|
||||
}
|
||||
}
|
||||
Keys.onPressed: event => {
|
||||
uiVisible = true;
|
||||
event.accepted = false;
|
||||
}
|
||||
Timer {
|
||||
id: fadeoutTimer
|
||||
interval: 10000
|
||||
onTriggered: {
|
||||
if (!lockScreenRoot.blockUI) {
|
||||
mainBlock.mainPasswordBox.showPassword = false;
|
||||
lockScreenRoot.uiVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: notificationRemoveTimer
|
||||
interval: 3000
|
||||
onTriggered: root.notification = ""
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if (( $# != 3 )); then
|
||||
printf 'Usage: %s SCRIPT PATCH FIXTURE\n' "${0##*/}" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
script=$1
|
||||
patch_file=$2
|
||||
fixture=$3
|
||||
tmpdir=$(mktemp -d)
|
||||
trap 'rm -rf -- "$tmpdir"' EXIT
|
||||
|
||||
root="$tmpdir/root"
|
||||
target_dir="$root/usr/share/plasma/shells/org.kde.plasma.desktop/contents/lockscreen"
|
||||
target="$target_dir/LockScreenUi.qml"
|
||||
mkdir -p "$target_dir"
|
||||
cp "$fixture" "$target"
|
||||
|
||||
run_tool() {
|
||||
PLASMA_ALWAYS_SHOW_UNLOCK_ROOT="$root" \
|
||||
PLASMA_ALWAYS_SHOW_UNLOCK_PATCH="$patch_file" \
|
||||
bash "$script" "$@"
|
||||
}
|
||||
|
||||
if run_tool status >/dev/null 2>&1; then
|
||||
printf 'Expected an unpatched fixture.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
run_tool apply >/dev/null
|
||||
run_tool status >/dev/null
|
||||
grep -q 'function onViewVisibleChanged()' "$target"
|
||||
grep -q 'running: parent.uiVisible' "$target"
|
||||
grep -q 'onTriggered: authenticator.startAuthenticating()' "$target"
|
||||
if grep -q 'seenPositionChange\|lockScreenRoot.uiVisible = false' "$target"; then
|
||||
printf 'The patched fixture still contains prompt-hiding logic.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
patched_checksum=$(sha256sum "$target")
|
||||
run_tool apply >/dev/null
|
||||
[[ $(sha256sum "$target") == "$patched_checksum" ]]
|
||||
|
||||
run_tool revert >/dev/null
|
||||
cmp "$fixture" "$target"
|
||||
|
||||
sed -i 's/property bool seenPositionChange: false/property bool unexpectedState: false/' "$target"
|
||||
unsupported_checksum=$(sha256sum "$target")
|
||||
if run_tool apply >/dev/null 2>&1; then
|
||||
printf 'Expected an unsupported modified fixture to be rejected.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
[[ $(sha256sum "$target") == "$unsupported_checksum" ]]
|
||||
|
||||
printf 'plasma-always-show-unlock tests passed\n'
|
||||
Reference in New Issue
Block a user