Commit 084b9a40 authored by David Edmundson's avatar David Edmundson

Merge switch user dialog into lockscreen

Summary:
This reduces a bunch of code, both hidden in the backend as well as the
mostly duplicated front end UI, making it more consistent for users too.

There is a behavioural change that switching user then cancelling will
require your own password.

KSMServer still has the same DBus slot for compatibility which then
proxies over to the screensaver. This could be calling itself, it might
be calling kwin when we're on wayland.

Depends on D15186

Test Plan:
Pressed switch user from the UI
Got a swich user dialog

Reviewers: #plasma, mart

Reviewed By: #plasma, mart

Subscribers: ngraham, mart, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D15187
parent 74713563
......@@ -11,7 +11,6 @@ add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(logout-greeter)
add_subdirectory(switchuser-greeter)
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
......@@ -45,6 +44,9 @@ qt5_add_dbus_interface( ksmserver_KDEINIT_SRCS ${kcminit_xml} kcminit_interface
set(klauncher_xml ${KINIT_DBUS_INTERFACES_DIR}/kf5_org.kde.KLauncher.xml)
qt5_add_dbus_interface( ksmserver_KDEINIT_SRCS ${klauncher_xml} klauncher_interface )
qt5_add_dbus_interface( ksmserver_KDEINIT_SRCS ${KDE_INSTALL_FULL_DBUSINTERFACEDIR}/org.kde.screensaver.xml kscreenlocker_interface )
qt5_add_dbus_adaptor( ksmserver_KDEINIT_SRCS org.kde.KSMServerInterface.xml server.h KSMServer )
kf5_add_kdeinit_executable( ksmserver ${ksmserver_KDEINIT_SRCS})
......
......@@ -67,6 +67,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <QPushButton>
#include <QRegExp>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QSocketNotifier>
#include <QStandardPaths>
#include <QDebug>
......@@ -91,7 +92,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <klauncher_interface.h>
#include <qstandardpaths.h>
#include "switchuserdialog.h"
#include "kscreenlocker_interface.h"
KSMServer* the_server = nullptr;
......@@ -623,7 +624,6 @@ KSMServer::KSMServer( const QString& windowManager, InitFlags flags )
shutdownType = KWorkSpace::ShutdownTypeNone;
state = Idle;
dialogActive = false;
saveSession = false;
wmPhase1WaitingCount = 0;
KConfigGroup config(KSharedConfig::openConfig(), "General");
......@@ -1091,20 +1091,9 @@ void KSMServer::rebootWithoutConfirmation()
void KSMServer::openSwitchUserDialog()
{
if (dialogActive) {
return;
}
QProcess *p = new QProcess(this);
p->setProgram(QStringLiteral(SWITCHUSER_GREETER_BIN));
connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, [this, p] {
p->deleteLater();
dialogActive = false;
});
dialogActive = true;
p->start();
//this method exists only for compatibility. Users should ideally call this directly
OrgKdeScreensaverInterface iface(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus());
iface.SwitchUser();
}
void KSMServer::runShutdownScripts()
......
set(KSMSERVER_SWITCHUSER_GREETER_SRCS main.cpp ../switchuserdialog.cpp ../ksmserver_debug.cpp)
add_executable(ksmserver-switchuser-greeter ${KSMSERVER_SWITCHUSER_GREETER_SRCS})
target_link_libraries(ksmserver-switchuser-greeter
PW::KWorkspace
Qt5::Quick
Qt5::X11Extras
KF5::Declarative
KF5::IconThemes
KF5::I18n
KF5::Package
KF5::QuickAddons
KF5::WaylandClient
KF5::WindowSystem
${X11_LIBRARIES}
)
install(TARGETS ksmserver-switchuser-greeter DESTINATION ${KDE_INSTALL_LIBEXECDIR})
/*****************************************************************
ksmserver - the KDE session management server
Copyright 2016 Martin Graesslin <mgraesslin@kde.org>
Copyright 2016 Kai Uwe Broulik <kde@privat.broulik.de>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************/
#include <QGuiApplication>
#include <QScreen>
#include "../switchuserdialog.h"
#include <KQuickAddons/QtQuickSettings>
#include <kdisplaymanager.h>
#include <KWindowSystem>
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/registry.h>
#include <KWayland/Client/plasmashell.h>
#include <unistd.h>
class Greeter : public QObject
{
Q_OBJECT
public:
Greeter();
~Greeter() override;
void init();
bool eventFilter(QObject *watched, QEvent *event) override;
private:
void adoptScreen(QScreen *screen);
void rejected();
void setupWaylandIntegration();
QVector<KSMSwitchUserDialog *> m_dialogs;
KWayland::Client::PlasmaShell *m_waylandPlasmaShell;
KDisplayManager m_displayManager;
};
Greeter::Greeter()
: QObject()
, m_waylandPlasmaShell(nullptr)
{
}
Greeter::~Greeter()
{
qDeleteAll(m_dialogs);
}
void Greeter::setupWaylandIntegration()
{
if (!KWindowSystem::isPlatformWayland()) {
return;
}
using namespace KWayland::Client;
ConnectionThread *connection = ConnectionThread::fromApplication(this);
if (!connection) {
return;
}
Registry *registry = new Registry(this);
registry->create(connection);
connect(registry, &Registry::plasmaShellAnnounced, this,
[this, registry] (quint32 name, quint32 version) {
m_waylandPlasmaShell = registry->createPlasmaShell(name, version, this);
}
);
registry->setup();
connection->roundtrip();
}
void Greeter::init()
{
setupWaylandIntegration();
foreach (QScreen *screen, qApp->screens()) {
adoptScreen(screen);
}
connect(qApp, &QGuiApplication::screenAdded, this, &Greeter::adoptScreen);
}
void Greeter::adoptScreen(QScreen* screen)
{
KSMSwitchUserDialog *w = new KSMSwitchUserDialog(&m_displayManager, m_waylandPlasmaShell);
w->installEventFilter(this);
m_dialogs << w;
QObject::connect(screen, &QObject::destroyed, w, [w, this] {
m_dialogs.removeOne(w);
w->deleteLater();
});
connect(w, &KSMSwitchUserDialog::dismissed, qApp, &QCoreApplication::quit);
w->setScreen(screen);
w->setGeometry(screen->geometry());
w->init();
}
bool Greeter::eventFilter(QObject *watched, QEvent *event)
{
if (qobject_cast<KSMSwitchUserDialog*>(watched)) {
if (event->type() == QEvent::MouseButtonPress) {
// check that the position is on no window
QMouseEvent *me = static_cast<QMouseEvent*>(event);
for (auto it = m_dialogs.constBegin(); it != m_dialogs.constEnd(); ++it) {
if ((*it)->geometry().contains(me->globalPos())) {
return false;
}
}
// click outside, close
qApp->quit();
}
}
return false;
}
int main(int argc, char *argv[])
{
// Qt does not currently (5.9.4) support fullscreen on xdg_shell v6.
qputenv("QT_WAYLAND_SHELL_INTEGRATION", "wl-shell");
KWorkSpace::detectPlatform(argc, argv);
QQuickWindow::setDefaultAlphaBuffer(true);
QGuiApplication app(argc, argv);
KQuickAddons::QtQuickSettings::init();
Greeter greeter;
greeter.init();
return app.exec();
}
#include "main.moc"
/***************************************************************************
* Copyright (C) 2015 Kai Uwe Broulik <kde@privat.broulik.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, 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 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 as Controls
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
import "../components"
PlasmaCore.ColorScope {
id: root
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
signal dismissed
signal ungrab
height:screenGeometry.height
width: screenGeometry.width
Rectangle {
anchors.fill: parent
color: PlasmaCore.ColorScope.backgroundColor
opacity: 0.5
}
SessionsModel {
id: sessionsModel
showNewSessionEntry: true
// the calls takes place asynchronously; if we were to dismiss the dialog right
// after startNewSession/switchUser we would be destroyed before the reply
// returned leaving us do nothing (Bug 356945)
onStartedNewSession: root.dismissed()
onSwitchedUser: root.dismissed()
onAboutToLockScreen: root.ungrab()
}
Controls.Action {
onTriggered: root.dismissed()
shortcut: "Escape"
}
Clock {
anchors.bottom: parent.verticalCenter
anchors.bottomMargin: units.gridUnit * 13
anchors.horizontalCenter: parent.horizontalCenter
}
MouseArea {
anchors.fill: parent
onClicked: root.dismissed()
}
SessionManagementScreen {
id: block
anchors.fill: parent
userListModel: sessionsModel
RowLayout {
PlasmaComponents.Button {
id: commitButton
text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Switch")
visible: sessionsModel.count > 0
onClicked: {
sessionsModel.switchUser(block.userListCurrentModelData.vtNumber, sessionsModel.shouldLock)
}
Controls.Action {
onTriggered: commitButton.clicked()
shortcut: "Return"
}
Controls.Action {
onTriggered: commitButton.clicked()
shortcut: "Enter" // on numpad
}
}
PlasmaComponents.Button {
text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Cancel")
onClicked: root.dismissed()
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment