[gnome-shell] layout: Add a fake root pixmap actor at startup, and fade it out



commit 5e12e5f42aa2eef5b7908250715def4f6fedc8cf
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Aug 22 04:22:30 2012 -0300

    layout: Add a fake root pixmap actor at startup, and fade it out
    
    This provides us with a smooth transition between plymouth and gdm.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=682428

 js/ui/layout.js    |   35 ++++++++++++++++++++++++++++++++++-
 src/shell-global.c |   40 ++++++++++++++++++++++++++++++++++++++++
 src/shell-global.h |    2 ++
 3 files changed, 76 insertions(+), 1 deletions(-)
---
diff --git a/js/ui/layout.js b/js/ui/layout.js
index 8244a86..9756813 100644
--- a/js/ui/layout.js
+++ b/js/ui/layout.js
@@ -17,6 +17,7 @@ const Tweener = imports.ui.tweener;
 const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
 const STARTUP_ANIMATION_TIME = 0.2;
 const KEYBOARD_ANIMATION_TIME = 0.5;
+const PLYMOUTH_TRANSITION_TIME = 1;
 
 const MonitorConstraint = new Lang.Class({
     Name: 'MonitorConstraint',
@@ -100,6 +101,7 @@ const LayoutManager = new Lang.Class({
         this.primaryMonitor = null;
         this.primaryIndex = -1;
         this._hotCorners = [];
+        this._rootPixmap = null;
         this._leftPanelBarrier = 0;
         this._rightPanelBarrier = 0;
         this._trayBarrier = 0;
@@ -319,10 +321,41 @@ const LayoutManager = new Lang.Class({
     },
 
     _startupAnimation: function() {
+        this.panelBox.anchor_y = this.panelBox.height;
+
+        let plymouthTransitionRunning = false;
+
+        // If we're the greeter, put up the xrootpmap actor
+        // and fade it out to have a nice transition from plymouth
+        // to the greeter. Otherwise, we'll just animate the panel,
+        // as usual.
+        if (Main.sessionMode.isGreeter) {
+            this._rootPixmap = global.create_xrootpmap_texture();
+            if (this._rootPixmap != null) {
+                Main.uiGroup.add_actor(this._rootPixmap);
+                Tweener.addTween(this._rootPixmap,
+                                 { opacity: 0,
+                                   time: PLYMOUTH_TRANSITION_TIME,
+                                   transition: 'linear',
+                                   onComplete: this._fadeRootpmapComplete,
+                                   onCompleteScope: this });
+                plymouthTransitionRunning = true;
+            }
+        }
+
+        if (!plymouthTransitionRunning)
+            this._fadeRootpmapComplete();
+    },
+
+    _fadeRootpmapComplete: function() {
         // Don't animate the strut
         this._chrome.freezeUpdateRegions();
 
-        this.panelBox.anchor_y = this.panelBox.height;
+        if (this._rootPixmap != null) {
+            this._rootPixmap.destroy();
+            this._rootPixmap = null;
+        }
+
         Tweener.addTween(this.panelBox,
                          { anchor_y: 0,
                            time: STARTUP_ANIMATION_TIME,
diff --git a/src/shell-global.c b/src/shell-global.c
index c95f078..d82885d 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -1693,3 +1693,43 @@ shell_global_get_session_mode (ShellGlobal *global)
 
   return global->session_mode;
 }
+
+/**
+ * shell_global_create_xrootpmap_texture:
+ * @global: The #ShellGlobal
+ *
+ * This returns the _XROOTPMAP_ID pixmap that gdm should have stuffed
+ * in the root window. The goal here is to allow a smooth fade between
+ * plymouth and the shell greeter. This is also a workaround for gjs not
+ * supporting raw xlib types.
+ *
+ * Returns: (transfer floating): A #ClutterActor that represents the
+ * _XROOTPMAP_ID pixmap property from the root window.
+ */
+ClutterActor *
+shell_global_create_xrootpmap_texture (ShellGlobal *global)
+{
+  Atom res_type;
+  int res_format;
+  unsigned long res_nitems, bytesafter;
+  unsigned char *data;
+  Pixmap root_pixmap_id = None;
+
+  g_return_val_if_fail (SHELL_IS_GLOBAL (global), NULL);
+
+  if (XGetWindowProperty (global->xdisplay,
+                          DefaultRootWindow (global->xdisplay),
+                          XInternAtom (global->xdisplay, "_XROOTPMAP_ID", False),
+                          0, G_MAXLONG, False, XA_PIXMAP,
+                          &res_type, &res_format, &res_nitems, &bytesafter, &data) == Success)
+    {
+      if (res_type == XA_PIXMAP && res_format == 32 && res_nitems == 1)
+        root_pixmap_id = * (Pixmap *) data;
+      XFree (data);
+    }
+
+  if (root_pixmap_id != None)
+    return clutter_x11_texture_pixmap_new_with_pixmap (root_pixmap_id);
+  else
+    return NULL;
+}
diff --git a/src/shell-global.h b/src/shell-global.h
index 95c18e0..693cb41 100644
--- a/src/shell-global.h
+++ b/src/shell-global.h
@@ -136,6 +136,8 @@ void     shell_global_reexec_self               (ShellGlobal  *global);
 
 const char *     shell_global_get_session_mode  (ShellGlobal  *global);
 
+ClutterActor * shell_global_create_xrootpmap_texture (ShellGlobal *global);
+
 G_END_DECLS
 
 #endif /* __SHELL_GLOBAL_H__ */



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