When I run this command:
notify-send "Test here" "Test body"
And than monitor with:
dbus-monitor "interface='org.freedesktop.Notifications',member='Notify'"
I get this output:
$ dbus-monitor "interface='org.freedesktop.Notifications',member='Notify'"
signal time=1737337906.487066 sender=org.freedesktop.DBus -> destination=:1.202 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
string ":1.202"
signal time=1737337906.487090 sender=org.freedesktop.DBus -> destination=:1.202 serial=4 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameLost
string ":1.202"
method call time=1737337958.906320 sender=:1.203 -> destination=:1.43 serial=9 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications; member=Notify
string "notify-send"
uint32 0
string ""
string "Test here"
string "Test body"
array [
]
array [
dict entry(
string "urgency"
variant byte 1
)
dict entry(
string "sender-pid"
variant int64 26834
)
]
int32 -1
method call time=1737337958.907631 sender=:1.43 -> destination=:1.34 serial=344 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications; member=Notify
string "notify-send"
uint32 0
string ""
string "Test here"
string "Test body"
array [
]
array [
dict entry(
string "urgency"
variant byte 1
)
dict entry(
string "sender-pid"
variant int64 26834
)
dict entry(
string "x-shell-sender-pid"
variant uint32 26834
)
dict entry(
string "x-shell-sender"
variant string ":1.203"
)
]
int32 -1
So I decided to write a C++ program that should also capture this system notifications:
#include <iostream>
#include <dbus/dbus.h>
#include <cstring>
void listenForNotifications()
{
DBusConnection* connection;
DBusError error;
// Initialize D-Bus error
dbus_error_init(&error);
// Connect to the D-Bus session bus
connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
if (!connection) {
std::cerr << "Failed to connect to D-Bus session bus." << std::endl;
return;
}
if (dbus_error_is_set(&error)) {
std::cerr << "D-Bus Connection Error: " << error.message << std::endl;
dbus_error_free(&error);
return;
}
// Debug: Print session bus address
const char* sessionBusAddress = getenv("DBUS_SESSION_BUS_ADDRESS");
if (sessionBusAddress) {
std::cout << "DBUS_SESSION_BUS_ADDRESS: " << sessionBusAddress << std::endl;
} else {
std::cerr << "DBUS_SESSION_BUS_ADDRESS not found in the environment!" << std::endl;
}
std::cout << "Connected to D-Bus session bus successfully." << std::endl;
// Add a match rule to listen to signals from Notifications
const char* match_rule = "type='method_call',interface='org.freedesktop.Notifications',member='Notify'";
dbus_bus_add_match(connection, match_rule, &error);
if (dbus_error_is_set(&error)) {
std::cerr << "D-Bus Add Match Error: " << error.message << std::endl;
dbus_error_free(&error);
return;
}
std::cout << "Listening for notifications..." << std::endl;
// Main event loop
while (true) {
dbus_connection_read_write(connection, 100);
DBusMessage* message = dbus_connection_pop_message(connection);
if (message) {
std::cout << "Message received!" << std::endl;
const char* interface = dbus_message_get_interface(message);
const char* member = dbus_message_get_member(message);
std::cout << "Received D-Bus message: " << std::endl;
std::cout << " Interface: " << (interface ? interface : "Unknown") << std::endl;
std::cout << " Member: " << (member ? member : "Unknown") << std::endl;
if (dbus_message_is_signal(message, "org.freedesktop.Notifications", "Notify")) {
const char* app_name = nullptr;
const char* summary = nullptr;
const char* body = nullptr;
dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &app_name,
DBUS_TYPE_STRING, &summary,
DBUS_TYPE_STRING, &body,
DBUS_TYPE_INVALID
);
if (!dbus_error_is_set(&error)) {
std::cout << "Notification from: " << (app_name ? app_name : "Unknown") << std::endl;
std::cout << "Title: " << (summary ? summary : "No Title") << std::endl;
std::cout << "Body: " << (body ? body : "No Body") << std::endl;
} else {
std::cerr << "Error parsing notification: " << error.message << std::endl;
dbus_error_free(&error);
}
}
dbus_message_unref(message);
}
}
}
int main()
{
listenForNotifications();
return 0;
}
However this only outputs the following:
DBUS_SESSION_BUS_ADDRESS: unix:path=/run/user/1000/bus
Connected to D-Bus session bus successfully.
Listening for notifications...
Message received!
Received D-Bus message:
Interface: org.freedesktop.DBus
Member: NameAcquired
And never shows anything when I run notify-send
.
What am I doing wrong, why my C++ app can't read properly the notification events?