ScreenShield: account for motion velocity when hiding the lock screen

Switch from a ClutterDragAction to a ClutterGestureAction, that gives
us the velocity of mouse motion at each step, and use it to compute the
animation time for completing the hide gesture.

https://bugzilla.gnome.org/show_bug.cgi?id=682537
This commit is contained in:
Giovanni Campagna 2012-08-31 16:36:40 +02:00
parent 09b738045c
commit 797b1ff8bb

View File

@ -367,6 +367,10 @@ const Arrow = new Lang.Class({
} }
}); });
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
/** /**
* To test screen shield, make sure to kill gnome-screensaver. * To test screen shield, make sure to kill gnome-screensaver.
* *
@ -424,14 +428,11 @@ const ScreenShield = new Lang.Class({
} }
this._lockScreenContents.add_actor(this._arrowContainer); this._lockScreenContents.add_actor(this._arrowContainer);
let dragArea = new Clutter.Rect({ origin: new Clutter.Point({ x: 0, y: -global.screen_height, }), this._dragAction = new Clutter.GestureAction();
size: new Clutter.Size({ width: global.screen_width, this._dragAction.connect('gesture-begin', Lang.bind(this, this._onDragBegin));
height: global.screen_height }) }); this._dragAction.connect('gesture-progress', Lang.bind(this, this._onDragMotion));
let action = new Clutter.DragAction({ drag_axis: Clutter.DragAxis.Y_AXIS, this._dragAction.connect('gesture-end', Lang.bind(this, this._onDragEnd));
drag_area: dragArea }); this._lockScreenGroup.add_action(this._dragAction);
action.connect('drag-begin', Lang.bind(this, this._onDragBegin));
action.connect('drag-end', Lang.bind(this, this._onDragEnd));
this._lockScreenGroup.add_action(action);
this._lockDialogGroup = new St.Widget({ x_expand: true, this._lockDialogGroup = new St.Widget({ x_expand: true,
y_expand: true, y_expand: true,
@ -495,7 +496,7 @@ const ScreenShield = new Lang.Class({
symbol == Clutter.KEY_Return || symbol == Clutter.KEY_Return ||
symbol == Clutter.KEY_KP_Enter) { symbol == Clutter.KEY_KP_Enter) {
this._ensureUnlockDialog(true); this._ensureUnlockDialog(true);
this._hideLockScreen(true); this._hideLockScreen(true, 0);
return true; return true;
} }
@ -518,7 +519,7 @@ const ScreenShield = new Lang.Class({
// 7 standard scrolls to lift up // 7 standard scrolls to lift up
if (this._lockScreenScrollCounter > 35) { if (this._lockScreenScrollCounter > 35) {
this._ensureUnlockDialog(false); this._ensureUnlockDialog(false);
this._hideLockScreen(true); this._hideLockScreen(true, 0);
} }
return true; return true;
@ -550,12 +551,27 @@ const ScreenShield = new Lang.Class({
Tweener.removeTweens(this._lockScreenGroup); Tweener.removeTweens(this._lockScreenGroup);
this._lockScreenState = MessageTray.State.HIDING; this._lockScreenState = MessageTray.State.HIDING;
this._ensureUnlockDialog(false); this._ensureUnlockDialog(false);
return true;
},
_onDragMotion: function() {
let [origX, origY] = this._dragAction.get_press_coords(0);
let [currentX, currentY] = this._dragAction.get_motion_coords(0);
let newY = currentY - origY;
newY = clamp(newY, -global.stage.height, 0);
this._lockScreenGroup.y = newY;
return true;
}, },
_onDragEnd: function(action, actor, eventX, eventY, modifiers) { _onDragEnd: function(action, actor, eventX, eventY, modifiers) {
if (this._lockScreenGroup.y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) { if (this._lockScreenGroup.y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) {
// Complete motion automatically // Complete motion automatically
this._hideLockScreen(true); let [velocity, velocityX, velocityY] = this._dragAction.get_velocity(0);
this._hideLockScreen(true, -velocityY);
} else { } else {
// restore the lock screen to its original place // restore the lock screen to its original place
// try to use the same speed as the normal animation // try to use the same speed as the normal animation
@ -639,7 +655,7 @@ const ScreenShield = new Lang.Class({
this.actor.show(); this.actor.show();
this._isGreeter = Main.sessionMode.isGreeter; this._isGreeter = Main.sessionMode.isGreeter;
this._ensureUnlockDialog(true); this._ensureUnlockDialog(true);
this._hideLockScreen(false); this._hideLockScreen(false, 0);
}, },
_bumpLockScreen: function() { _bumpLockScreen: function() {
@ -657,14 +673,21 @@ const ScreenShield = new Lang.Class({
}); });
}, },
_hideLockScreen: function(animate) { _hideLockScreen: function(animate, velocity) {
this._lockScreenState = MessageTray.State.HIDING; this._lockScreenState = MessageTray.State.HIDING;
if (animate) { if (animate) {
// Tween the lock screen out of screen // Tween the lock screen out of screen
// try to use the same speed regardless of original position // if velocity is not specified (i.e. we come here from pressing ESC),
// use the same speed regardless of original position
// if velocity is specified, it's in pixels per milliseconds
let h = global.stage.height; let h = global.stage.height;
let time = CURTAIN_SLIDE_TIME * (h + this._lockScreenGroup.y) / h; let delta = (h + this._lockScreenGroup.y);
let min_velocity = global.stage.height / (CURTAIN_SLIDE_TIME * 1000);
velocity = Math.max(min_velocity, velocity);
let time = (delta / velocity) / 1000;
Tweener.removeTweens(this._lockScreenGroup); Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup, Tweener.addTween(this._lockScreenGroup,
{ y: -h, { y: -h,