Files
super-earth-sddm/Login.qml
2025-07-31 22:50:58 -05:00

169 lines
5.3 KiB
QML

import org.kde.breeze.components
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15 as QQC2
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.kirigami 2.20 as Kirigami
SessionManagementScreen {
id: root
property Item mainPasswordBox: passwordBox
property bool showUsernamePrompt: !showUserList
property string lastUserName
property bool loginScreenUiVisible: false
//the y position that should be ensured visible when the on screen keyboard is visible
property int visibleBoundary: mapFromItem(loginButton, 0, 0).y
onHeightChanged: visibleBoundary = mapFromItem(loginButton, 0, 0).y + loginButton.height + Kirigami.Units.smallSpacing
property real fontSize: Kirigami.Theme.defaultFont.pointSize
signal loginRequest(string username, string password)
onShowUsernamePromptChanged: {
if (!showUsernamePrompt) {
lastUserName = ""
}
}
onUserSelected: {
// Don't startLogin() here, because the signal is connected to the
// Escape key as well, for which it wouldn't make sense to trigger
// login.
passwordBox.clear()
focusFirstVisibleFormControl();
}
QQC2.StackView.onActivating: {
// Controls are not visible yet.
Qt.callLater(focusFirstVisibleFormControl);
}
function focusFirstVisibleFormControl() {
const nextControl = (userNameInput.visible
? userNameInput
: (passwordBox.visible
? passwordBox
: loginButton));
// Using TabFocusReason, so that the loginButton gets the visual highlight.
nextControl.forceActiveFocus(Qt.TabFocusReason);
}
/*
* Login has been requested with the following username and password
* If username field is visible, it will be taken from that, otherwise from the "name" property of the currentIndex
*/
function startLogin() {
const username = showUsernamePrompt ? userNameInput.text : userList.selectedUser
const password = passwordBox.text
footer.enabled = false
mainStack.enabled = false
userListComponent.userList.opacity = 0
// This is partly because it looks nicer, but more importantly it
// works round a Qt bug that can trigger if the app is closed with a
// TextField focused.
//
// See https://bugreports.qt.io/browse/QTBUG-55460
loginButton.forceActiveFocus();
loginRequest(username, password);
}
PlasmaComponents3.TextField {
id: userNameInput
font.pointSize: fontSize + 1
Layout.fillWidth: true
text: lastUserName
visible: showUsernamePrompt
focus: showUsernamePrompt && !lastUserName //if there's a username prompt it gets focus first, otherwise password does
placeholderText: i18nd("plasma-desktop-sddm-theme", "Username")
// Add padding for yellow border
leftPadding: Kirigami.Units.smallSpacing * 2 // ~8px padding
rightPadding: Kirigami.Units.smallSpacing * 2
topPadding: Kirigami.Units.smallSpacing
bottomPadding: Kirigami.Units.smallSpacing
// Custom background with yellow border and no fill
background: Rectangle {
color: "transparent" // No background fill
border.color: "#FFE710" // Yellow border
border.width: 3 // Border thickness
radius: 4 // Optional: slight rounding for aesthetics
}
onAccepted: {
if (root.loginScreenUiVisible) {
passwordBox.forceActiveFocus()
}
}
}
Rectangle {
width: 2560
height: 1440
color: "transparent"
PlasmaExtras.PasswordField {
id: passwordBox
x: -330
y: 243
width: parent.width * 0.8
font.pointSize: fontSize + 20
placeholderText: i18nd("plasma-desktop-sddm-theme", "Password")
focus: !showUsernamePrompt || lastUserName
rightActions: []
leftPadding: Kirigami.Units.smallSpacing * 2
rightPadding: Kirigami.Units.smallSpacing * 2
topPadding: Kirigami.Units.smallSpacing
bottomPadding: Kirigami.Units.smallSpacing
background: Rectangle {
color: "transparent"
}
visible: root.showUsernamePrompt || userList.currentItem.needsPassword
onAccepted: {
if (root.loginScreenUiVisible) {
startLogin();
}
}
Keys.onEscapePressed: {
mainStack.currentItem.forceActiveFocus();
}
Keys.onPressed: event => {
if (event.key === Qt.Key_Left && !text) {
userList.decrementCurrentIndex();
event.accepted = true
}
if (event.key === Qt.Key_Right && !text) {
userList.incrementCurrentIndex();
event.accepted = true
}
}
Connections {
target: sddm
function onLoginFailed() {
passwordBox.selectAll()
passwordBox.forceActiveFocus()
}
}
}
}
}