diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index cf76732e9..0768dee34 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -1825,7 +1825,7 @@ var AppSearchProvider = class AppSearchProvider { this._parentalControlsManager = ParentalControlsManager.getDefault(); } - getResultMetas(apps, callback) { + getResultMetas(apps) { const { scaleFactor } = St.ThemeContext.get_for_stage(global.stage); let metas = []; for (let id of apps) { @@ -1852,24 +1852,25 @@ var AppSearchProvider = class AppSearchProvider { } } - callback(metas); + return new Promise(resolve => resolve(metas)); } filterResults(results, maxNumber) { return results.slice(0, maxNumber); } - getInitialResultSet(terms, callback, _cancellable) { + getInitialResultSet(terms, cancellable) { // Defer until the parental controls manager is initialised, so the // results can be filtered correctly. if (!this._parentalControlsManager.initialized) { - let initializedId = this._parentalControlsManager.connect('app-filter-changed', () => { - if (this._parentalControlsManager.initialized) { - this._parentalControlsManager.disconnect(initializedId); - this.getInitialResultSet(terms, callback, _cancellable); - } + return new Promise(resolve => { + let initializedId = this._parentalControlsManager.connect('app-filter-changed', async () => { + if (this._parentalControlsManager.initialized) { + this._parentalControlsManager.disconnect(initializedId); + resolve(await this.getInitialResultSet(terms, cancellable)); + } + }); }); - return; } let query = terms.join(' '); @@ -1887,12 +1888,11 @@ var AppSearchProvider = class AppSearchProvider { }); results = results.concat(this._systemActions.getMatchingActions(terms)); - - callback(results); + return new Promise(resolve => resolve(results)); } - getSubsearchResultSet(previousResults, terms, callback, cancellable) { - this.getInitialResultSet(terms, callback, cancellable); + getSubsearchResultSet(previousResults, terms, cancellable) { + return this.getInitialResultSet(terms, cancellable); } createResultObject(resultMeta) { diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js index d9eef287f..0358b3404 100644 --- a/js/ui/remoteSearch.js +++ b/js/ui/remoteSearch.js @@ -250,48 +250,43 @@ var RemoteSearchProvider = class { return regularResults.slice(0, maxNumber).concat(specialResults.slice(0, maxNumber)); } - _getResultsFinished(results, error, callback) { - if (error) { - if (error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) - return; - - log(`Received error from D-Bus search provider ${this.id}: ${error}`); - callback([]); - return; + async getInitialResultSet(terms, cancellable) { + try { + const [results] = await this.proxy.GetInitialResultSetAsync(terms, cancellable); + return results; + } catch (error) { + if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) + log(`Received error from D-Bus search provider ${this.id}: ${error}`); + return []; } - - callback(results[0]); } - getInitialResultSet(terms, callback, cancellable) { - this.proxy.GetInitialResultSetRemote(terms, - (results, error) => { - this._getResultsFinished(results, error, callback); - }, - cancellable); + async getSubsearchResultSet(previousResults, newTerms, cancellable) { + try { + const [results] = await this.proxy.GetSubsearchResultSetAsync(previousResults, newTerms, cancellable); + return results; + } catch (error) { + if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) + log(`Received error from D-Bus search provider ${this.id}: ${error}`); + return []; + } } - getSubsearchResultSet(previousResults, newTerms, callback, cancellable) { - this.proxy.GetSubsearchResultSetRemote(previousResults, newTerms, - (results, error) => { - this._getResultsFinished(results, error, callback); - }, - cancellable); - } - - _getResultMetasFinished(results, error, callback) { - if (error) { + async getResultMetas(ids, cancellable) { + let metas; + try { + [metas] = await this.proxy.GetResultMetasAsync(ids, cancellable); + } catch (error) { if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) log(`Received error from D-Bus search provider ${this.id} during GetResultMetas: ${error}`); - callback([]); - return; + return []; } - let metas = results[0]; + let resultMetas = []; for (let i = 0; i < metas.length; i++) { for (let prop in metas[i]) { // we can use the serialized icon variant directly - if (prop != 'icon') + if (prop !== 'icon') metas[i][prop] = metas[i][prop].deep_unpack(); } @@ -303,15 +298,7 @@ var RemoteSearchProvider = class { clipboardText: metas[i]['clipboardText'], }); } - callback(resultMetas); - } - - getResultMetas(ids, callback, cancellable) { - this.proxy.GetResultMetasRemote(ids, - (results, error) => { - this._getResultMetasFinished(results, error, callback); - }, - cancellable); + return resultMetas; } activateResult(id) { diff --git a/js/ui/search.js b/js/ui/search.js index 5375e7fc6..71870a039 100644 --- a/js/ui/search.js +++ b/js/ui/search.js @@ -208,47 +208,40 @@ var SearchResultsBase = GObject.registerClass({ _setMoreCount(_count) { } - _ensureResultActors(results, callback) { + async _ensureResultActors(results) { let metasNeeded = results.filter( resultId => this._resultDisplays[resultId] === undefined); - if (metasNeeded.length === 0) { - callback(true); - } else { - this._cancellable.cancel(); - this._cancellable.reset(); + if (metasNeeded.length === 0) + return; - this.provider.getResultMetas(metasNeeded, metas => { - if (this._cancellable.is_cancelled()) { - if (metas.length > 0) - log(`Search provider ${this.provider.id} returned results after the request was canceled`); - callback(false); - return; - } - if (metas.length != metasNeeded.length) { - log(`Wrong number of result metas returned by search provider ${this.provider.id}: ` + - `expected ${metasNeeded.length} but got ${metas.length}`); - callback(false); - return; - } - if (metas.some(meta => !meta.name || !meta.id)) { - log(`Invalid result meta returned from search provider ${this.provider.id}`); - callback(false); - return; - } + this._cancellable.cancel(); + this._cancellable.reset(); - metasNeeded.forEach((resultId, i) => { - let meta = metas[i]; - let display = this._createResultDisplay(meta); - display.connect('key-focus-in', this._keyFocusIn.bind(this)); - this._resultDisplays[resultId] = display; - }); - callback(true); - }, this._cancellable); + const metas = await this.provider.getResultMetas(metasNeeded, this._cancellable); + + if (this._cancellable.is_cancelled()) { + if (metas.length > 0) + throw new Error(`Search provider ${this.provider.id} returned results after the request was canceled`); } + + if (metas.length !== metasNeeded.length) { + throw new Error(`Wrong number of result metas returned by search provider ${this.provider.id}: ` + + `expected ${metasNeeded.length} but got ${metas.length}`); + } + + if (metas.some(meta => !meta.name || !meta.id)) + throw new Error(`Invalid result meta returned from search provider ${this.provider.id}`); + + metasNeeded.forEach((resultId, i) => { + let meta = metas[i]; + let display = this._createResultDisplay(meta); + display.connect('key-focus-in', this._keyFocusIn.bind(this)); + this._resultDisplays[resultId] = display; + }); } - updateSearch(providerResults, terms, callback) { + async updateSearch(providerResults, terms, callback) { this._terms = terms; if (providerResults.length == 0) { this._clearResultDisplay(); @@ -261,25 +254,23 @@ var SearchResultsBase = GObject.registerClass({ : providerResults; let moreCount = Math.max(providerResults.length - results.length, 0); - this._ensureResultActors(results, successful => { - if (!successful) { - this._clearResultDisplay(); - callback(); - return; - } + try { + await this._ensureResultActors(results); // To avoid CSS transitions causing flickering when // the first search result stays the same, we hide the // content while filling in the results. this.hide(); this._clearResultDisplay(); - results.forEach(resultId => { - this._addItem(this._resultDisplays[resultId]); - }); + results.forEach( + resultId => this._addItem(this._resultDisplays[resultId])); this._setMoreCount(this.provider.canLaunchSearch ? moreCount : 0); this.show(); callback(); - }); + } catch (e) { + this._clearResultDisplay(); + callback(); + } } } }); @@ -638,11 +629,6 @@ var SearchResultsView = GObject.registerClass({ provider.display.destroy(); } - _gotResults(results, provider) { - this._results[provider.id] = results; - this._updateResults(provider, results); - } - _clearSearchTimeout() { if (this._searchTimeoutId > 0) { GLib.source_remove(this._searchTimeoutId); @@ -661,6 +647,25 @@ var SearchResultsView = GObject.registerClass({ this._updateSearchProgress(); } + async _doProviderSearch(provider, previousResults) { + provider.searchInProgress = true; + + let results; + if (this._isSubSearch && previousResults) { + results = await provider.getSubsearchResultSet( + previousResults, + this._terms, + this._cancellable); + } else { + results = await provider.getInitialResultSet( + this._terms, + this._cancellable); + } + + this._results[provider.id] = results; + this._updateResults(provider, results); + } + _doSearch() { this._startingSearch = false; @@ -668,23 +673,8 @@ var SearchResultsView = GObject.registerClass({ this._results = {}; this._providers.forEach(provider => { - provider.searchInProgress = true; - let previousProviderResults = previousResults[provider.id]; - if (this._isSubSearch && previousProviderResults) { - provider.getSubsearchResultSet(previousProviderResults, - this._terms, - results => { - this._gotResults(results, provider); - }, - this._cancellable); - } else { - provider.getInitialResultSet(this._terms, - results => { - this._gotResults(results, provider); - }, - this._cancellable); - } + this._doProviderSearch(provider, previousProviderResults); }); this._updateSearchProgress();