diff --git a/daemon/main.cpp b/daemon/main.cpp index 0e7f934..39ecf21 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -1,15 +1,22 @@ #include #include #include +#include + #include +#include +#include #include "session_manager.h" #include "sessionmanageradaptor.h" // generated by qt6_add_dbus_adaptor -static void signalHandler(int sig) +// Async-signal-safe shutdown via socketpair +static int sigFd[2]; + +static void signalHandler(int) { - qDebug() << "Received signal" << sig << "- shutting down"; - QCoreApplication::quit(); + char c = 1; + write(sigFd[0], &c, 1); } int main(int argc, char *argv[]) @@ -18,7 +25,20 @@ int main(int argc, char *argv[]) app.setApplicationName("ollie-kde"); app.setOrganizationName("ollie"); - // Handle SIGTERM/SIGINT gracefully + // Set up signal handling via socketpair (async-signal-safe) + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sigFd) != 0) { + qCritical() << "Cannot create signal socketpair"; + return 1; + } + + auto *sigNotifier = new QSocketNotifier(sigFd[1], QSocketNotifier::Read, &app); + QObject::connect(sigNotifier, &QSocketNotifier::activated, &app, [&]() { + char c; + read(sigFd[1], &c, 1); + qDebug() << "Received shutdown signal, exiting gracefully..."; + app.quit(); + }); + signal(SIGTERM, signalHandler); signal(SIGINT, signalHandler); @@ -49,5 +69,8 @@ int main(int argc, char *argv[]) qDebug() << "ollie-kde daemon started on D-Bus: org.ollie.SessionManager"; - return app.exec(); + int rc = app.exec(); + + qDebug() << "ollie-kde daemon exiting"; + return rc; } diff --git a/kate/ollie_kate.cpp b/kate/ollie_kate.cpp index a7666d4..8aeddfa 100644 --- a/kate/ollie_kate.cpp +++ b/kate/ollie_kate.cpp @@ -265,6 +265,8 @@ void OllieKateView::newSession() m_chatOffset = 0; m_sessionLabel->setText("○ " + m_sessionId.left(14) + " [idle]"); m_cwdLabel->setText(cwd); + } else { + m_chatView->setPlainText("Error creating session: " + reply.error().message()); } } @@ -273,6 +275,10 @@ void OllieKateView::newSession() void OllieKateView::ensureSession() { if (!m_sessionId.isEmpty()) return; + if (!m_iface->isValid()) { + m_chatView->setPlainText("Error: ollie-kde daemon not running.\nStart with: ollie-kde or rc-service --user ollie-kde start"); + return; + } newSession(); } diff --git a/krunner/ollie_runner.cpp b/krunner/ollie_runner.cpp index 33411b2..4a9789b 100644 --- a/krunner/ollie_runner.cpp +++ b/krunner/ollie_runner.cpp @@ -38,6 +38,11 @@ void OllieRunner::match(KRunner::RunnerContext &context) return; } + // Bail if daemon isn't running + if (!m_iface->isValid()) { + return; + } + QString args = query.mid(6).trimmed(); // everything after "ollie " if (args.isEmpty() || args == QLatin1String("list")) { diff --git a/tray/main.cpp b/tray/main.cpp index ba85286..f420771 100644 --- a/tray/main.cpp +++ b/tray/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "ollie_tray.h" @@ -12,20 +13,36 @@ int main(int argc, char *argv[]) app.setOrganizationName("ollie"); app.setQuitOnLastWindowClosed(false); - // Verify the daemon is reachable QDBusConnection bus = QDBusConnection::sessionBus(); if (!bus.isConnected()) { qCritical() << "Cannot connect to D-Bus session bus"; return 1; } - if (!bus.interface()->isServiceRegistered("org.ollie.SessionManager")) { - qCritical() << "ollie-kde daemon not running (org.ollie.SessionManager not registered)"; - return 1; - } - OllieTray tray; - qDebug() << "ollie-tray started"; + + // Watch for daemon appearing/disappearing + auto *watcher = new QDBusServiceWatcher( + "org.ollie.SessionManager", + bus, + QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, + &app); + + QObject::connect(watcher, &QDBusServiceWatcher::serviceRegistered, [&]() { + qDebug() << "Daemon appeared on D-Bus"; + tray.updateStatus(); + }); + + QObject::connect(watcher, &QDBusServiceWatcher::serviceUnregistered, [&]() { + qDebug() << "Daemon disappeared from D-Bus"; + tray.updateStatus(); + }); + + if (bus.interface()->isServiceRegistered("org.ollie.SessionManager")) { + qDebug() << "ollie-tray started (daemon running)"; + } else { + qDebug() << "ollie-tray started (waiting for daemon)"; + } return app.exec(); } diff --git a/tray/ollie_tray.h b/tray/ollie_tray.h index d84d91d..2a21f7e 100644 --- a/tray/ollie_tray.h +++ b/tray/ollie_tray.h @@ -15,6 +15,8 @@ public: explicit OllieTray(QObject *parent = nullptr); ~OllieTray() override; + void updateStatus(); + private slots: void onSessionCreated(const QString &session_id); void onSessionKilled(const QString &session_id); @@ -27,7 +29,6 @@ private slots: private: void setupMenu(); - void updateStatus(); void updateTooltip(); QStringList callListSessions(); bool callKillSession(const QString &id);