[NetworkManager/f17] Fix gnome-shell detection in nm-applet
Dan Winship
danw at fedoraproject.org
Mon Apr 2 14:08:14 UTC 2012
commit 868a8f2680c03f097fb8ff25dbba907db463827e
Author: Dan Winship <danw at gnome.org>
Date: Mon Apr 2 10:08:00 2012 -0400
Fix gnome-shell detection in nm-applet
NetworkManager.spec | 7 +-
nm-applet-detect-shell.patch | 471 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 477 insertions(+), 1 deletions(-)
---
diff --git a/NetworkManager.spec b/NetworkManager.spec
index 81fbc9b..040e702 100644
--- a/NetworkManager.spec
+++ b/NetworkManager.spec
@@ -21,7 +21,7 @@ Name: NetworkManager
Summary: Network connection manager and user applications
Epoch: 1
Version: 0.9.4.0
-Release: 1%{snapshot}%{?dist}
+Release: 2%{snapshot}%{?dist}
Group: System Environment/Base
License: GPLv2+
URL: http://www.gnome.org/projects/NetworkManager/
@@ -36,6 +36,7 @@ Patch4: nm-polkit-permissive.patch
Patch5: nm-applet-wifi-dialog-ui-fixes.patch
Patch6: nss-error.patch
Patch7: applet-ignore-deprecated.patch
+Patch8: nm-applet-detect-shell.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Requires(post): chkconfig
@@ -218,6 +219,7 @@ tar -xjf %{SOURCE1}
%patch5 -p1 -b .applet-wifi-ui
%patch6 -p1 -b .nss-error
%patch7 -p1 -b .no-deprecated
+%patch8 -p1 -b .detect-shell
%build
@@ -493,6 +495,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%{_libdir}/libnm-gtk.so
%changelog
+* Mon Apr 2 2012 Dan Winship <danw at redhat.com> - 0.9.4.0-2.git20120328
+- Fix gnome-shell detection in nm-applet
+
* Wed Mar 28 2012 Jiří Klimeš <jklimes at redhat.com> - 0.9.4.0-1.git20120328
- Update to 0.9.4 release
- libnm-glib: ensure bindings-created NMClient object really work (rh #802536)
diff --git a/nm-applet-detect-shell.patch b/nm-applet-detect-shell.patch
new file mode 100644
index 0000000..44e2607
--- /dev/null
+++ b/nm-applet-detect-shell.patch
@@ -0,0 +1,471 @@
+--- NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/shell-watcher.h.detect-shell 2012-03-30 16:36:03.818237360 -0400
++++ NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/shell-watcher.h 2012-03-30 16:36:15.717004721 -0400
+@@ -0,0 +1,60 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
++/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
++ *
++ * 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>
++
++#if GLIB_CHECK_VERSION(2,26,0)
++
++#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 /* GLIB_CHECK_VERSION(2,26,0) */
++
++#endif
+--- NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/applet.c.detect-shell 2012-03-30 16:35:49.770151627 -0400
++++ NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/applet.c 2012-03-30 16:36:15.715004423 -0400
+@@ -79,6 +79,7 @@
+ #include "applet-vpn-request.h"
+ #include "utils.h"
+ #include "gconf-helpers.h"
++#include "shell-watcher.h"
+
+ #define NOTIFY_CAPS_ACTIONS_KEY "actions"
+
+@@ -2955,7 +2956,7 @@
+ NMApplet *applet = NM_APPLET (user_data);
+
+ /* If the shell is running and the agent just got registered, unregister it */
+- if ( (applet->shell_version >= 3.4)
++ if ( (nm_shell_watcher_version_at_least (applet->shell_watcher, 3, 4))
+ && nm_secret_agent_get_registered (NM_SECRET_AGENT (agent))) {
+ g_message ("Stopping registered applet secret agent because GNOME Shell is running");
+ nm_secret_agent_unregister (NM_SECRET_AGENT (agent));
+@@ -3249,55 +3250,16 @@
+ return FALSE;
+ }
+
+-static gboolean
+-get_shell_version (GDBusProxy *proxy, gdouble *out_version)
+-{
+- GVariant *v;
+- char *version, *p;
+- gboolean success = FALSE;
+- gdouble converted;
+-
+- /* Ask for the shell's version */
+- v = g_dbus_proxy_get_cached_property (proxy, "ShellVersion");
+- if (v) {
+- g_warn_if_fail (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING));
+- version = g_variant_dup_string (v, NULL);
+- if (version) {
+- /* Terminate at the second dot if there is one */
+- p = strchr (version, '.');
+- if (p && (p = strchr (p + 1, '.')))
+- *p = '\0';
+-
+- converted = strtod (version, NULL);
+- g_warn_if_fail (converted > 0);
+- g_warn_if_fail (converted < 1000);
+- if (converted > 0 && converted < 1000) {
+- *out_version = converted;
+- success = TRUE;
+- }
+- g_free (version);
+- }
+- g_variant_unref (v);
+- }
+- return success;
+-}
+-
+ static void
+-name_owner_changed_cb (GDBusProxy *proxy, GParamSpec *pspec, gpointer user_data)
++shell_version_changed_cb (NMShellWatcher *watcher, GParamSpec *pspec, gpointer user_data)
+ {
+ NMApplet *applet = user_data;
+- char *owner;
+
+- owner = g_dbus_proxy_get_name_owner (proxy);
+- if (owner) {
+- applet->shell_version = 0;
++ if (nm_shell_watcher_version_at_least (watcher, 3, 4)) {
+ if (applet->agent_start_id)
+ g_source_remove (applet->agent_start_id);
+
+- if ( get_shell_version (proxy, &applet->shell_version)
+- && applet->shell_version >= 3.4
+- && applet->agent
+- && nm_secret_agent_get_registered (NM_SECRET_AGENT (applet->agent))) {
++ if (applet->agent && nm_secret_agent_get_registered (NM_SECRET_AGENT (applet->agent))) {
+ g_message ("Stopping applet secret agent because GNOME Shell appeared");
+ nm_secret_agent_unregister (NM_SECRET_AGENT (applet->agent));
+ }
+@@ -3305,14 +3267,12 @@
+ /* If the shell quit and our agent wasn't already registered, do it
+ * now on a delay (just in case the shell is restarting.
+ */
+- applet->shell_version = 0;
+ if (applet->agent_start_id)
+ g_source_remove (applet->agent_start_id);
+
+ if (nm_secret_agent_get_registered (NM_SECRET_AGENT (applet->agent)) == FALSE)
+ applet->agent_start_id = g_timeout_add_seconds (4, delayed_start_agent, applet);
+ }
+- g_free (owner);
+ }
+ #endif
+
+@@ -3469,19 +3429,11 @@
+
+ #if GLIB_CHECK_VERSION(2,26,0)
+ /* Watch GNOME Shell so we can unregister our applet agent if it appears */
+- applet->shell_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+- G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+- NULL,
+- "org.gnome.Shell",
+- "/org/gnome/Shell",
+- "org.gnome.Shell",
+- NULL,
+- NULL);
+- g_signal_connect (applet->shell_proxy,
+- "notify::g-name-owner",
+- G_CALLBACK (name_owner_changed_cb),
++ applet->shell_watcher = nm_shell_watcher_new ();
++ g_signal_connect (applet->shell_watcher,
++ "notify::shell-version",
++ G_CALLBACK (shell_version_changed_cb),
+ applet);
+- name_owner_changed_cb (applet->shell_proxy, NULL, applet);
+ #endif
+
+ return G_OBJECT (applet);
+@@ -3551,8 +3503,8 @@
+ dbus_g_connection_unref (applet->session_bus);
+
+ #if GLIB_CHECK_VERSION(2,26,0)
+- if (applet->shell_proxy)
+- g_object_unref (applet->shell_proxy);
++ if (applet->shell_watcher)
++ g_object_unref (applet->shell_watcher);
+ #endif
+ if (applet->agent_start_id)
+ g_source_remove (applet->agent_start_id);
+--- NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/Makefile.am.detect-shell 2012-03-30 16:35:40.926839155 -0400
++++ NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/Makefile.am 2012-03-30 16:36:15.714004274 -0400
+@@ -63,7 +63,9 @@
+ applet-device-bt.c \
+ applet-device-wimax.h \
+ applet-device-wimax.c \
+- fallback-icon.h
++ fallback-icon.h \
++ shell-watcher.h \
++ shell-watcher.c
+
+ nm_applet_LDADD = \
+ -lm \
+--- NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/applet.h.detect-shell 2012-03-30 16:35:53.160654931 -0400
++++ NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/applet.h 2012-03-30 16:36:15.716004572 -0400
+@@ -46,6 +46,7 @@
+ #include <nm-active-connection.h>
+ #include <nm-remote-settings.h>
+ #include "applet-agent.h"
++#include "shell-watcher.h"
+
+ #define NM_TYPE_APPLET (nma_get_type())
+ #define NM_APPLET(object) (G_TYPE_CHECK_INSTANCE_CAST((object), NM_TYPE_APPLET, NMApplet))
+@@ -85,10 +86,9 @@
+ DBusGConnection *session_bus;
+
+ #if GLIB_CHECK_VERSION(2,26,0)
+- GDBusProxy *shell_proxy;
++ NMShellWatcher *shell_watcher;
+ #endif
+ guint agent_start_id;
+- gdouble shell_version;
+
+ NMClient *nm_client;
+ NMRemoteSettings *settings;
+--- NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/shell-watcher.c.detect-shell 2012-03-30 16:36:02.363021262 -0400
++++ NetworkManager-0.9.4.0/network-manager-applet-0.9.4.0/src/shell-watcher.c 2012-03-30 16:36:15.717004721 -0400
+@@ -0,0 +1,242 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
++/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
++ *
++ * 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"
++
++#if GLIB_CHECK_VERSION(2,26,0)
++
++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;
++};
++
++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;
++ 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 = 0;
++ 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;
++}
++
++#endif /* GLIB_CHECK_VERSION(2,26,0) */
More information about the scm-commits
mailing list