Use gdbus to eavesdrop Notifications using BecomeMonitor

I am trying to listen to all notifications, sent by any application using gdbus. Since BecomeMonitor is now the preferred way to eavesdrop, how can I achieve this using gdbus. My final goal is to listen to org/freedesktop/Notifications. I have tried following:

GDBusConnection connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);

GVariantBuilder *match_rule = g_variant_builder_new (G_VARIANT_TYPE ("as"));
g_variant_builder_add (match_rule, "s", "type='signal'");
g_variant_builder_add (
    match_rule, "s",
    "type='signal',interface='org.freedesktop.Notifications',member='"
    "Notify',path='/org/freedesktop/Notifications'"
);

g_dbus_connection_call_sync (
    connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
    "org.freedesktop.DBus.Monitoring", "BecomeMonitor",
    g_variant_new ("(asu)", match_rule, 0), NULL, G_DBUS_CALL_FLAGS_NONE,
    -1, NULL, &error
);

void
on_notification_received (
    GDBusConnection *connection, const gchar *sender_name,
    const gchar *object_path, const gchar *interface_name,
    const gchar *signal_name, GVariant *parameters, gpointer n_listener_object
)

int subscription_id = g_dbus_connection_signal_subscribe (
    connection, NULL, NULL, NULL, NULL, NULL,
    G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, on_notification_received,
    (gpointer)data, NULL
);

I guess this is what is happening. Because I can see that BecomeMonitor call is successfull, or atleast that is what I can figure out from busctl monitor. I will try this when I get time.

Okay, so I was right. One needs to use a filter to drop all outgoing messages and then use filter to get messages one wants.

Hope this helps out someone.

A rough version is given below:


// Init Connection
GDBusConnection connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);

// Get Method_Calls from /org/freedesktop/Notifications
GVariantBuilder *match_rule = g_variant_builder_new (G_VARIANT_TYPE ("as"));
g_variant_builder_add (match_rule, "s", "type='signal'");
g_variant_builder_add (
    match_rule, "s",
    "type='method_call',interface='org.freedesktop.Notifications',member='Notify',path='/org/freedesktop/Notifications'"
);

// Filter to drop outgoing messages
// Just declaration, definition below
static GDBusMessage *
filter_drop_outgoing (
    GDBusConnection *connection, 
    GDBusMessage *message, 
    gboolean incoming,
    gpointer user_data
)

// Custom filter to filter out just notifications
// Just declaration, definition below
static GDBusMessage *
n_listener_dbus_notif_filter (
    GDBusConnection *connection, 
    GDBusMessage *received_message,
    gboolean incoming, 
    gpointer user_data
)

g_dbus_connection_add_filter (
    self->connection, filter_drop_outgoing, NULL, NULL
);

g_dbus_connection_add_filter (
    self->connection, custom_notif_filter, self, NULL
);

static GDBusMessage *
filter_drop_outgoing (
    GDBusConnection *connection, 
    GDBusMessage *message, 
    gboolean incoming,
    gpointer user_data
)
{
    if (!incoming)
        {
            g_object_unref (message);
            message = NULL;
        }
    return message;
}

static GDBusMessage *
n_listener_dbus_notif_filter (
    GDBusConnection *connection, 
    GDBusMessage *received_message,
    gboolean incoming, 
    gpointer user_data
)
{
    const gchar *object_path = g_dbus_message_get_path (received_message);
    gboolean obj_path_notif
        = !g_strcmp0 (object_path, "/org/freedesktop/Notifications");
    GDBusMessageType received_message_type
        = g_dbus_message_get_message_type (received_message);
    gboolean message_method_call
        = (received_message_type == G_DBUS_MESSAGE_TYPE_METHOD_CALL);
    if (obj_path_notif && message_method_call)
        {
            
            // DO WHATEVER YOU WANT WITH NOTIFICATION
            // THEY ARE OF GVARIANT TYPE "(susssasa{sv}i)"


           GVariant *received_message_body = g_dbus_message_get_body (received_message);
            g_print ("%s", g_variant_print (received_message_body, TRUE));

        }
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.