From e5ff320cfb3f387166d63674499c4e8f06256575 Mon Sep 17 00:00:00 2001
From: c4pp4
Date: Mon, 4 Aug 2025 04:15:02 +0200
Subject: [PATCH 1/1] Show notifications via libnotify when in Unity

Signed-off-by: c4pp4
---
 meson.build     |  3 +++
 src/applet.c    | 69 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/applet.h    |  3 +++
 src/meson.build |  1 +
 4 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index c72597c..0c2c240 100644
--- a/meson.build
+++ b/meson.build
@@ -122,6 +122,9 @@ gtk_dep = declare_dependency(
   ]
 )
 
+# Check for libnotify >= 0.7
+libnotify_dep = dependency('libnotify', version: '>= 0.7')
+
 # API documentation
 nm_req_version = '>= 1.7'
 
diff --git a/src/applet.c b/src/applet.c
index 24019e7..217e5e2 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -21,6 +21,7 @@
 #include <unistd.h>
 #include <sys/socket.h>
 #include <stdlib.h>
+#include <libnotify/notify.h>
 
 #include "applet.h"
 #include "applet-device-bt.h"
@@ -684,6 +685,27 @@ applet_menu_item_create_device_item_helper (NMDevice *device,
 	return item;
 }
 
+gboolean
+in_desktop_unity (void)
+{
+	const gchar *desktop_name_list;
+	gchar **names;
+	gboolean in_list = FALSE;
+	gint i;
+
+	desktop_name_list = g_getenv ("XDG_CURRENT_DESKTOP");
+	if (!desktop_name_list)
+		return FALSE;
+
+	names = g_strsplit (desktop_name_list, ":", -1);
+	for (i = 0; names[i] && !in_list; i++)
+		if ((strcmp (names[i], "Unity") == 0) || (strcmp (names[i], "unity-greeter") == 0))
+			in_list = TRUE;
+	g_strfreev (names);
+
+	return in_list;
+}
+
 void
 applet_do_notify (NMApplet *applet,
                   const char *title,
@@ -691,7 +713,6 @@ applet_do_notify (NMApplet *applet,
                   const char *icon_name,
                   const char *pref)
 {
-	gs_unref_object GNotification *notify = NULL;
 	GIcon *icon;
 	char *escaped;
 
@@ -716,6 +737,41 @@ applet_do_notify (NMApplet *applet,
 	if (!applet->agent)
 		return;
 
+	if (in_desktop_unity ()) {
+		NotifyNotification *notify;
+		GError *error = NULL;
+
+		escaped = utils_escape_notify_body (body);
+
+		if (applet->notification == NULL) {
+			notify = notify_notification_new (title,
+							  escaped,
+							  icon_name ? icon_name : "network-workgroup");
+			applet->notification = notify;
+		} else {
+			notify = applet->notification;
+			notify_notification_update (notify,
+						    title,
+						    escaped,
+						    icon_name ? icon_name : "network-workgroup");
+		}
+
+		g_free (escaped);
+ 
+		notify_notification_set_hint (notify, "transient", g_variant_new_boolean (TRUE));
+		notify_notification_set_hint (notify, "desktop-entry", g_variant_new_string ("nm-applet"));
+
+		notify_notification_set_urgency (notify, NOTIFY_URGENCY_LOW);
+		notify_notification_set_timeout (notify, NOTIFY_EXPIRES_DEFAULT);
+ 
+		if (!notify_notification_show (notify, &error)) {
+			g_warning ("Failed to show notification: %s",
+				error && error->message ? error->message : "(unknown)");
+			g_clear_error (&error);
+		}
+	} else {
+		gs_unref_object GNotification *notify = NULL;
+
 	notify = g_notification_new (title);
 
 	escaped = utils_escape_notify_body (body);
@@ -734,6 +790,7 @@ applet_do_notify (NMApplet *applet,
 	}
 
 	g_application_send_notification (G_APPLICATION (applet), "nm-applet", notify);
+	}
 }
 
 static gboolean
@@ -3312,6 +3369,9 @@ applet_startup (GApplication *app, gpointer user_data)
 	                                            nm_g_object_unref);
 	nma_icons_init (applet);
 
+	if (in_desktop_unity () && !notify_is_initted ())
+		notify_init ("NetworkManager");
+
 	/* Initialize device classes */
 	applet->ethernet_class = applet_device_ethernet_get_class (applet);
 	g_assert (applet->ethernet_class);
@@ -3375,6 +3435,13 @@ static void finalize (GObject *object)
 	while (g_slist_length (applet->secrets_reqs))
 		applet_secrets_request_free ((SecretsRequest *) applet->secrets_reqs->data);
 
+	if (applet->notification) {
+		notify_notification_close (applet->notification, NULL);
+		g_object_unref (applet->notification);
+		applet->notification = NULL;
+	}
+	notify_uninit();
+
 	g_clear_object (&applet->info_dialog_ui);
 	g_clear_object (&applet->gsettings);
 	g_clear_object (&applet->nm_client);
diff --git a/src/applet.h b/src/applet.h
index 7978ba7..b9cbe2f 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -15,6 +15,8 @@
 
 #include <net/ethernet.h>
 
+#include <libnotify/notify.h>
+
 #ifdef WITH_APPINDICATOR
 #if USE_AYATANA_INDICATORS
 #include <libayatana-appindicator/app-indicator.h>
@@ -137,6 +139,7 @@ typedef struct {
 	GtkWidget *     connections_menu_item;
 
 	GtkBuilder *    info_dialog_ui;
+	NotifyNotification* notification;
 
 	/* Tracker objects for secrets requests */
 	GSList *        secrets_reqs;
diff --git a/src/meson.build b/src/meson.build
index ce7ab94..fade5af 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -47,6 +47,7 @@ deps = [
   gtk_dep,
   libnm_dep,
   libnma_dep,
+  libnotify_dep,
   libsecret_dep,
   m_dep,
   libutils_libnm_dep
-- 
2.49.1

