phase 7a: desktop notifications on turn completion

- Daemon tracks per-session state transitions
- Fires freedesktop notification when any session goes non-idle→idle
- 5 second auto-dismiss timeout
This commit is contained in:
Levi Neely 2026-07-05 23:36:16 +02:00
parent aec392baf9
commit 2767387f8e
2 changed files with 45 additions and 4 deletions

View File

@ -1,6 +1,7 @@
#include "session_manager.h"
#include "libollie.h"
#include <QDBusInterface>
#include <QDebug>
#include <QMetaObject>
@ -14,10 +15,9 @@ static void onStateChange(const char *session_id, const char *state)
if (!g_instance) return;
QString sid = QString::fromUtf8(session_id);
QString st = QString::fromUtf8(state);
// Marshal to the Qt event loop thread
QMetaObject::invokeMethod(g_instance, [sid, st]() {
emit g_instance->StateChanged(sid, st);
}, Qt::QueuedConnection);
QMetaObject::invokeMethod(g_instance, "handleStateChange",
Qt::QueuedConnection,
Q_ARG(QString, sid), Q_ARG(QString, st));
}
static void onChatUpdate(const char *session_id, int64_t offset, const char *text, int len)
@ -103,6 +103,7 @@ bool SessionManager::KillSession(const QString &session_id)
QByteArray idUtf8 = session_id.toUtf8();
int rc = ollie_kill_session(const_cast<char*>(idUtf8.constData()));
if (rc == 0) {
m_sessionStates.remove(session_id);
emit SessionKilled(session_id);
return true;
}
@ -306,3 +307,35 @@ bool SessionManager::PeerSubmit(const QString &session_id, const QString &peer_i
const_cast<char*>(promptUtf8.constData()));
return rc == 0;
}
// --- Notifications ---
void SessionManager::handleStateChange(const QString &session_id, const QString &new_state)
{
QString prev = m_sessionStates.value(session_id, "idle");
m_sessionStates[session_id] = new_state;
if (new_state == "idle" && prev != "idle") {
sendNotification("Ollie", "Session " + session_id.left(12) + " finished");
}
emit StateChanged(session_id, new_state);
}
void SessionManager::sendNotification(const QString &title, const QString &body)
{
QDBusInterface notifyIface(
"org.freedesktop.Notifications",
"/org/freedesktop/Notifications",
"org.freedesktop.Notifications",
QDBusConnection::sessionBus());
notifyIface.call("Notify",
"ollie-kde", // app_name
(uint)0, // replaces_id
"system-run", // app_icon
title, // summary
body, // body
QStringList(), // actions
QVariantMap(), // hints
(int)5000); // timeout ms
}

View File

@ -5,6 +5,8 @@
#include <QString>
#include <QStringList>
#include <QDBusConnection>
#include <QDBusInterface>
#include <QHash>
// SessionManager is the D-Bus adaptee. The generated SessionManagerAdaptor
// (from qt6_add_dbus_adaptor) forwards D-Bus method calls to slots here.
@ -62,6 +64,12 @@ signals:
private:
void installCallbacks();
void sendNotification(const QString &title, const QString &body);
QHash<QString, QString> m_sessionStates;
private slots:
void handleStateChange(const QString &session_id, const QString &new_state);
};
#endif // SESSION_MANAGER_H