Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 347626 Details for
Bug 468916
kde-base/libkworkspace: add systemd support (patch)
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
add systemd support to libkworkspace
kde-workspace-4.10.2-systemd-displaymanager.patch (text/plain), 21.49 KB, created by
Fabio Erculiani (RETIRED)
on 2013-05-07 18:48:12 UTC
(
hide
)
Description:
add systemd support to libkworkspace
Filename:
MIME Type:
Creator:
Fabio Erculiani (RETIRED)
Created:
2013-05-07 18:48:12 UTC
Size:
21.49 KB
patch
obsolete
>--- a/libs/kworkspace/kdisplaymanager.cpp 2013-03-01 07:32:25.116846223 +0100 >+++ b/libs/kworkspace/kdisplaymanager.cpp 2013-04-25 15:22:19.749417953 +0200 >@@ -40,6 +40,166 @@ > #include <errno.h> > #include <stdio.h> > >+#define _DBUS_PROPERTIES_IFACE "org.freedesktop.DBus.Properties" >+#define _DBUS_PROPERTIES_GET "Get" >+ >+#define DBUS_PROPERTIES_IFACE QLatin1String(_DBUS_PROPERTIES_IFACE) >+#define DBUS_PROPERTIES_GET QLatin1String(_DBUS_PROPERTIES_GET) >+ >+#define _SYSTEMD_SERVICE "org.freedesktop.login1" >+#define _SYSTEMD_BASE_PATH "/org/freedesktop/login1" >+#define _SYSTEMD_MANAGER_IFACE _SYSTEMD_SERVICE ".Manager" >+#define _SYSTEMD_SESSION_BASE_PATH _SYSTEMD_BASE_PATH "/Session" >+#define _SYSTEMD_SEAT_IFACE _SYSTEMD_SERVICE ".Seat" >+#define _SYSTEMD_SEAT_BASE_PATH _SYSTEMD_BASE_PATH "/Seat" >+#define _SYSTEMD_SESSION_IFACE _SYSTEMD_SERVICE ".Session" >+#define _SYSTEMD_USER_PROPERTY "User" >+#define _SYSTEMD_SEAT_PROPERTY "Seat" >+#define _SYSTEMD_SESSIONS_PROPERTY "Sessions" >+#define _SYSTEMD_SWITCH_PROPERTY "Activate" >+ >+#define SYSTEMD_SERVICE QLatin1String(_SYSTEMD_SERVICE) >+#define SYSTEMD_BASE_PATH QLatin1String(_SYSTEMD_BASE_PATH) >+#define SYSTEMD_MANAGER_IFACE QLatin1String(_SYSTEMD_MANAGER_IFACE) >+#define SYSTEMD_SESSION_BASE_PATH QLatin1String(_SYSTEMD_SESSION_BASE_PATH) >+#define SYSTEMD_SEAT_IFACE QLatin1String(_SYSTEMD_SEAT_IFACE) >+#define SYSTEMD_SEAT_BASE_PATH QLatin1String(_SYSTEMD_SEAT_BASE_PATH) >+#define SYSTEMD_SESSION_IFACE QLatin1String(_SYSTEMD_SESSION_IFACE) >+#define SYSTEMD_USER_PROPERTY QLatin1String(_SYSTEMD_USER_PROPERTY) >+#define SYSTEMD_SEAT_PROPERTY QLatin1String(_SYSTEMD_SEAT_PROPERTY) >+#define SYSTEMD_SESSIONS_PROPERTY QLatin1String(_SYSTEMD_SESSIONS_PROPERTY) >+#define SYSTEMD_SWITCH_CALL QLatin1String(_SYSTEMD_SWITCH_PROPERTY) >+ >+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( >+ SYSTEMD_SERVICE, >+ SYSTEMD_BASE_PATH, >+ SYSTEMD_MANAGER_IFACE, >+ QDBusConnection::systemBus()) {} >+}; >+ >+class SystemdSeat : public QDBusInterface >+{ >+public: >+ SystemdSeat(const QDBusObjectPath &path) : >+ QDBusInterface( >+ SYSTEMD_SERVICE, >+ path.path(), >+ SYSTEMD_SEAT_IFACE, >+ QDBusConnection::systemBus()) {} >+ /* HACK to be able to extract a(so) type from QDBus, property doesn't do the trick */ >+ QList<NamedDBusObjectPath> getSessions() { >+ QDBusMessage message = QDBusMessage::createMethodCall(service(), path(), DBUS_PROPERTIES_IFACE, DBUS_PROPERTIES_GET); >+ message << interface() << SYSTEMD_SESSIONS_PROPERTY; >+ QDBusMessage reply = QDBusConnection::systemBus().call(message); >+ >+ QVariantList args = reply.arguments(); >+ if (!args.isEmpty()) { >+ QList<NamedDBusObjectPath> namedPathList = qdbus_cast< QList<NamedDBusObjectPath> >(args.at(0).value<QDBusVariant>().variant().value<QDBusArgument>()); >+ return namedPathList; >+ } >+ return QList<NamedDBusObjectPath>(); >+ } >+}; >+ >+class SystemdSession : public QDBusInterface >+{ >+public: >+ SystemdSession(const QDBusObjectPath &path) : >+ QDBusInterface( >+ SYSTEMD_SERVICE, >+ path.path(), >+ SYSTEMD_SESSION_IFACE, >+ QDBusConnection::systemBus()) {} >+ /* HACK to be able to extract (so) type from QDBus, property doesn't do the trick */ >+ NamedDBusObjectPath getSeat() { >+ QDBusMessage message = QDBusMessage::createMethodCall(service(), path(), DBUS_PROPERTIES_IFACE, DBUS_PROPERTIES_GET); >+ message << interface() << SYSTEMD_SEAT_PROPERTY; >+ QDBusMessage reply = QDBusConnection::systemBus().call(message); >+ >+ QVariantList args = reply.arguments(); >+ if (!args.isEmpty()) { >+ NamedDBusObjectPath namedPath; >+ args.at(0).value<QDBusVariant>().variant().value<QDBusArgument>() >> namedPath; >+ return namedPath; >+ } >+ return NamedDBusObjectPath(); >+ } >+ NumberedDBusObjectPath getUser() { >+ QDBusMessage message = QDBusMessage::createMethodCall(service(), path(), DBUS_PROPERTIES_IFACE, DBUS_PROPERTIES_GET); >+ message << interface() << SYSTEMD_USER_PROPERTY; >+ QDBusMessage reply = QDBusConnection::systemBus().call(message); >+ >+ QVariantList args = reply.arguments(); >+ if (!args.isEmpty()) { >+ NumberedDBusObjectPath numberedPath; >+ args.at(0).value<QDBusVariant>().variant().value<QDBusArgument>() >> numberedPath; >+ return numberedPath; >+ } >+ return NumberedDBusObjectPath(); >+ } >+ void getSessionLocation(SessEnt &se) >+ { >+ se.tty = (property("Type").toString() != QLatin1String("x11")); >+ se.display = property(se.tty ? "TTY" : "Display").toString(); >+ se.vt = property("VTNr").toInt(); >+ } >+}; >+ > class CKManager : public QDBusInterface > { > public: >@@ -68,9 +228,26 @@ > CKSession(const QDBusObjectPath &path) : > QDBusInterface( > QLatin1String("org.freedesktop.ConsoleKit"), >- path.path(), >+ path.path(), > QLatin1String("org.freedesktop.ConsoleKit.Session"), > QDBusConnection::systemBus()) {} >+ void getSessionLocation(SessEnt &se) >+ { >+ QString tty; >+ QDBusReply<QString> r = call(QLatin1String("GetX11Display")); >+ if (r.isValid() && !r.value().isEmpty()) { >+ QDBusReply<QString> r2 = call(QLatin1String("GetX11DisplayDevice")); >+ tty = r2.value(); >+ se.display = r.value(); >+ se.tty = false; >+ } else { >+ QDBusReply<QString> r2 = call(QLatin1String("GetDisplayDevice")); >+ tty = r2.value(); >+ se.display = tty; >+ se.tty = true; >+ } >+ se.vt = tty.mid(strlen("/dev/tty")).toInt(); >+ } > }; > > class GDMFactory : public QDBusInterface >@@ -115,6 +292,10 @@ > const char *ptr; > struct sockaddr_un sa; > >+ qDBusRegisterMetaType<NamedDBusObjectPath>(); >+ qDBusRegisterMetaType<QList<NamedDBusObjectPath> >(); >+ qDBusRegisterMetaType<NumberedDBusObjectPath>(); >+ > if (DMType == Dunno) { > if (!(dpy = ::getenv("DISPLAY"))) > DMType = NoDM; >@@ -242,17 +423,31 @@ > > static bool getCurrentSeat(QDBusObjectPath *currentSession, QDBusObjectPath *currentSeat) > { >- CKManager man; >- QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetCurrentSession")); >+ SystemdManager man; >+ QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetSessionByPID"), (uint) QCoreApplication::applicationPid()); > if (r.isValid()) { >- CKSession sess(r.value()); >+ SystemdSession sess(r.value()); > if (sess.isValid()) { >- QDBusReply<QDBusObjectPath> r2 = sess.call(QLatin1String("GetSeatId")); >- if (r2.isValid()) { >- if (currentSession) >- *currentSession = r.value(); >- *currentSeat = r2.value(); >- return true; >+ NamedDBusObjectPath namedPath = sess.getSeat(); >+ if (currentSession) >+ *currentSession = r.value(); >+ *currentSeat = namedPath.path; >+ return true; >+ } >+ } >+ else { >+ CKManager man; >+ QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetCurrentSession")); >+ if (r.isValid()) { >+ CKSession sess(r.value()); >+ if (sess.isValid()) { >+ QDBusReply<QDBusObjectPath> r2 = sess.call(QLatin1String("GetSeatId")); >+ if (r2.isValid()) { >+ if (currentSession) >+ *currentSession = r.value(); >+ *currentSeat = r2.value(); >+ return true; >+ } > } > } > } >@@ -261,44 +456,44 @@ > > static QList<QDBusObjectPath> getSessionsForSeat(const QDBusObjectPath &path) > { >- CKSeat seat(path); >- if (seat.isValid()) { >- QDBusReply<QList<QDBusObjectPath> > r = seat.call(QLatin1String("GetSessions")); >- if (r.isValid()) { >- // 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 r.value(); >+ if (path.path().startsWith(SYSTEMD_BASE_PATH)) { // systemd path incoming >+ SystemdSeat seat(path); >+ if (seat.isValid()) { >+ QList<NamedDBusObjectPath> r = seat.getSessions(); >+ QList<QDBusObjectPath> result; >+ foreach (const NamedDBusObjectPath &namedPath, r) >+ result.append(namedPath.path); >+ // This pretty much can't contain any other than local sessions as the seat is retrieved from the current session >+ return result; >+ } >+ } >+ else if (path.path().startsWith("/org/freedesktop/ConsoleKit")) { >+ CKSeat seat(path); >+ if (seat.isValid()) { >+ QDBusReply<QList<QDBusObjectPath> > r = seat.call(QLatin1String("GetSessions")); >+ if (r.isValid()) { >+ // 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 r.value(); >+ } > } > } > return QList<QDBusObjectPath>(); > } > >-static void getSessionLocation(CKSession &lsess, SessEnt &se) >-{ >- QString tty; >- QDBusReply<QString> r = lsess.call(QLatin1String("GetX11Display")); >- if (r.isValid() && !r.value().isEmpty()) { >- QDBusReply<QString> r2 = lsess.call(QLatin1String("GetX11DisplayDevice")); >- tty = r2.value(); >- se.display = r.value(); >- se.tty = false; >- } else { >- QDBusReply<QString> r2 = lsess.call(QLatin1String("GetDisplayDevice")); >- tty = r2.value(); >- se.display = tty; >- se.tty = true; >- } >- se.vt = tty.mid(strlen("/dev/tty")).toInt(); >-} >- > #ifndef KDM_NO_SHUTDOWN > bool > KDisplayManager::canShutdown() > { > if (DMType == NewGDM || DMType == NoDM || DMType == LightDM) { >+ QDBusReply<QString> canPowerOff = SystemdManager().call(QLatin1String("CanPowerOff")); >+ if (canPowerOff.isValid()) >+ return canPowerOff.value() != QLatin1String("no"); > QDBusReply<bool> canStop = CKManager().call(QLatin1String("CanStop")); >- return (canStop.isValid() && canStop.value()); >+ if (canStop.isValid()) >+ return canStop.value(); >+ return false; > } > > if (DMType == OldKDM) >@@ -329,9 +524,21 @@ > return; > > if (DMType == NewGDM || DMType == NoDM || DMType == LightDM) { >- // FIXME: entirely ignoring shutdownMode >- CKManager().call(QLatin1String( >- shutdownType == KWorkSpace::ShutdownTypeReboot ? "Restart" : "Stop")); >+ // systemd supports only 2 modes: >+ // * interactive = true: brings up a PolicyKit prompt if other sessions are active >+ // * interactive = false: rejects the shutdown if other sessions are active >+ // There are no schedule or force modes. >+ // We try to map our 4 shutdown modes in the sanest way. >+ bool interactive = (shutdownMode == KWorkSpace::ShutdownModeInteractive >+ || shutdownMode == KWorkSpace::ShutdownModeForceNow); >+ QDBusReply<QString> check = SystemdManager().call(QLatin1String( >+ shutdownType == KWorkSpace::ShutdownTypeReboot ? "Reboot" : "PowerOff"), interactive); >+ if (!check.isValid()) { >+ // FIXME: entirely ignoring shutdownMode >+ CKManager().call(QLatin1String( >+ shutdownType == KWorkSpace::ShutdownTypeReboot ? "Restart" : "Stop")); >+ // if even CKManager call fails, there is nothing more to be done >+ } > return; > } > >@@ -406,9 +613,15 @@ > if (DMType == NewGDM || DMType == LightDM) { > QDBusObjectPath currentSeat; > if (getCurrentSeat(0, ¤tSeat)) { >- CKSeat seat(currentSeat); >- if (seat.isValid()) { >- QDBusReply<bool> r = seat.call(QLatin1String("CanActivateSessions")); >+ SystemdSeat SDseat(currentSeat); >+ if (SDseat.isValid()) { >+ QVariant prop = SDseat.property("CanMultiSession"); >+ if (prop.isValid()) >+ return prop.toBool(); >+ } >+ CKSeat CKseat(currentSeat); >+ if (CKseat.isValid()) { >+ QDBusReply<bool> r = CKseat.call(QLatin1String("CanActivateSessions")); > if (r.isValid()) > return r.value(); > } >@@ -465,26 +678,61 @@ > if (DMType == OldKDM) > return false; > >- if (DMType == NewGDM || DMType == LightDM) { >+ // FIXME TODO WARNING HACK beware of this workaround, will get rid of it in a few days (if it's not spring 2013 and this line is still here, please smack mbriza-at-redhat-dot-com) >+ if (DMType != OldGDM) { > QDBusObjectPath currentSession, currentSeat; > if (getCurrentSeat(¤tSession, ¤tSeat)) { >- foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) { >- CKSession lsess(sp); >- if (lsess.isValid()) { >- SessEnt se; >- getSessionLocation(lsess, se); >- // "Warning: we haven't yet defined the allowed values for this property. >- // It is probably best to avoid this until we do." >- QDBusReply<QString> r = lsess.call(QLatin1String("GetSessionType")); >- if (r.value() != QLatin1String("LoginWindow")) { >- QDBusReply<unsigned> r2 = lsess.call(QLatin1String("GetUnixUser")); >- se.user = KUser(K_UID(r2.value())).loginName(); >- se.session = "<unknown>"; >+ // we'll divide the code in two branches to reduce the overhead of calls to non-existent services >+ // systemd part // preferred >+ if (QDBusConnection::systemBus().interface()->isServiceRegistered(SYSTEMD_SERVICE)) { >+ foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) { >+ SystemdSession lsess(sp); >+ if (lsess.isValid()) { >+ SessEnt se; >+ lsess.getSessionLocation(se); >+ if ((lsess.property("Class").toString() != QLatin1String("greeter")) && >+ (lsess.property("State").toString() == QLatin1String("online") || >+ lsess.property("State").toString() == QLatin1String("active"))) { >+ NumberedDBusObjectPath numberedPath = lsess.getUser(); >+ se.display = lsess.property("Display").toString(); >+ se.vt = lsess.property("VTNr").toInt(); >+ se.user = KUser(K_UID(numberedPath.num)).loginName(); >+ /* TODO: >+ * regarding the session name in this, it IS possible to find it out - logind tracks the session leader PID >+ * the problem is finding out the name of the process, I could come only with reading /proc/PID/comm which >+ * doesn't seem exactly... right to me --mbriza >+ */ >+ se.session = "<unknown>"; >+ se.self = lsess.property("Display").toString() == ::getenv("DISPLAY"); /* Bleh once again */ >+ se.tty = !lsess.property("TTY").toString().isEmpty(); >+ } >+ list.append(se); >+ } >+ } >+ } >+ // ConsoleKit part >+ else if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.freedesktop.ConsoleKit")) { >+ foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) { >+ CKSession lsess(sp); >+ if (lsess.isValid()) { >+ SessEnt se; >+ lsess.getSessionLocation(se); >+ // "Warning: we haven't yet defined the allowed values for this property. >+ // It is probably best to avoid this until we do." >+ QDBusReply<QString> r = lsess.call(QLatin1String("GetSessionType")); >+ if (r.value() != QLatin1String("LoginWindow")) { >+ QDBusReply<unsigned> r2 = lsess.call(QLatin1String("GetUnixUser")); >+ se.user = KUser(K_UID(r2.value())).loginName(); >+ se.session = "<unknown>"; >+ } >+ se.self = (sp == currentSession); >+ list.append(se); > } >- se.self = (sp == currentSession); >- list.append(se); > } > } >+ else { >+ return false; >+ } > return true; > } > return false; >@@ -507,21 +755,6 @@ > se.tty = false; > list.append(se); > } >- } else { >- if (!exec("list\talllocal\n", re)) >- return false; >- const QStringList sess = QString(re.data() + 3).split(QChar('\t'), QString::SkipEmptyParts); >- for (QStringList::ConstIterator it = sess.constBegin(); it != sess.constEnd(); ++it) { >- QStringList ts = (*it).split(QChar(',')); >- SessEnt se; >- se.display = ts[0]; >- se.vt = ts[1].mid(2).toInt(); >- se.user = ts[2]; >- se.session = ts[3]; >- se.self = (ts[4].indexOf('*') >= 0); >- se.tty = (ts[4].indexOf('t') >= 0); >- list.append(se); >- } > } > return true; > } >@@ -566,16 +799,33 @@ > if (DMType == NewGDM || DMType == LightDM) { > QDBusObjectPath currentSeat; > if (getCurrentSeat(0, ¤tSeat)) { >- foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) { >- CKSession lsess(sp); >- if (lsess.isValid()) { >- SessEnt se; >- getSessionLocation(lsess, se); >- if (se.vt == vt) { >- if (se.tty) // ConsoleKit simply ignores these >- return false; >- lsess.call(QLatin1String("Activate")); >- return true; >+ // systemd part // preferred >+ if (QDBusConnection::systemBus().interface()->isServiceRegistered(SYSTEMD_SERVICE)) { >+ foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) { >+ SystemdSession lsess(sp); >+ if (lsess.isValid()) { >+ SessEnt se; >+ lsess.getSessionLocation(se); >+ if (se.vt == vt) { >+ lsess.call(SYSTEMD_SWITCH_CALL); >+ return true; >+ } >+ } >+ } >+ } >+ // ConsoleKit part >+ else if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.freedesktop.ConsoleKit")) { >+ foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) { >+ CKSession lsess(sp); >+ if (lsess.isValid()) { >+ SessEnt se; >+ lsess.getSessionLocation(se); >+ if (se.vt == vt) { >+ if (se.tty) // ConsoleKit simply ignores these >+ return false; >+ lsess.call(QLatin1String("Activate")); >+ return true; >+ } > } > } > } >@@ -643,3 +893,4 @@ > } > > #endif // Q_WS_X11 >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 468916
: 347626