[gnome-desktop] GnomeRR: add async construction of GnomeRRScreen



commit eb34fd08196bdb75958087bfbf5e73ae8638465c
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sun Aug 18 01:14:04 2013 +0200

    GnomeRR: add async construction of GnomeRRScreen
    
    We aren't going anywhere, if gnome-settings-daemon blocks on
    mutter which is blocking on gnome-settings-daemon...
    
    https://bugzilla.gnome.org/show_bug.cgi?id=705510

 libgnome-desktop/gnome-rr-private.h |    1 +
 libgnome-desktop/gnome-rr.c         |  115 ++++++++++++++++++++++++++++++++++-
 libgnome-desktop/gnome-rr.h         |    5 ++
 3 files changed, 119 insertions(+), 2 deletions(-)
---
diff --git a/libgnome-desktop/gnome-rr-private.h b/libgnome-desktop/gnome-rr-private.h
index ea536f6..f7d1cd9 100644
--- a/libgnome-desktop/gnome-rr-private.h
+++ b/libgnome-desktop/gnome-rr-private.h
@@ -47,6 +47,7 @@ struct GnomeRRScreenPrivate
     GdkWindow *                        gdk_root;
     ScreenInfo *               info;
 
+    int                         init_name_watch_id;
     MetaDBusDisplayConfig      *proxy;
 };
 
diff --git a/libgnome-desktop/gnome-rr.c b/libgnome-desktop/gnome-rr.c
index 33c9451..d2cd561 100644
--- a/libgnome-desktop/gnome-rr.c
+++ b/libgnome-desktop/gnome-rr.c
@@ -141,8 +141,10 @@ static void gnome_rr_screen_set_property (GObject*, guint, const GValue*, GParam
 static void gnome_rr_screen_get_property (GObject*, guint, GValue*, GParamSpec*);
 static gboolean gnome_rr_screen_initable_init (GInitable*, GCancellable*, GError**);
 static void gnome_rr_screen_initable_iface_init (GInitableIface *iface);
+static void gnome_rr_screen_async_initable_init (GAsyncInitableIface *iface);
 G_DEFINE_TYPE_WITH_CODE (GnomeRRScreen, gnome_rr_screen, G_TYPE_OBJECT,
-        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gnome_rr_screen_initable_iface_init))
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gnome_rr_screen_initable_iface_init)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, gnome_rr_screen_async_initable_init))
 
 G_DEFINE_BOXED_TYPE (GnomeRRCrtc, gnome_rr_crtc, crtc_copy, crtc_free)
 G_DEFINE_BOXED_TYPE (GnomeRROutput, gnome_rr_output, output_copy, output_free)
@@ -570,12 +572,95 @@ gnome_rr_screen_initable_init (GInitable *initable, GCancellable *canc, GError *
     return TRUE;
 }
 
-void
+static void
+on_proxy_acquired (GObject      *object,
+                   GAsyncResult *result,
+                   gpointer      user_data)
+{
+    GTask *task = user_data;
+    GnomeRRScreen *self = g_task_get_source_object (task);
+    GnomeRRScreenPrivate *priv = self->priv;
+    MetaDBusDisplayConfig *proxy;
+    GError *error;
+
+    error = NULL;
+    proxy = meta_dbus_display_config_proxy_new_for_bus_finish (result, &error);
+    if (!proxy)
+       return g_task_return_error (task, error);
+
+    priv->proxy = META_DBUS_DISPLAY_CONFIG (proxy);
+
+    priv->info = screen_info_new (self, &error);
+    if (!priv->info)
+       return g_task_return_error (task, error);
+
+    g_signal_connect_object (priv->gdk_screen, "monitors-changed",
+                            G_CALLBACK (screen_on_monitors_changed), self, 0);
+    g_task_return_boolean (task, TRUE);
+}
+
+static void
+on_name_appeared (GDBusConnection *connection,
+                  const char      *name,
+                  const char      *name_owner,
+                  gpointer         user_data)
+{
+    GTask *task = user_data;
+    GnomeRRScreen *self = g_task_get_source_object (task);
+    GnomeRRScreenPrivate *priv = self->priv;
+
+    meta_dbus_display_config_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                                                G_DBUS_PROXY_FLAGS_NONE,
+                                                "org.gnome.Mutter.DisplayConfig",
+                                                "/org/gnome/Mutter/DisplayConfig",
+                                                g_task_get_cancellable (task),
+                                                on_proxy_acquired, g_object_ref (task));
+
+    g_bus_unwatch_name (priv->init_name_watch_id);
+}
+
+static void
+gnome_rr_screen_async_initable_init_async (GAsyncInitable      *initable,
+                                           int                  io_priority,
+                                           GCancellable        *canc,
+                                           GAsyncReadyCallback  callback,
+                                           gpointer             user_data)
+{
+    GnomeRRScreen *self = GNOME_RR_SCREEN (initable);
+    GnomeRRScreenPrivate *priv = self->priv;
+    GTask *task;
+
+    task = g_task_new (self, canc, callback, user_data);
+
+    priv->init_name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+                                                 "org.gnome.Mutter.DisplayConfig",
+                                                 G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                                 on_name_appeared,
+                                                 NULL,
+                                                 task, g_object_unref);
+}
+
+static gboolean
+gnome_rr_screen_async_initable_init_finish (GAsyncInitable    *initable,
+                                            GAsyncResult      *result,
+                                            GError           **error)
+{
+    return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
 gnome_rr_screen_initable_iface_init (GInitableIface *iface)
 {
     iface->init = gnome_rr_screen_initable_init;
 }
 
+static void
+gnome_rr_screen_async_initable_init (GAsyncInitableIface *iface)
+{
+    iface->init_async = gnome_rr_screen_async_initable_init_async;
+    iface->init_finish = gnome_rr_screen_async_initable_init_finish;
+}
+
 void
 gnome_rr_screen_finalize (GObject *gobject)
 {
@@ -767,6 +852,32 @@ gnome_rr_screen_new (GdkScreen *screen,
     return rr_screen;
 }
 
+void
+gnome_rr_screen_new_async (GdkScreen           *screen,
+                           GAsyncReadyCallback  callback,
+                           gpointer             user_data)
+{
+    g_return_if_fail (GDK_IS_SCREEN (screen));
+
+    g_async_initable_new_async (GNOME_TYPE_RR_SCREEN, G_PRIORITY_DEFAULT,
+                                NULL, callback, user_data,
+                                "gdk-screen", screen, NULL);
+}
+
+GnomeRRScreen *
+gnome_rr_screen_new_finish (GAsyncResult  *result,
+                            GError       **error)
+{
+    GObject *source_object;
+    GnomeRRScreen *screen;
+
+    source_object = g_async_result_get_source_object (result);
+    screen = GNOME_RR_SCREEN (g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error));
+
+    g_object_unref (source_object);
+    return screen;
+}
+
 /**
  * gnome_rr_screen_get_ranges:
  * @screen: a #GnomeRRScreen
diff --git a/libgnome-desktop/gnome-rr.h b/libgnome-desktop/gnome-rr.h
index bf7546f..15f1f4d 100644
--- a/libgnome-desktop/gnome-rr.h
+++ b/libgnome-desktop/gnome-rr.h
@@ -107,6 +107,11 @@ GType gnome_rr_mode_get_type (void);
 /* GnomeRRScreen */
 GnomeRRScreen * gnome_rr_screen_new                (GdkScreen             *screen,
                                                    GError               **error);
+void            gnome_rr_screen_new_async          (GdkScreen             *screen,
+                                                    GAsyncReadyCallback    callback,
+                                                    gpointer               user_data);
+GnomeRRScreen * gnome_rr_screen_new_finish         (GAsyncResult          *result,
+                                                    GError               **error);
 GnomeRROutput **gnome_rr_screen_list_outputs       (GnomeRRScreen         *screen);
 GnomeRRCrtc **  gnome_rr_screen_list_crtcs         (GnomeRRScreen         *screen);
 GnomeRRMode **  gnome_rr_screen_list_modes         (GnomeRRScreen         *screen);


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