[gnome-shell/wip/re-search-v2: 9/29] remote-search: deal with LaunchSearch not being available



commit 87502cc3a3fd107dfac1cc64ceef9b26dc6c89ba
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Mon Nov 26 23:50:49 2012 -0500

    remote-search: deal with LaunchSearch not being available
    
    If LaunchSearch() is not available on the remote search provider:
    - don't show a 'more' emblem over the provider icon
    - launch the application itself when the provider icon is clicked
    - log a message, so we can file bugs for apps

 js/ui/remoteSearch.js  |   39 ++++++++++++++++++++++++++++++++++++---
 js/ui/search.js        |    4 ++++
 js/ui/searchDisplay.js |    4 +++-
 3 files changed, 43 insertions(+), 4 deletions(-)
---
diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js
index 503e632..458f32d 100644
--- a/js/ui/remoteSearch.js
+++ b/js/ui/remoteSearch.js
@@ -32,6 +32,13 @@ const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
 </method>
 </interface>;
 
+const IntrospectableIface = <interface name="org.freedesktop.DBus.Introspectable">
+<method name="Introspect">
+    <arg type="s" direction="out" />
+</method>
+</interface>;
+
+var IntrospectableProxy = Gio.DBusProxy.makeProxyWrapper(IntrospectableIface);
 var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
 
 function loadRemoteSearchProviders(addProviderCallback) {
@@ -172,9 +179,12 @@ const RemoteSearchProvider = new Lang.Class({
     _init: function(appInfo, dbusName, dbusPath) {
         this._proxy = new SearchProviderProxy(Gio.DBus.session,
             dbusName, dbusPath, Lang.bind(this, this._onProxyConstructed));
+        this._introspectable = new IntrospectableProxy(Gio.DBus.session, dbusName, dbusPath);
 
         this.parent(appInfo.get_name().toUpperCase(), appInfo, true);
         this._cancellable = new Gio.Cancellable();
+
+        this._canLaunchSearch = null;
     },
 
     _onProxyConstructed: function(proxy) {
@@ -263,9 +273,32 @@ const RemoteSearchProvider = new Lang.Class({
         this._proxy.ActivateResultRemote(id);
     },
 
+    canLaunchSearch: function() {
+        if (this._canLaunchSearch == null) {
+            let data = this._introspectable.IntrospectSync();
+            let xml = data.toString();
+            // strip preamble comments
+            xml = xml.substr(xml.indexOf('<node>'));
+
+            let iface = Gio.DBusInterfaceInfo.new_for_xml(xml);
+            let method = iface.lookup_method('LaunchSearch');
+
+            this._canLaunchSearch = (method != null);
+        }
+
+        return this._canLaunchSearch;
+    },
+
     launchSearch: function(terms) {
-        this._proxy.LaunchSearchRemote(terms);
+        let canLaunchSearch = this.canLaunchSearch();
+
+        if (canLaunchSearch) {
+            this._proxy.LaunchSearchRemote(terms);
+        } else {
+            // the provider is not compatible with this version of the interface, launch
+            // the app itself but warn so we can catch the error in logs
+            log('Search provider ' + this.appInfo.get_id() + ' does not implement LaunchSearch');
+            this.appInfo.launch([], global.create_app_launch_context());
+        }
     }
 });
-
-
diff --git a/js/ui/search.js b/js/ui/search.js
index a963143..f4d9088 100644
--- a/js/ui/search.js
+++ b/js/ui/search.js
@@ -174,6 +174,10 @@ const SearchProvider = new Lang.Class({
      */
     launchSearch: function(terms) {
         throw new Error('Not implemented');
+    },
+
+    canLaunchSearch: function() {
+        return false;
     }
 });
 Signals.addSignalMethods(SearchProvider.prototype);
diff --git a/js/ui/searchDisplay.js b/js/ui/searchDisplay.js
index 2463b05..6b57b66 100644
--- a/js/ui/searchDisplay.js
+++ b/js/ui/searchDisplay.js
@@ -492,7 +492,9 @@ const SearchDisplay = new Lang.Class({
             let results = meta.resultDisplay.getResultsForDisplay();
 
             if (meta.icon)
-                meta.icon.moreIcon.visible = meta.resultDisplay.hasMoreResults();
+                meta.icon.moreIcon.visible =
+                    meta.resultDisplay.hasMoreResults() &&
+                    provider.canLaunchSearch();
 
             provider.getResultMetas(results, Lang.bind(this, function(metas) {
                 this._clearDisplayForProvider(provider);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]