This gist includes few updates to the KDE Breeze Login SDDM theme. The updates include a rounded password box with transparency, along with a matching login button.
To be used with the Monochrome KDE theme.
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 int fontSize: parseInt(config.fontSize) | |
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. | |
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.5 | |
// 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_lookandfeel_org.kde.lookandfeel", "Username") | |
onAccepted: { | |
if (root.loginScreenUiVisible) { | |
passwordBox.forceActiveFocus() | |
} | |
} | |
} | |
RowLayout { | |
Layout.fillWidth: true | |
PlasmaExtras.PasswordField { | |
id: passwordBox | |
font.pointSize: fontSize + 1 | |
Layout.fillWidth: true | |
implicitHeight: 35 | |
leftPadding: 10 | |
rightPadding: 10 | |
background: Rectangle { | |
color: '#000000' | |
opacity: 0.3 | |
radius: 5 | |
} | |
placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Password") | |
focus: !showUsernamePrompt || lastUserName | |
// Disable reveal password action because SDDM does not have the breeze icon set loaded | |
rightActions: [] | |
onAccepted: { | |
if (root.loginScreenUiVisible) { | |
startLogin(); | |
} | |
} | |
onTextChanged: { | |
if (text.length === 0) { | |
font.pointSize = fontSize + 1 | |
} else { | |
font.pointSize = 10 | |
} | |
} | |
visible: root.showUsernamePrompt || userList.currentItem.needsPassword | |
Keys.onEscapePressed: { | |
mainStack.currentItem.forceActiveFocus(); | |
} | |
//if empty and left or right is pressed change selection in user switch | |
//this cannot be in keys.onLeftPressed as then it doesn't reach the password box | |
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() | |
} | |
} | |
} | |
PlasmaComponents3.Button { | |
id: loginButton | |
Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Log In") | |
Layout.preferredHeight: passwordBox.implicitHeight | |
Layout.preferredWidth: text.length === 0 ? loginButton.Layout.preferredHeight : -1 | |
// Adds inner padding to button (to scale down the arrow icon) | |
leftPadding: 10 | |
rightPadding: 10 | |
topPadding: 10 | |
bottomPadding: 10 | |
// Button background to match with the password box | |
background: Rectangle { | |
implicitWidth: loginButton.implicitWidth | |
implicitHeight: loginButton.implicitHeight | |
radius: 5 | |
color: "black" | |
opacity: loginButton.pressed ? 0.8 : (loginButton.hovered ? 0.6 : 0.3) | |
border.color: "transparent" | |
border.width: 1 | |
MouseArea { | |
anchors.fill: parent | |
onClicked: loginButton.clicked() | |
onPressedChanged: loginButton.pressed = pressed | |
onEntered: loginButton.hovered = true | |
onExited: loginButton.hovered = false | |
} | |
} | |
icon.name: text.length === 0 ? (root.LayoutMirroring.enabled ? "go-previous" : "go-next") : "" | |
text: root.showUsernamePrompt || userList.currentItem.needsPassword ? "" : i18n("Log In") | |
onClicked: startLogin() | |
Keys.onEnterPressed: clicked() | |
Keys.onReturnPressed: clicked() | |
} | |
} | |
} |