mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-13 22:46:34 -04:00
fix(lock): bypass IME for password input (#2609)
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
package qmlchecks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLockScreenPasswordFieldBypassesTextInputIME(t *testing.T) {
|
||||||
|
data, err := os.ReadFile("../../../quickshell/Modules/Lock/LockScreenContent.qml")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("read lock screen QML: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
content := string(data)
|
||||||
|
textInputPasswordField := regexp.MustCompile(`(?s)TextInput\s*\{[^{}]*id:\s*passwordField`)
|
||||||
|
if textInputPasswordField.MatchString(content) {
|
||||||
|
t.Fatalf("passwordField must not be a TextInput because TextInput can route physical keyboard input through IME")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(content, "Keys.onPressed") || !strings.Contains(content, "event.text") {
|
||||||
|
t.Fatalf("passwordField should handle physical key text manually instead of relying on a text input control")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -753,9 +753,46 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextInput {
|
FocusScope {
|
||||||
id: passwordField
|
id: passwordField
|
||||||
|
|
||||||
|
property string text: root.passwordBuffer
|
||||||
|
property int cursorPosition: text.length
|
||||||
|
|
||||||
|
signal accepted()
|
||||||
|
|
||||||
|
function clampCursorPosition() {
|
||||||
|
cursorPosition = Math.max(0, Math.min(cursorPosition, text.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
text = "";
|
||||||
|
cursorPosition = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertText(value) {
|
||||||
|
if (value.length === 0)
|
||||||
|
return;
|
||||||
|
clampCursorPosition();
|
||||||
|
text = text.slice(0, cursorPosition) + value + text.slice(cursorPosition);
|
||||||
|
cursorPosition += value.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function backspace() {
|
||||||
|
clampCursorPosition();
|
||||||
|
if (cursorPosition === 0)
|
||||||
|
return;
|
||||||
|
text = text.slice(0, cursorPosition - 1) + text.slice(cursorPosition);
|
||||||
|
cursorPosition -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPrintableText(value) {
|
||||||
|
if (value.length === 0)
|
||||||
|
return false;
|
||||||
|
const code = value.charCodeAt(0);
|
||||||
|
return code >= 0x20 && code !== 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: lockIconContainer.width + Theme.spacingM * 2
|
anchors.leftMargin: lockIconContainer.width + Theme.spacingM * 2
|
||||||
anchors.rightMargin: {
|
anchors.rightMargin: {
|
||||||
@@ -781,7 +818,6 @@ Item {
|
|||||||
focus: true
|
focus: true
|
||||||
enabled: !demoMode
|
enabled: !demoMode
|
||||||
activeFocusOnTab: !demoMode
|
activeFocusOnTab: !demoMode
|
||||||
echoMode: parent.showPassword ? TextInput.Normal : TextInput.Password
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if (!demoMode) {
|
if (!demoMode) {
|
||||||
root.passwordBuffer = text;
|
root.passwordBuffer = text;
|
||||||
@@ -809,6 +845,8 @@ Item {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clear();
|
clear();
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pam.passwd.active) {
|
if (pam.passwd.active) {
|
||||||
@@ -816,6 +854,23 @@ Item {
|
|||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||||
|
accepted();
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.key === Qt.Key_Backspace) {
|
||||||
|
backspace();
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPrintableText(event.text)) {
|
||||||
|
insertText(event.text);
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
@@ -849,6 +904,17 @@ Item {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
|
||||||
|
function onPasswordBufferChanged() {
|
||||||
|
if (passwordField.text === root.passwordBuffer)
|
||||||
|
return;
|
||||||
|
passwordField.text = root.passwordBuffer;
|
||||||
|
passwordField.cursorPosition = passwordField.text.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardController {
|
KeyboardController {
|
||||||
|
|||||||
Reference in New Issue
Block a user