[balsa/gtk3] Port to GNetworkMonitor from NetworkManager



commit 5e3745d5eed7dbb097ca44a88e4a98714a43f324
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Mon Apr 22 22:38:00 2013 -0400

    Port to GNetworkMonitor from NetworkManager
    
        * configure.ac: if configure --with-nm when GNetworkMonitor
        is available (glib >= 2.32), announce that we will actually
        use GNetworkMonitor.
        * src/main-window.c: Use GNetworkMonitor, when available,
        instead of NetworkManager.
        * src/main-window.h: replace NMState nm_state with gboolean
        network_available.

 ChangeLog         |  12 +++++
 configure.ac      |   3 ++
 src/main-window.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 src/main-window.h |  10 +++-
 4 files changed, 153 insertions(+), 11 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d690fd4..97e2f33 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2013-04-22  Peter Bloomfield
 
+       Port to GNetworkMonitor from NetworkManager
+
+       * configure.ac: if configure --with-nm when GNetworkMonitor
+       is available (glib >= 2.32), announce that we will actually
+       use GNetworkMonitor.
+       * src/main-window.c: Use GNetworkMonitor, when available,
+       instead of NetworkManager.
+       * src/main-window.h: replace NMState nm_state with gboolean
+       network_available.
+
+2013-04-22  Peter Bloomfield
+
        New message header widget, based on GtkInfoBar
 
        * src/balsa-message.c (bm_header_tl_buttons),
diff --git a/configure.ac b/configure.ac
index d75ad00..fddd7c9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -759,6 +759,9 @@ fi
 
 # NetworkManager
 if test "$with_nm" != no ; then
+  if $PKG_CONFIG --atleast-version=2.32.0 glib-2.0 ; then
+    with_nm="no; using GNetworkMonitor instead"
+  fi
   PKG_CHECK_EXISTS([libnm-glib], 
   [ PKG_CHECK_MODULES(LIBNM_GLIB, [ libnm-glib >= 0.7.0]) ],
   [ PKG_CHECK_MODULES(LIBNM_GLIB, [ libnm_glib >= 0.7.0]) ])
diff --git a/src/main-window.c b/src/main-window.c
index 2fbcb04..85e28fe 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -45,7 +45,9 @@
 #  include "macosx-helpers.h"
 #endif
 
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+#include <gio/gio.h>
+#elif defined(HAVE_LIBNM_GLIB)
 #include <nm-client.h>
 #endif
 
@@ -113,7 +115,7 @@ static void bw_check_messages_thread(struct check_messages_thread_info
 #endif
 static void bw_display_new_mail_notification(int num_new, int has_new);
 
-#if defined(HAVE_LIBNM_GLIB)
+#if !GLIB_CHECK_VERSION(2, 32, 0) && defined(HAVE_LIBNM_GLIB)
 static void bw_nm_client_state_report(NMState state);
 static void bw_nm_client_state_changed_cb(GObject * gobject,
                                           GParamSpec * pspec,
@@ -998,10 +1000,41 @@ balsa_window_class_init(BalsaWindowClass * klass)
 
 }
 
+static gboolean bw_change_connection_status_idle(gpointer data);
+#define PRINT_NETWORK_STATUS(available)                 \
+    g_printerr("Network is %s (%u)\n",                  \
+               (available) ? "available" : "unavailable", \
+               (guint) time(NULL))
+
+static void
+bw_network_changed_cb(GNetworkMonitor * monitor,
+                      gboolean          available,
+                      gpointer          user_data)
+{
+    BalsaWindow *window = user_data;
+
+    if (window->network_available != available) {
+        window->network_available = available;
+        PRINT_NETWORK_STATUS(available);
+        g_idle_add(bw_change_connection_status_idle,
+                   GINT_TO_POINTER(available));
+    }
+}
+
 static void
 balsa_window_init(BalsaWindow * window)
 {
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+    GNetworkMonitor *monitor;
+
+    monitor = g_network_monitor_get_default();
+    window->network_available =
+        g_network_monitor_get_network_available(monitor);
+    PRINT_NETWORK_STATUS(window->network_available);
+    g_signal_connect(monitor, "network-changed",
+                     G_CALLBACK(bw_network_changed_cb), window);
+    window->last_check_time = 0;
+#elif defined(HAVE_LIBNM_GLIB)
     NMClient *client = nm_client_new();
     if (client) {
         window->nm_state = nm_client_get_state(client);
@@ -2838,7 +2871,11 @@ bw_show_about_box(GtkAction * action, gpointer user_data)
 static void
 bw_check_mailbox_list(BalsaWindow * window, GList * mailbox_list)
 {
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+    if (window && !window->network_available) {
+        return;
+    }
+#elif defined(HAVE_LIBNM_GLIB)
     if (window && window->nm_state != NM_STATE_CONNECTED) {
         return;
     }
@@ -2960,7 +2997,13 @@ bw_mailbox_check(LibBalsaMailbox * mailbox, BalsaWindow * window)
     if (libbalsa_mailbox_get_subscribe(mailbox) == LB_MAILBOX_SUBSCRIBE_NO)
         return;
 
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+    if (LIBBALSA_IS_MAILBOX_IMAP(mailbox)) {
+        if (window && !window->network_available) {
+                return;
+        }
+    }
+#elif defined(HAVE_LIBNM_GLIB)
     if (LIBBALSA_IS_MAILBOX_IMAP(mailbox)) {
             if (window && window->nm_state != NM_STATE_CONNECTED) {
                 return;
@@ -3051,7 +3094,10 @@ check_new_messages_real(BalsaWindow * window, int type)
     if (window)
         bw_set_sensitive(window, "GetNewMail", TRUE);
 
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+    if (window->network_available)
+        time(&window->last_check_time);
+#elif defined(HAVE_LIBNM_GLIB)
     if (window->nm_state == NM_STATE_CONNECTED)
         time(&window->last_check_time);
 #endif                          /* defined(HAVE_LIBNM_GLIB) */
@@ -3179,7 +3225,11 @@ bw_mailbox_check(LibBalsaMailbox * mailbox, BalsaWindow * window)
         return;
 
     if (LIBBALSA_IS_MAILBOX_IMAP(mailbox)) {
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+        if (window && !window->network_available) {
+                return;
+        }
+#elif defined(HAVE_LIBNM_GLIB)
             if (window && window->nm_state != NM_STATE_CONNECTED) {
                 return;
         }
@@ -3234,7 +3284,10 @@ bw_check_messages_thread(struct check_messages_thread_info *info)
     if (info->window) {
         g_idle_add((GSourceFunc) bw_check_messages_thread_idle_cb,
                    g_object_ref(info->window));
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+        if (info->window->network_available)
+            time(&info->window->last_check_time);
+#elif defined(HAVE_LIBNM_GLIB)
         if (info->window->nm_state == NM_STATE_CONNECTED)
             time(&info->window->last_check_time);
 #endif                          /* defined(HAVE_LIBNM_GLIB) */
@@ -3616,7 +3669,75 @@ bw_display_new_mail_notification(int num_new, int has_new)
     g_free(msg);
 }
 
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+/*Callback to create or disconnect an IMAP mbox. */
+static gboolean
+mw_mbox_change_connection_status(GtkTreeModel * model, GtkTreePath * path,
+                                 GtkTreeIter * iter, gpointer arg)
+{
+    BalsaMailboxNode *mbnode;
+    LibBalsaMailbox *mailbox;
+
+    gtk_tree_model_get(model, iter, 0, &mbnode, -1);
+    g_return_val_if_fail(mbnode, FALSE);
+
+    if ((mailbox = mbnode->mailbox)) {  /* mailbox, not a folder */
+        if (LIBBALSA_IS_MAILBOX_IMAP(mailbox)) {
+            const gchar *host =
+                LIBBALSA_MAILBOX_REMOTE(mailbox)->server->host;
+            GNetworkMonitor *monitor;
+            GSocketConnectable *address;
+
+            monitor = g_network_monitor_get_default();
+            address = g_network_address_new(host, 0);
+            if (g_network_monitor_can_reach(monitor, address, NULL, NULL)) {
+                libbalsa_mailbox_imap_reconnect
+                    (LIBBALSA_MAILBOX_IMAP(mailbox));
+            } else {
+                libbalsa_mailbox_imap_force_disconnect
+                    (LIBBALSA_MAILBOX_IMAP(mailbox));
+            }
+            g_object_unref(address);
+        }
+    }
+    g_object_unref(mbnode);
+
+    return FALSE;
+}
+
+static gboolean
+check_new_messages_idle(gpointer user_data)
+{
+    check_new_messages_cb(NULL, balsa_app.main_window);
+    return FALSE;
+}
+
+static gboolean
+bw_change_connection_status_idle(gpointer arg)
+{
+    gboolean is_connected = GPOINTER_TO_INT(arg);
+
+    gtk_tree_model_foreach(GTK_TREE_MODEL(balsa_app.mblist_tree_store),
+                          (GtkTreeModelForeachFunc)
+                           mw_mbox_change_connection_status,
+                           NULL);
+
+    /* GLib timeouts are now triggered by g_get_monotonic_time(),
+     * which doesn't increment while we're suspended, so we must
+     * check for ourselves whether a scheduled mail check was
+     * missed. */
+    if (is_connected &&
+        difftime(time(NULL), balsa_app.main_window->last_check_time) >
+        balsa_app.check_mail_timer * 60) {
+        /* Check the mail now, and reset the timer, remembering it
+           must be called from a main thread. */
+        g_idle_add(check_new_messages_idle, NULL);
+    }
+
+    return FALSE;
+}
+
+#elif defined(HAVE_LIBNM_GLIB)
 /*Callback to create or disconnect an IMAP mbox. */
 static gboolean
 mw_mbox_change_connection_status(GtkTreeModel * model, GtkTreePath * path,
diff --git a/src/main-window.h b/src/main-window.h
index 5fa87dc..172f828 100644
--- a/src/main-window.h
+++ b/src/main-window.h
@@ -28,7 +28,9 @@
 #include <libnotify/notify.h>
 #endif
 
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+#include <gio/gio.h>
+#elif defined(HAVE_LIBNM_GLIB)
 #include <nm-client.h>
 #endif
 
@@ -98,7 +100,11 @@ struct _BalsaWindow {
     NotifyNotification *new_mail_note;
 #endif                         /* HAVE_NOTIFY */
 
-#if defined(HAVE_LIBNM_GLIB)
+#if GLIB_CHECK_VERSION(2, 32, 0)
+    /* Support GNetworkMonitor: */
+    gboolean network_available;
+    time_t last_check_time;
+#elif defined(HAVE_LIBNM_GLIB)
     /* NetworkManager state */
     NMState nm_state;
     time_t last_check_time;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]