[gnome-shell] search: Add RemoteSearchProvider
- From: Florian MÃllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] search: Add RemoteSearchProvider
- Date: Tue, 21 Feb 2012 22:02:04 +0000 (UTC)
commit f6749fb2045efd6c94719cbf62353225a3b26216
Author: Florian MÃllner <fmuellner gnome org>
Date: Thu Nov 17 00:11:05 2011 +0100
search: Add RemoteSearchProvider
Add an asynchronous search provider for results from a DBus service
implementing the org.gnome.Shell.SearchProvider interface; this
will allow applications to hook into the Shell's search without
implementing it in Shell itself or requiring an extension.
https://bugzilla.gnome.org/show_bug.cgi?id=663125
data/Makefile.am | 4 +
data/org.gnome.ShellSearchProvider.xml | 147 ++++++++++++++++++++++++++++++++
js/Makefile.am | 1 +
js/ui/remoteSearch.js | 131 ++++++++++++++++++++++++++++
4 files changed, 283 insertions(+), 0 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index cbc7b79..4803081 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -17,6 +17,9 @@ dist_searchproviders_DATA = \
open-search-providers/google.xml \
open-search-providers/wikipedia.xml
+introspectiondir = $(datadir)/dbus-1/interfaces
+introspection_DATA = org.gnome.ShellSearchProvider.xml
+
themedir = $(pkgdatadir)/theme
dist_theme_DATA = \
theme/calendar-arrow-left.svg \
@@ -73,6 +76,7 @@ shaders_DATA = \
EXTRA_DIST = \
gnome-shell.desktop.in.in \
gnome-shell-extension-prefs.desktop.in.in \
+ $(introspection_DATA) \
$(menu_DATA) \
$(shaders_DATA) \
$(convert_DATA) \
diff --git a/data/org.gnome.ShellSearchProvider.xml b/data/org.gnome.ShellSearchProvider.xml
new file mode 100644
index 0000000..16fa9ad
--- /dev/null
+++ b/data/org.gnome.ShellSearchProvider.xml
@@ -0,0 +1,147 @@
+<!DOCTYPE node PUBLIC
+'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
+'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
+<node>
+ <interface name="org.gnome.Shell.SearchProvider">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ The interface used for integrating into GNOME Shell's search
+ interface.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+
+ <method name="GetInitialResultSet">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Called when the user first begins a search.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="as" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ Array of search terms, which the provider should treat as
+ logical AND.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" direction="out">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of result identifier strings representing items which
+ match the given search terms. Identifiers must be unique within
+ the provider's domain, but other than that may be chosen freely
+ by the provider.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <method name="GetSubsearchResultSet">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Called when a search is performed which is a "subsearch" of
+ the previous search, e.g. the method may return less results, but
+ not more or different results.
+
+ This allows search providers to only search through the previous
+ result set, rather than possibly performing a full re-query.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="as" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ Array of item identifiers
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ Array of updated search terms, which the provider should treat as
+ logical AND.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" direction="out">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of result identifier strings representing items which
+ match the given search terms. Identifiers must be unique within
+ the provider's domain, but other than that may be chosen freely
+ by the provider.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <method name="GetResultMetas">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Return an array of meta data used to display each given result
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="as" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of result identifiers as returned by
+ GetInitialResultSet() or GetSubsearchResultSet()
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="a{sv}" direction="out">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ A dictionary describing the given search result, containing
+ 'id', 'name' (both strings) and either 'icon' (a serialized
+ GIcon) or 'icon-data' (raw image data as (iiibiiay) - width,
+ height, rowstride, has-alpha, bits per sample, channels, data)
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <method name="ActivateResult">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Called when the users chooses a given result. The result should
+ be displayed in the application associated with the corresponding
+ provider.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="s" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ A result identifier as returned by GetInitialResultSet() or
+ GetSubsearchResultSet()
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+ </interface>
+</node>
diff --git a/js/Makefile.am b/js/Makefile.am
index 98f7a48..6780617 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -75,6 +75,7 @@ nobase_dist_js_DATA = \
ui/placeDisplay.js \
ui/polkitAuthenticationAgent.js \
ui/popupMenu.js \
+ ui/remoteSearch.js \
ui/runDialog.js \
ui/scripting.js \
ui/search.js \
diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js
new file mode 100644
index 0000000..18e5749
--- /dev/null
+++ b/js/ui/remoteSearch.js
@@ -0,0 +1,131 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Gio = imports.gi.Gio;
+const Lang = imports.lang;
+const St = imports.gi.St;
+
+const Search = imports.ui.search;
+
+const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
+<method name="GetInitialResultSet">
+ <arg type="as" direction="in" />
+ <arg type="as" direction="out" />
+</method>
+<method name="GetSubsearchResultSet">
+ <arg type="as" direction="in" />
+ <arg type="as" direction="in" />
+ <arg type="as" direction="out" />
+</method>
+<method name="GetResultMetas">
+ <arg type="as" direction="in" />
+ <arg type="aa{sv}" direction="out" />
+</method>
+<method name="ActivateResult">
+ <arg type="s" direction="in" />
+</method>
+</interface>;
+
+var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
+
+
+const RemoteSearchProvider = new Lang.Class({
+ Name: 'RemoteSearchProvider',
+ Extends: Search.SearchProvider,
+
+ _init: function(title, icon, dbusName, dbusPath) {
+ this._proxy = new SearchProviderProxy(Gio.DBus.session,
+ dbusName, dbusPath);
+
+ this.parent(title.toUpperCase());
+ this.async = true;
+ this._cancellable = new Gio.Cancellable();
+ },
+
+ createIcon: function(size, meta) {
+ if (meta['gicon']) {
+ return new St.Icon({ gicon: Gio.icon_new_for_string(meta['gicon']),
+ icon_size: size,
+ icon_type: St.IconType.FULLCOLOR });
+ } else if (meta['icon-data']) {
+ let [width, height, rowStride, hasAlpha,
+ bitsPerSample, nChannels, data] = meta['icon-data'];
+ let textureCache = St.TextureCache.get_default();
+ return textureCache.load_from_raw(data, hasAlpha,
+ width, height, rowStride, size);
+ }
+
+ // Ugh, but we want to fall back to something ...
+ return new St.Icon({ icon_name: 'text-x-generic',
+ icon_size: size,
+ icon_type: St.IconType.FULLCOLOR });
+ },
+
+ _getResultsFinished: function(results, error) {
+ if (error)
+ return;
+ this.searchSystem.pushResults(this, results[0]);
+ },
+
+ getInitialResultSetAsync: function(terms) {
+ this._cancellable.cancel();
+ this._cancellable.reset();
+ try {
+ this._proxy.GetInitialResultSetRemote(terms,
+ Lang.bind(this, this._getResultsFinished),
+ this._cancellable);
+ } catch(e) {
+ log('Error calling GetInitialResultSet for provider %s: %s'.format( this.title, e.toString()));
+ this.searchSystem.pushResults(this, []);
+ }
+ },
+
+ getSubsearchResultSetAsync: function(previousResults, newTerms) {
+ this._cancellable.cancel();
+ this._cancellable.reset();
+ try {
+ this._proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
+ Lang.bind(this, this._getResultsFinished),
+ this._cancellable);
+ } catch(e) {
+ log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.title, e.toString()));
+ this.searchSystem.pushResults(this, []);
+ }
+ },
+
+ _getResultMetasFinished: function(results, error, callback) {
+ if (error) {
+ callback([]);
+ return;
+ }
+ let metas = results[0];
+ let resultMetas = [];
+ for (let i = 0; i < metas.length; i++) {
+ for (let prop in metas[i])
+ metas[i][prop] = metas[i][prop].deep_unpack();
+ resultMetas.push({ id: metas[i]['id'],
+ name: metas[i]['name'],
+ createIcon: Lang.bind(this,
+ this.createIcon, metas[i]) });
+ }
+ callback(resultMetas);
+ },
+
+ getResultMetasAsync: function(ids, callback) {
+ this._cancellable.cancel();
+ this._cancellable.reset();
+ try {
+ this._proxy.GetResultMetasRemote(ids,
+ Lang.bind(this, this._getResultMetasFinished, callback),
+ this._cancellable);
+ } catch(e) {
+ log('Error calling GetResultMetas for provider %s: %s'.format(this.title, e.toString()));
+ callback([]);
+ }
+ },
+
+ activateResult: function(id) {
+ this._proxy.ActivateResultRemote(id);
+ }
+});
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]