#include "services/dbus/notification.hpp" #include #include "services/notificationController.hpp" #include "glib.h" #include "glibconfig.h" void NotificationService::onBusAcquired(const Glib::RefPtr &connection, const Glib::ustring &name) { std::cout << "Acquired bus name: " << name << std::endl; auto introspection_data = Gio::DBus::NodeInfo::create_for_xml(introspection_xml); // Register the object at the standard path connection->register_object( "/org/freedesktop/Notifications", introspection_data->lookup_interface("org.freedesktop.Notifications"), getMessageInterfaceVTable()); } const Gio::DBus::InterfaceVTable &NotificationService::getMessageInterfaceVTable() { static Gio::DBus::InterfaceVTable vtable( sigc::mem_fun(*this, &NotificationService::on_method_call)); return vtable; } void NotificationService::on_method_call(const Glib::RefPtr &, const Glib::ustring &, const Glib::ustring &, const Glib::ustring &, const Glib::ustring &method_name, const Glib::VariantContainerBase ¶meters, const Glib::RefPtr &invocation) { if (method_name == "Notify") { handle_notify(parameters, invocation); } else if (method_name == "GetCapabilities") { auto caps = std::vector{"body"}; invocation->return_value(Glib::VariantContainerBase::create_tuple( Glib::Variant>::create(caps))); } else if (method_name == "GetServerInformation") { invocation->return_value(Glib::VariantContainerBase::create_tuple({Glib::Variant::create("MyGtkmmNotifier"), Glib::Variant::create("Custom"), Glib::Variant::create("1.0"), Glib::Variant::create("1.2")})); } else { // Handle other methods or return error invocation->return_value(Glib::VariantContainerBase()); } } void NotificationService::handle_notify(const Glib::VariantContainerBase ¶meters, const Glib::RefPtr &invocation) { Glib::VariantBase app_name_var, replaces_id_var, app_icon_var, summary_var, body_var, actions_var, hints_var, timeout_var; parameters.get_child(app_name_var, 0); parameters.get_child(replaces_id_var, 1); parameters.get_child(app_icon_var, 2); parameters.get_child(summary_var, 3); parameters.get_child(body_var, 4); parameters.get_child(actions_var, 5); parameters.get_child(hints_var, 6); parameters.get_child(timeout_var, 7); Glib::ustring app_name = Glib::VariantBase::cast_dynamic>(app_name_var).get(); guint32 replaces_id = Glib::VariantBase::cast_dynamic>(replaces_id_var).get(); Glib::ustring app_icon = Glib::VariantBase::cast_dynamic>(app_icon_var).get(); Glib::ustring summary = Glib::VariantBase::cast_dynamic>(summary_var).get(); Glib::ustring body = Glib::VariantBase::cast_dynamic>(body_var).get(); std::vector actions = Glib::VariantBase::cast_dynamic>>(actions_var).get(); // std::map hints = Glib::VariantBase::cast_dynamic>>(hints_var).get(); gint32 expire_timeout = Glib::VariantBase::cast_dynamic>(timeout_var).get(); std::cout << "Notification Received: " << summary << " - " << body << std::endl; NotifyMessage notify; notify.app_name = app_name; notify.replaces_id = replaces_id; notify.app_icon = app_icon; notify.summary = summary; notify.body = body; std::vector actions_converted; actions_converted.reserve(actions.size()); for (const auto &a : actions) { actions_converted.emplace_back(static_cast(a)); } notify.actions = actions_converted; // notify.hints = hints; notify.expire_timeout = expire_timeout; guint id = notificationIdCounter++; // Set up the callback to emit ActionInvoked on D-Bus Glib::RefPtr dbus_conn = invocation->get_connection(); notify.on_action = [dbus_conn, id](const std::string &action_id) { try { dbus_conn->emit_signal( "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "ActionInvoked", "", // destination bus name (empty for broadcast) Glib::VariantContainerBase::create_tuple({Glib::Variant::create(id), Glib::Variant::create(action_id)})); } catch (const std::exception &e) { std::cerr << "Failed to emit ActionInvoked: " << e.what() << std::endl; } }; NotificationController::getInstance()->showNotificationOnAllMonitors(notify); invocation->return_value(Glib::VariantContainerBase::create_tuple( Glib::Variant::create(id))); }