|
|
efe155 |
From dc441b5d71f80e2b6dcdccbb4d6562c5b799294f Mon Sep 17 00:00:00 2001
|
|
|
efe155 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
efe155 |
Date: Mon, 28 Sep 2020 22:28:08 -0400
|
|
|
efe155 |
Subject: [PATCH 11/13] screenShield: Fix pointer motion signal handler leak
|
|
|
efe155 |
|
|
|
efe155 |
The screen shield code listens for motion events on the stage
|
|
|
efe155 |
so that it can hide the pointer until the user moves the mouse.
|
|
|
efe155 |
|
|
|
efe155 |
Unfortunately, if the user never moves the mouse, the signal
|
|
|
efe155 |
handler connection gets leaked.
|
|
|
efe155 |
|
|
|
efe155 |
This commit makes sure the connection gets disconnected when the
|
|
|
efe155 |
shield goes away.
|
|
|
efe155 |
---
|
|
|
efe155 |
js/ui/screenShield.js | 31 +++++++++++++++++++++----------
|
|
|
efe155 |
1 file changed, 21 insertions(+), 10 deletions(-)
|
|
|
efe155 |
|
|
|
efe155 |
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
|
|
|
efe155 |
index ebba6c82a..bbfceba57 100644
|
|
|
efe155 |
--- a/js/ui/screenShield.js
|
|
|
efe155 |
+++ b/js/ui/screenShield.js
|
|
|
efe155 |
@@ -905,91 +905,110 @@ var ScreenShield = new Lang.Class({
|
|
|
efe155 |
this._completeLockScreenShown();
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
showDialog() {
|
|
|
efe155 |
if (!this._becomeModal()) {
|
|
|
efe155 |
// In the login screen, this is a hard error. Fail-whale
|
|
|
efe155 |
log('Could not acquire modal grab for the login screen. Aborting login process.');
|
|
|
efe155 |
Meta.quit(Meta.ExitCode.ERROR);
|
|
|
efe155 |
}
|
|
|
efe155 |
|
|
|
efe155 |
this.actor.show();
|
|
|
efe155 |
this._isGreeter = Main.sessionMode.isGreeter;
|
|
|
efe155 |
this._isLocked = true;
|
|
|
efe155 |
if (this._ensureUnlockDialog(true, true))
|
|
|
efe155 |
this._hideLockScreen(false, 0);
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_hideLockScreenComplete() {
|
|
|
efe155 |
if (Main.sessionMode.currentMode == 'lock-screen')
|
|
|
efe155 |
Main.sessionMode.popMode('lock-screen');
|
|
|
efe155 |
|
|
|
efe155 |
this._lockScreenState = MessageTray.State.HIDDEN;
|
|
|
efe155 |
this._lockScreenGroup.hide();
|
|
|
efe155 |
|
|
|
efe155 |
if (this._dialog) {
|
|
|
efe155 |
this._dialog.actor.grab_key_focus();
|
|
|
efe155 |
this._dialog.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
|
|
efe155 |
}
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
+ _showPointer() {
|
|
|
efe155 |
+ this._cursorTracker.set_pointer_visible(true);
|
|
|
efe155 |
+
|
|
|
efe155 |
+ if (this._motionId) {
|
|
|
efe155 |
+ global.stage.disconnect(this._motionId);
|
|
|
efe155 |
+ this._motionId = 0;
|
|
|
efe155 |
+ }
|
|
|
efe155 |
+ },
|
|
|
efe155 |
+
|
|
|
efe155 |
+ _hidePointerUntilMotion() {
|
|
|
efe155 |
+ this._motionId = global.stage.connect('captured-event', (stage, event) => {
|
|
|
efe155 |
+ if (event.type() == Clutter.EventType.MOTION)
|
|
|
efe155 |
+ this._showPointer();
|
|
|
efe155 |
+
|
|
|
efe155 |
+ return Clutter.EVENT_PROPAGATE;
|
|
|
efe155 |
+ });
|
|
|
efe155 |
+ this._cursorTracker.set_pointer_visible(false);
|
|
|
efe155 |
+ },
|
|
|
efe155 |
+
|
|
|
efe155 |
_hideLockScreen(animate, velocity) {
|
|
|
efe155 |
if (this._lockScreenState == MessageTray.State.HIDDEN)
|
|
|
efe155 |
return;
|
|
|
efe155 |
|
|
|
efe155 |
this._lockScreenState = MessageTray.State.HIDING;
|
|
|
efe155 |
|
|
|
efe155 |
Tweener.removeTweens(this._lockScreenGroup);
|
|
|
efe155 |
|
|
|
efe155 |
if (animate) {
|
|
|
efe155 |
// Tween the lock screen out of screen
|
|
|
efe155 |
// if velocity is not specified (i.e. we come here from pressing ESC),
|
|
|
efe155 |
// use the same speed regardless of original position
|
|
|
efe155 |
// if velocity is specified, it's in pixels per milliseconds
|
|
|
efe155 |
let h = global.stage.height;
|
|
|
efe155 |
let delta = (h + this._lockScreenGroup.y);
|
|
|
efe155 |
let min_velocity = global.stage.height / (CURTAIN_SLIDE_TIME * 1000);
|
|
|
efe155 |
|
|
|
efe155 |
velocity = Math.max(min_velocity, velocity);
|
|
|
efe155 |
let time = (delta / velocity) / 1000;
|
|
|
efe155 |
|
|
|
efe155 |
Tweener.addTween(this._lockScreenGroup,
|
|
|
efe155 |
{ y: -h,
|
|
|
efe155 |
time: time,
|
|
|
efe155 |
transition: 'easeInQuad',
|
|
|
efe155 |
onComplete: this._hideLockScreenComplete.bind(this),
|
|
|
efe155 |
});
|
|
|
efe155 |
} else {
|
|
|
efe155 |
this._hideLockScreenComplete();
|
|
|
efe155 |
}
|
|
|
efe155 |
|
|
|
efe155 |
- this._cursorTracker.set_pointer_visible(true);
|
|
|
efe155 |
+ this._showPointer();
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_ensureUnlockDialog(onPrimary, allowCancel) {
|
|
|
efe155 |
if (!this._dialog) {
|
|
|
efe155 |
let constructor = Main.sessionMode.unlockDialog;
|
|
|
efe155 |
if (!constructor) {
|
|
|
efe155 |
// This session mode has no locking capabilities
|
|
|
efe155 |
this.deactivate(true);
|
|
|
efe155 |
return false;
|
|
|
efe155 |
}
|
|
|
efe155 |
|
|
|
efe155 |
this._dialog = new constructor(this._lockDialogGroup);
|
|
|
efe155 |
|
|
|
efe155 |
|
|
|
efe155 |
let time = global.get_current_time();
|
|
|
efe155 |
if (!this._dialog.open(time, onPrimary)) {
|
|
|
efe155 |
// This is kind of an impossible error: we're already modal
|
|
|
efe155 |
// by the time we reach this...
|
|
|
efe155 |
log('Could not open login dialog: failed to acquire grab');
|
|
|
efe155 |
this.deactivate(true);
|
|
|
efe155 |
return false;
|
|
|
efe155 |
}
|
|
|
efe155 |
|
|
|
efe155 |
this._dialog.connect('failed', this._onUnlockFailed.bind(this));
|
|
|
efe155 |
}
|
|
|
efe155 |
|
|
|
efe155 |
this._dialog.allowCancel = allowCancel;
|
|
|
efe155 |
return true;
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
@@ -1069,69 +1088,61 @@ var ScreenShield = new Lang.Class({
|
|
|
efe155 |
Mainloop.source_remove(this._arrowAnimationId);
|
|
|
efe155 |
this._arrowAnimationId = 0;
|
|
|
efe155 |
}
|
|
|
efe155 |
if (this._arrowActiveWatchId) {
|
|
|
efe155 |
this.idleMonitor.remove_watch(this._arrowActiveWatchId);
|
|
|
efe155 |
this._arrowActiveWatchId = 0;
|
|
|
efe155 |
}
|
|
|
efe155 |
if (this._arrowWatchId) {
|
|
|
efe155 |
this.idleMonitor.remove_watch(this._arrowWatchId);
|
|
|
efe155 |
this._arrowWatchId = 0;
|
|
|
efe155 |
}
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_checkArrowAnimation() {
|
|
|
efe155 |
let idleTime = this.idleMonitor.get_idletime();
|
|
|
efe155 |
|
|
|
efe155 |
if (idleTime < ARROW_IDLE_TIME)
|
|
|
efe155 |
this._startArrowAnimation();
|
|
|
efe155 |
else
|
|
|
efe155 |
this._pauseArrowAnimation();
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_lockScreenShown(params) {
|
|
|
efe155 |
if (this._dialog && !this._isGreeter) {
|
|
|
efe155 |
this._dialog.destroy();
|
|
|
efe155 |
this._dialog = null;
|
|
|
efe155 |
}
|
|
|
efe155 |
|
|
|
efe155 |
this._checkArrowAnimation();
|
|
|
efe155 |
|
|
|
efe155 |
- let motionId = global.stage.connect('captured-event', (stage, event) => {
|
|
|
efe155 |
- if (event.type() == Clutter.EventType.MOTION) {
|
|
|
efe155 |
- this._cursorTracker.set_pointer_visible(true);
|
|
|
efe155 |
- global.stage.disconnect(motionId);
|
|
|
efe155 |
- }
|
|
|
efe155 |
-
|
|
|
efe155 |
- return Clutter.EVENT_PROPAGATE;
|
|
|
efe155 |
- });
|
|
|
efe155 |
- this._cursorTracker.set_pointer_visible(false);
|
|
|
efe155 |
+ this._hidePointerUntilMotion();
|
|
|
efe155 |
|
|
|
efe155 |
this._lockScreenState = MessageTray.State.SHOWN;
|
|
|
efe155 |
this._lockScreenGroup.fixed_position_set = false;
|
|
|
efe155 |
this._lockScreenScrollCounter = 0;
|
|
|
efe155 |
|
|
|
efe155 |
if (params.fadeToBlack && params.animateFade) {
|
|
|
efe155 |
// Take a beat
|
|
|
efe155 |
|
|
|
efe155 |
let id = Mainloop.timeout_add(1000 * MANUAL_FADE_TIME, () => {
|
|
|
efe155 |
this._activateFade(this._shortLightbox, MANUAL_FADE_TIME);
|
|
|
efe155 |
return GLib.SOURCE_REMOVE;
|
|
|
efe155 |
});
|
|
|
efe155 |
GLib.Source.set_name_by_id(id, '[gnome-shell] this._activateFade');
|
|
|
efe155 |
} else {
|
|
|
efe155 |
if (params.fadeToBlack)
|
|
|
efe155 |
this._activateFade(this._shortLightbox, 0);
|
|
|
efe155 |
|
|
|
efe155 |
this._completeLockScreenShown();
|
|
|
efe155 |
}
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_completeLockScreenShown() {
|
|
|
efe155 |
this._setActive(true);
|
|
|
efe155 |
this.emit('lock-screen-shown');
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
// Some of the actors in the lock screen are heavy in
|
|
|
efe155 |
// resources, so we only create them when needed
|
|
|
efe155 |
_ensureLockScreen() {
|
|
|
efe155 |
if (this._hasLockScreen)
|
|
|
efe155 |
--
|
|
|
efe155 |
2.25.1
|
|
|
efe155 |
|