Try to do more async initialization

Synchronous calls in the main loop are a performance killer, especially
at login.
This commit is contained in:
Giovanni Campagna 2012-10-26 19:19:03 +02:00
parent a6b4d68a1d
commit afcc1b7b52
11 changed files with 273 additions and 64 deletions

View File

@ -35,7 +35,13 @@ const PowerMenuButton = new Lang.Class({
/* Translators: accessible name of the power menu in the login screen */ /* Translators: accessible name of the power menu in the login screen */
this.parent('system-shutdown-symbolic', _("Power")); this.parent('system-shutdown-symbolic', _("Power"));
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginManager = manager;
this._updateHaveShutdown();
this._updateHaveRestart();
this._updateHaveSuspend();
}));
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed::disable-restart-buttons', this._settings.connect('changed::disable-restart-buttons',
@ -64,6 +70,12 @@ const PowerMenuButton = new Lang.Class({
}, },
_updateHaveShutdown: function() { _updateHaveShutdown: function() {
if (!this._loginManager) {
this._haveShutdown = false;
this._powerOffItem.actor.visible = false;
return;
}
this._loginManager.canPowerOff(Lang.bind(this, function(result) { this._loginManager.canPowerOff(Lang.bind(this, function(result) {
this._haveShutdown = result; this._haveShutdown = result;
this._powerOffItem.actor.visible = this._haveShutdown; this._powerOffItem.actor.visible = this._haveShutdown;
@ -72,6 +84,12 @@ const PowerMenuButton = new Lang.Class({
}, },
_updateHaveRestart: function() { _updateHaveRestart: function() {
if (!this._loginManager) {
this._haveRestart = false;
this._restartItem.actor.visible = false;
return;
}
this._loginManager.canReboot(Lang.bind(this, function(result) { this._loginManager.canReboot(Lang.bind(this, function(result) {
this._haveRestart = result; this._haveRestart = result;
this._restartItem.actor.visible = this._haveRestart; this._restartItem.actor.visible = this._haveRestart;
@ -80,6 +98,12 @@ const PowerMenuButton = new Lang.Class({
}, },
_updateHaveSuspend: function() { _updateHaveSuspend: function() {
if (!this._loginManager) {
this._haveSuspend = false;
this._suspendItem.actor.visible = false;
return;
}
this._loginManager.canSuspend(Lang.bind(this, function(result) { this._loginManager.canSuspend(Lang.bind(this, function(result) {
this._haveSuspend = result; this._haveSuspend = result;
this._suspendItem.actor.visible = this._haveSuspend; this._suspendItem.actor.visible = this._haveSuspend;

View File

@ -86,7 +86,6 @@ const Manager = new Lang.Class({
_init: function(parentActor) { _init: function(parentActor) {
this._aggregateProvider = new Provider(); this._aggregateProvider = new Provider();
this._aggregateProvider.init(null);
this._realms = {}; this._realms = {};
this._aggregateProvider.connect('g-properties-changed', this._aggregateProvider.connect('g-properties-changed',
@ -94,6 +93,16 @@ const Manager = new Lang.Class({
if ('Realms' in properties.deep_unpack()) if ('Realms' in properties.deep_unpack())
this._reloadRealms(); this._reloadRealms();
})); }));
this._aggregateProvider.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
} catch(e) {
return;
}
this._reloadRealms();
}));
}, },
_reloadRealms: function() { _reloadRealms: function() {

View File

@ -2,6 +2,7 @@
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang; const Lang = imports.lang;
const Mainloop = imports.mainloop; const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
@ -105,41 +106,102 @@ function haveSystemd() {
} }
let _loginManager = null; let _loginManager = null;
let _pendingAsyncCallbacks = [];
/** /**
* LoginManager: * LoginManager:
* An abstraction over systemd/logind and ConsoleKit. * An abstraction over systemd/logind and ConsoleKit.
* *
*/ */
function getLoginManager() { function getLoginManager(asyncCallback) {
if (_loginManager == null) { if (_loginManager == null) {
if (haveSystemd()) if (_pendingAsyncCallbacks.length == 0) {
_loginManager = new LoginManagerSystemd(); let manager;
else
_loginManager = new LoginManagerConsoleKit();
}
return _loginManager; if (haveSystemd())
manager = new LoginManagerSystemd();
else
manager = new LoginManagerConsoleKit();
manager.initAsync(null, function(obj, result) {
obj.initFinish(result);
_loginManager = manager;
_pendingAsyncCallbacks.forEach(function (f) { f(obj) });
_pendingAsyncCallbacks = [];
});
_pendingAsyncCallbacks = [asyncCallback];
} else {
_pendingAsyncCallbacks.push(asyncCallback);
}
} else {
GLib.idle_add(GLib.PRIORITY_DEFAULT, function() {
asyncCallback(_loginManager);
});
}
} }
const LoginManagerSystemd = new Lang.Class({ const LoginManagerSystemd = new Lang.Class({
Name: 'LoginManagerSystemd', Name: 'LoginManagerSystemd',
Extends: GObject.Object,
_init: function() { _init: function() {
this.parent();
this._proxy = new SystemdLoginManager(); this._proxy = new SystemdLoginManager();
this._proxy.init(null); },
initAsync: function(cancellable, asyncCallback) {
let simpleResult = Gio.SimpleAsyncResult.new(this, asyncCallback, null);
simpleResult.set_check_cancellable(cancellable);
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
if (cancellable && cancellable.is_cancelled())
return;
this._fetchCurrentSession(cancellable, simpleResult);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
simpleResult.complete();
}
}));
},
initFinish: function(simpleResult) {
if (!simpleResult.propagate_error())
return simpleResult.get_op_res_gboolean();
return true;
},
_fetchCurrentSession: function(cancellable, simpleResult) {
this._currentSession = new SystemdLoginSession('/org/freedesktop/login1/session/' +
GLib.getenv('XDG_SESSION_ID'));
this._currentSession.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
simpleResult.set_op_res_gboolean(true);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
}
simpleResult.complete();
}));
}, },
// Having this function is a bit of a hack since the Systemd and ConsoleKit // Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are // session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment. // Lock/Unlock signals, and that's all we count upon at the moment.
//
// This is only valid after async initialization
getCurrentSessionProxy: function() { getCurrentSessionProxy: function() {
if (!this._currentSession) {
this._currentSession = new SystemdLoginSession('/org/freedesktop/login1/session/' +
GLib.getenv('XDG_SESSION_ID'));
this._currentSession.init(null);
}
return this._currentSession; return this._currentSession;
}, },
@ -198,24 +260,76 @@ const LoginManagerSystemd = new Lang.Class({
const LoginManagerConsoleKit = new Lang.Class({ const LoginManagerConsoleKit = new Lang.Class({
Name: 'LoginManagerConsoleKit', Name: 'LoginManagerConsoleKit',
Extends: GObject.Object,
_init: function() { _init: function() {
this._proxy = new ConsoleKitManager(); this.parent();
this._proxy.init(null);
this._proxy = new ConsoleKitManager();
this._upClient = new UPowerGlib.Client(); this._upClient = new UPowerGlib.Client();
}, },
initAsync: function(cancellable, asyncCallback) {
let simpleResult = Gio.SimpleAsyncResult.new(this, asyncCallback, null);
simpleResult.set_check_cancellable(cancellable);
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
if (cancellable && cancellable.is_cancelled())
return;
this._fetchCurrentSession(cancellable, simpleResult);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
simpleResult.complete();
}
}));
},
initFinish: function(simpleResult) {
if (!simpleResult.propagate_error())
return simpleResult.get_op_res_gboolean();
return true;
},
_fetchCurrentSession: function(cancellable, simpleResult) {
this._proxy.GetCurrentSessionRemote(cancellable, Lang.bind(this, function(proxy, result) {
try {
let [currentSessionId] = proxy.GetCurrentSessionFinish(result);
if (cancellable && cancellable.is_cancelled())
return;
this._createSessionProxy(currentSessionId, cancellable, simpleResult);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
simpleResult.complete();
}
}));
},
_createSessionProxy: function(currentSessionId, cancellable, simpleResult) {
this._currentSession = new ConsoleKitSession(currentSessionId);
this._currentSession.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
simpleResult.set_op_res_gboolean(true);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
}
simpleResult.complete();
}));
},
// Having this function is a bit of a hack since the Systemd and ConsoleKit // Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are // session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment. // Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function() { getCurrentSessionProxy: function() {
if (!this._currentSession) {
let [currentSessionId] = this._proxy.GetCurrentSessionSync(null);
this._currentSession = new ConsoleKitSession(currentSessionId);
this._currentSession.init(null);
}
return this._currentSession; return this._currentSession;
}, },

View File

@ -239,14 +239,17 @@ const DBusEventSource = new Lang.Class({
this._resetCache(); this._resetCache();
this._dbusProxy = new CalendarServer(); this._dbusProxy = new CalendarServer();
this._dbusProxy.init(null);
this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged)); this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
this._dbusProxy.connect('notify::g-name-owner', Lang.bind(this, function() { this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
if (this._dbusProxy.g_name_owner) try {
this._onNameAppeared(); proxy.init_finish(result);
else } catch(e) {
this._onNameVanished(); return;
}
this._resetCache();
this.emit('changed');
})); }));
}, },
@ -256,16 +259,6 @@ const DBusEventSource = new Lang.Class({
this._lastRequestEnd = null; this._lastRequestEnd = null;
}, },
_onNameAppeared: function(owner) {
this._resetCache();
this._loadEvents(true);
},
_onNameVanished: function(oldOwner) {
this._resetCache();
this.emit('changed');
},
_onChanged: function() { _onChanged: function() {
this._loadEvents(false); this._loadEvents(false);
}, },
@ -404,7 +397,6 @@ const Calendar = new Lang.Class({
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() { this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() {
this._update(false); this._update(false);
})); }));
this._update(true);
} }
}, },

View File

@ -33,7 +33,9 @@ const AutomountManager = new Lang.Class({
Lang.bind(this, this._InhibitorsChanged)); Lang.bind(this, this._InhibitorsChanged));
this._inhibited = false; this._inhibited = false;
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginManager = manager;
}));
this._volumeMonitor = Gio.VolumeMonitor.get(); this._volumeMonitor = Gio.VolumeMonitor.get();
}, },
@ -85,7 +87,7 @@ const AutomountManager = new Lang.Class({
_onDriveConnected: function() { _onDriveConnected: function() {
// if we're not in the current ConsoleKit session, // if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds // or screensaver is active, don't play sounds
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
global.play_theme_sound(0, 'device-added-media'); global.play_theme_sound(0, 'device-added-media');
@ -94,7 +96,7 @@ const AutomountManager = new Lang.Class({
_onDriveDisconnected: function() { _onDriveDisconnected: function() {
// if we're not in the current ConsoleKit session, // if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds // or screensaver is active, don't play sounds
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
global.play_theme_sound(0, 'device-removed-media'); global.play_theme_sound(0, 'device-removed-media');
@ -103,7 +105,7 @@ const AutomountManager = new Lang.Class({
_onDriveEjectButton: function(monitor, drive) { _onDriveEjectButton: function(monitor, drive) {
// TODO: this code path is not tested, as the GVfs volume monitor // TODO: this code path is not tested, as the GVfs volume monitor
// doesn't emit this signal just yet. // doesn't emit this signal just yet.
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
// we force stop/eject in this case, so we don't have to pass a // we force stop/eject in this case, so we don't have to pass a
@ -143,7 +145,7 @@ const AutomountManager = new Lang.Class({
if (params.checkSession) { if (params.checkSession) {
// if we're not in the current ConsoleKit session, // if we're not in the current ConsoleKit session,
// don't attempt automount // don't attempt automount
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
} }

View File

@ -171,7 +171,9 @@ const AutorunManager = new Lang.Class({
Name: 'AutorunManager', Name: 'AutorunManager',
_init: function() { _init: function() {
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginManager = manager;
}));
this._volumeMonitor = Gio.VolumeMonitor.get(); this._volumeMonitor = Gio.VolumeMonitor.get();
@ -224,7 +226,7 @@ const AutorunManager = new Lang.Class({
_onMountAdded: function(monitor, mount) { _onMountAdded: function(monitor, mount) {
// don't do anything if our session is not the currently // don't do anything if our session is not the currently
// active one // active one
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
this._processMount(mount, true); this._processMount(mount, true);

View File

@ -32,7 +32,10 @@ const Bus = new Gio.DBusProxyClass({
_init: function() { _init: function() {
this.parent({ g_bus_type: Gio.BusType.SESSION, this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: 'org.freedesktop.DBus', g_name: 'org.freedesktop.DBus',
g_object_path: '/org/freedesktop/DBus' }); g_object_path: '/org/freedesktop/DBus',
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES |
Gio.DBusProxyFlags.DO_NOT_CONNECT_SIGNALS |
Gio.DBusProxyFlags.DO_NOT_AUTO_START) });
} }
}); });
@ -121,6 +124,7 @@ const NotificationDaemon = new Gio.DBusImplementerClass({
this._senderToPid = {}; this._senderToPid = {};
this._notifications = {}; this._notifications = {};
this._busProxy = new Bus(); this._busProxy = new Bus();
// This is synchronous but fast because of the flags we use.
this._busProxy.init(null); this._busProxy.init(null);
this._trayManager = new Shell.TrayManager(); this._trayManager = new Shell.TrayManager();

View File

@ -97,13 +97,22 @@ function loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallb
icon, icon,
busName, busName,
objectPath); objectPath);
remoteProvider.initAsync(null, function(obj, result) {
try {
remoteProvider.initFinish(result);
} catch(e) {
log('Failed to add search provider "%s": %s'.format(title, e.toString()));
return;
}
addProviderCallback(remoteProvider);
});
loadedProviders[objectPath] = remoteProvider; loadedProviders[objectPath] = remoteProvider;
} catch(e) { } catch(e) {
log('Failed to add search provider "%s": %s'.format(title, e.toString())); log('Failed to add search provider "%s": %s'.format(title, e.toString()));
continue; continue;
} }
addProviderCallback(remoteProvider);
} }
})); }));
@ -114,14 +123,41 @@ const RemoteSearchProvider = new Lang.Class({
Extends: Search.SearchProvider, Extends: Search.SearchProvider,
_init: function(title, icon, dbusName, dbusPath) { _init: function(title, icon, dbusName, dbusPath) {
this.parent(title.toUpperCase());
this._proxy = new SearchProviderProxy({ g_name: dbusName, this._proxy = new SearchProviderProxy({ g_name: dbusName,
g_object_path: dbusPath }); g_object_path: dbusPath });
this._proxy.init(null);
this.parent(title.toUpperCase());
this._cancellable = new Gio.Cancellable(); this._cancellable = new Gio.Cancellable();
}, },
initAsync: function(cancellable, asyncCallback) {
// Can't pass "this" as source object, because RemoteSearchProvider
// is not a GObject.Object (and in gjs you can't inherit from a JS
// type that in turn inherits from GObject)
let simpleResult = Gio.SimpleAsyncResult.new(null, asyncCallback, null);
simpleResult.set_check_cancellable(cancellable);
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
simpleResult.set_op_res_gboolean(true);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
}
simpleResult.complete();
}));
},
initFinish: function(simpleResult) {
if (!simpleResult.propagate_error())
return simpleResult.get_op_res_gboolean();
return false;
},
createIcon: function(size, meta) { createIcon: function(size, meta) {
if (meta['gicon']) { if (meta['gicon']) {
return new St.Icon({ gicon: Gio.icon_new_for_string(meta['gicon']), return new St.Icon({ gicon: Gio.icon_new_for_string(meta['gicon']),

View File

@ -418,10 +418,11 @@ const ScreenShield = new Lang.Class({
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this); this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginSession = this._loginManager.getCurrentSessionProxy(); this._loginSession = manager.getCurrentSessionProxy();
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); })); this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); })); this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
}));
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
@ -875,6 +876,7 @@ const ScreenShieldFallback = new Lang.Class({
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START | g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES), Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES),
}); });
// This is synchronous but it is the fallback case.
this._proxy.init(null); this._proxy.init(null);
this._proxy.connect('g-signal', Lang.bind(this, this._onSignal)); this._proxy.connect('g-signal', Lang.bind(this, this._onSignal));

View File

@ -2,6 +2,7 @@
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang; const Lang = imports.lang;
const Signals = imports.signals; const Signals = imports.signals;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
@ -75,6 +76,8 @@ const SearchProvider = new Lang.Class({
Name: 'SearchProvider', Name: 'SearchProvider',
_init: function(title) { _init: function(title) {
this.parent();
this.title = title; this.title = title;
this.searchSystem = null; this.searchSystem = null;
}, },

View File

@ -495,14 +495,22 @@ const UserMenuButton = new Lang.Class({
})); }));
})); }));
this._session = new GnomeSession.SessionManager(); let session = new GnomeSession.SessionManager();
this._session.init(null); session.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
// This should never fail.
proxy.init_finish(result);
this._session = proxy;
this._updateHaveShutdown();
}));
this._haveShutdown = true; this._haveShutdown = true;
this._haveSuspend = true; this._haveSuspend = true;
this._accountMgr = Tp.AccountManager.dup(); this._accountMgr = Tp.AccountManager.dup();
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginManager = manager;
}));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._iconBox = new St.Bin(); this._iconBox = new St.Bin();
@ -647,6 +655,11 @@ const UserMenuButton = new Lang.Class({
}, },
_updateHaveShutdown: function() { _updateHaveShutdown: function() {
if (!this._session) {
this._haveShutdown = false;
return;
}
this._session.CanShutdownRemote(null, Lang.bind(this, function(proxy, result) { this._session.CanShutdownRemote(null, Lang.bind(this, function(proxy, result) {
try { try {
[this._haveShutdown] = proxy.CanShutdownFinish(result); [this._haveShutdown] = proxy.CanShutdownFinish(result);
@ -660,6 +673,11 @@ const UserMenuButton = new Lang.Class({
}, },
_updateHaveSuspend: function() { _updateHaveSuspend: function() {
if (!this._loginManager) {
this._haveSuspend = false;
return;
}
this._loginManager.canSuspend(Lang.bind(this, this._loginManager.canSuspend(Lang.bind(this,
function(result) { function(result) {
this._haveSuspend = result; this._haveSuspend = result;
@ -849,14 +867,17 @@ const UserMenuButton = new Lang.Class({
_onQuitSessionActivate: function() { _onQuitSessionActivate: function() {
Main.overview.hide(); Main.overview.hide();
this._session.LogoutRemote(0, null, null);
if (this._session)
this._session.LogoutRemote(0, null, null);
}, },
_onInstallUpdatesActivate: function() { _onInstallUpdatesActivate: function() {
Main.overview.hide(); Main.overview.hide();
Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']); Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']);
this._session.RebootRemote(); if (this._haveShutdown)
this._session.RebootRemote(null, null);
}, },
_onSuspendOrPowerOffActivate: function() { _onSuspendOrPowerOffActivate: function() {
@ -865,7 +886,7 @@ const UserMenuButton = new Lang.Class({
if (this._haveShutdown && if (this._haveShutdown &&
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) { this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
this._session.ShutdownRemote(null, null); this._session.ShutdownRemote(null, null);
} else { } else if (this._haveSuspend) {
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) { if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() { let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
Main.screenShield.disconnect(tmpId); Main.screenShield.disconnect(tmpId);