diff --git a/components/sessionsprivate/sessionsmodel.h b/components/sessionsprivate/sessionsmodel.h --- a/components/sessionsprivate/sessionsmodel.h +++ b/components/sessionsprivate/sessionsmodel.h @@ -84,6 +84,16 @@ Q_INVOKABLE void switchUser(int vt, bool shouldLock = false); Q_INVOKABLE void startNewSession(bool shouldLock = false); + /** + * Returns the virtual terminal number of a graphical session of the given + * user which can be used to provide a "Switch To" button when on the login + * screen and the user is already logged in. + * + * @param userName the name of the user + * @return the virtual terminal number or -1 if no such session exists + */ + Q_INVOKABLE int graphicalSessionOfUser(const QString &userName) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QHash roleNames() const override; diff --git a/components/sessionsprivate/sessionsmodel.cpp b/components/sessionsprivate/sessionsmodel.cpp --- a/components/sessionsprivate/sessionsmodel.cpp +++ b/components/sessionsprivate/sessionsmodel.cpp @@ -128,6 +128,19 @@ }); } +int SessionsModel::graphicalSessionOfUser(const QString &userName) const +{ + auto it = std::find_if(m_data.constBegin(), m_data.constEnd(), [&userName](const SessionEntry &item) { + return !item.isTty && item.name == userName; + }); + + if (it != m_data.constEnd()) { + return it->vtNumber; + } + + return -1; +} + void SessionsModel::reload() { static QHash kusers; diff --git a/sddm-theme/Login.qml b/sddm-theme/Login.qml --- a/sddm-theme/Login.qml +++ b/sddm-theme/Login.qml @@ -6,12 +6,24 @@ import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents +import org.kde.plasma.private.sessions 2.0 as Sessions + SessionManagementScreen { property bool showUsernamePrompt: !showUserList + readonly property int selectedUserVt: sessionsModel.graphicalSessionOfUser(userListCurrentModelData.name) + signal loginRequest(string username, string password) + // SessionManagementScreen has a default property alias'd to "children" + // where you cannot assign non-graphical items + data: [ + Sessions.SessionsModel { + id: sessionsModel + } + ] + /* * 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 @@ -43,8 +55,9 @@ placeholderText: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Password") focus: !showUsernamePrompt echoMode: TextInput.Password + visible: selectedUserVt === -1 - onAccepted: startLogin() + onAccepted: loginButton.clicked(null /* "mouse" argument*/) Keys.onEscapePressed: { mainStack.currentItem.forceActiveFocus(); @@ -75,8 +88,9 @@ id: loginButton Layout.fillWidth: true - text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login") - onClicked: startLogin(); + text: selectedUserVt > -1 ? i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Switch To") + : i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login") + onClicked: selectedUserVt > -1 ? sessionsModel.switchUser(selectedUserVt) : startLogin() } }