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() } } } } }