[kde-workspace] Port shutdown/restart code to systemd (#788171)

Rex Dieter rdieter at fedoraproject.org
Mon Mar 12 16:18:47 UTC 2012


commit 8073e0810976054541fd8318447431f8c86b72f8
Author: Rex Dieter <rdieter at fedoraproject.org>
Date:   Mon Mar 12 11:17:27 2012 -0500

    Port shutdown/restart code to systemd (#788171)
    
    not enabled yet, work in progress

 kde-workspace-4.8.0-systemd-shutdown.patch |  319 ++++++++++++++++++++++++++++
 kde-workspace.spec                         |   14 ++-
 2 files changed, 332 insertions(+), 1 deletions(-)
---
diff --git a/kde-workspace-4.8.0-systemd-shutdown.patch b/kde-workspace-4.8.0-systemd-shutdown.patch
new file mode 100644
index 0000000..007ee7c
--- /dev/null
+++ b/kde-workspace-4.8.0-systemd-shutdown.patch
@@ -0,0 +1,319 @@
+diff -ur kde-workspace-4.8.0/libs/kworkspace/CMakeLists.txt kde-workspace-4.8.0-systemd-shutdown/libs/kworkspace/CMakeLists.txt
+--- kde-workspace-4.8.0/libs/kworkspace/CMakeLists.txt	2012-01-18 21:08:42.000000000 +0100
++++ kde-workspace-4.8.0-systemd-shutdown/libs/kworkspace/CMakeLists.txt	2012-03-01 07:19:09.000000000 +0100
+@@ -36,6 +36,11 @@
+ endif(SOPRANO_PLUGIN_RAPTORPARSER_FOUND AND SHAREDDESKTOPONTOLOGIES_ROOT_DIR)
+ 
+ 
++option(KWORKSPACE_USE_SYSTEMD "Use systemd instead of ConsoleKit in libkworkspace" OFF)
++if (KWORKSPACE_USE_SYSTEMD)
++    add_definitions(-DKWORKSPACE_USE_SYSTEMD=1)
++endif (KWORKSPACE_USE_SYSTEMD)
++
+ 
+ set(ksmserver_xml  ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml)
+ qt4_add_dbus_interface( kworkspace_LIB_SRCS ${ksmserver_xml} ksmserver_interface )
+diff -ur kde-workspace-4.8.0/libs/kworkspace/kdisplaymanager.cpp kde-workspace-4.8.0-systemd-shutdown/libs/kworkspace/kdisplaymanager.cpp
+--- kde-workspace-4.8.0/libs/kworkspace/kdisplaymanager.cpp	2012-01-18 21:08:42.000000000 +0100
++++ kde-workspace-4.8.0-systemd-shutdown/libs/kworkspace/kdisplaymanager.cpp	2012-03-01 07:14:23.000000000 +0100
+@@ -40,6 +40,91 @@
+ #include <errno.h>
+ #include <stdio.h>
+ 
++#ifdef KWORKSPACE_USE_SYSTEMD
++struct NamedDBusObjectPath
++{
++    QString name;
++    QDBusObjectPath path;
++};
++Q_DECLARE_METATYPE(NamedDBusObjectPath)
++Q_DECLARE_METATYPE(QList<NamedDBusObjectPath>)
++
++// Marshall the NamedDBusObjectPath data into a D-Bus argument
++QDBusArgument &operator<<(QDBusArgument &argument, const NamedDBusObjectPath &namedPath)
++{
++    argument.beginStructure();
++    argument << namedPath.name << namedPath.path;
++    argument.endStructure();
++    return argument;
++}
++
++// Retrieve the NamedDBusObjectPath data from the D-Bus argument
++const QDBusArgument &operator>>(const QDBusArgument &argument, NamedDBusObjectPath &namedPath)
++{
++    argument.beginStructure();
++    argument >> namedPath.name >> namedPath.path;
++    argument.endStructure();
++    return argument;
++}
++
++struct NumberedDBusObjectPath
++{
++    uint num;
++    QDBusObjectPath path;
++};
++Q_DECLARE_METATYPE(NumberedDBusObjectPath)
++
++// Marshall the NumberedDBusObjectPath data into a D-Bus argument
++QDBusArgument &operator<<(QDBusArgument &argument, const NumberedDBusObjectPath &numberedPath)
++{
++    argument.beginStructure();
++    argument << numberedPath.num << numberedPath.path;
++    argument.endStructure();
++    return argument;
++}
++
++// Retrieve the NumberedDBusObjectPath data from the D-Bus argument
++const QDBusArgument &operator>>(const QDBusArgument &argument, NumberedDBusObjectPath &numberedPath)
++{
++    argument.beginStructure();
++    argument >> numberedPath.num >> numberedPath.path;
++    argument.endStructure();
++    return argument;
++}
++
++class SystemdManager : public QDBusInterface
++{
++public:
++    SystemdManager() :
++        QDBusInterface(
++                QLatin1String("org.freedesktop.login1"),
++                QLatin1String("/org/freedesktop/login1/Manager"),
++                QLatin1String("org.freedesktop.login1.Manager"),
++                QDBusConnection::systemBus()) {}
++};
++
++class SystemdSeat : public QDBusInterface
++{
++public:
++    SystemdSeat(const QDBusObjectPath &path) :
++        QDBusInterface(
++                QLatin1String("org.freedesktop.login1"),
++                path.path(),
++                QLatin1String("org.freedesktop.login1.Seat"),
++                QDBusConnection::systemBus()) {}
++};
++
++class SystemdSession : public QDBusInterface
++{
++public:
++    SystemdSession(const QDBusObjectPath &path) :
++        QDBusInterface(
++                QLatin1String("org.freedesktop.login1"),
++                path.path(),
++                QLatin1String("org.freedesktop.login1.Session"),
++                QDBusConnection::systemBus()) {}
++};
++#else
+ class CKManager : public QDBusInterface
+ {
+ public:
+@@ -68,10 +153,11 @@
+     CKSession(const QDBusObjectPath &path) :
+         QDBusInterface(
+                 QLatin1String("org.freedesktop.ConsoleKit"),
+-            path.path(),
++                path.path(),
+                 QLatin1String("org.freedesktop.ConsoleKit.Session"),
+                 QDBusConnection::systemBus()) {}
+ };
++#endif
+ 
+ class GDMFactory : public QDBusInterface
+ {
+@@ -131,6 +217,11 @@
+     }
+     switch (DMType) {
+     default:
++#ifdef KWORKSPACE_USE_SYSTEMD
++        qDBusRegisterMetaType<NamedDBusObjectPath>();
++        qDBusRegisterMetaType<QList<NamedDBusObjectPath> >();
++        qDBusRegisterMetaType<NumberedDBusObjectPath>();
++#endif
+         return;
+     case NewKDM:
+     case OldGDM:
+@@ -242,6 +333,23 @@
+ 
+ static bool getCurrentSeat(QDBusObjectPath *currentSession, QDBusObjectPath *currentSeat)
+ {
++#ifdef KWORKSPACE_USE_SYSTEMD
++    SystemdManager man;
++    QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetSessionByPID"), (uint) QCoreApplication::applicationPid());
++    if (r.isValid()) {
++        SystemdSession sess(r.value());
++        if (sess.isValid()) {
++            QVariant p = sess.property(QLatin1String("Seat"));
++            if (p.canConvert<NamedDBusObjectPath>()) {
++                NamedDBusObjectPath namedPath = p.value<NamedDBusObjectPath>();
++                if (currentSession)
++                    *currentSession = r.value();
++                *currentSeat = namedPath.path;
++                return true;
++            }
++        }
++    }
++#else
+     CKManager man;
+     QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetCurrentSession"));
+     if (r.isValid()) {
+@@ -256,11 +364,28 @@
+             }
+         }
+     }
++#endif
+     return false;
+ }
+ 
+ static QList<QDBusObjectPath> getSessionsForSeat(const QDBusObjectPath &path)
+ {
++#ifdef KWORKSPACE_USE_SYSTEMD
++    SystemdSeat seat(path);
++    if (seat.isValid()) {
++        QVariant p = seat.property(QLatin1String("Sessions"));
++        if (p.canConvert<QList<NamedDBusObjectPath> >()) {
++            QList<NamedDBusObjectPath> r = p.value<QList<NamedDBusObjectPath> >();
++            QList<QDBusObjectPath> result;
++            foreach (const NamedDBusObjectPath &namedPath, r)
++                result.append(r.path);
++            // This will contain only local sessions:
++            // - this is only ever called when isSwitchable() is true => local seat
++            // - remote logins into the machine are assigned to other seats
++            return result;
++        }
++    }
++#else
+     CKSeat seat(path);
+     if (seat.isValid()) {
+         QDBusReply<QList<QDBusObjectPath> > r = seat.call(QLatin1String("GetSessions"));
+@@ -271,9 +396,18 @@
+             return r.value();
+         }
+     }
++#endif
+     return QList<QDBusObjectPath>();
+ }
+ 
++#ifdef KWORKSPACE_USE_SYSTEMD
++static void getSessionLocation(SystemdSession &lsess, SessEnt &se)
++{
++    se.tty = (lsess.property(QLatin1String("Type")).toString() != QLatin1String("x11"));
++    se.display = lsess.property(QLatin1String(se.tty ? "TTY" : "Display")).toString();
++    se.vt = lsess.property(QLatin1String("VTNr")).toInt();
++}
++#else
+ static void getSessionLocation(CKSession &lsess, SessEnt &se)
+ {
+     QString tty;
+@@ -291,13 +425,18 @@
+     }
+     se.vt = tty.mid(strlen("/dev/tty")).toInt();
+ }
++#endif
+ 
+ #ifndef KDM_NO_SHUTDOWN
+ bool
+ KDisplayManager::canShutdown()
+ {
+     if (DMType == NewGDM || DMType == NoDM || DMType == LightDM) {
++#ifdef KWORKSPACE_USE_SYSTEMD
++        QDBusReply<bool> canStop = SystemdManager().call(QLatin1String("CanPowerOff"));
++#else
+         QDBusReply<bool> canStop = CKManager().call(QLatin1String("CanStop"));
++#endif
+         return (canStop.isValid() && canStop.value());
+     }
+ 
+@@ -330,8 +469,13 @@
+ 
+         if (DMType == NewGDM || DMType == NoDM || DMType == LightDM) {
+             // FIXME: entirely ignoring shutdownMode
++#ifdef KWORKSPACE_USE_SYSTEMD
++            SystemdManager().call(QLatin1String(
++                    shutdownType == KWorkSpace::ShutdownTypeReboot ? "Reboot" : "PowerOff"));
++#else
+             CKManager().call(QLatin1String(
+                     shutdownType == KWorkSpace::ShutdownTypeReboot ? "Restart" : "Stop"));
++#endif
+             return;
+         }
+ 
+@@ -406,12 +550,18 @@
+     if (DMType == NewGDM || DMType == LightDM) {
+         QDBusObjectPath currentSeat;
+         if (getCurrentSeat(0, &currentSeat)) {
++#ifdef KWORKSPACE_USE_SYSTEMD
++            SystemdSeat seat(currentSeat);
++            if (seat.isValid())
++                return seat.property(QLatin1String("CanMultiSession")).toBool();
++#else
+             CKSeat seat(currentSeat);
+             if (seat.isValid()) {
+                 QDBusReply<bool> r = seat.call(QLatin1String("CanActivateSessions"));
+                 if (r.isValid())
+                     return r.value();
+             }
++#endif
+         }
+         return false;
+     }
+@@ -469,6 +619,21 @@
+         QDBusObjectPath currentSession, currentSeat;
+         if (getCurrentSeat(&currentSession, &currentSeat)) {
+             foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
++#ifdef KWORKSPACE_USE_SYSTEMD
++                SystemdSession lsess(sp);
++                if (lsess.isValid()) {
++                    SessEnt se;
++                    getSessionLocation(lsess, se);
++                    if (lsess.property(QLatin1String("Class")).toString() != QLatin1String("greeter")) {
++                        QVariant p = lsess.property(QLatin1String("User"));
++                        NumberedDBusObjectPath numberedPath = p.value<NumberedDBusObjectPath>();
++                        se.user = KUser(K_UID(numberedPath.num)).loginName();
++                        se.session = "<unknown>";
++                    }
++                    se.self = (sp == currentSession);
++                    list.append(se);
++                }
++#else
+                 CKSession lsess(sp);
+                 if (lsess.isValid()) {
+                     SessEnt se;
+@@ -484,6 +649,7 @@
+                     se.self = (sp == currentSession);
+                     list.append(se);
+                 }
++#endif
+             }
+             return true;
+         }
+@@ -567,6 +733,21 @@
+         QDBusObjectPath currentSeat;
+         if (getCurrentSeat(0, &currentSeat)) {
+             foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
++#ifdef KWORKSPACE_USE_SYSTEMD
++                SystemdSession lsess(sp);
++                if (lsess.isValid()) {
++                    SessEnt se;
++                    getSessionLocation(lsess, se);
++                    if (se.vt == vt) {
++#if 0
++                        if (se.tty) // FIXME: Does systemd ignore these like ConsoleKit does?
++                            return false;
++#endif
++                        lsess.call(QLatin1String("Activate"));
++                        return true;
++                    }
++                }
++#else
+                 CKSession lsess(sp);
+                 if (lsess.isValid()) {
+                     SessEnt se;
+@@ -578,6 +759,7 @@
+                         return true;
+                     }
+                 }
++#endif
+             }
+         }
+         return false;
diff --git a/kde-workspace.spec b/kde-workspace.spec
index b1b208f..9febaf9 100644
--- a/kde-workspace.spec
+++ b/kde-workspace.spec
@@ -7,10 +7,14 @@
 %define consolekit 1
 %endif
 
+#if 0%{?fedora} > 16
+#define systemd 1
+#endif
+
 Summary: KDE Workspace
 Name:    kde-workspace
 Version: 4.8.1
-Release: 2%{?dist}
+Release: 3%{?dist}
 
 License: GPLv2
 URL:     https://projects.kde.org/projects/kde/kde-workspace
@@ -101,6 +105,9 @@ Patch56: kde-workspace-4.8.0-kwin_llvmpipe_whitelist.patch
 # http://bugzilla.redhat.com/796969
 Patch57: kde-workspace-4.8.0-bug796969.patch
 
+# initial systemd support
+Patch58: kde-workspace-4.8.0-systemd-shutdown.patch
+
 ## upstream patches
 # https://projects.kde.org/projects/kde/kde-workspace/repository/revisions/a91f888dac689bd64d1ac9290769bd881af9e319
 Patch100:  kde-workspace-4.8.1-settings_style.patch
@@ -425,6 +432,7 @@ Requires: akonadi
 ## omit for now, llvmpipe is not ready (http://bugzilla.redhat.com/794835)
 #patch56 -p1 -b .kwin_llvmpipe_whitelist
 %patch57 -p1 -b .bug796969
+%patch58 -p1 -b .systemd-shutdown
 
 # upstream patches
 %patch100 -p1 -b .settings_style
@@ -447,6 +455,7 @@ pushd %{_target_platform}
   -DKDE4_KDM_PAM_SERVICE=kdm \
   -DKDE4_KCHECKPASS_PAM_SERVICE=kcheckpass \
   -DKDE4_KSCREENSAVER_PAM_SERVICE=kscreensaver \
+  %{?systemd:-DKWORKSPACE_USE_SYSTEMD:BOOL=ON} \
   ..
 popd
 
@@ -967,6 +976,9 @@ fi
 
 
 %changelog
+* Mon Mar 12 2012 Rex Dieter <rdieter at fedoraproject.org> 4.8.1-3
+- Port shutdown/restart code from ConsoleKit to systemd (#788171)
+
 * Thu Mar 08 2012 Rex Dieter <rdieter at fedoraproject.org> 4.8.1-2
 - 4.8 branch commit for settings_style support
 


More information about the scm-commits mailing list