[gnome-settings-daemon] remote-display: Merge plugin into XSettings



commit 6486696fb16140e3344564a28a75bd92ded5e9ea
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Aug 8 18:41:16 2013 +0200

    remote-display: Merge plugin into XSettings
    
    We merge the remote display object into XSettings, so that
    we can override the enable-animations settings without modifying
    GSettings. This was especially problematic on startup, or when
    overriding user settings.
    
    UNTESTED
    
    https://bugzilla.gnome.org/show_bug.cgi?id=694692

 configure.ac                                       |    1 -
 ...gnome.settings-daemon.plugins.gschema.xml.in.in |   13 -
 plugins/Makefile.am                                |    1 -
 plugins/remote-display/Makefile.am                 |   62 ----
 .../remote-display/gsd-remote-display-manager.c    |  284 ------------------
 .../remote-display/gsd-remote-display-manager.h    |   57 ----
 plugins/remote-display/gsd-remote-display-plugin.c |   33 --
 .../remote-display.gnome-settings-plugin.in        |    9 -
 plugins/remote-display/test-remote-display.c       |    7 -
 plugins/xsettings/Makefile.am                      |    2 +
 plugins/xsettings/gsd-remote-display-manager.c     |  308 ++++++++++++++++++++
 plugins/xsettings/gsd-remote-display-manager.h     |   37 +++
 plugins/xsettings/gsd-xsettings-manager.c          |   36 +++-
 po/POTFILES.in                                     |    1 -
 14 files changed, 382 insertions(+), 469 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 8a8c211..2f7c5e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -540,7 +540,6 @@ plugins/media-keys/gvc/Makefile
 plugins/mouse/Makefile
 plugins/orientation/Makefile
 plugins/print-notifications/Makefile
-plugins/remote-display/Makefile
 plugins/rfkill/Makefile
 plugins/screensaver-proxy/Makefile
 plugins/smartcard/Makefile
diff --git a/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in 
b/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in
index 57a058d..65682df 100644
--- a/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in
@@ -23,7 +23,6 @@
     <child name="orientation" schema="org.gnome.settings-daemon.plugins.orientation"/>
     <child name="power" schema="org.gnome.settings-daemon.plugins.power"/>
     <child name="print-notifications" schema="org.gnome.settings-daemon.plugins.print-notifications"/>
-    <child name="remote-display" schema="org.gnome.settings-daemon.plugins.remote-display"/>
     <child name="screensaver-proxy" schema="org.gnome.settings-daemon.plugins.screensaver-proxy"/>
     <child name="smartcard" schema="org.gnome.settings-daemon.plugins.smartcard"/>
     <child name="sound" schema="org.gnome.settings-daemon.plugins.sound"/>
@@ -91,18 +90,6 @@
       <_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
     </key>
   </schema>
-  <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.remote-display" 
path="/org/gnome/settings-daemon/plugins/remote-display/">
-    <key name="active" type="b">
-      <default>true</default>
-      <_summary>Activation of this plugin</_summary>
-      <_description>Whether this plugin would be activated by gnome-settings-daemon or not</_description>
-    </key>
-    <key name="priority" type="i">
-      <default>0</default>
-      <_summary>Priority to use for this plugin</_summary>
-      <_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
-    </key>
-  </schema>
   <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.rfkill" 
path="/org/gnome/settings-daemon/plugins/rfkill/">
     <key name="active" type="b">
       <default>true</default>
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 2f4840d..04f8e2a 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -13,7 +13,6 @@ enabled_plugins =     \
        keyboard        \
        media-keys      \
        mouse           \
-       remote-display  \
        screensaver-proxy \
        sound           \
        xrandr          \
diff --git a/plugins/xsettings/Makefile.am b/plugins/xsettings/Makefile.am
index 467fc85..c20de6f 100644
--- a/plugins/xsettings/Makefile.am
+++ b/plugins/xsettings/Makefile.am
@@ -40,6 +40,8 @@ gsd_test_xsettings_SOURCES =  \
        xsettings-manager.h     \
        fontconfig-monitor.c    \
        fontconfig-monitor.h    \
+       gsd-remote-display-manager.c \
+       gsd-remote-display-manager.h \
        test-xsettings.c
 
 gsd_test_xsettings_CFLAGS = $(test_gtk_modules_CFLAGS)
diff --git a/plugins/xsettings/gsd-remote-display-manager.c b/plugins/xsettings/gsd-remote-display-manager.c
new file mode 100644
index 0000000..c876c4a
--- /dev/null
+++ b/plugins/xsettings/gsd-remote-display-manager.c
@@ -0,0 +1,308 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Bastien Nocera <hadess hadess net>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include </usr/include/X11/Xatom.h>
+
+#include "gnome-settings-bus.h"
+#include "gnome-settings-profile.h"
+#include "gsd-remote-display-manager.h"
+
+#define GSD_REMOTE_DISPLAY_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), 
GSD_TYPE_REMOTE_DISPLAY_MANAGER, GsdRemoteDisplayManagerPrivate))
+
+enum
+{
+    PROP_0,
+    PROP_FORCE_DISABLE_ANIMATIONS
+};
+
+typedef struct GsdRemoteDisplayManagerPrivate GsdRemoteDisplayManagerPrivate;
+
+struct GsdRemoteDisplayManagerClass {
+        GObjectClass parent_class;
+};
+
+struct GsdRemoteDisplayManager {
+        GObject parent;
+        GsdRemoteDisplayManagerPrivate *priv;
+};
+
+struct GsdRemoteDisplayManagerPrivate
+{
+        /* Proxy for the force-disable-animations property */
+        gboolean      disabled;
+
+        GDBusProxy   *vino_proxy;
+        GCancellable *cancellable;
+        guint         vino_watch_id;
+        gboolean      vnc_in_use;
+};
+
+static void     gsd_remote_display_manager_class_init  (GsdRemoteDisplayManagerClass *klass);
+static void     gsd_remote_display_manager_init        (GsdRemoteDisplayManager      
*remote_display_manager);
+
+G_DEFINE_TYPE (GsdRemoteDisplayManager, gsd_remote_display_manager, G_TYPE_OBJECT)
+
+static void
+update_property_from_variant (GsdRemoteDisplayManager *manager,
+                              GVariant                *variant)
+{
+        manager->priv->vnc_in_use = g_variant_get_boolean (variant);
+
+        g_debug ("%s because of remote display status (vnc: %d)",
+                 !manager->priv->vnc_in_use ? "Enabling" : "Disabling",
+                 manager->priv->vnc_in_use);
+        manager->priv->disabled = !manager->priv->vnc_in_use;
+        g_object_notify (G_OBJECT (manager), "force-disable-animations");
+}
+
+static void
+props_changed (GDBusProxy              *proxy,
+               GVariant                *changed_properties,
+               GStrv                    invalidated_properties,
+               GsdRemoteDisplayManager *manager)
+{
+        GVariant *v;
+
+        v = g_variant_lookup_value (changed_properties, "Connected", G_VARIANT_TYPE_BOOLEAN);
+        if (v) {
+                g_debug ("Received connected change");
+                update_property_from_variant (manager, v);
+                g_variant_unref (v);
+        }
+}
+
+static void
+got_vino_proxy (GObject                 *source_object,
+                GAsyncResult            *res,
+                GsdRemoteDisplayManager *manager)
+{
+        GError *error = NULL;
+        GVariant *v;
+
+        manager->priv->vino_proxy = g_dbus_proxy_new_finish (res, &error);
+        if (manager->priv->vino_proxy == NULL) {
+                g_warning ("Failed to get Vino's D-Bus proxy: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+
+        g_signal_connect (manager->priv->vino_proxy, "g-properties-changed",
+                          G_CALLBACK (props_changed), manager);
+
+        v = g_dbus_proxy_get_cached_property (manager->priv->vino_proxy, "Connected");
+        if (v) {
+                g_debug ("Setting original state");
+                update_property_from_variant (manager, v);
+                g_variant_unref (v);
+        }
+}
+
+static void
+vino_appeared_cb (GDBusConnection         *connection,
+                  const gchar             *name,
+                  const gchar             *name_owner,
+                  GsdRemoteDisplayManager *manager)
+{
+        g_debug ("Vino appeared");
+        g_dbus_proxy_new (connection,
+                          G_DBUS_PROXY_FLAGS_NONE,
+                          NULL,
+                          name,
+                          "/org/gnome/vino/screens/0",
+                          "org.gnome.VinoScreen",
+                          manager->priv->cancellable,
+                          (GAsyncReadyCallback) got_vino_proxy,
+                          manager);
+}
+
+static void
+vino_vanished_cb (GDBusConnection         *connection,
+                  const char              *name,
+                  GsdRemoteDisplayManager *manager)
+{
+        g_debug ("Vino vanished");
+        if (manager->priv->cancellable != NULL) {
+                g_cancellable_cancel (manager->priv->cancellable);
+                g_clear_object (&manager->priv->cancellable);
+        }
+        g_clear_object (&manager->priv->vino_proxy);
+
+        /* And reset for us to have animations */
+        manager->priv->disabled = FALSE;
+        g_object_notify (G_OBJECT (manager), "force-disable-animations");
+}
+
+static gboolean
+gsd_display_has_extension (const gchar *ext)
+{
+        int op, event, error;
+
+        return XQueryExtension (gdk_x11_get_default_xdisplay (),
+                                ext, &op, &event, &error);
+}
+
+static gboolean
+gsd_display_has_llvmpipe (void)
+{
+        glong is_software_rendering_atom;
+        Atom type;
+        gint format;
+        gulong nitems;
+        gulong bytes_after;
+        guchar *data;
+        GdkDisplay *display;
+
+        display = gdk_display_get_default ();
+        is_software_rendering_atom = gdk_x11_get_xatom_by_name_for_display (display, 
"_GNOME_IS_SOFTWARE_RENDERING");
+        gdk_x11_display_error_trap_push (display);
+        XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),  gdk_x11_get_default_root_xwindow (),
+                            is_software_rendering_atom,
+                            0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems,
+                            &bytes_after, &data);
+        gdk_x11_display_error_trap_pop_ignored (display);
+
+        if (type == XA_CARDINAL) {
+               glong *is_accelerated_ptr = (glong*) data;
+
+               return (*is_accelerated_ptr == 1);
+        }
+
+        return FALSE;
+}
+
+static void
+gsd_remote_display_manager_get_property (GObject    *object,
+                                         guint       prop_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+        GsdRemoteDisplayManager *manager;
+
+        manager = GSD_REMOTE_DISPLAY_MANAGER (object);
+
+        switch (prop_id) {
+        case PROP_FORCE_DISABLE_ANIMATIONS:
+                g_value_set_boolean (value, manager->priv->disabled);
+                break;
+
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gsd_remote_display_manager_panel_finalize (GObject *object)
+{
+        GsdRemoteDisplayManager *manager = GSD_REMOTE_DISPLAY_MANAGER (object);
+        g_debug ("Stopping remote_display manager");
+
+        if (manager->priv->cancellable != NULL) {
+                g_cancellable_cancel (manager->priv->cancellable);
+                g_clear_object (&manager->priv->cancellable);
+        }
+        g_clear_object (&manager->priv->vino_proxy);
+}
+
+static void
+gsd_remote_display_manager_class_init (GsdRemoteDisplayManagerClass *klass)
+{
+        GObjectClass    *object_class = G_OBJECT_CLASS (klass);
+        GParamSpec      *pspec;
+
+        g_type_class_add_private (klass, sizeof (GsdRemoteDisplayManagerPrivate));
+
+        object_class->get_property = gsd_remote_display_manager_get_property;
+        object_class->finalize = gsd_remote_display_manager_panel_finalize;
+
+        pspec = g_param_spec_boolean ("force-disable-animations",
+                                      "Force disable animations",
+                                      "Force disable animations",
+                                      FALSE,
+                                      G_PARAM_READABLE);
+        g_object_class_install_property (object_class, PROP_FORCE_DISABLE_ANIMATIONS, pspec);
+}
+
+static void
+gsd_remote_display_manager_init (GsdRemoteDisplayManager *manager)
+{
+
+        manager->priv = GSD_REMOTE_DISPLAY_MANAGER_GET_PRIVATE (manager);
+
+        g_debug ("Starting remote-display manager");
+
+        /* Check if spice is used:
+         * https://bugzilla.gnome.org/show_bug.cgi?id=680195#c7
+         * This doesn't change at run-time, so it's to the point */
+        if (g_file_test ("/dev/virtio-ports/com.redhat.spice.0", G_FILE_TEST_EXISTS)) {
+                g_debug ("Disabling animations because SPICE is in use");
+                manager->priv->disabled = TRUE;
+                g_object_notify (G_OBJECT (manager), "force-disable-animations");
+                return;
+        }
+
+        /* Xvnc exposes an extension named VNC-EXTENSION */
+        if (gsd_display_has_extension ("VNC-EXTENSION")) {
+                g_debug ("Disabling animations because VNC-EXTENSION was detected");
+                manager->priv->disabled = TRUE;
+                g_object_notify (G_OBJECT (manager), "force-disable-animations");
+                return;
+        }
+
+       /* disable animations if running under llvmpipe */
+       if (gsd_display_has_llvmpipe ()) {
+               g_debug ("Disabling animations because llvmpipe was detected");
+               manager->priv->disabled = TRUE;
+               g_object_notify (G_OBJECT (manager), "force-disable-animations");
+               return;
+       }
+
+        /* Monitor Vino's usage */
+        manager->priv->vino_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+                                                         "org.gnome.Vino",
+                                                         G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                                         (GBusNameAppearedCallback) vino_appeared_cb,
+                                                         (GBusNameVanishedCallback) vino_vanished_cb,
+                                                         manager, NULL);
+
+
+}
+
+GsdRemoteDisplayManager *
+gsd_remote_display_manager_new (void)
+{
+        return GSD_REMOTE_DISPLAY_MANAGER (g_object_new (GSD_TYPE_REMOTE_DISPLAY_MANAGER, NULL));
+}
diff --git a/plugins/xsettings/gsd-remote-display-manager.h b/plugins/xsettings/gsd-remote-display-manager.h
new file mode 100644
index 0000000..4821a48
--- /dev/null
+++ b/plugins/xsettings/gsd-remote-display-manager.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Bastien Nocera <hadess hadess net>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+
+#define GSD_TYPE_REMOTE_DISPLAY_MANAGER            (gsd_remote_display_manager_get_type ())
+#define GSD_REMOTE_DISPLAY_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GSD_TYPE_REMOTE_DISPLAY_MANAGER, GsdRemoteDisplayManager))
+#define GSD_IS_REMOTE_DISPLAY_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GSD_TYPE_REMOTE_DISPLAY_MANAGER))
+#define GSD_REMOTE_DISPLAY_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), 
GSD_TYPE_REMOTE_DISPLAY_MANAGER, GsdRemoteDisplayManagerClass))
+#define GSD_IS_REMOTE_DISPLAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GSD_TYPE_REMOTE_DISPLAY_MANAGER))
+#define GSD_REMOTE_DISPLAY_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GSD_TYPE_REMOTE_DISPLAY_MANAGER, GsdRemoteDisplayManagerClass))
+
+typedef struct GsdRemoteDisplayManager GsdRemoteDisplayManager;
+typedef struct GsdRemoteDisplayManagerClass GsdRemoteDisplayManagerClass;
+
+GType gsd_remote_display_manager_get_type (void) G_GNUC_CONST;
+
+GsdRemoteDisplayManager * gsd_remote_display_manager_new (void);
diff --git a/plugins/xsettings/gsd-xsettings-manager.c b/plugins/xsettings/gsd-xsettings-manager.c
index 933228c..03dcb6a 100644
--- a/plugins/xsettings/gsd-xsettings-manager.c
+++ b/plugins/xsettings/gsd-xsettings-manager.c
@@ -44,6 +44,7 @@
 #include "gsd-xsettings-gtk.h"
 #include "xsettings-manager.h"
 #include "fontconfig-monitor.h"
+#include "gsd-remote-display-manager.h"
 
 #define GNOME_XSETTINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), 
GNOME_TYPE_XSETTINGS_MANAGER, GnomeXSettingsManagerPrivate))
 
@@ -254,6 +255,8 @@ struct GnomeXSettingsManagerPrivate
 
         GsdXSettingsGtk   *gtk;
 
+        GsdRemoteDisplayManager *remote_display;
+
         guint              shell_name_watch_id;
         gboolean           have_shell;
 
@@ -373,7 +376,6 @@ static TranslationEntry translations [] = {
         { "org.gnome.desktop.interface", "gtk-im-module",          "Gtk/IMModule",            
translate_string_string },
         { "org.gnome.desktop.interface", "icon-theme",             "Net/IconThemeName",       
translate_string_string },
         { "org.gnome.desktop.interface", "menubar-accel",          "Gtk/MenuBarAccel",        
translate_string_string },
-        { "org.gnome.desktop.interface", "enable-animations",      "Gtk/EnableAnimations",    
translate_bool_int },
         { "org.gnome.desktop.interface", "cursor-theme",           "Gtk/CursorThemeName",     
translate_string_string },
         /* cursor-size is handled via the Xft side as it needs the scaling factor */
 
@@ -941,6 +943,29 @@ start_shell_monitor (GnomeXSettingsManager *manager)
                                                                NULL);
 }
 
+static void
+force_disable_animation_changed (GObject    *gobject,
+                                 GParamSpec *pspec,
+                                 GnomeXSettingsManager *manager)
+{
+        gboolean force_disable, value;
+        int i;
+
+        g_object_get (gobject, "force-disable-animations", &force_disable, NULL);
+        if (force_disable)
+                value = FALSE;
+        else {
+                GSettings *settings;
+
+                settings = g_hash_table_lookup (manager->priv->settings, "org.gnome.desktop.interface");
+                value = g_settings_get_boolean (settings, "enable-animations");
+        }
+
+        for (i = 0; manager->priv->managers [i]; i++) {
+                xsettings_manager_set_int (manager->priv->managers [i], "Gtk/EnableAnimations", value);
+        }
+}
+
 gboolean
 gnome_xsettings_manager_start (GnomeXSettingsManager *manager,
                                GError               **error)
@@ -959,6 +984,10 @@ gnome_xsettings_manager_start (GnomeXSettingsManager *manager,
                 return FALSE;
         }
 
+        manager->priv->remote_display = gsd_remote_display_manager_new ();
+        g_signal_connect (G_OBJECT (manager->priv->remote_display), "notify::force-disable-animations",
+                          G_CALLBACK (force_disable_animation_changed), manager);
+
         manager->priv->settings = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                          NULL, (GDestroyNotify) g_object_unref);
 
@@ -1008,6 +1037,9 @@ gnome_xsettings_manager_start (GnomeXSettingsManager *manager,
                           G_CALLBACK (gtk_modules_callback), manager);
         gtk_modules_callback (manager->priv->gtk, NULL, manager);
 
+        /* Animation settings */
+        force_disable_animation_changed (G_OBJECT (manager->priv->remote_display), NULL, manager);
+
         /* Xft settings */
         update_xft_settings (manager);
 
@@ -1041,6 +1073,8 @@ gnome_xsettings_manager_stop (GnomeXSettingsManager *manager)
 
         g_debug ("Stopping xsettings manager");
 
+        g_clear_object (&manager->priv->remote_display);
+
         if (p->managers != NULL) {
                 for (i = 0; p->managers [i]; ++i)
                         xsettings_manager_destroy (p->managers [i]);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d36823d..878d5c1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -48,7 +48,6 @@ plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in
 plugins/print-notifications/gsd-printer.c
 plugins/print-notifications/gsd-print-notifications-manager.c
 [type: gettext/ini]plugins/print-notifications/print-notifications.gnome-settings-plugin.in
-[type: gettext/ini]plugins/remote-display/remote-display.gnome-settings-plugin.in
 [type: gettext/ini]plugins/rfkill/rfkill.gnome-settings-plugin.in
 [type: gettext/ini]plugins/screensaver-proxy/screensaver-proxy.gnome-settings-plugin.in
 plugins/smartcard/gsd-smartcard-manager.c


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