diff options
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/gtk-application-player.vala | 123 | ||||
-rw-r--r-- | src/metadata-menu-item.vala | 3 | ||||
-rw-r--r-- | src/mpris2-controller.vala | 4 | ||||
-rw-r--r-- | src/player-controller.vala | 2 |
5 files changed, 131 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0a67a7c..381da56 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -67,7 +67,8 @@ music_bridge_VALASOURCES = \ settings-manager.vala \ playlists-menu-item.vala \ freedesktop-interfaces.vala \ - fetch-file.vala + fetch-file.vala \ + gtk-application-player.vala music_bridge_VALAFLAGS = \ --ccode \ diff --git a/src/gtk-application-player.vala b/src/gtk-application-player.vala new file mode 100644 index 0000000..8422ca5 --- /dev/null +++ b/src/gtk-application-player.vala @@ -0,0 +1,123 @@ +/* +Copyright 2013 Canonical Ltd. + +Authors: + Marco Trevisan <marco.trevisan@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +[DBus (name = "org.gtk.Application")] +public interface DBusGtkApplication : Object { + public abstract void Activate(GLib.HashTable<string, Variant?> platform_data) throws IOError; +} + +public class GtkApplicationPlayer : GLib.Object +{ + public PlayerController owner {get; construct;} + + private bool gtk_application_searched = false; + private DBusGtkApplication gtk_application; + + public GtkApplicationPlayer(PlayerController ctrl) + { + GLib.Object(owner: ctrl); + } + + public void activate(uint timestamp) + { + this.setup_gtk_application(); + + if (this.gtk_application == null) { + return; + } + + var context = Gdk.Display.get_default().get_app_launch_context(); + context.set_timestamp(timestamp); + + var data = new GLib.HashTable<string, Variant?>(str_hash, str_equal); + data["desktop-startup-id"] = context.get_startup_notify_id(this.owner.app_info, new GLib.List<GLib.File>()); + + try { + this.gtk_application.Activate(data); + } + catch (IOError e) {} + } + + private void setup_gtk_application() + { + if (owner.current_state != PlayerController.state.CONNECTED) + return; + + if (this.gtk_application != null || this.gtk_application_searched) + return; + + try { + var connection = Bus.get_sync(BusType.SESSION); + var name = this.owner.dbus_name; + string gtk_application_path; + this.find_iface_path(connection, name, "/", "org.gtk.Application", out gtk_application_path); + this.gtk_application_searched = true; + + if (gtk_application_path != null) { + this.gtk_application = Bus.get_proxy_sync(BusType.SESSION, this.owner.dbus_name, gtk_application_path); + } + } catch (Error e) { + return; + } + } + + private void find_iface_path(DBusConnection connection, string name, string path, string target_iface, out string found_path) + { + found_path = null; + DBusNodeInfo node = null; + + try { + unowned string xml_string; + var xml = connection.call_sync(name, path, "org.freedesktop.DBus.Introspectable", "Introspect", null, new VariantType("(s)"), DBusCallFlags.NONE, 1000); + xml.get("(&s)", out xml_string); + node = new DBusNodeInfo.for_xml(xml_string); + } catch (Error e) { + return; + } + + if (node == null) { + return; + } + + foreach (var iface in node.interfaces) { + if (iface.name == target_iface) { + found_path = path; + return; + } + } + + bool is_root = (path == "/"); + + foreach (var subnode in node.nodes) { + string new_path = path; + + if (!is_root) { + new_path += "/"; + } + + new_path += subnode.path; + + find_iface_path(connection, name, new_path, target_iface, out found_path); + + if (found_path != null) { + return; + } + } + } +}
\ No newline at end of file diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala index bcd4378..a81c143 100644 --- a/src/metadata-menu-item.vala +++ b/src/metadata-menu-item.vala @@ -176,7 +176,8 @@ public class MetadataMenuitem : PlayerItem { this.owner.instantiate(timestamp); } - else if(this.owner.current_state == PlayerController.state.CONNECTED){ + else if (this.owner.current_state == PlayerController.state.CONNECTED) { + this.owner.gtk_app_player.activate(timestamp); this.owner.mpris_bridge.expose(timestamp); } } diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 5015f80..9230a59 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -208,9 +208,9 @@ public class Mpris2Controller : GLib.Object return (this.player != null && this.mpris2_root != null); } - public void expose(uint timestamp) + public void expose(uint timestmap) { - if(this.connected() == true){ + if (this.connected() == true) { this.mpris2_root.Raise.begin(); } } diff --git a/src/player-controller.vala b/src/player-controller.vala index 764efa5..dbe7c3c 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -45,6 +45,7 @@ public class PlayerController : GLib.Object public string dbus_name { get; set;} public ArrayList<PlayerItem> custom_items; public Mpris2Controller mpris_bridge; + public GtkApplicationPlayer gtk_app_player; public AppInfo? app_info { get; set;} public int menu_offset { get; set;} public string icon_name { get; set; } @@ -149,6 +150,7 @@ public class PlayerController : GLib.Object debug ( " establish mpris connection - use playlists value = %s ", this.use_playlists.to_string() ); this.mpris_bridge = new Mpris2Controller (this); + this.gtk_app_player = new GtkApplicationPlayer (this); this.determine_state (); } |