viewSelector: Move all of the provider-loading logic to SearchSystem

The existing provider system is split between a confusing mess of
RemoteSearch, SearchSystem, SearchDisplay, and ViewSelector, partly
because of the vestigal in-shell search system. Move most of the
logic to search.js so it's easier to read.
This commit is contained in:
Jasper St. Pierre 2013-10-30 12:38:46 -04:00
parent c0c20d49a5
commit 0590962d36
2 changed files with 69 additions and 81 deletions

View File

@ -2,16 +2,19 @@
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const Lang = imports.lang; const Lang = imports.lang;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk; const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const Signals = imports.signals; const Signals = imports.signals;
const St = imports.gi.St; const St = imports.gi.St;
const Atk = imports.gi.Atk; const Atk = imports.gi.Atk;
const AppDisplay = imports.ui.appDisplay;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const IconGrid = imports.ui.iconGrid; const IconGrid = imports.ui.iconGrid;
const Main = imports.ui.main; const Main = imports.ui.main;
const Overview = imports.ui.overview; const Overview = imports.ui.overview;
const RemoteSearch = imports.ui.remoteSearch;
const Separator = imports.ui.separator; const Separator = imports.ui.separator;
const Search = imports.ui.search; const Search = imports.ui.search;
const Util = imports.misc.util; const Util = imports.misc.util;
@ -26,38 +29,67 @@ const SearchSystem = new Lang.Class({
_init: function() { _init: function() {
this._providers = []; this._providers = [];
this._remoteProviders = [];
this.reset(); this._registerProvider(new AppDisplay.AppSearchProvider());
this._searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::disable-external', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));
this._reloadRemoteProviders();
}, },
registerProvider: function (provider) { _shouldUseSearchProvider: function(provider) {
// the disable-external GSetting only affects remote providers
if (!provider.isRemoteProvider)
return true;
if (this._searchSettings.get_boolean('disable-external'))
return false;
let appId = provider.appInfo.get_id();
let disable = this._searchSettings.get_strv('disabled');
return disable.indexOf(appId) == -1;
},
addProvider: function(provider) {
this._providers.push(provider);
this.emit('providers-changed');
},
_reloadRemoteProviders: function() {
let remoteProviders = this._providers.filter(function(provider) {
return provider.isRemoteProvider;
});
remoteProviders.forEach(Lang.bind(this, function(provider) {
this._unregisterProvider(provider);
}));
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, function(provider) {
if (!this._shouldUseSearchProvider(provider))
return;
this._registerProvider(provider);
}));
this.emit('providers-changed');
},
_registerProvider: function (provider) {
provider.searchSystem = this; provider.searchSystem = this;
this._providers.push(provider); this._providers.push(provider);
if (provider.isRemoteProvider)
this._remoteProviders.push(provider);
}, },
unregisterProvider: function (provider) { _unregisterProvider: function (provider) {
let index = this._providers.indexOf(provider); let index = this._providers.indexOf(provider);
if (index == -1)
return;
provider.searchSystem = null;
this._providers.splice(index, 1); this._providers.splice(index, 1);
provider.searchSystem = null;
let remoteIndex = this._remoteProviders.indexOf(provider);
if (remoteIndex != -1)
this._remoteProviders.splice(remoteIndex, 1);
}, },
getProviders: function() { getProviders: function() {
return this._providers; return this._providers;
}, },
getRemoteProviders: function() {
return this._remoteProviders;
},
getTerms: function() { getTerms: function() {
return this._previousTerms; return this._previousTerms;
}, },
@ -76,7 +108,7 @@ const SearchSystem = new Lang.Class({
this.emit('search-updated', this._previousResults[i]); this.emit('search-updated', this._previousResults[i]);
}, },
updateSearchResults: function(terms) { setTerms: function(terms) {
if (!terms) if (!terms)
return; return;
@ -443,10 +475,7 @@ Signals.addSignalMethods(GridSearchResults.prototype);
const SearchResults = new Lang.Class({ const SearchResults = new Lang.Class({
Name: 'SearchResults', Name: 'SearchResults',
_init: function(searchSystem) { _init: function() {
this._searchSystem = searchSystem;
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateResults));
this.actor = new St.BoxLayout({ name: 'searchResults', this.actor = new St.BoxLayout({ name: 'searchResults',
vertical: true }); vertical: true });
@ -481,12 +510,14 @@ const SearchResults = new Lang.Class({
y_align: St.Align.MIDDLE }); y_align: St.Align.MIDDLE });
this._content.add(this._statusBin, { expand: true }); this._content.add(this._statusBin, { expand: true });
this._statusBin.add_actor(this._statusText); this._statusBin.add_actor(this._statusText);
this._searchSystem.getProviders().forEach(Lang.bind(this, function(provider) {
this.createProviderDisplay(this._providers[i]);
}));
this._highlightDefault = false; this._highlightDefault = false;
this._defaultResult = null; this._defaultResult = null;
this._searchSystem = new SearchSystem();
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateResults));
this._searchSystem.connect('providers-changed', Lang.bind(this, this._updateProviderDisplays));
this._updateProviderDisplays();
}, },
_onPan: function(action) { _onPan: function(action) {
@ -500,7 +531,10 @@ const SearchResults = new Lang.Class({
Util.ensureActorVisibleInScrollView(this._scrollView, actor); Util.ensureActorVisibleInScrollView(this._scrollView, actor);
}, },
createProviderDisplay: function(provider) { _ensureProviderDisplay: function(provider) {
if (provider.display)
return;
let providerDisplay; let providerDisplay;
if (provider.appInfo) if (provider.appInfo)
providerDisplay = new ListSearchResults(provider); providerDisplay = new ListSearchResults(provider);
@ -512,9 +546,8 @@ const SearchResults = new Lang.Class({
provider.display = providerDisplay; provider.display = providerDisplay;
}, },
destroyProviderDisplay: function(provider) { _updateProviderDisplays: function() {
provider.display.destroy(); this._searchSystem.getProviders().forEach(Lang.bind(this, this._ensureProviderDisplay));
provider.display = null;
}, },
_clearDisplay: function() { _clearDisplay: function() {
@ -536,6 +569,10 @@ const SearchResults = new Lang.Class({
this._statusBin.show(); this._statusBin.show();
}, },
setTerms: function(terms) {
this._searchSystem.setTerms(terms);
},
_maybeSetInitialSelection: function() { _maybeSetInitialSelection: function() {
let newDefaultResult = null; let newDefaultResult = null;

View File

@ -14,7 +14,6 @@ const AppDisplay = imports.ui.appDisplay;
const Main = imports.ui.main; const Main = imports.ui.main;
const OverviewControls = imports.ui.overviewControls; const OverviewControls = imports.ui.overviewControls;
const Params = imports.misc.params; const Params = imports.misc.params;
const RemoteSearch = imports.ui.remoteSearch;
const Search = imports.ui.search; const Search = imports.ui.search;
const ShellEntry = imports.ui.shellEntry; const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
@ -64,8 +63,6 @@ const ViewSelector = new Lang.Class({
this._searchActive = false; this._searchActive = false;
this._searchTimeoutId = 0; this._searchTimeoutId = 0;
this._searchSystem = new Search.SearchSystem();
this._entry = searchEntry; this._entry = searchEntry;
ShellEntry.addContextMenu(this._entry); ShellEntry.addContextMenu(this._entry);
@ -101,22 +98,11 @@ const ViewSelector = new Lang.Class({
this._appsPage = this._addPage(this.appDisplay.actor, this._appsPage = this._addPage(this.appDisplay.actor,
_("Applications"), 'view-grid-symbolic'); _("Applications"), 'view-grid-symbolic');
this._searchResults = new Search.SearchResults(this._searchSystem); this._searchResults = new Search.SearchResults();
this._searchPage = this._addPage(this._searchResults.actor, this._searchPage = this._addPage(this._searchResults.actor,
_("Search"), 'edit-find-symbolic', _("Search"), 'edit-find-symbolic',
{ a11yFocus: this._entry }); { a11yFocus: this._entry });
this._searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::disable-external', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));
// Default search providers
this.addSearchProvider(new AppDisplay.AppSearchProvider());
// Load remote search providers provided by applications
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
// Since the entry isn't inside the results container we install this // Since the entry isn't inside the results container we install this
// dummy widget as the last results container child so that we can // dummy widget as the last results container child so that we can
// include the entry in the keynav tab path // include the entry in the keynav tab path
@ -482,45 +468,10 @@ const ViewSelector = new Lang.Class({
let terms = getTermsForSearchString(this._entry.get_text()); let terms = getTermsForSearchString(this._entry.get_text());
this._searchSystem.updateSearchResults(terms); this._searchResults.setTerms(terms);
this._showPage(this._searchPage); this._showPage(this._searchPage);
}, },
_shouldUseSearchProvider: function(provider) {
// the disable-external GSetting only affects remote providers
if (!provider.isRemoteProvider)
return true;
if (this._searchSettings.get_boolean('disable-external'))
return false;
let appId = provider.appInfo.get_id();
let disable = this._searchSettings.get_strv('disabled');
return disable.indexOf(appId) == -1;
},
_reloadRemoteProviders: function() {
// removeSearchProvider() modifies the provider list we iterate on,
// so make a copy first
let remoteProviders = this._searchSystem.getRemoteProviders().slice(0);
remoteProviders.forEach(Lang.bind(this, this.removeSearchProvider));
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
},
addSearchProvider: function(provider) {
if (!this._shouldUseSearchProvider(provider))
return;
this._searchSystem.registerProvider(provider);
this._searchResults.createProviderDisplay(provider);
},
removeSearchProvider: function(provider) {
this._searchSystem.unregisterProvider(provider);
this._searchResults.destroyProviderDisplay(provider);
},
getActivePage: function() { getActivePage: function() {
if (this._activePage == this._workspacesPage) if (this._activePage == this._workspacesPage)
return ViewPage.WINDOWS; return ViewPage.WINDOWS;