From 04b92f38a2ebce2479670580857f722e9b3b3be4 Mon Sep 17 00:00:00 2001
From: Dan Williams <dcbw@redhat.com>
Date: Tue, 25 Nov 2014 17:45:05 -0600
Subject: [PATCH 1/2] Revert "applet: don't check for gnome shell (bgo
#707953)"
This reverts commit 4473e6a48fcfda1d87d4a4bc9f5c0589235dcfe0.
---
src/applet.c | 47 +++++++++-
src/applet.h | 4 +
src/shell-watcher.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/shell-watcher.h | 56 ++++++++++++
4 files changed, 347 insertions(+), 1 deletion(-)
create mode 100644 src/shell-watcher.c
create mode 100644 src/shell-watcher.h
diff --git a/src/applet.c b/src/applet.c
index f0536f8..f3f4344 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -87,6 +87,7 @@
#include "nm-wifi-dialog.h"
#include "applet-vpn-request.h"
#include "utils.h"
+#include "shell-watcher.h"
#include "nm-ui-utils.h"
#include "nm-glib-compat.h"
@@ -3542,6 +3543,39 @@ register_agent (NMApplet *applet)
G_CALLBACK (applet_agent_cancel_secrets_cb), applet);
}
+static void
+shell_version_changed_cb (NMShellWatcher *watcher, GParamSpec *pspec, gpointer user_data)
+{
+ NMApplet *applet = user_data;
+
+ if (nm_shell_watcher_version_at_least (watcher, 3, 0)) {
+ g_debug ("gnome-shell is running");
+
+ if (applet->agent) {
+ g_debug ("destroying secret agent");
+
+ g_signal_handlers_disconnect_by_func (applet->agent,
+ G_CALLBACK (applet_agent_get_secrets_cb),
+ applet);
+ g_signal_handlers_disconnect_by_func (applet->agent,
+ G_CALLBACK (applet_agent_cancel_secrets_cb),
+ applet);
+ nm_secret_agent_unregister (NM_SECRET_AGENT (applet->agent));
+ g_clear_object (&applet->agent);
+ }
+
+ /* We don't need the watcher any more */
+ g_signal_handlers_disconnect_by_func (applet->shell_watcher,
+ G_CALLBACK (shell_version_changed_cb),
+ applet);
+ g_clear_object (&applet->shell_watcher);
+ } else if (!applet->agent) {
+ /* No shell */
+ g_debug ("gnome-shell is not running, registering secret agent");
+ register_agent (applet);
+ }
+}
+
static gboolean
dbus_setup (NMApplet *applet, GError **error)
{
@@ -3694,7 +3728,15 @@ initable_init (GInitable *initable, GCancellable *cancellable, GError **error)
G_CALLBACK (applet_embedded_cb), NULL);
applet_embedded_cb (G_OBJECT (applet->status_icon), NULL, NULL);
- register_agent (applet);
+ /* Watch GNOME Shell so we can unregister our applet agent if it appears */
+ if (!shell_debug) {
+ applet->shell_watcher = nm_shell_watcher_new ();
+ g_signal_connect (applet->shell_watcher,
+ "notify::shell-version",
+ G_CALLBACK (shell_version_changed_cb),
+ applet);
+ } else
+ register_agent (applet);
return TRUE;
}
@@ -3764,6 +3806,9 @@ static void finalize (GObject *object)
if (applet->session_bus)
dbus_g_connection_unref (applet->session_bus);
+ if (applet->shell_watcher)
+ g_object_unref (applet->shell_watcher);
+
G_OBJECT_CLASS (nma_parent_class)->finalize (object);
}
diff --git a/src/applet.h b/src/applet.h
index 23632f7..cd5ac97 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -44,6 +44,7 @@
#include <nm-active-connection.h>
#include <nm-remote-settings.h>
#include "applet-agent.h"
+#include "shell-watcher.h"
#if WITH_MODEM_MANAGER_1
#include <libmm-glib.h>
@@ -86,6 +87,9 @@ typedef struct
GMainLoop *loop;
DBusGConnection *session_bus;
+ NMShellWatcher *shell_watcher;
+ guint agent_start_id;
+
NMClient *nm_client;
NMRemoteSettings *settings;
AppletAgent *agent;
diff --git a/src/shell-watcher.c b/src/shell-watcher.c
new file mode 100644
index 0000000..da62121
--- /dev/null
+++ b/src/shell-watcher.c
@@ -0,0 +1,241 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "shell-watcher.h"
+
+G_DEFINE_TYPE (NMShellWatcher, nm_shell_watcher, G_TYPE_OBJECT)
+
+struct NMShellWatcherPrivate {
+ GDBusProxy *shell_proxy;
+ guint signal_id;
+
+ guint retry_timeout;
+ guint retries;
+
+ guint shell_version;
+ gboolean shell_version_set;
+};
+
+enum {
+ PROP_0,
+ PROP_SHELL_VERSION,
+ LAST_PROP
+};
+
+static void create_gnome_shell_proxy (NMShellWatcher *watcher);
+
+static gboolean
+retry_create_shell_proxy (gpointer user_data)
+{
+ NMShellWatcher *watcher = user_data;
+ NMShellWatcherPrivate *priv = watcher->priv;
+
+ priv->retry_timeout = 0;
+ create_gnome_shell_proxy (watcher);
+ return FALSE;
+}
+
+static void
+try_update_version (NMShellWatcher *watcher)
+{
+ NMShellWatcherPrivate *priv = watcher->priv;
+ GVariant *v;
+ char *version, *p;
+
+ v = g_dbus_proxy_get_cached_property (priv->shell_proxy, "ShellVersion");
+ if (!v) {
+ /* The shell has claimed the name, but not yet registered its interfaces...
+ * (https://bugzilla.gnome.org/show_bug.cgi?id=673182). There's no way
+ * to make GDBusProxy re-read the properties at this point, so we
+ * have to destroy this proxy and try again.
+ */
+ if (priv->signal_id) {
+ g_signal_handler_disconnect (priv->shell_proxy, priv->signal_id);
+ priv->signal_id = 0;
+ }
+ g_object_unref (priv->shell_proxy);
+ priv->shell_proxy = NULL;
+
+ priv->retry_timeout = g_timeout_add_seconds (2, retry_create_shell_proxy, watcher);
+ return;
+ }
+
+ g_warn_if_fail (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING));
+ version = g_variant_dup_string (v, NULL);
+ if (version) {
+ guint major, minor;
+
+ major = strtoul (version, &p, 10);
+ if (*p == '.')
+ minor = strtoul (p + 1, NULL, 10);
+ else
+ minor = 0;
+
+ g_warn_if_fail (major < 256);
+ g_warn_if_fail (minor < 256);
+
+ priv->shell_version = (major << 8) | minor;
+ priv->shell_version_set = TRUE;
+ g_object_notify (G_OBJECT (watcher), "shell-version");
+ }
+
+ g_variant_unref (v);
+}
+
+static void
+name_owner_changed_cb (GDBusProxy *proxy, GParamSpec *pspec, gpointer user_data)
+{
+ NMShellWatcher *watcher = user_data;
+ NMShellWatcherPrivate *priv = watcher->priv;
+ char *owner;
+
+ owner = g_dbus_proxy_get_name_owner (proxy);
+ if (owner) {
+ try_update_version (watcher);
+ g_free (owner);
+ } else if (priv->shell_version || !priv->shell_version_set) {
+ priv->shell_version = 0;
+ priv->shell_version_set = TRUE;
+ g_object_notify (G_OBJECT (watcher), "shell-version");
+ }
+}
+
+static void
+got_shell_proxy (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ NMShellWatcher *watcher = user_data;
+ NMShellWatcherPrivate *priv = watcher->priv;
+ GError *error = NULL;
+
+ priv->shell_proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
+ if (!priv->shell_proxy) {
+ g_warning ("Could not create GDBusProxy for org.gnome.Shell: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ priv->signal_id = g_signal_connect (priv->shell_proxy,
+ "notify::g-name-owner",
+ G_CALLBACK (name_owner_changed_cb),
+ watcher);
+
+ name_owner_changed_cb (priv->shell_proxy, NULL, watcher);
+ g_object_unref (watcher);
+}
+
+static void
+create_gnome_shell_proxy (NMShellWatcher *watcher)
+{
+ NMShellWatcherPrivate *priv = watcher->priv;
+
+ if (priv->retries++ == 5) {
+ g_warning ("Could not find ShellVersion property on org.gnome.Shell after 5 tries");
+ return;
+ }
+
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ NULL,
+ "org.gnome.Shell",
+ "/org/gnome/Shell",
+ "org.gnome.Shell",
+ NULL,
+ got_shell_proxy,
+ g_object_ref (watcher));
+}
+
+static void
+nm_shell_watcher_init (NMShellWatcher *watcher)
+{
+ watcher->priv = G_TYPE_INSTANCE_GET_PRIVATE (watcher, NM_TYPE_SHELL_WATCHER,
+ NMShellWatcherPrivate);
+ create_gnome_shell_proxy (watcher);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMShellWatcher *watcher = NM_SHELL_WATCHER (object);
+
+ switch (prop_id) {
+ case PROP_SHELL_VERSION:
+ g_value_set_uint (value, watcher->priv->shell_version);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+finalize (GObject *object)
+{
+ NMShellWatcher *watcher = NM_SHELL_WATCHER (object);
+ NMShellWatcherPrivate *priv = watcher->priv;
+
+ if (priv->retry_timeout)
+ g_source_remove (priv->retry_timeout);
+ if (priv->signal_id)
+ g_signal_handler_disconnect (priv->shell_proxy, priv->signal_id);
+ if (priv->shell_proxy)
+ g_object_unref (priv->shell_proxy);
+
+ G_OBJECT_CLASS (nm_shell_watcher_parent_class)->finalize (object);
+}
+
+static void
+nm_shell_watcher_class_init (NMShellWatcherClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (NMShellWatcherPrivate));
+
+ oclass->get_property = get_property;
+ oclass->finalize = finalize;
+
+ g_object_class_install_property (oclass, PROP_SHELL_VERSION,
+ g_param_spec_uint ("shell-version",
+ "Shell version",
+ "Running GNOME Shell version, eg, 0x0304",
+ 0, 0xFFFF, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+NMShellWatcher *
+nm_shell_watcher_new (void)
+{
+ return g_object_new (NM_TYPE_SHELL_WATCHER, NULL);
+}
+
+gboolean
+nm_shell_watcher_version_at_least (NMShellWatcher *watcher, guint major, guint minor)
+{
+ guint version = (major << 8) | minor;
+
+ return watcher->priv->shell_version >= version;
+}
diff --git a/src/shell-watcher.h b/src/shell-watcher.h
new file mode 100644
index 0000000..a6065f8
--- /dev/null
+++ b/src/shell-watcher.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ */
+
+#ifndef SHELL_WATCHER_H
+#define SHELL_WATCHER_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+
+#define NM_TYPE_SHELL_WATCHER (nm_shell_watcher_get_type())
+#define NM_SHELL_WATCHER(object) (G_TYPE_CHECK_INSTANCE_CAST((object), NM_TYPE_SHELL_WATCHER, NMShellWatcher))
+#define NM_SHELL_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_SHELL_WATCHER, NMShellWatcherClass))
+#define NM_IS_SHELL_WATCHER(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), NM_TYPE_SHELL_WATCHER))
+#define NM_IS_SHELL_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SHELL_WATCHER))
+#define NM_SHELL_WATCHER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), NM_TYPE_SHELL_WATCHER, NMShellWatcherClass))
+
+typedef struct NMShellWatcherPrivate NMShellWatcherPrivate;
+
+typedef struct {
+ GObject parent_instance;
+
+ NMShellWatcherPrivate *priv;
+} NMShellWatcher;
+
+typedef struct {
+ GObjectClass parent_class;
+} NMShellWatcherClass;
+
+GType nm_shell_watcher_get_type (void);
+
+NMShellWatcher *nm_shell_watcher_new (void);
+
+gboolean nm_shell_watcher_version_at_least (NMShellWatcher *watcher,
+ guint major, guint minor);
+
+#endif
--
1.9.3
From bfc24e17555126bb1a9783c2d3c2771bb886ed58 Mon Sep 17 00:00:00 2001
From: Dan Williams <dcbw@redhat.com>
Date: Tue, 25 Nov 2014 17:45:11 -0600
Subject: [PATCH 2/2] Revert "build: fix build after "applet: don't check for
gnome shell (bgo #707953)""
This reverts commit 2014927869cb92be2c9e360f1a6a4b118b866403.
---
src/Makefile.am | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 0e85dd5..d8c1238 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -69,7 +69,9 @@ nm_applet_SOURCES = \
applet-device-bridge.c \
applet-device-infiniband.h \
applet-device-infiniband.c \
- fallback-icon.h
+ fallback-icon.h \
+ shell-watcher.h \
+ shell-watcher.c
nm_applet_LDADD = \
-lm \
--
1.9.3