From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= Date: Thu, 23 Aug 2018 20:00:57 +0200 Subject: search: call XUbuntuCancel method on providers when no data is needed Add XUbuntuCancel method to search providers and call it when a search provider is still doing operations. Ignore the result when the method does not exist or is cancelled. This will allow to stop operations on providers. Fixes LP: #1756826 Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/bionic/+source/gnome-shell/+bug/1756826 Forwarded: not-needed --- .../org.gnome.ShellSearchProvider.xml | 6 ++++ .../org.gnome.ShellSearchProvider2.xml | 6 ++++ js/ui/remoteSearch.js | 12 ++++++++ js/ui/search.js | 33 ++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/data/dbus-interfaces/org.gnome.ShellSearchProvider.xml b/data/dbus-interfaces/org.gnome.ShellSearchProvider.xml index 78ad305..393cb01 100644 --- a/data/dbus-interfaces/org.gnome.ShellSearchProvider.xml +++ b/data/dbus-interfaces/org.gnome.ShellSearchProvider.xml @@ -69,5 +69,11 @@ + + + diff --git a/data/dbus-interfaces/org.gnome.ShellSearchProvider2.xml b/data/dbus-interfaces/org.gnome.ShellSearchProvider2.xml index 9502340..8141bc0 100644 --- a/data/dbus-interfaces/org.gnome.ShellSearchProvider2.xml +++ b/data/dbus-interfaces/org.gnome.ShellSearchProvider2.xml @@ -83,5 +83,11 @@ + + + diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js index 6bd282b..4804bdd 100644 --- a/js/ui/remoteSearch.js +++ b/js/ui/remoteSearch.js @@ -29,6 +29,7 @@ const SearchProviderIface = ` + `; @@ -57,6 +58,7 @@ const SearchProvider2Iface = ` + `; @@ -307,6 +309,16 @@ class RemoteSearchProvider { return resultMetas; } + async XUbuntuCancel(cancellable) { + try { + await this.proxy.XUbuntuCancelAsync(cancellable); + } catch (error) { + if (!error.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD) && + !error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) + log(`Received error from D-Bus search provider ${this.id} during XUbuntuCancel: ${error}`); + } + } + activateResult(id) { this.proxy.ActivateResultAsync(id).catch(logError); } diff --git a/js/ui/search.js b/js/ui/search.js index b938b03..4e68bd7 100644 --- a/js/ui/search.js +++ b/js/ui/search.js @@ -224,7 +224,9 @@ const SearchResultsBase = GObject.registerClass({ this._cancellable.cancel(); this._cancellable.reset(); + this.provider.resultsMetasInProgress = true; const metas = await this.provider.getResultMetas(metasNeeded, this._cancellable); + this.provider.resultsMetasInProgress = this._cancellable.is_cancelled(); if (this._cancellable.is_cancelled()) { if (metas.length > 0) @@ -602,6 +604,10 @@ export const SearchResultsView = GObject.registerClass({ this._searchTimeoutId = 0; this._cancellable = new Gio.Cancellable(); + this._searchCancelCancellable = new Gio.Cancellable(); + const cancellableCancelledId = this._cancellable.connect(() => + this._cancelSearchProviderRequest()); + this.connect('destroy', () => this._cancellable.disconnect(cancellableCancelledId)); this._registerProvider(new AppDisplay.AppSearchProvider()); @@ -650,11 +656,31 @@ export const SearchResultsView = GObject.registerClass({ } } + _cancelSearchProviderRequest() { + if (this._terms.length !== 0 || this._searchCancelTimeoutId) + return; + + this._searchCancelTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => { + Promise.all(this._providers.map(async provider => { + if (provider.isRemoteProvider && + (provider.searchInProgress || provider.resultsMetasInProgress)) { + await provider.XUbuntuCancel(this._searchCancelCancellable); + provider.searchInProgress = false; + provider.resultsMetasInProgress = false; + } + })).catch(logError); + + delete this._searchCancelTimeoutId; + return GLib.SOURCE_REMOVE; + }); + } + _reset() { this._terms = []; this._results = {}; this._clearDisplay(); this._clearSearchTimeout(); + this._cancelSearchProviderRequest(); this._defaultResult = null; this._startingSearch = false; @@ -726,6 +752,13 @@ export const SearchResultsView = GObject.registerClass({ if (this._terms.length > 0) isSubSearch = searchString.indexOf(previousSearchString) === 0; + this._searchCancelCancellable.cancel(); + this._searchCancelCancellable.reset(); + if (this._searchCancelTimeoutId) { + GLib.source_remove(this._searchCancelTimeoutId); + delete this._searchCancelTimeoutId; + } + this._terms = terms; this._isSubSearch = isSubSearch; this._updateSearchProgress();