diff --git a/lookandfeel/contents/components/SessionManagementScreen.qml b/lookandfeel/contents/components/SessionManagementScreen.qml index 5617e801e..a9acd2b58 100644 --- a/lookandfeel/contents/components/SessionManagementScreen.qml +++ b/lookandfeel/contents/components/SessionManagementScreen.qml @@ -1,115 +1,117 @@ /* * Copyright 2016 David Edmundson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.2 import QtQuick.Layouts 1.1 import QtQuick.Controls 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents Item { id: root /* * Any message to be displayed to the user, visible above the text fields */ property alias notificationMessage: notificationsLabel.text /* * A list of Items (typically ActionButtons) to be shown in a Row beneath the prompts */ property alias actionItems: actionItemsLayout.children /* * A model with a list of users to show in the view * The following roles should exist: * - name * - iconSource * * The following are also handled: * - vtNumber * - displayNumber * - session * - isTty */ property alias userListModel: userListView.model /* * Self explanatory */ property alias userListCurrentIndex: userListView.currentIndex property var userListCurrentModelData: userListView.currentItem === null ? [] : userListView.currentItem.m + property bool showUserList: true property alias userList: userListView default property alias _children: innerLayout.children UserList { id: userListView + visible: showUserList anchors { bottom: parent.verticalCenter left: parent.left right: parent.right } } //goal is to show the prompts, in ~16 grid units high, then the action buttons //but collapse the space between the prompts and actions if there's no room //ui is constrained to 16 grid units wide, or the screen ColumnLayout { id: prompts anchors.top: parent.verticalCenter anchors.topMargin: units.gridUnit * 0.5 anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom PlasmaComponents.Label { id: notificationsLabel Layout.maximumWidth: units.gridUnit * 16 Layout.alignment: Qt.AlignHCenter wrapMode: Text.WordWrap font.italic: true } ColumnLayout { Layout.minimumHeight: implicitHeight Layout.maximumHeight: units.gridUnit * 10 Layout.maximumWidth: units.gridUnit * 16 Layout.alignment: Qt.AlignHCenter ColumnLayout { id: innerLayout Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true } Item { Layout.fillHeight: true } } Row { //deliberately not rowlayout as I'm not trying to resize child items id: actionItemsLayout spacing: units.smallSpacing Layout.alignment: Qt.AlignHCenter } Item { Layout.fillHeight: true } } } diff --git a/sddm-theme/Login.qml b/sddm-theme/Login.qml index 85546b4d3..5f8418cd0 100644 --- a/sddm-theme/Login.qml +++ b/sddm-theme/Login.qml @@ -1,82 +1,82 @@ import "components" import QtQuick 2.0 import QtQuick.Layouts 1.2 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents SessionManagementScreen { - property bool showUsernamePrompt: false + property bool showUsernamePrompt: !showUserList signal loginRequest(string username, string password) /* * 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() { var username = showUsernamePrompt ? userNameInput.text : userList.selectedUser var password = passwordBox.text //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 focussed //DAVE REPORT THE FRICKING THING AND PUT A LINK loginButton.forceActiveFocus(); loginRequest(username, password); } PlasmaComponents.TextField { id: userNameInput Layout.fillWidth: true visible: showUsernamePrompt focus: showUsernamePrompt //if there's a username prompt it gets focus first, otherwise password does placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Username") } PlasmaComponents.TextField { id: passwordBox Layout.fillWidth: true placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Password") focus: !showUsernamePrompt echoMode: TextInput.Password onAccepted: startLogin() 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: { 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 onLoginFailed: { passwordBox.selectAll() passwordBox.forceActiveFocus() } } } PlasmaComponents.Button { id: loginButton Layout.fillWidth: true text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login") onClicked: startLogin(); } } diff --git a/sddm-theme/Main.qml b/sddm-theme/Main.qml index 5e7bb58eb..5c3cce537 100644 --- a/sddm-theme/Main.qml +++ b/sddm-theme/Main.qml @@ -1,212 +1,215 @@ /* * Copyright 2016 David Edmundson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.2 import QtQuick.Layouts 1.1 import QtQuick.Controls 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.extras 2.0 as PlasmaExtras import "components" PlasmaCore.ColorScope { id: root colorGroup: PlasmaCore.Theme.ComplementaryColorGroup width: 1600 height: 900 property string notificationMessage LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft LayoutMirroring.childrenInherit: true Repeater { model: screenModel Background { x: geometry.x; y: geometry.y; width: geometry.width; height:geometry.height source: config.background fillMode: Image.PreserveAspectCrop } } Clock { visible: y > 0 anchors.bottom: parent.verticalCenter anchors.bottomMargin: units.gridUnit * 13 anchors.horizontalCenter: parent.horizontalCenter } StackView { id: mainStack anchors { top: parent.top bottom: footer.top left: parent.left right: parent.right topMargin: footer.height // effectively centre align within the view } focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it Timer { //SDDM has a bug in 0.13 where even though we set the focus on the right item within the window, the window doesn't have focus //it is fixed in 6d5b36b28907b16280ff78995fef764bb0c573db which will be 0.14 //we need to call "window->activate()" *After* it's been shown. We can't control that in QML so we use a shoddy timer //it's been this way for all Plasma 5.x without a huge problem running: true repeat: false interval: 200 onTriggered: mainStack.forceActiveFocus() } initialItem: Login { + id: userListComponent userListModel: userModel userListCurrentIndex: userModel.lastIndex >= 0 ? userModel.lastIndex : 0 + showUserList: (userListModel.count && userListModel.disableAvatarsThreshold) ? userListModel.count <= userListModel.disableAvatarsThreshold : true notificationMessage: root.notificationMessage actionItems: [ ActionButton { iconSource: "system-suspend" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Suspend") onClicked: sddm.suspend() enabled: sddm.canSuspend }, ActionButton { iconSource: "system-reboot" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Restart") onClicked: sddm.reboot() enabled: sddm.canReboot }, ActionButton { iconSource: "system-shutdown" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Shutdown") onClicked: sddm.powerOff() enabled: sddm.canPowerOff }, ActionButton { iconSource: "system-search" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Different User") - onClicked: mainStack.push(userPrompt) + onClicked: mainStack.push(userPromptComponent) enabled: true + visible: !userListComponent.showUsernamePrompt } ] onLoginRequest: { root.notificationMessage = "" sddm.login(username, password, sessionButton.currentIndex) } } Behavior on opacity { OpacityAnimator { duration: units.longDuration } } } Component { - id: userPrompt + id: userPromptComponent Login { showUsernamePrompt: true notificationMessage: root.notificationMessage userListModel: QtObject { property string name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login as different user") property string iconSource: "" } onLoginRequest: { root.notificationMessage = "" sddm.login(username, password, sessionButton.currentIndex) } actionItems: [ ActionButton { iconSource: "go-previous" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Back") onClicked: mainStack.pop() } ] } } //Footer RowLayout { id: footer anchors { bottom: parent.bottom left: parent.left right: parent.right margins: units.smallSpacing } Behavior on opacity { OpacityAnimator { duration: units.longDuration } } KeyboardButton { } SessionButton { id: sessionButton } Item { Layout.fillWidth: true } Battery { } } Connections { target: sddm onLoginFailed: { notificationMessage = i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login Failed") } onLoginSucceeded: { //note SDDM will kill the greeter at some random point after this //there is no certainty any transition will finish, it depends on the time it //takes to complete the init mainStack.opacity = 0 footer.opacity = 0 } } onNotificationMessageChanged: { if (notificationMessage) { notificationResetTimer.start(); } } Timer { id: notificationResetTimer interval: 3000 onTriggered: notificationMessage = "" } }