diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c index 8ce4bd1..37b2121 100644 --- a/src/applet-device-wifi.c +++ b/src/applet-device-wifi.c @@ -1305,6 +1305,8 @@ wifi_notify_connected (NMDevice *device, ap = _active_ap_get (applet, device); + g_object_set_data_full (G_OBJECT(device), "canonical-last-essid", g_strdup (esc_ssid), (GDestroyNotify) g_free); + esc_ssid = get_ssid_utf8 (ap); if (!ap) diff --git a/src/applet.c b/src/applet.c index ac4f03d..e43c1e4 100644 --- a/src/applet.c +++ b/src/applet.c @@ -141,6 +141,19 @@ get_device_class_from_connection (NMConnection *connection, NMApplet *applet) return NULL; } +struct _OfflineNotificationContextInfo { + NMState state; + NMDeviceState device_state; + NMDeviceStateReason device_state_reason; + NMDeviceType device_type; + gchar* title; + gchar* text; + const gchar* icon; + NotifyUrgency urgency; +}; + +typedef struct _OfflineNotificationContextInfo OfflineNotificationContextInfo; + static NMActiveConnection * applet_get_best_activating_connection (NMApplet *applet, NMDevice **device) { @@ -2127,6 +2140,64 @@ applet_get_exported_connection_for_device (NMDevice *device, NMApplet *applet) return NULL; } +static gboolean +select_merged_notification_text (OfflineNotificationContextInfo *info) +{ + info->urgency = NOTIFY_URGENCY_LOW; + /* only do something if this is about full offline state */ + if(info->state != NM_STATE_UNKNOWN || info->device_state != NM_DEVICE_STATE_UNKNOWN) { + info->urgency = NOTIFY_URGENCY_NORMAL; + if (!info->text) + info->text = g_strdup (_("Network")); + if (info->state == NM_STATE_DISCONNECTED || info->state == NM_STATE_ASLEEP) { + info->title = _("Disconnected - you are now offline"); + } else + info->title = _("Disconnected"); + + switch (info->device_type) { + case NM_DEVICE_TYPE_ETHERNET: + info->icon = "notification-network-ethernet-disconnected"; + break; + case NM_DEVICE_TYPE_WIFI: + info->icon = "notification-network-wireless-disconnected"; + break; + case NM_DEVICE_TYPE_MODEM: + info->icon = "notification-gsm-disconnected"; + break; + default: + info->icon = "nm-no-connection"; + break; + } + g_debug("going for offline with icon: %s", info->icon); + return TRUE; + } + return FALSE; +} + +static gboolean +foo_online_offline_deferred_notify (gpointer user_data) +{ + NMApplet *applet = NM_APPLET (user_data); + OfflineNotificationContextInfo *info = applet->notification_queue_data; + if(select_merged_notification_text (info)) + if (!g_settings_get_boolean (applet->gsettings, PREF_DISABLE_DISCONNECTED_NOTIFICATIONS)) + applet_do_notify (applet, info->urgency, info->title, + info->text, info->icon, + PREF_DISABLE_DISCONNECTED_NOTIFICATIONS, + _("Don't show this message again"), + notify_dont_show_cb, + applet); + else + g_debug("no notification because merged found that we have nothing to say (e.g. not offline)"); + if (info->text) + g_free (info->text); + info->text = NULL; + g_free (applet->notification_queue_data); + applet->notification_queue_data = NULL; + applet->deferred_id = 0; + return FALSE; +} + static void applet_common_device_state_changed (NMDevice *device, NMDeviceState new_state, @@ -2141,6 +2212,54 @@ applet_common_device_state_changed (NMDevice *device, switch (new_state) { + case NM_DEVICE_STATE_FAILED: + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + { + if (old_state != NM_DEVICE_STATE_FAILED && + old_state != NM_DEVICE_STATE_UNKNOWN && + old_state != NM_DEVICE_STATE_DISCONNECTED && + old_state != NM_DEVICE_STATE_UNMANAGED && + old_state != NM_DEVICE_STATE_UNAVAILABLE) { + OfflineNotificationContextInfo *info = applet->notification_queue_data; + if (!info) { + info = g_new0(OfflineNotificationContextInfo, 1); + applet->notification_queue_data = info; + } + + info->device_state = new_state; + info->device_state_reason = reason; + if (info->text) { + g_free(info->text); + info->text = NULL; + } + if (NM_IS_DEVICE_WIFI (device)) { + info->device_type = NM_DEVICE_TYPE_WIFI; + info->text = g_strdup(g_object_get_data (G_OBJECT(device), "canonical-last-essid")); + if (!info->text) + info->text = g_strdup (_("Wireless network")); + } else if (NM_IS_DEVICE_ETHERNET (device)) { + info->device_type = NM_DEVICE_TYPE_ETHERNET; + info->text = g_strdup(_("Ethernet network")); + } else if (NM_IS_DEVICE_MODEM (device)) { + info->device_type = NM_DEVICE_TYPE_MODEM; + info->text = g_strdup (_("Modem network")); + } else { + info->device_type = NM_DEVICE_TYPE_UNKNOWN; + info->text = g_strdup (_("Network")); + } + + if (applet->deferred_id) + g_source_remove (applet->deferred_id); + applet->deferred_id = g_timeout_add (1000, foo_online_offline_deferred_notify, applet); + + clear_animation_timeout (applet); + } else { + g_debug ("old state indicates that this was not a disconnect %d", old_state); + } + break; + } case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_CONFIG: case NM_DEVICE_STATE_NEED_AUTH: @@ -2227,13 +2346,26 @@ foo_client_state_changed_cb (NMClient *client, GParamSpec *pspec, gpointer user_ { NMApplet *applet = NM_APPLET (user_data); + g_debug("foo_client_state_changed_cb"); switch (nm_client_get_state (client)) { case NM_STATE_DISCONNECTED: - applet_do_notify_with_pref (applet, _("Disconnected"), - _("The network connection has been disconnected."), - "nm-no-connection", - PREF_DISABLE_DISCONNECTED_NOTIFICATIONS); - break; + case NM_STATE_ASLEEP: + { + OfflineNotificationContextInfo *info = applet->notification_queue_data; + if (!info) { + info = g_new0(OfflineNotificationContextInfo, 1); + applet->notification_queue_data = info; + } + + info->state = nm_client_get_state (client); + select_merged_notification_text (info); + + if (applet->deferred_id) + g_source_remove (applet->deferred_id); + applet->deferred_id = g_timeout_add (1000, foo_online_offline_deferred_notify, applet); + + /* Fall through */ + } default: break; } diff --git a/src/applet.h b/src/applet.h index 7a0cb8f..958ba56 100644 --- a/src/applet.h +++ b/src/applet.h @@ -135,8 +135,11 @@ typedef struct { /* Tracker objects for secrets requests */ GSList * secrets_reqs; - guint wifi_scan_id; + + gpointer notification_queue_data; + guint deferred_id; + } NMApplet; typedef void (*AppletNewAutoConnectionCallback) (NMConnection *connection,