summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2012-12-24 15:46:21 +0100
committerGiovanni Campagna <gcampagna@src.gnome.org>2013-02-05 00:11:19 +0100
commit3e79d293f7d44a24d44f8d504f395531bcc766ac (patch)
treeb3a06408d8ea3370d83289c5bf0c95f9be1992dc
parentd457073c10c90d31b879fe814cb5dddfa7a8762f (diff)
downloadgnome-shell-wip/gcampax/background.tar.gz
LayoutManager: implement new design for the startup animationwip/gcampax/background
The design calls for two different startup animations, in the GDM and in the normal session case. In both cases, we implement fading from the previous situation by acquiring the root background pixmap and turning it into a TFP texture, which is then animated and blended by Clutter as normal. https://bugzilla.gnome.org/show_bug.cgi?id=682429
-rw-r--r--js/ui/layout.js104
-rw-r--r--js/ui/main.js8
2 files changed, 103 insertions, 9 deletions
diff --git a/js/ui/layout.js b/js/ui/layout.js
index 53ea4bdf0..18200ed5f 100644
--- a/js/ui/layout.js
+++ b/js/ui/layout.js
@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
+const ClutterX11 = imports.gi.ClutterX11;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
@@ -15,9 +16,8 @@ const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
-const STARTUP_ANIMATION_TIME = 0.2;
+const STARTUP_ANIMATION_TIME = 1;
const KEYBOARD_ANIMATION_TIME = 0.15;
-const PLYMOUTH_TRANSITION_TIME = 1;
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
const MonitorConstraint = new Lang.Class({
@@ -171,7 +171,7 @@ const LayoutManager = new Lang.Class({
Lang.bind(this, this._panelBoxChanged));
this.trayBox = new St.Widget({ name: 'trayBox',
- layout_manager: new Clutter.BinLayout() });
+ layout_manager: new Clutter.BinLayout() });
this.addChrome(this.trayBox);
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
@@ -197,7 +197,8 @@ const LayoutManager = new Lang.Class({
Main.overview.connect('showing', Lang.bind(this, this._overviewShowing));
Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden));
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
- this._startupAnimation();
+
+ this._prepareStartupAnimation();
},
_overviewShowing: function() {
@@ -412,21 +413,106 @@ const LayoutManager = new Lang.Class({
return this._keyboardIndex;
},
- _startupAnimation: function() {
- this.panelBox.translation_y = -this.panelBox.height;
+ _acquireRootBackground: function() {
+ let rootpmap = Shell.util_get_root_background();
+ let texture = ClutterX11.TexturePixmap.new_with_pixmap(rootpmap);
+ // The texture size might not match the screen size, for example
+ // if the session has a different XRandR configuration than the greeter
+ texture.x = 0;
+ texture.y = 0;
+ texture.width = global.screen_width;
+ texture.height = global.screen_height;
+ texture.set_automatic(true);
+
+ this._rootTexture = texture;
+ },
+
+ // Startup Animations
+ //
+ // We have two different animations, depending on whether we're a greeter
+ // or a normal session.
+ //
+ // In the greeter, we want to animate the panel from the top, and smoothly
+ // fade the login dialog on top of whatever plymouth left on screen, which we
+ // grab as a X11 texture_from_pixmap.
+ // Here we just have the code to animate the panel, the login dialog animation
+ // is handled by modalDialog.js
+ //
+ // In a normal session, we want to take the root background, which now holds
+ // the final frame of the GDM greeter, and slide it from the bottom, while
+ // at the same time scaling the UI contents of the new shell on top of the
+ // stage background.
+ //
+ // Usually, we don't want to paint the stage background color because the
+ // MetaBackgroundActor inside global.window_group covers the entirety of the
+ // screen. So, we set no_clear_hint at the end of the animation.
+
+ _prepareStartupAnimation: function() {
+ // Set ourselves to FULLSCREEN input mode while the animation is running
+ // so events don't get delivered to X11 windows (which are distorted by the animation)
+ global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
+
+ this._acquireRootBackground();
+ if (Main.sessionMode.isGreeter) {
+ global.stage.insert_child_below(this._rootTexture, null);
+
+ this._panelBox.translation_y = -this._panelBox.height;
+ } else {
+ global.stage.insert_child_above(this._rootTexture, null);
+
+ this.uiGroup.set_pivot_point(0.5, 0.5);
+ this.uiGroup.scale_x = this.uiGroup.scale_y = 0;
+ }
+ },
+
+ startupAnimation: function() {
+ if (Main.sessionMode.isGreeter)
+ this._startupAnimationGreeter();
+ else
+ this._startupAnimationSession();
+ },
+
+ _startupAnimationGreeter: function() {
+ // Don't animate the strut
this._freezeUpdateRegions();
- Tweener.addTween(this.panelBox,
+ Tweener.addTween(this._panelBox,
{ translation_y: 0,
time: STARTUP_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: this._startupAnimationComplete,
- onCompleteScope: this
- });
+ onCompleteScope: this });
+ },
+
+ _startupAnimationSession: function() {
+ // Don't animate the strut
+ this._freezeUpdateRegions();
+
+ Tweener.addTween(this._rootTexture,
+ { translation_y: -global.screen_height,
+ time: STARTUP_ANIMATION_TIME,
+ transition: 'linear' });
+
+ Tweener.addTween(this.uiGroup,
+ { scale_x: 1,
+ scale_y: 1,
+ time: STARTUP_ANIMATION_TIME,
+ transition: 'easeOutQuad',
+ onComplete: this._startupAnimationComplete,
+ onCompleteScope: this });
},
_startupAnimationComplete: function() {
+ // At this point, the UI group is covering everything, so
+ // we no longer need to clear the stage
+ global.stage.no_clear_hint = true;
+
+ global.stage_input_mode = Shell.StageInputMode.NORMAL;
+
+ this._rootTexture.destroy();
+ this._rootTexture = null;
+
this.emit('panel-box-changed');
this._thawUpdateRegions();
},
diff --git a/js/ui/main.js b/js/ui/main.js
index a5d35e3d5..e79ba603e 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -175,6 +175,14 @@ function start() {
ExtensionDownloader.init();
ExtensionSystem.init();
+
+ // Run the startup animation as soon as the mainloop is idle enough
+ // This is necessary to have it smooth and without interruptions from
+ // completed IO tasks
+ GLib.idle_add(GLib.PRIORITY_LOW, function() {
+ layoutManager.startupAnimation();
+ return false;
+ });
}
let _workspaces = [];