[gnome-shell/wip/gdbus-2: 2/3] Try to do more async initialization



commit afcc1b7b5212d6f6309bcf76ade86c805ce3f112
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Fri Oct 26 19:19:03 2012 +0200

    Try to do more async initialization
    
    Synchronous calls in the main loop are a performance killer, especially
    at login.

 js/gdm/powerMenu.js                  |   26 ++++++-
 js/gdm/realmd.js                     |   11 ++-
 js/misc/loginManager.js              |  158 +++++++++++++++++++++++++++++-----
 js/ui/calendar.js                    |   26 ++----
 js/ui/components/automountManager.js |   12 ++-
 js/ui/components/autorunManager.js   |    6 +-
 js/ui/notificationDaemon.js          |    6 +-
 js/ui/remoteSearch.js                |   46 +++++++++-
 js/ui/screenShield.js                |   10 ++-
 js/ui/search.js                      |    3 +
 js/ui/userMenu.js                    |   33 ++++++--
 11 files changed, 273 insertions(+), 64 deletions(-)
---
diff --git a/js/gdm/powerMenu.js b/js/gdm/powerMenu.js
index a341619..552148f 100644
--- a/js/gdm/powerMenu.js
+++ b/js/gdm/powerMenu.js
@@ -35,7 +35,13 @@ const PowerMenuButton = new Lang.Class({
         /* Translators: accessible name of the power menu in the login screen */
         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.connect('changed::disable-restart-buttons',
@@ -64,6 +70,12 @@ const PowerMenuButton = new Lang.Class({
     },
 
     _updateHaveShutdown: function() {
+        if (!this._loginManager) {
+            this._haveShutdown = false;
+            this._powerOffItem.actor.visible = false;
+            return;
+        }
+
         this._loginManager.canPowerOff(Lang.bind(this, function(result) {
             this._haveShutdown = result;
             this._powerOffItem.actor.visible = this._haveShutdown;
@@ -72,6 +84,12 @@ const PowerMenuButton = new Lang.Class({
     },
 
     _updateHaveRestart: function() {
+        if (!this._loginManager) {
+            this._haveRestart = false;
+            this._restartItem.actor.visible = false;
+            return;
+        }
+
         this._loginManager.canReboot(Lang.bind(this, function(result) {
             this._haveRestart = result;
             this._restartItem.actor.visible = this._haveRestart;
@@ -80,6 +98,12 @@ const PowerMenuButton = new Lang.Class({
     },
 
     _updateHaveSuspend: function() {
+        if (!this._loginManager) {
+            this._haveSuspend = false;
+            this._suspendItem.actor.visible = false;
+            return;
+        }
+
         this._loginManager.canSuspend(Lang.bind(this, function(result) {
             this._haveSuspend = result;
             this._suspendItem.actor.visible = this._haveSuspend;
diff --git a/js/gdm/realmd.js b/js/gdm/realmd.js
index 4e93ce1..20a2305 100644
--- a/js/gdm/realmd.js
+++ b/js/gdm/realmd.js
@@ -86,7 +86,6 @@ const Manager = new Lang.Class({
 
     _init: function(parentActor) {
         this._aggregateProvider = new Provider();
-        this._aggregateProvider.init(null);
         this._realms = {};
 
         this._aggregateProvider.connect('g-properties-changed',
@@ -94,6 +93,16 @@ const Manager = new Lang.Class({
                                             if ('Realms' in properties.deep_unpack())
                                                 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() {
diff --git a/js/misc/loginManager.js b/js/misc/loginManager.js
index 7fca78d..67dd064 100644
--- a/js/misc/loginManager.js
+++ b/js/misc/loginManager.js
@@ -2,6 +2,7 @@
 
 const GLib = imports.gi.GLib;
 const Gio = imports.gi.Gio;
+const GObject = imports.gi.GObject;
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 const Shell = imports.gi.Shell;
@@ -105,41 +106,102 @@ function haveSystemd() {
 }
 
 let _loginManager = null;
+let _pendingAsyncCallbacks = [];
 
 /**
  * LoginManager:
  * An abstraction over systemd/logind and ConsoleKit.
  *
  */
-function getLoginManager() {
+function getLoginManager(asyncCallback) {
     if (_loginManager == null) {
-        if (haveSystemd())
-            _loginManager = new LoginManagerSystemd();
-        else
-            _loginManager = new LoginManagerConsoleKit();
-    }
+        if (_pendingAsyncCallbacks.length == 0) {
+            let manager;
+
+            if (haveSystemd())
+                manager = new LoginManagerSystemd();
+            else
+                manager = new LoginManagerConsoleKit();
+
+            manager.initAsync(null, function(obj, result) {
+                obj.initFinish(result);
+
+                _loginManager = manager;
 
-    return _loginManager;
+                _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({
     Name: 'LoginManagerSystemd',
+    Extends: GObject.Object,
 
     _init: function() {
+        this.parent();
+
         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
     // session objects have different interfaces - but in both cases there are
     // Lock/Unlock signals, and that's all we count upon at the moment.
+    //
+    // This is only valid after async initialization
     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;
     },
 
@@ -198,24 +260,76 @@ const LoginManagerSystemd = new Lang.Class({
 
 const LoginManagerConsoleKit = new Lang.Class({
     Name: 'LoginManagerConsoleKit',
+    Extends: GObject.Object,
 
     _init: function() {
-        this._proxy = new ConsoleKitManager();
-        this._proxy.init(null);
+        this.parent();
 
+        this._proxy = new ConsoleKitManager();
         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
     // session objects have different interfaces - but in both cases there are
     // Lock/Unlock signals, and that's all we count upon at the moment.
     getCurrentSessionProxy: function() {
-        if (!this._currentSession) {
-            let [currentSessionId] = this._proxy.GetCurrentSessionSync(null);
-            this._currentSession = new ConsoleKitSession(currentSessionId);
-            this._currentSession.init(null);
-        }
-
         return this._currentSession;
     },
 
diff --git a/js/ui/calendar.js b/js/ui/calendar.js
index 3da38f8..9afb306 100644
--- a/js/ui/calendar.js
+++ b/js/ui/calendar.js
@@ -239,14 +239,17 @@ const DBusEventSource = new Lang.Class({
         this._resetCache();
 
         this._dbusProxy = new CalendarServer();
-        this._dbusProxy.init(null);
         this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
 
-        this._dbusProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
-            if (this._dbusProxy.g_name_owner)
-                this._onNameAppeared();
-            else
-                this._onNameVanished();
+        this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
+            try {
+                proxy.init_finish(result);
+            } catch(e) {
+                return;
+            }
+
+            this._resetCache();
+            this.emit('changed');
         }));
     },
 
@@ -256,16 +259,6 @@ const DBusEventSource = new Lang.Class({
         this._lastRequestEnd = null;
     },
 
-    _onNameAppeared: function(owner) {
-        this._resetCache();
-        this._loadEvents(true);
-    },
-
-    _onNameVanished: function(oldOwner) {
-        this._resetCache();
-        this.emit('changed');
-    },
-
     _onChanged: function() {
         this._loadEvents(false);
     },
@@ -404,7 +397,6 @@ const Calendar = new Lang.Class({
             this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() {
                 this._update(false);
             }));
-            this._update(true);
         }
     },
 
diff --git a/js/ui/components/automountManager.js b/js/ui/components/automountManager.js
index 9081e80..3d3d02b 100644
--- a/js/ui/components/automountManager.js
+++ b/js/ui/components/automountManager.js
@@ -33,7 +33,9 @@ const AutomountManager = new Lang.Class({
                                     Lang.bind(this, this._InhibitorsChanged));
         this._inhibited = false;
 
-        this._loginManager = LoginManager.getLoginManager();
+        LoginManager.getLoginManager(Lang.bind(this, function(manager) {
+            this._loginManager = manager;
+        }));
         this._volumeMonitor = Gio.VolumeMonitor.get();
     },
 
@@ -85,7 +87,7 @@ const AutomountManager = new Lang.Class({
     _onDriveConnected: function() {
         // if we're not in the current ConsoleKit session,
         // or screensaver is active, don't play sounds
-        if (!this._loginManager.sessionActive)
+        if (!this._loginManager || !this._loginManager.sessionActive)
             return;
 
         global.play_theme_sound(0, 'device-added-media');
@@ -94,7 +96,7 @@ const AutomountManager = new Lang.Class({
     _onDriveDisconnected: function() {
         // if we're not in the current ConsoleKit session,
         // or screensaver is active, don't play sounds
-        if (!this._loginManager.sessionActive)
+        if (!this._loginManager || !this._loginManager.sessionActive)
             return;
 
         global.play_theme_sound(0, 'device-removed-media');        
@@ -103,7 +105,7 @@ const AutomountManager = new Lang.Class({
     _onDriveEjectButton: function(monitor, drive) {
         // TODO: this code path is not tested, as the GVfs volume monitor
         // doesn't emit this signal just yet.
-        if (!this._loginManager.sessionActive)
+        if (!this._loginManager || !this._loginManager.sessionActive)
             return;
 
         // 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 we're not in the current ConsoleKit session,
             // don't attempt automount
-            if (!this._loginManager.sessionActive)
+            if (!this._loginManager || !this._loginManager.sessionActive)
                 return;
         }
 
diff --git a/js/ui/components/autorunManager.js b/js/ui/components/autorunManager.js
index fc55b0d..25d20e9 100644
--- a/js/ui/components/autorunManager.js
+++ b/js/ui/components/autorunManager.js
@@ -171,7 +171,9 @@ const AutorunManager = new Lang.Class({
     Name: 'AutorunManager',
 
     _init: function() {
-        this._loginManager = LoginManager.getLoginManager();
+        LoginManager.getLoginManager(Lang.bind(this, function(manager) {
+            this._loginManager = manager;
+        }));
 
         this._volumeMonitor = Gio.VolumeMonitor.get();
 
@@ -224,7 +226,7 @@ const AutorunManager = new Lang.Class({
     _onMountAdded: function(monitor, mount) {
         // don't do anything if our session is not the currently
         // active one
-        if (!this._loginManager.sessionActive)
+        if (!this._loginManager || !this._loginManager.sessionActive)
             return;
 
         this._processMount(mount, true);
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index 1a7a483..d23280a 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -32,7 +32,10 @@ const Bus = new Gio.DBusProxyClass({
     _init: function() {
         this.parent({ g_bus_type: Gio.BusType.SESSION,
                       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._notifications = {};
         this._busProxy = new Bus();
+        // This is synchronous but fast because of the flags we use.
         this._busProxy.init(null);
 
         this._trayManager = new Shell.TrayManager();
diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js
index 5f45157..54fa1d6 100644
--- a/js/ui/remoteSearch.js
+++ b/js/ui/remoteSearch.js
@@ -97,13 +97,22 @@ function loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallb
                                                           icon,
                                                           busName,
                                                           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;
             } catch(e) {
                 log('Failed to add search provider "%s": %s'.format(title, e.toString()));
                 continue;
             }
-
-            addProviderCallback(remoteProvider);
         }
     }));
 
@@ -114,14 +123,41 @@ const RemoteSearchProvider = new Lang.Class({
     Extends: Search.SearchProvider,
 
     _init: function(title, icon, dbusName, dbusPath) {
+        this.parent(title.toUpperCase());
+
         this._proxy = new SearchProviderProxy({ g_name: dbusName,
                                                 g_object_path: dbusPath });
-        this._proxy.init(null);
-
-        this.parent(title.toUpperCase());
         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) {
         if (meta['gicon']) {
             return new St.Icon({ gicon: Gio.icon_new_for_string(meta['gicon']),
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
index 52c7dcc..9843748 100644
--- a/js/ui/screenShield.js
+++ b/js/ui/screenShield.js
@@ -418,10 +418,11 @@ const ScreenShield = new Lang.Class({
 
         this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
 
-        this._loginManager = LoginManager.getLoginManager();
-        this._loginSession = this._loginManager.getCurrentSessionProxy();
-        this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
-        this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
+        LoginManager.getLoginManager(Lang.bind(this, function(manager) {
+            this._loginSession = manager.getCurrentSessionProxy();
+            this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
+            this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
+        }));
 
         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 |
                                                     Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES),
                                         });
+        // This is synchronous but it is the fallback case.
         this._proxy.init(null);
 
         this._proxy.connect('g-signal', Lang.bind(this, this._onSignal));
diff --git a/js/ui/search.js b/js/ui/search.js
index 22f53d9..97acb5d 100644
--- a/js/ui/search.js
+++ b/js/ui/search.js
@@ -2,6 +2,7 @@
 
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
 const Lang = imports.lang;
 const Signals = imports.signals;
 const Shell = imports.gi.Shell;
@@ -75,6 +76,8 @@ const SearchProvider = new Lang.Class({
     Name: 'SearchProvider',
 
     _init: function(title) {
+        this.parent();
+
         this.title = title;
         this.searchSystem = null;
     },
diff --git a/js/ui/userMenu.js b/js/ui/userMenu.js
index eecb75a..65d5339 100644
--- a/js/ui/userMenu.js
+++ b/js/ui/userMenu.js
@@ -495,14 +495,22 @@ const UserMenuButton = new Lang.Class({
             }));
         }));
 
-        this._session = new GnomeSession.SessionManager();
-        this._session.init(null);
+        let session = new GnomeSession.SessionManager();
+        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._haveSuspend = true;
 
         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._iconBox = new St.Bin();
@@ -647,6 +655,11 @@ const UserMenuButton = new Lang.Class({
     },
 
     _updateHaveShutdown: function() {
+        if (!this._session) {
+            this._haveShutdown = false;
+            return;
+        }
+
         this._session.CanShutdownRemote(null, Lang.bind(this, function(proxy, result) {
             try {
                 [this._haveShutdown] = proxy.CanShutdownFinish(result);
@@ -660,6 +673,11 @@ const UserMenuButton = new Lang.Class({
     },
 
     _updateHaveSuspend: function() {
+        if (!this._loginManager) {
+            this._haveSuspend = false;
+            return;
+        }
+
         this._loginManager.canSuspend(Lang.bind(this,
             function(result) {
                 this._haveSuspend = result;
@@ -849,14 +867,17 @@ const UserMenuButton = new Lang.Class({
 
     _onQuitSessionActivate: function() {
         Main.overview.hide();
-        this._session.LogoutRemote(0, null, null);
+
+        if (this._session)
+            this._session.LogoutRemote(0, null, null);
     },
 
     _onInstallUpdatesActivate: function() {
         Main.overview.hide();
         Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']);
 
-        this._session.RebootRemote();
+        if (this._haveShutdown)
+            this._session.RebootRemote(null, null);
     },
 
     _onSuspendOrPowerOffActivate: function() {
@@ -865,7 +886,7 @@ const UserMenuButton = new Lang.Class({
         if (this._haveShutdown &&
             this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
             this._session.ShutdownRemote(null, null);
-        } else {
+        } else if (this._haveSuspend) {
             if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
                 let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
                     Main.screenShield.disconnect(tmpId);



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