js: Promisify async operations

Promises make asynchronous operations easier to manage, in particular
when used through the async/await syntax that allows for asynchronous
code to closely resemble synchronous one.

gjs has included a Gio._promisify() helper for a while now, which
monkey-patches methods that follow GIO's async pattern to return a
Promise when called without a callback argument.

Use that to get rid of all those GAsyncReadyCallbacks!

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1126
This commit is contained in:
Florian Müllner 2019-12-19 20:50:37 +01:00 committed by Florian Müllner
parent 18742fcc32
commit 764527c8c9
20 changed files with 409 additions and 428 deletions

View File

@ -2,7 +2,7 @@
/* exported BANNER_MESSAGE_KEY, BANNER_MESSAGE_TEXT_KEY, LOGO_KEY, /* exported BANNER_MESSAGE_KEY, BANNER_MESSAGE_TEXT_KEY, LOGO_KEY,
DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor */ DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor */
const { Clutter, Gio, GLib } = imports.gi; const { Clutter, Gdm, Gio, GLib } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const Batch = imports.gdm.batch; const Batch = imports.gdm.batch;
@ -12,6 +12,15 @@ const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
const SmartcardManager = imports.misc.smartcardManager; const SmartcardManager = imports.misc.smartcardManager;
Gio._promisify(Gdm.Client.prototype,
'open_reauthentication_channel', 'open_reauthentication_channel_finish');
Gio._promisify(Gdm.Client.prototype,
'get_user_verifier', 'get_user_verifier_finish');
Gio._promisify(Gdm.UserVerifierProxy.prototype,
'call_begin_verification_for_user', 'call_begin_verification_for_user_finish');
Gio._promisify(Gdm.UserVerifierProxy.prototype,
'call_begin_verification', 'call_begin_verification_finish');
var PASSWORD_SERVICE_NAME = 'gdm-password'; var PASSWORD_SERVICE_NAME = 'gdm-password';
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint'; var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard'; var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
@ -168,14 +177,12 @@ var ShellUserVerifier = class {
this._checkForFingerprintReader(); this._checkForFingerprintReader();
if (userName) {
// If possible, reauthenticate an already running session, // If possible, reauthenticate an already running session,
// so any session specific credentials get updated appropriately // so any session specific credentials get updated appropriately
this._client.open_reauthentication_channel(userName, this._cancellable, if (userName)
this._reauthenticationChannelOpened.bind(this)); this._openReauthenticationChannel(userName);
} else { else
this._client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this)); this._getUserVerifier();
}
} }
cancel() { cancel() {
@ -339,10 +346,11 @@ var ShellUserVerifier = class {
this._verificationFailed(false); this._verificationFailed(false);
} }
_reauthenticationChannelOpened(client, result) { async _openReauthenticationChannel(userName) {
try { try {
this._clearUserVerifier(); this._clearUserVerifier();
this._userVerifier = client.open_reauthentication_channel_finish(result); this._userVerifier = await this._client.open_reauthentication_channel(
userName, this._cancellable);
} catch (e) { } catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return; return;
@ -351,8 +359,7 @@ var ShellUserVerifier = class {
// Gdm emits org.freedesktop.DBus.Error.AccessDenied when there // Gdm emits org.freedesktop.DBus.Error.AccessDenied when there
// is no session to reauthenticate. Fall back to performing // is no session to reauthenticate. Fall back to performing
// verification from this login session // verification from this login session
client.get_user_verifier(this._cancellable, this._getUserVerifier();
this._userVerifierGot.bind(this));
return; return;
} }
@ -366,10 +373,11 @@ var ShellUserVerifier = class {
this._hold.release(); this._hold.release();
} }
_userVerifierGot(client, result) { async _getUserVerifier() {
try { try {
this._clearUserVerifier(); this._clearUserVerifier();
this._userVerifier = client.get_user_verifier_finish(result); this._userVerifier =
await this._client.get_user_verifier(this._cancellable);
} catch (e) { } catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return; return;
@ -421,35 +429,25 @@ var ShellUserVerifier = class {
} }
} }
_startService(serviceName) { async _startService(serviceName) {
this._hold.acquire(); this._hold.acquire();
try {
if (this._userName) { if (this._userName) {
this._userVerifier.call_begin_verification_for_user(serviceName, this._userName, this._cancellable, (obj, result) => { await this._userVerifier.call_begin_verification_for_user(
try { serviceName, this._userName, this._cancellable);
obj.call_begin_verification_for_user_finish(result);
} catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return;
this._reportInitError('Failed to start verification for user', e);
return;
}
this._hold.release();
});
} else { } else {
this._userVerifier.call_begin_verification(serviceName, this._cancellable, (obj, result) => { await this._userVerifier.call_begin_verification(
try { serviceName, this._cancellable);
obj.call_begin_verification_finish(result); }
} catch (e) { } catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return; return;
this._reportInitError('Failed to start verification', e); this._reportInitError(this._userName
? 'Failed to start verification for user'
: 'Failed to start verification', e);
return; return;
} }
this._hold.release(); this._hold.release();
});
}
} }
_beginVerification() { _beginVerification() {

View File

@ -6,6 +6,15 @@ const Signals = imports.signals;
const IBusCandidatePopup = imports.ui.ibusCandidatePopup; const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
Gio._promisify(IBus.Bus.prototype,
'list_engines_async', 'list_engines_async_finish');
Gio._promisify(IBus.Bus.prototype,
'request_name_async', 'request_name_async_finish');
Gio._promisify(IBus.Bus.prototype,
'get_global_engine_async', 'get_global_engine_async_finish');
Gio._promisify(IBus.Bus.prototype,
'set_global_engine_async', 'set_global_engine_async_finish');
// Ensure runtime version matches // Ensure runtime version matches
_checkIBusVersion(1, 5, 2); _checkIBusVersion(1, 5, 2);
@ -102,16 +111,14 @@ var IBusManager = class {
_onConnected() { _onConnected() {
this._cancellable = new Gio.Cancellable(); this._cancellable = new Gio.Cancellable();
this._ibus.list_engines_async(-1, this._cancellable, this._initEngines();
this._initEngines.bind(this)); this._initPanelService();
this._ibus.request_name_async(IBus.SERVICE_PANEL,
IBus.BusNameFlag.REPLACE_EXISTING, -1, this._cancellable,
this._initPanelService.bind(this));
} }
_initEngines(ibus, result) { async _initEngines() {
try { try {
let enginesList = this._ibus.list_engines_async_finish(result); const enginesList =
await this._ibus.list_engines_async(-1, this._cancellable);
for (let i = 0; i < enginesList.length; ++i) { for (let i = 0; i < enginesList.length; ++i) {
let name = enginesList[i].get_name(); let name = enginesList[i].get_name();
this._engines.set(name, enginesList[i]); this._engines.set(name, enginesList[i]);
@ -126,9 +133,10 @@ var IBusManager = class {
} }
} }
_initPanelService(ibus, result) { async _initPanelService() {
try { try {
this._ibus.request_name_async_finish(result); await this._ibus.request_name_async(IBus.SERVICE_PANEL,
IBus.BusNameFlag.REPLACE_EXISTING, -1, this._cancellable);
} catch (e) { } catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) { if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
logError(e); logError(e);
@ -163,19 +171,15 @@ var IBusManager = class {
this._panelService.connect('set-content-type', this._setContentType.bind(this)); this._panelService.connect('set-content-type', this._setContentType.bind(this));
} catch (e) { } catch (e) {
} }
// If an engine is already active we need to get its properties
this._ibus.get_global_engine_async(-1, this._cancellable, (_bus, res) => {
let engine;
try { try {
engine = this._ibus.get_global_engine_async_finish(res); // If an engine is already active we need to get its properties
if (!engine) const engine =
return; await this._ibus.get_global_engine_async(-1, this._cancellable);
} catch (e) {
return;
}
this._engineChanged(this._ibus, engine.get_name()); this._engineChanged(this._ibus, engine.get_name());
});
this._updateReadiness(); this._updateReadiness();
} catch (e) {
}
} }
_updateReadiness() { _updateReadiness() {
@ -223,7 +227,7 @@ var IBusManager = class {
return this._engines.get(id); return this._engines.get(id);
} }
setEngine(id, callback) { async setEngine(id, callback) {
// Send id even if id == this._currentEngineName // Send id even if id == this._currentEngineName
// because 'properties-registered' signal can be emitted // because 'properties-registered' signal can be emitted
// while this._ibusSources == null on a lock screen. // while this._ibusSources == null on a lock screen.
@ -233,18 +237,16 @@ var IBusManager = class {
return; return;
} }
this._ibus.set_global_engine_async(id,
this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
this._cancellable, (_bus, res) => {
try { try {
this._ibus.set_global_engine_async_finish(res); await this._ibus.set_global_engine_async(id,
this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
this._cancellable);
} catch (e) { } catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
logError(e); logError(e);
} }
if (callback) if (callback)
callback(); callback();
});
} }
preloadEngines(ids) { preloadEngines(ids) {

View File

@ -4,6 +4,9 @@ const { Clutter, GLib, Gio, GObject, IBus } = imports.gi;
const Keyboard = imports.ui.status.keyboard; const Keyboard = imports.ui.status.keyboard;
Gio._promisify(IBus.Bus.prototype,
'create_input_context_async', 'create_input_context_async_finish');
var HIDE_PANEL_TIME = 50; var HIDE_PANEL_TIME = 50;
var InputMethod = GObject.registerClass( var InputMethod = GObject.registerClass(
@ -46,15 +49,11 @@ class InputMethod extends Clutter.InputMethod {
this._currentSource = this._inputSourceManager.currentSource; this._currentSource = this._inputSourceManager.currentSource;
} }
_onConnected() { async _onConnected() {
this._cancellable = new Gio.Cancellable(); this._cancellable = new Gio.Cancellable();
this._ibus.create_input_context_async('gnome-shell', -1,
this._cancellable, this._setContext.bind(this));
}
_setContext(bus, res) {
try { try {
this._context = this._ibus.create_input_context_async_finish(res); this._context = await this._ibus.create_input_context_async(
'gnome-shell', -1, this._cancellable);
} catch (e) { } catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) { if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
logError(e); logError(e);

View File

@ -50,25 +50,22 @@ function canLock() {
} }
function registerSessionWithGDM() { async function registerSessionWithGDM() {
log("Registering session with GDM"); log("Registering session with GDM");
Gio.DBus.system.call('org.gnome.DisplayManager', try {
await Gio.DBus.system.call(
'org.gnome.DisplayManager',
'/org/gnome/DisplayManager/Manager', '/org/gnome/DisplayManager/Manager',
'org.gnome.DisplayManager.Manager', 'org.gnome.DisplayManager.Manager',
'RegisterSession', 'RegisterSession',
GLib.Variant.new('(a{sv})', [{}]), null, GLib.Variant.new('(a{sv})', [{}]), null,
Gio.DBusCallFlags.NONE, -1, null, Gio.DBusCallFlags.NONE, -1, null);
(source, result) => {
try {
source.call_finish(result);
} catch (e) { } catch (e) {
if (!e.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD)) if (!e.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD))
log(`Error registering session with GDM: ${e.message}`); log(`Error registering session with GDM: ${e.message}`);
else else
log("Not calling RegisterSession(): method not exported, GDM too old?"); log('Not calling RegisterSession(): method not exported, GDM too old?');
} }
}
);
} }
let _loginManager = null; let _loginManager = null;
@ -174,24 +171,19 @@ var LoginManagerSystemd = class {
this._proxy.SuspendRemote(true); this._proxy.SuspendRemote(true);
} }
inhibit(reason, callback) { async inhibit(reason, callback) {
let inVariant = GLib.Variant.new('(ssss)',
['sleep',
'GNOME Shell',
reason,
'delay']);
this._proxy.call_with_unix_fd_list('Inhibit', inVariant, 0, -1, null, null,
(proxy, result) => {
let fd = -1;
try { try {
let [outVariant_, fdList] = proxy.call_with_unix_fd_list_finish(result); const inVariant = new GLib.Variant('(ssss)',
fd = fdList.steal_fds()[0]; ['sleep', 'GNOME Shell', reason, 'delay']);
const [outVariant_, fdList] =
await this._proxy.call_with_unix_fd_list('Inhibit',
inVariant, 0, -1, null, null);
const [fd] = fdList.steal_fds();
callback(new Gio.UnixInputStream({ fd })); callback(new Gio.UnixInputStream({ fd }));
} catch (e) { } catch (e) {
logError(e, "Error getting systemd inhibitor"); logError(e, 'Error getting systemd inhibitor');
callback(null); callback(null);
} }
});
} }
_prepareForSleep(proxy, sender, [aboutToSuspend]) { _prepareForSleep(proxy, sender, [aboutToSuspend]) {

View File

@ -57,9 +57,7 @@ var ObjectManager = class {
// Start out inhibiting load until at least the proxy // Start out inhibiting load until at least the proxy
// manager is loaded and the remote objects are fetched // manager is loaded and the remote objects are fetched
this._numLoadInhibitors = 1; this._numLoadInhibitors = 1;
this._managerProxy.init_async(GLib.PRIORITY_DEFAULT, this._initManagerProxy();
this._cancellable,
this._onManagerProxyLoaded.bind(this));
} }
_tryToCompleteLoad() { _tryToCompleteLoad() {
@ -73,7 +71,7 @@ var ObjectManager = class {
} }
} }
_addInterface(objectPath, interfaceName, onFinished) { async _addInterface(objectPath, interfaceName, onFinished) {
let info = this._interfaceInfos[interfaceName]; let info = this._interfaceInfos[interfaceName];
if (!info) { if (!info) {
@ -89,9 +87,8 @@ var ObjectManager = class {
g_interface_info: info, g_interface_info: info,
g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START }); g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
proxy.init_async(GLib.PRIORITY_DEFAULT, this._cancellable, (initable, result) => {
try { try {
initable.init_finish(result); await proxy.init_async(GLib.PRIORITY_DEFAULT, this._cancellable);
} catch (e) { } catch (e) {
logError(e, `could not initialize proxy for interface ${interfaceName}`); logError(e, `could not initialize proxy for interface ${interfaceName}`);
@ -122,7 +119,6 @@ var ObjectManager = class {
if (onFinished) if (onFinished)
onFinished(); onFinished();
});
} }
_removeInterface(objectPath, interfaceName) { _removeInterface(objectPath, interfaceName) {
@ -151,9 +147,10 @@ var ObjectManager = class {
} }
} }
_onManagerProxyLoaded(initable, result) { async _initManagerProxy() {
try { try {
initable.init_finish(result); await this._managerProxy.init_async(
GLib.PRIORITY_DEFAULT, this._cancellable);
} catch (e) { } catch (e) {
logError(e, `could not initialize object manager for object ${this._serviceName}`); logError(e, `could not initialize object manager for object ${this._serviceName}`);

View File

@ -7,6 +7,8 @@ const PermissionStore = imports.misc.permissionStore;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
Gio._promisify(Geoclue.Simple, 'new', 'new_finish');
const WeatherIntegrationIface = loadInterfaceXML('org.gnome.Shell.WeatherIntegration'); const WeatherIntegrationIface = loadInterfaceXML('org.gnome.Shell.WeatherIntegration');
const WEATHER_BUS_NAME = 'org.gnome.Weather'; const WEATHER_BUS_NAME = 'org.gnome.Weather';
@ -79,16 +81,7 @@ var WeatherClient = class {
this._weatherApp = null; this._weatherApp = null;
this._weatherProxy = null; this._weatherProxy = null;
let nodeInfo = Gio.DBusNodeInfo.new_for_xml(WeatherIntegrationIface); this._createWeatherProxy();
Gio.DBusProxy.new(
Gio.DBus.session,
Gio.DBusProxyFlags.DO_NOT_AUTO_START | Gio.DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
nodeInfo.lookup_interface(WEATHER_INTEGRATION_IFACE),
WEATHER_BUS_NAME,
WEATHER_OBJECT_PATH,
WEATHER_INTEGRATION_IFACE,
null,
this._onWeatherProxyReady.bind(this));
this._settings = new Gio.Settings({ this._settings = new Gio.Settings({
schema_id: 'org.gnome.shell.weather', schema_id: 'org.gnome.shell.weather',
@ -146,9 +139,17 @@ var WeatherClient = class {
(!this._needsAuth || this._weatherAuthorized); (!this._needsAuth || this._weatherAuthorized);
} }
_onWeatherProxyReady(o, res) { async _createWeatherProxy() {
const nodeInfo = Gio.DBusNodeInfo.new_for_xml(WeatherIntegrationIface);
try { try {
this._weatherProxy = Gio.DBusProxy.new_finish(res); this._weatherProxy = await Gio.DBusProxy.new(
Gio.DBus.session,
Gio.DBusProxyFlags.DO_NOT_AUTO_START | Gio.DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
nodeInfo.lookup_interface(WEATHER_INTEGRATION_IFACE),
WEATHER_BUS_NAME,
WEATHER_OBJECT_PATH,
WEATHER_INTEGRATION_IFACE,
null);
} catch (e) { } catch (e) {
log(`Failed to create GNOME Weather proxy: ${e}`); log(`Failed to create GNOME Weather proxy: ${e}`);
return; return;
@ -239,16 +240,15 @@ var WeatherClient = class {
} }
} }
_startGClueService() { async _startGClueService() {
if (this._gclueStarting) if (this._gclueStarting)
return; return;
this._gclueStarting = true; this._gclueStarting = true;
Geoclue.Simple.new('org.gnome.Shell', Geoclue.AccuracyLevel.CITY, null,
(o, res) => {
try { try {
this._gclueService = Geoclue.Simple.new_finish(res); this._gclueService = await Geoclue.Simple.new(
'org.gnome.Shell', Geoclue.AccuracyLevel.CITY, null);
} catch (e) { } catch (e) {
log(`Failed to connect to Geoclue2 service: ${e.message}`); log(`Failed to connect to Geoclue2 service: ${e.message}`);
this._setLocation(this._mostRecentLocation); this._setLocation(this._mostRecentLocation);
@ -257,7 +257,6 @@ var WeatherClient = class {
this._gclueStarted = true; this._gclueStarted = true;
this._gclueService.get_client().distance_threshold = 100; this._gclueService.get_client().distance_threshold = 100;
this._updateLocationMonitoring(); this._updateLocationMonitoring();
});
} }
_onGClueLocationChanged() { _onGClueLocationChanged() {

View File

@ -2546,20 +2546,19 @@ var AppIconMenu = class AppIconMenu extends PopupMenu.PopupMenu {
if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) { if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) {
this._appendSeparator(); this._appendSeparator();
let item = this._appendMenuItem(_("Show Details")); let item = this._appendMenuItem(_("Show Details"));
item.connect('activate', () => { item.connect('activate', async () => {
let id = this._source.app.get_id(); let id = this._source.app.get_id();
let args = GLib.Variant.new('(ss)', [id, '']); let args = GLib.Variant.new('(ss)', [id, '']);
Gio.DBus.get(Gio.BusType.SESSION, null, (o, res) => { const bus = await Gio.DBus.get(Gio.BusType.SESSION, null);
let bus = Gio.DBus.get_finish(res); bus.call(
bus.call('org.gnome.Software', 'org.gnome.Software',
'/org/gnome/Software', '/org/gnome/Software',
'org.gtk.Actions', 'Activate', 'org.gtk.Actions', 'Activate',
GLib.Variant.new('(sava{sv})', new GLib.Variant.new(
['details', [args], null]), '(sava{sv})', ['details', [args], null]),
null, 0, -1, null, null); null, 0, -1, null, null);
Main.overview.hide(); Main.overview.hide();
}); });
});
} }
} }
} }

View File

@ -199,14 +199,16 @@ class DBusEventSource extends EventSourceBase {
this._initialized = false; this._initialized = false;
this._dbusProxy = new CalendarServer(); this._dbusProxy = new CalendarServer();
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, (object, result) => { this._initProxy();
}
async _initProxy() {
let loaded = false; let loaded = false;
try { try {
this._dbusProxy.init_finish(result); await this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null);
loaded = true; loaded = true;
} catch (e) { } catch (e) {
if (e.matches(Gio.DBusError, Gio.DBusError.TIMED_OUT)) {
// Ignore timeouts and install signals as normal, because with high // Ignore timeouts and install signals as normal, because with high
// probability the service will appear later on, and we will get a // probability the service will appear later on, and we will get a
// NameOwnerChanged which will finish loading // NameOwnerChanged which will finish loading
@ -214,7 +216,7 @@ class DBusEventSource extends EventSourceBase {
// (But still _initialized to false, because the proxy does not know // (But still _initialized to false, because the proxy does not know
// about the HasCalendars property and would cause an exception trying // about the HasCalendars property and would cause an exception trying
// to read it) // to read it)
} else { if (!e.matches(Gio.DBusError, Gio.DBusError.TIMED_OUT)) {
log('Error loading calendars: %s'.format(e.message)); log('Error loading calendars: %s'.format(e.message));
return; return;
} }
@ -238,7 +240,6 @@ class DBusEventSource extends EventSourceBase {
this.notify('has-calendars'); this.notify('has-calendars');
this._onNameAppeared(); this._onNameAppeared();
} }
});
} }
destroy() { destroy() {

View File

@ -10,6 +10,7 @@ const MessageTray = imports.ui.messageTray;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry; const ShellEntry = imports.ui.shellEntry;
Gio._promisify(Shell.NetworkAgent.prototype, 'init_async', 'init_finish');
Gio._promisify(Shell.NetworkAgent.prototype, Gio._promisify(Shell.NetworkAgent.prototype,
'search_vpn_plugin', 'search_vpn_plugin_finish'); 'search_vpn_plugin', 'search_vpn_plugin_finish');
@ -482,11 +483,11 @@ var VPNRequestHandler = class {
} }
} }
_readStdoutOldStyle() { async _readStdoutOldStyle() {
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, result) => { const [line, len_] =
let [line, len_] = this._dataStdout.read_line_finish_utf8(result); await this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null);
if (line == null) { if (line === null) {
// end of file // end of file
this._stdout.close(null); this._stdout.close(null);
return; return;
@ -496,14 +497,13 @@ var VPNRequestHandler = class {
// try to read more! // try to read more!
this._readStdoutOldStyle(); this._readStdoutOldStyle();
});
} }
_readStdoutNewStyle() { async _readStdoutNewStyle() {
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, (stream, result) => { const cnt =
let cnt = this._dataStdout.fill_finish(result); await this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null);
if (cnt == 0) { if (cnt === 0) {
// end of file // end of file
this._showNewStyleDialog(); this._showNewStyleDialog();
@ -514,7 +514,6 @@ var VPNRequestHandler = class {
// Try to read more // Try to read more
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size()); this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
this._readStdoutNewStyle(); this._readStdoutNewStyle();
});
} }
_showNewStyleDialog() { _showNewStyleDialog() {
@ -621,15 +620,17 @@ var NetworkAgent = class {
this._native.connect('cancel-request', this._cancelRequest.bind(this)); this._native.connect('cancel-request', this._cancelRequest.bind(this));
this._initialized = false; this._initialized = false;
this._native.init_async(GLib.PRIORITY_DEFAULT, null, (o, res) => { this._initNative();
}
async _initNative() {
try { try {
this._native.init_finish(res); await this._native.init_async(GLib.PRIORITY_DEFAULT, null);
this._initialized = true; this._initialized = true;
} catch (e) { } catch (e) {
this._native = null; this._native = null;
logError(e, 'error initializing the NetworkManager Agent'); logError(e, 'error initializing the NetworkManager Agent');
} }
});
} }
enable() { enable() {

View File

@ -7,6 +7,14 @@ var Tpl = null;
var Tp = null; var Tp = null;
try { try {
({ TelepathyGLib: Tp, TelepathyLogger: Tpl } = imports.gi); ({ TelepathyGLib: Tp, TelepathyLogger: Tpl } = imports.gi);
Gio._promisify(Tp.Channel.prototype, 'close_async', 'close_finish');
Gio._promisify(Tp.Channel.prototype,
'send_message_async', 'send_message_finish');
Gio._promisify(Tp.ChannelDispatchOperation.prototype,
'claim_with_async', 'claim_with_finish');
Gio._promisify(Tpl.LogManager.prototype,
'get_filtered_events_async', 'get_filtered_events_finish');
} catch (e) { } catch (e) {
log('Telepathy is not available, chat integration will be disabled.'); log('Telepathy is not available, chat integration will be disabled.');
} }
@ -215,7 +223,7 @@ class TelepathyClient extends Tp.BaseClient {
// We can only handle text channel, so close any other channel // We can only handle text channel, so close any other channel
if (!(channel instanceof Tp.TextChannel)) { if (!(channel instanceof Tp.TextChannel)) {
channel.close_async(null); channel.close_async();
continue; continue;
} }
@ -261,7 +269,7 @@ class TelepathyClient extends Tp.BaseClient {
} }
} }
_approveTextChannel(account, conn, channel, dispatchOp, context) { async _approveTextChannel(account, conn, channel, dispatchOp, context) {
let [targetHandle_, targetHandleType] = channel.get_handle(); let [targetHandle_, targetHandleType] = channel.get_handle();
if (targetHandleType != Tp.HandleType.CONTACT) { if (targetHandleType != Tp.HandleType.CONTACT) {
@ -270,17 +278,15 @@ class TelepathyClient extends Tp.BaseClient {
return; return;
} }
context.accept();
// Approve private text channels right away as we are going to handle it // Approve private text channels right away as we are going to handle it
dispatchOp.claim_with_async(this, (o, result) => {
try { try {
dispatchOp.claim_with_finish(result); await dispatchOp.claim_with_async(this);
this._handlingChannels(account, conn, [channel], false); this._handlingChannels(account, conn, [channel], false);
} catch (err) { } catch (err) {
log('Failed to Claim channel: %s'.format(err.toString())); log('Failed to Claim channel: %s'.format(err.toString()));
} }
});
context.accept();
} }
_delegatedChannelsCb(_client, _channels) { _delegatedChannelsCb(_client, _channels) {
@ -441,17 +447,14 @@ class ChatSource extends MessageTray.Source {
} }
} }
_getLogMessages() { async _getLogMessages() {
let logManager = Tpl.LogManager.dup_singleton(); let logManager = Tpl.LogManager.dup_singleton();
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT); let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
logManager.get_filtered_events_async(this._account, entity, const [events] = await logManager.get_filtered_events_async(
this._account, entity,
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES, Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
null, this._displayPendingMessages.bind(this)); null);
}
_displayPendingMessages(logManager, result) {
let [success_, events] = logManager.get_filtered_events_finish(result);
let logMessages = events.map(e => ChatMessage.newFromTplTextEvent(e)); let logMessages = events.map(e => ChatMessage.newFromTplTextEvent(e));
this._ensureNotification(); this._ensureNotification();
@ -509,9 +512,7 @@ class ChatSource extends MessageTray.Source {
this._ackMessages(); this._ackMessages();
// The chat box has been destroyed so it can't // The chat box has been destroyed so it can't
// handle the channel any more. // handle the channel any more.
this._channel.close_async((channel, result) => { this._channel.close_async();
channel.close_finish(result);
});
} else { } else {
// Don't indicate any unread messages when the notification // Don't indicate any unread messages when the notification
// that represents them has been destroyed. // that represents them has been destroyed.
@ -609,9 +610,7 @@ class ChatSource extends MessageTray.Source {
} }
let msg = Tp.ClientMessage.new_text(type, text); let msg = Tp.ClientMessage.new_text(type, text);
this._channel.send_message_async(msg, 0, (src, result) => { this._channel.send_message_async(msg, 0);
this._channel.send_message_finish(result);
});
} }
setChatState(state) { setChatState(state) {

View File

@ -29,8 +29,6 @@ const UserWidget = imports.ui.userWidget;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
Gio._promisify(Gio.DBusConnection.prototype, 'call', 'call_finish');
const _ITEM_ICON_SIZE = 64; const _ITEM_ICON_SIZE = 64;
const EndSessionDialogIface = loadInterfaceXML('org.gnome.SessionManager.EndSessionDialog'); const EndSessionDialogIface = loadInterfaceXML('org.gnome.SessionManager.EndSessionDialog');
@ -280,7 +278,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog'); this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
} }
_onPkOfflineProxyCreated(proxy, error) { async _onPkOfflineProxyCreated(proxy, error) {
if (error) { if (error) {
log(error.message); log(error.message);
return; return;
@ -295,15 +293,12 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
} }
// It only makes sense to check for this permission if PackageKit is available. // It only makes sense to check for this permission if PackageKit is available.
Polkit.Permission.new(
'org.freedesktop.packagekit.trigger-offline-update', null, null,
(source, res) => {
try { try {
this._updatesPermission = Polkit.Permission.new_finish(res); this._updatesPermission = await Polkit.Permission.new(
'org.freedesktop.packagekit.trigger-offline-update', null, null);
} catch (e) { } catch (e) {
log('No permission to trigger offline updates: %s'.format(e.toString())); log('No permission to trigger offline updates: %s'.format(e.toString()));
} }
});
} }
_onDestroy() { _onDestroy() {

View File

@ -10,10 +10,21 @@ imports.gi.versions.Gtk = '3.0';
imports.gi.versions.TelepathyGLib = '0.12'; imports.gi.versions.TelepathyGLib = '0.12';
imports.gi.versions.TelepathyLogger = '0.2'; imports.gi.versions.TelepathyLogger = '0.2';
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Meta, Polkit, Shell, St } = imports.gi;
const Gettext = imports.gettext; const Gettext = imports.gettext;
const System = imports.system; const System = imports.system;
Gio._promisify(Gio.DataInputStream.prototype, 'fill_async', 'fill_finish');
Gio._promisify(Gio.DataInputStream.prototype,
'read_line_async', 'read_line_finish');
Gio._promisify(Gio.DBus, 'get', 'get_finish');
Gio._promisify(Gio.DBusConnection.prototype, 'call', 'call_finish');
Gio._promisify(Gio.DBusProxy, 'new', 'new_finish');
Gio._promisify(Gio.DBusProxy.prototype, 'init_async', 'init_finish');
Gio._promisify(Gio.DBusProxy.prototype,
'call_with_unix_fd_list', 'call_with_unix_fd_list_finish');
Gio._promisify(Polkit.Permission, 'new', 'new_finish');
let _localTimeZone = null; let _localTimeZone = null;
// We can't import shell JS modules yet, because they may have // We can't import shell JS modules yet, because they may have

View File

@ -90,19 +90,17 @@ class AppMenu extends PopupMenu.PopupMenu {
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._detailsItem = this.addAction(_("Show Details"), () => { this._detailsItem = this.addAction(_('Show Details'), async () => {
let id = this._app.get_id(); let id = this._app.get_id();
let args = GLib.Variant.new('(ss)', [id, '']); let args = GLib.Variant.new('(ss)', [id, '']);
Gio.DBus.get(Gio.BusType.SESSION, null, (o, res) => { const bus = await Gio.DBus.get(Gio.BusType.SESSION, null);
let bus = Gio.DBus.get_finish(res); bus.call(
bus.call('org.gnome.Software', 'org.gnome.Software',
'/org/gnome/Software', '/org/gnome/Software',
'org.gtk.Actions', 'Activate', 'org.gtk.Actions', 'Activate',
GLib.Variant.new('(sava{sv})', new GLib.Variant('(sava{sv})', ['details', [args], null]),
['details', [args], null]),
null, 0, -1, null, null); null, 0, -1, null, null);
}); });
});
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());

View File

@ -204,7 +204,7 @@ var RemoteSearchProvider = class {
g_interface_info: proxyInfo, g_interface_info: proxyInfo,
g_interface_name: proxyInfo.name, g_interface_name: proxyInfo.name,
gFlags }); gFlags });
this.proxy.init_async(GLib.PRIORITY_DEFAULT, null, null); this.proxy.init_async(GLib.PRIORITY_DEFAULT, null);
this.appInfo = appInfo; this.appInfo = appInfo;
this.id = appInfo.get_id(); this.id = appInfo.get_id();

View File

@ -7,6 +7,13 @@ const GrabHelper = imports.ui.grabHelper;
const Lightbox = imports.ui.lightbox; const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main; const Main = imports.ui.main;
Gio._promisify(Shell.Screenshot.prototype, 'pick_color', 'pick_color_finish');
Gio._promisify(Shell.Screenshot.prototype, 'screenshot', 'screenshot_finish');
Gio._promisify(Shell.Screenshot.prototype,
'screenshot_window', 'screenshot_window_finish');
Gio._promisify(Shell.Screenshot.prototype,
'screenshot_area', 'screenshot_area_finish');
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot'); const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot');
@ -156,7 +163,7 @@ var ScreenshotService = class {
return [x, y, width, height]; return [x, y, width, height];
} }
ScreenshotAreaAsync(params, invocation) { async ScreenshotAreaAsync(params, invocation) {
let [x, y, width, height, flash, filename] = params; let [x, y, width, height, flash, filename] = params;
[x, y, width, height] = this._scaleArea(x, y, width, height); [x, y, width, height] = this._scaleArea(x, y, width, height);
if (!this._checkArea(x, y, width, height)) { if (!this._checkArea(x, y, width, height)) {
@ -173,21 +180,17 @@ var ScreenshotService = class {
if (!stream) if (!stream)
return; return;
screenshot.screenshot_area(x, y, width, height, stream,
(o, res) => {
try { try {
let [success_, area] = let [area] =
screenshot.screenshot_area_finish(res); await screenshot.screenshot_area(x, y, width, height, stream);
this._onScreenshotComplete( this._onScreenshotComplete(area, stream, file, flash, invocation);
area, stream, file, flash, invocation);
} catch (e) { } catch (e) {
this._removeShooterForSender(invocation.get_sender()); this._removeShooterForSender(invocation.get_sender());
invocation.return_value(new GLib.Variant('(bs)', [false, ''])); invocation.return_value(new GLib.Variant('(bs)', [false, '']));
} }
});
} }
ScreenshotWindowAsync(params, invocation) { async ScreenshotWindowAsync(params, invocation) {
let [includeFrame, includeCursor, flash, filename] = params; let [includeFrame, includeCursor, flash, filename] = params;
let screenshot = this._createScreenshot(invocation); let screenshot = this._createScreenshot(invocation);
if (!screenshot) if (!screenshot)
@ -197,21 +200,17 @@ var ScreenshotService = class {
if (!stream) if (!stream)
return; return;
screenshot.screenshot_window(includeFrame, includeCursor, stream,
(o, res) => {
try { try {
let [success_, area] = let [area] =
screenshot.screenshot_window_finish(res); await screenshot.screenshot_window(includeFrame, includeCursor, stream);
this._onScreenshotComplete( this._onScreenshotComplete(area, stream, file, flash, invocation);
area, stream, file, flash, invocation);
} catch (e) { } catch (e) {
this._removeShooterForSender(invocation.get_sender()); this._removeShooterForSender(invocation.get_sender());
invocation.return_value(new GLib.Variant('(bs)', [false, ''])); invocation.return_value(new GLib.Variant('(bs)', [false, '']));
} }
});
} }
ScreenshotAsync(params, invocation) { async ScreenshotAsync(params, invocation) {
let [includeCursor, flash, filename] = params; let [includeCursor, flash, filename] = params;
let screenshot = this._createScreenshot(invocation); let screenshot = this._createScreenshot(invocation);
if (!screenshot) if (!screenshot)
@ -221,18 +220,13 @@ var ScreenshotService = class {
if (!stream) if (!stream)
return; return;
screenshot.screenshot(includeCursor, stream,
(o, res) => {
try { try {
let [success_, area] = let [area] = await screenshot.screenshot(includeCursor, stream);
screenshot.screenshot_finish(res); this._onScreenshotComplete(area, stream, file, flash, invocation);
this._onScreenshotComplete(
area, stream, file, flash, invocation);
} catch (e) { } catch (e) {
this._removeShooterForSender(invocation.get_sender()); this._removeShooterForSender(invocation.get_sender());
invocation.return_value(new GLib.Variant('(bs)', [false, ''])); invocation.return_value(new GLib.Variant('(bs)', [false, '']));
} }
});
} }
async SelectAreaAsync(params, invocation) { async SelectAreaAsync(params, invocation) {
@ -273,10 +267,9 @@ var ScreenshotService = class {
if (!screenshot) if (!screenshot)
return; return;
screenshot.pick_color(coords.x, coords.y, (_o, res) => { const [color] = await screenshot.pick_color(coords.x, coords.y);
let [success_, color] = screenshot.pick_color_finish(res); const { red, green, blue } = color;
let { red, green, blue } = color; const retval = GLib.Variant.new('(a{sv})', [{
let retval = GLib.Variant.new('(a{sv})', [{
color: GLib.Variant.new('(ddd)', [ color: GLib.Variant.new('(ddd)', [
red / 255.0, red / 255.0,
green / 255.0, green / 255.0,
@ -285,7 +278,6 @@ var ScreenshotService = class {
}]); }]);
this._removeShooterForSender(invocation.get_sender()); this._removeShooterForSender(invocation.get_sender());
invocation.return_value(retval); invocation.return_value(retval);
});
} catch (e) { } catch (e) {
invocation.return_error_literal( invocation.return_error_literal(
Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED, Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,

View File

@ -325,8 +325,7 @@ var GnomeShellExtensions = class {
null, null,
Gio.DBusCallFlags.NONE, Gio.DBusCallFlags.NONE,
-1, -1,
null, null);
(conn, res) => conn.call_finish(res));
} }
ReloadExtensionAsync(params, invocation) { ReloadExtensionAsync(params, invocation) {

View File

@ -199,36 +199,36 @@ var InputSourceSystemSettings = class extends InputSourceSettings {
this._reload.bind(this)); this._reload.bind(this));
} }
_reload() { async _reload() {
Gio.DBus.system.call(this._BUS_NAME, let props;
try {
const result = await Gio.DBus.system.call(
this._BUS_NAME,
this._BUS_PATH, this._BUS_PATH,
this._BUS_PROPS_IFACE, this._BUS_PROPS_IFACE,
'GetAll', 'GetAll',
new GLib.Variant('(s)', [this._BUS_IFACE]), new GLib.Variant('(s)', [this._BUS_IFACE]),
null, Gio.DBusCallFlags.NONE, -1, null, null, Gio.DBusCallFlags.NONE, -1, null);
(conn, result) => { [props] = result.deep_unpack();
let props;
try {
props = conn.call_finish(result).deep_unpack()[0];
} catch (e) { } catch (e) {
log('Could not get properties from %s'.format(this._BUS_NAME)); log('Could not get properties from %s'.format(this._BUS_NAME));
return; return;
} }
let layouts = props['X11Layout'].unpack();
let variants = props['X11Variant'].unpack();
let options = props['X11Options'].unpack();
if (layouts != this._layouts || const layouts = props['X11Layout'].unpack();
variants != this._variants) { const variants = props['X11Variant'].unpack();
const options = props['X11Options'].unpack();
if (layouts !== this._layouts ||
variants !== this._variants) {
this._layouts = layouts; this._layouts = layouts;
this._variants = variants; this._variants = variants;
this._emitInputSourcesChanged(); this._emitInputSourcesChanged();
} }
if (options != this._options) { if (options !== this._options) {
this._options = options; this._options = options;
this._emitKeyboardOptionsChanged(); this._emitKeyboardOptionsChanged();
} }
});
} }
get inputSources() { get inputSources() {

View File

@ -15,6 +15,10 @@ const Util = imports.misc.util;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
Gio._promisify(NM.Client, 'new_async', 'new_finish');
Gio._promisify(NM.Client.prototype,
'check_connectivity_async', 'check_connectivity_finish');
const NMConnectionCategory = { const NMConnectionCategory = {
INVALID: 'invalid', INVALID: 'invalid',
WIRED: 'wired', WIRED: 'wired',
@ -1627,11 +1631,11 @@ class Indicator extends PanelMenu.SystemIndicator {
this._ctypes[NM.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN; this._ctypes[NM.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
this._ctypes[NM.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN; this._ctypes[NM.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
NM.Client.new_async(null, this._clientGot.bind(this)); this._getClient();
} }
_clientGot(obj, result) { async _getClient() {
this._client = NM.Client.new_finish(result); this._client = await NM.Client.new_async(null);
this._activeConnections = []; this._activeConnections = [];
this._connections = []; this._connections = [];
@ -1982,7 +1986,7 @@ class Indicator extends PanelMenu.SystemIndicator {
} }
} }
_portalHelperDone(proxy, emitter, parameters) { async _portalHelperDone(proxy, emitter, parameters) {
let [path, result] = parameters; let [path, result] = parameters;
if (result == PortalHelperResult.CANCELLED) { if (result == PortalHelperResult.CANCELLED) {
@ -1993,13 +1997,11 @@ class Indicator extends PanelMenu.SystemIndicator {
} else if (result == PortalHelperResult.COMPLETED) { } else if (result == PortalHelperResult.COMPLETED) {
this._closeConnectivityCheck(path); this._closeConnectivityCheck(path);
} else if (result == PortalHelperResult.RECHECK) { } else if (result == PortalHelperResult.RECHECK) {
this._client.check_connectivity_async(null, (client, res) => {
try { try {
let state = client.check_connectivity_finish(res); const state = await this._client.check_connectivity_async(null);
if (state >= NM.ConnectivityState.FULL) if (state >= NM.ConnectivityState.FULL)
this._closeConnectivityCheck(path); this._closeConnectivityCheck(path);
} catch (e) { } } catch (e) { }
});
} else { } else {
log('Invalid result from portal helper: %s'.format(result)); log('Invalid result from portal helper: %s'.format(result));
} }

View File

@ -52,22 +52,21 @@ const BOLT_DBUS_PATH = '/org/freedesktop/bolt';
var Client = class { var Client = class {
constructor() { constructor() {
this._proxy = null; this._proxy = null;
this.probing = false;
this._getProxy();
}
async _getProxy() {
let nodeInfo = Gio.DBusNodeInfo.new_for_xml(BoltClientInterface); let nodeInfo = Gio.DBusNodeInfo.new_for_xml(BoltClientInterface);
Gio.DBusProxy.new(Gio.DBus.system, try {
this._proxy = await Gio.DBusProxy.new(
Gio.DBus.system,
Gio.DBusProxyFlags.DO_NOT_AUTO_START, Gio.DBusProxyFlags.DO_NOT_AUTO_START,
nodeInfo.lookup_interface(BOLT_DBUS_CLIENT_IFACE), nodeInfo.lookup_interface(BOLT_DBUS_CLIENT_IFACE),
BOLT_DBUS_NAME, BOLT_DBUS_NAME,
BOLT_DBUS_PATH, BOLT_DBUS_PATH,
BOLT_DBUS_CLIENT_IFACE, BOLT_DBUS_CLIENT_IFACE,
null, null);
this._onProxyReady.bind(this));
this.probing = false;
}
_onProxyReady(o, res) {
try {
this._proxy = Gio.DBusProxy.new_finish(res);
} catch (e) { } catch (e) {
log('error creating bolt proxy: %s'.format(e.message)); log('error creating bolt proxy: %s'.format(e.message));
return; return;
@ -243,14 +242,15 @@ class Indicator extends PanelMenu.SystemIndicator {
this._source = null; this._source = null;
this._perm = null; this._perm = null;
this._createPermission();
}
Polkit.Permission.new('org.freedesktop.bolt.enroll', null, null, (source, res) => { async _createPermission() {
try { try {
this._perm = Polkit.Permission.new_finish(res); this._perm = await Polkit.Permission.new('org.freedesktop.bolt.enroll', null, null);
} catch (e) { } catch (e) {
log('Failed to get PolKit permission: %s'.format(e.toString())); log('Failed to get PolKit permission: %s'.format(e.toString()));
} }
});
} }
_onDestroy() { _onDestroy() {

View File

@ -201,10 +201,7 @@ var ExtensionsWindow = GObject.registerClass({
null, null,
Gio.DBusCallFlags.NONE, Gio.DBusCallFlags.NONE,
-1, -1,
null, null);
(o, res) => {
o.call_finish(res);
});
} }
_sortList(row1, row2) { _sortList(row1, row2) {