From a964487e2fcd11946b5f95ab36b20cbd1bea4a57 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 9 Dec 2010 11:36:33 +0000 Subject: moving towards testing proposed playlists api --- src/Makefile.am | 1 + src/common-defs.h | 3 + src/mpris2-controller.vala | 34 ++++++- src/mpris2-interfaces.vala | 24 +++++ src/player-controller.vala | 11 ++- src/playlists-menu-item.vala | 46 +++++++++ src/sound-service.c | 4 +- vapi/Indicate-0.2.vapi | 218 ------------------------------------------- vapi/common-defs.vapi | 37 +++++--- 9 files changed, 136 insertions(+), 242 deletions(-) create mode 100644 src/playlists-menu-item.vala delete mode 100644 vapi/Indicate-0.2.vapi diff --git a/src/Makefile.am b/src/Makefile.am index 1c381f5..214507b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,6 +64,7 @@ music_bridge_VALASOURCES = \ mpris2-watcher.vala \ mpris2-controller.vala \ player-item.vala \ + playlists-menu-item.vala \ familiar-players-db.vala \ fetch-file.vala diff --git a/src/common-defs.h b/src/common-defs.h index 214f60a..8ec69e8 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -49,3 +49,6 @@ with this program. If not, see . #define DBUSMENU_SCRUB_MENUITEM_POSITION "x-canonical-sound-menu-player-scrub-position" #define DBUSMENU_SCRUB_MENUITEM_PLAY_STATE "x-canonical-sound-menu-player-scrub-play-state" +#define DBUSMENU_PLAYLISTS_MENUITEM_TYPE "x-canonical-sound-menu-player-playlists-type" +#define DBUSMENU_PLAYLISTS_MENUITEM_TITLE "x-canonical-sound-menu-player-playlists-title" +#define DBUSMENU_PLAYLISTS_MENUITEM_PLAYLISTS "x-canonical-sound-menu-player-playlists-playlists" \ No newline at end of file diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 59e3122..2c19606 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -21,8 +21,8 @@ using Dbusmenu; [DBus (name = "org.freedesktop.DBus.Properties")] public interface FreeDesktopProperties : Object{ - public signal void PropertiesChanged(string source, HashTable changed_properties, - string[] invalid); + public signal void PropertiesChanged (string source, HashTable changed_properties, + string[] invalid ); } /* @@ -34,13 +34,14 @@ public class Mpris2Controller : GLib.Object public static const string root_interface = "org.mpris.MediaPlayer2" ; public MprisRoot mpris2_root {get; construct;} public MprisPlayer player {get; construct;} + public MprisPlaylists playlists {get; construct;} public FreeDesktopProperties properties_interface {get; construct;} public PlayerController owner {get; construct;} - + public Mpris2Controller(PlayerController ctrl) { - GLib.Object(owner: ctrl); + GLib.Object(owner: ctrl); } construct{ @@ -51,6 +52,9 @@ public class Mpris2Controller : GLib.Object this.player = Bus.get_proxy_sync ( BusType.SESSION, root_interface.concat(".").concat(this.owner.mpris_name), "/org/mpris/MediaPlayer2" ); + this.playlists = Bus.get_proxy_sync ( BusType.SESSION, + root_interface.concat(".").concat(this.owner.mpris_name), + "/org/mpris/MediaPlayer2" ); this.properties_interface = Bus.get_proxy_sync ( BusType.SESSION, "org.freedesktop.Properties.PropertiesChanged", @@ -127,12 +131,14 @@ public class Mpris2Controller : GLib.Object GLib.HashTable? cleaned_metadata = this.clean_metadata(); this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, MetadataMenuitem.attributes_format()); + this.fetch_playlists(); } public void transport_update(TransportMenuitem.action command) { debug("transport_event input = %i", (int)command); if(command == TransportMenuitem.action.PLAY_PAUSE){ + this.fetch_playlists(); this.player.PlayPause.begin(); } else if(command == TransportMenuitem.action.PREVIOUS){ @@ -143,6 +149,26 @@ public class Mpris2Controller : GLib.Object } } + public void fetch_playlists() + { + if (this.playlists == null){ + warning("Playlists object is null"); + return; + } + PlaylistDetails[] current_playlists = this.playlists.GetPlaylists(0, 10, "Alphabetical", false); + if( current_playlists != null ){ + debug( "Size of the playlist array = %i", current_playlists.length ); + PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; + playlists_item.update(current_playlists); + /*foreach(PlaylistDetails detail in current_playlists){ + debug( "Playlist Name = %s", detail.name); + debug( "Playlist path = %s", detail.path); + debug( "Playlist icon path = %s", detail.icon_path); + debug(" \n \n \n \n \n "); + }*/ + } + } + public bool connected() { return (this.player != null && this.mpris2_root != null); diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index ebea135..3f5519b 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -44,3 +44,27 @@ public interface MprisPlayer : Object { // signals public signal void Seeked(int64 new_position); } + + +// Playlist container +public struct PlaylistDetails{ + public ObjectPath path; + public string name; + public string icon_path; +} + +[DBus (name = "org.mpris.MediaPlayer2.Playlists")] +// TODO: API criticisms +// get playlists should be able to be async => pass in struct to be populated or pass in callback +public interface MprisPlaylists : Object { + //properties + public abstract string[] Orderings{owned get; set;} + public abstract uint32 PlaylistCount{owned get; set;} + + //methods + public abstract async void ActivatePlaylist(ObjectPath playlist_id) throws IOError; + public abstract PlaylistDetails[] GetPlaylists ( uint32 index, + uint32 max_count, + string order, + bool reverse_order ) throws IOError; +} \ No newline at end of file diff --git a/src/player-controller.vala b/src/player-controller.vala index 0b540f9..b9e275f 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -23,13 +23,14 @@ using Gee; public class PlayerController : GLib.Object { - public const int WIDGET_QUANTITY = 4; + public const int WIDGET_QUANTITY = 5; public static enum widget_order{ SEPARATOR, TITLE, METADATA, TRANSPORT, + PLAYLISTS } public enum state{ @@ -158,7 +159,11 @@ public class PlayerController : GLib.Object // Transport item TransportMenuitem transport_item = new TransportMenuitem(this); this.custom_items.add(transport_item); - + + // Playlist item + PlaylistsMenuitem playlist_menuitem = new PlaylistsMenuitem(this); + this.custom_items.add(playlist_menuitem); + foreach(PlayerItem item in this.custom_items){ root_menu.child_add_position(item, this.menu_offset + this.custom_items.index_of(item)); } @@ -184,7 +189,7 @@ public class PlayerController : GLib.Object this.update_state(state.CONNECTED); TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem; title.toggle_active_triangle(true); - this.mpris_bridge.initial_update(); + this.mpris_bridge.initial_update(); } else{ this.update_state(state.DISCONNECTED); diff --git a/src/playlists-menu-item.vala b/src/playlists-menu-item.vala new file mode 100644 index 0000000..8106600 --- /dev/null +++ b/src/playlists-menu-item.vala @@ -0,0 +1,46 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +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 . +*/ + +using Dbusmenu; +using DbusmenuPlaylists; +using Gee; + +public class PlaylistsMenuitem : PlayerItem +{ + public PlaylistsMenuitem ( PlayerController parent ) + { + Object ( item_type: MENUITEM_TYPE, owner: parent ); + } + + public void update (PlaylistDetails[] playlists) + { + foreach ( PlaylistDetail detail in playlists ){ + + } + } + + public static HashSet attributes_format() + { + HashSet attrs = new HashSet(); + attrs.add(MENUITEM_TITLE); + attrs.add(MENUITEM_PLAYLISTS); + return attrs; + } + +} diff --git a/src/sound-service.c b/src/sound-service.c index 98f1881..defcb94 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } diff --git a/vapi/Indicate-0.2.vapi b/vapi/Indicate-0.2.vapi deleted file mode 100644 index 1381037..0000000 --- a/vapi/Indicate-0.2.vapi +++ /dev/null @@ -1,218 +0,0 @@ -/* Indicate-0.2.vapi generated by vapigen, do not modify. */ - -[CCode (cprefix = "Indicate", lower_case_cprefix = "indicate_")] -namespace Indicate { - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public class Indicator : GLib.Object { - public weak GLib.Object parent; - [CCode (has_construct_function = false)] - public Indicator (); - public bool get_displayed (); - public uint get_id (); - public virtual GLib.Value get_property (string key); - public GLib.Value get_property_value (string key); - public Indicate.Server get_server (); - public bool is_visible (); - public string[] list_properties (); - public void set_displayed (bool displayed); - public virtual void set_property (string key, GLib.Value data); - public void set_property_bool (string key, bool value); - public void set_property_int (string key, int value); - public void set_property_time (string key, GLib.TimeVal time); - public void set_property_value (string key, GLib.Value value); - public void set_server (Indicate.Server server); - [CCode (has_construct_function = false)] - public Indicator.with_server (Indicate.Server server); - public signal void displayed (bool object); - [HasEmitter] - public signal void hide (); - public signal void modified (string object); - [HasEmitter] - public signal void show (); - [HasEmitter] - public signal void user_display (uint object); - } - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public class Listener : GLib.Object { - public weak GLib.Object parent; - [CCode (has_construct_function = false)] - public Listener (); - public void display (Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, uint timestamp); - public void displayed (Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, bool displayed); - public void get_property (Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, [CCode (delegate_target_pos = 0)] Indicate.listener_get_property_cb callback); - public void get_property_bool (Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, [CCode (delegate_target_pos = 0)] Indicate.listener_get_property_bool_cb callback); - public void get_property_int (Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, [CCode (delegate_target_pos = 0)] Indicate.listener_get_property_int_cb callback); - public void get_property_time (Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, [CCode (delegate_target_pos = 0)] Indicate.listener_get_property_time_cb callback); - public void get_property_value (Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, [CCode (delegate_target_pos = 0)] Indicate.listener_get_property_value_cb callback); - public static GLib.Type indicator_get_gtype (); - public static Indicate.Listener ref_default (); - public bool server_check_interest (Indicate.ListenerServer server, Indicate.Interests interest); - public void server_get_count (Indicate.ListenerServer server, [CCode (delegate_target_pos = 0)] Indicate.listener_get_server_uint_property_cb callback); - public void server_get_desktop (Indicate.ListenerServer server, [CCode (delegate_target_pos = 0)] Indicate.listener_get_server_property_cb callback, void* data); - public static GLib.Type server_get_gtype (); - public void server_get_menu (Indicate.ListenerServer server, [CCode (delegate_target_pos = 0)] Indicate.listener_get_server_property_cb callback); - public static void server_get_type (Indicate.Listener listener, Indicate.ListenerServer server, [CCode (delegate_target_pos = 0)] Indicate.listener_get_server_property_cb callback); - public void server_remove_interest (Indicate.ListenerServer server, Indicate.Interests interest); - public void server_show_interest (Indicate.ListenerServer server, Indicate.Interests interest); - public void set_default_max_indicators (int max); - public void set_server_max_indicators (Indicate.ListenerServer server, int max); - public signal void indicator_added (Indicate.ListenerServer object, Indicate.ListenerIndicator p0); - public signal void indicator_modified (Indicate.ListenerServer object, Indicate.ListenerIndicator p0, string p1); - public signal void indicator_removed (Indicate.ListenerServer object, Indicate.ListenerIndicator p0); - public signal void indicator_servers_report (); - public signal void server_added (Indicate.ListenerServer object, string p0); - public signal void server_count_changed (Indicate.ListenerServer object, uint p0); - public signal void server_removed (Indicate.ListenerServer object, string p0); - } - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public class Server : GLib.Object { - public weak GLib.Object parent; - public void add_indicator (Indicate.Indicator indicator); - public virtual bool check_interest (Indicate.Interests interest); - public virtual bool get_indicator_count (out uint count) throws GLib.Error; - public virtual bool get_indicator_property (uint id, owned string property, GLib.Value value) throws GLib.Error; - public int get_max_indicators (); - public virtual uint get_next_id (); - public void hide (); - public virtual void indicator_added (uint id); - public virtual bool indicator_displayed (owned string sender, uint id, bool displayed) throws GLib.Error; - public virtual void indicator_removed (uint id); - public virtual int max_indicators_get (); - public virtual bool max_indicators_set (owned string sender, int max); - public static Indicate.Server ref_default (); - public void remove_indicator (Indicate.Indicator indicator); - public virtual bool remove_interest (owned string sender, Indicate.Interests interest); - public void set_count (uint count); - public static void set_dbus_object (string obj); - public void set_default (); - public void set_desktop_file (string path); - public void set_menu (Dbusmenu.Server menu); - public void set_type (string type); - public void show (); - public virtual bool show_indicator_to_user (uint id, uint timestamp) throws GLib.Error; - public virtual bool show_interest (owned string sender, Indicate.Interests interest); - public uint count { get; set; } - public string desktop { get; set; } - public string type { get; set; } - public signal void indicator_delete (uint object); - public signal void indicator_modified (uint object, string p0); - public signal void indicator_new (uint object); - public signal void interest_added (uint object); - public signal void interest_removed (uint object); - public signal void max_indicators_changed (int object); - public signal void server_count_changed (uint object); - public signal void server_display (uint object); - public signal void server_hide (string object); - public signal void server_show (string object); - } - [CCode (type_id = "INDICATE_TYPE_LISTENER_INDICATOR", cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public struct ListenerIndicator { - public uint get_id (); - } - [CCode (type_id = "INDICATE_TYPE_LISTENER_SERVER", cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public struct ListenerServer { - public unowned string get_dbusname (); - } - [CCode (cprefix = "INDICATE_INTEREST_", cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public enum Interests { - NONE, - SERVER_DISPLAY, - SERVER_SIGNAL, - INDICATOR_DISPLAY, - INDICATOR_SIGNAL, - INDICATOR_COUNT, - LAST - } - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate string[] indicator_list_properties_slot_t (Indicate.Indicator indicator); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate void listener_get_property_bool_cb (Indicate.Listener listener, Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, bool propertydata, void* data); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate void listener_get_property_cb (Indicate.Listener listener, Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, string propertydata, void* data); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate void listener_get_property_int_cb (Indicate.Listener listener, Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, int propertydata, void* data); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate void listener_get_property_time_cb (Indicate.Listener listener, Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, GLib.TimeVal propertydata, void* data); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate void listener_get_property_value_cb (Indicate.Listener listener, Indicate.ListenerServer server, Indicate.ListenerIndicator indicator, owned string property, GLib.Value propertydata, void* data); - [CCode (cname ="indicate_listener_get_server_property_cb", cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate void listener_get_server_property_cb (Indicate.Listener listener, Indicate.ListenerServer server, owned string value, void* data); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate void listener_get_server_uint_property_cb (Indicate.Listener listener, Indicate.ListenerServer server, uint value, void* data); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate bool server_get_indicator_list_slot_t (Indicate.Server server, out unowned Indicate.Indicator[] indicators); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate bool server_get_indicator_properties_slot_t (Indicate.Server server, uint id, out string[] properties); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h", has_target = false)] - public delegate bool server_get_indicator_property_group_slot_t (Indicate.Server server, uint id, string[] properties, out string[] value); - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const int INDICATOR_H_INCLUDED__; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const int INDICATOR_MESSAGES_H_INCLUDED__; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_MESSAGES_PROP_ATTENTION; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_MESSAGES_PROP_COUNT; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_MESSAGES_PROP_ICON; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_MESSAGES_PROP_NAME; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_MESSAGES_PROP_TIME; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_MESSAGES_SERVER_TYPE; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_SIGNAL_DISPLAY; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_SIGNAL_DISPLAYED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_SIGNAL_HIDE; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_SIGNAL_MODIFIED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_SIGNAL_SHOW; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_VALUE_FALSE; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string INDICATOR_VALUE_TRUE; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const int INTERESTS_H_INCLUDED__; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const int LISTENER_H_INCLUDED__; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string LISTENER_SIGNAL_INDICATOR_ADDED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string LISTENER_SIGNAL_INDICATOR_MODIFIED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string LISTENER_SIGNAL_INDICATOR_REMOVED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string LISTENER_SIGNAL_SERVER_ADDED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string LISTENER_SIGNAL_SERVER_COUNT_CHANGED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string LISTENER_SIGNAL_SERVER_REMOVED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const int SERVER_H_INCLUDED__; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const int SERVER_INDICATOR_NULL; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_INDICATOR_ADDED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_INDICATOR_MODIFIED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_INDICATOR_REMOVED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_INTEREST_ADDED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_INTEREST_REMOVED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_MAX_INDICATORS_CHANGED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_SERVER_COUNT_CHANGED; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_SERVER_DISPLAY; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_SERVER_HIDE; - [CCode (cheader_filename = "libindicate/./indicator-messages.h,libindicate/./indicator.h,libindicate/./interests.h,libindicate/./listener.h,libindicate/./server.h")] - public const string SERVER_SIGNAL_SERVER_SHOW; -} diff --git a/vapi/common-defs.vapi b/vapi/common-defs.vapi index 6938420..2946d25 100644 --- a/vapi/common-defs.vapi +++ b/vapi/common-defs.vapi @@ -19,31 +19,38 @@ with this program. If not, see . [CCode (cheader_filename = "common-defs.h")] namespace DbusmenuMetadata{ - public const string MENUITEM_TYPE; - public const string MENUITEM_ARTIST; - public const string MENUITEM_TITLE; - public const string MENUITEM_ALBUM; - public const string MENUITEM_ARTURL; + public const string MENUITEM_TYPE; + public const string MENUITEM_ARTIST; + public const string MENUITEM_TITLE; + public const string MENUITEM_ALBUM; + public const string MENUITEM_ARTURL; } [CCode (cheader_filename = "common-defs.h")] namespace DbusmenuTransport{ - public const string MENUITEM_TYPE; - public const string MENUITEM_PLAY_STATE; + public const string MENUITEM_TYPE; + public const string MENUITEM_PLAY_STATE; } [CCode (cheader_filename = "common-defs.h")] namespace DbusmenuTitle{ - public const string MENUITEM_TYPE; - public const string MENUITEM_NAME; - public const string MENUITEM_ICON; - public const string MENUITEM_RUNNING; + public const string MENUITEM_TYPE; + public const string MENUITEM_NAME; + public const string MENUITEM_ICON; + public const string MENUITEM_RUNNING; } [CCode (cheader_filename = "common-defs.h")] namespace DbusmenuScrub{ - public const string MENUITEM_TYPE; - public const string MENUITEM_POSITION; - public const string MENUITEM_DURATION; - public const string MENUITEM_PLAY_STATE; + public const string MENUITEM_TYPE; + public const string MENUITEM_POSITION; + public const string MENUITEM_DURATION; + public const string MENUITEM_PLAY_STATE; +} + +[CCode (cheader_filename = "common-defs.h")] +namespace DbusmenuPlaylists{ + public const string MENUITEM_TYPE; + public const string MENUITEM_TITLE; + public const string MENUITEM_PLAYLISTS; } \ No newline at end of file -- cgit v1.2.3 From f3b321919e3390f3d3af2eea33ad71611616ce61 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 10 Dec 2010 13:02:16 +0000 Subject: playlist widget population --- src/dbus-menu-manager.c | 1 + src/mpris2-controller.vala | 8 ++++---- src/mpris2-interfaces.vala | 22 +++++++++++++++------- src/player-controller.vala | 20 +++++++++++++++----- src/player-item.vala | 4 ++-- src/playlists-menu-item.vala | 29 +++++++++++++++++++++++++---- 6 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 37e1c18..f92c324 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -214,6 +214,7 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service // Sound preferences dialog DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Sound Preferences...")); + //_("Sound Preferences...")); dbusmenu_menuitem_child_append(root, settings_mi); g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 2c19606..0bd5562 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -138,7 +138,6 @@ public class Mpris2Controller : GLib.Object { debug("transport_event input = %i", (int)command); if(command == TransportMenuitem.action.PLAY_PAUSE){ - this.fetch_playlists(); this.player.PlayPause.begin(); } else if(command == TransportMenuitem.action.PREVIOUS){ @@ -160,12 +159,13 @@ public class Mpris2Controller : GLib.Object debug( "Size of the playlist array = %i", current_playlists.length ); PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; playlists_item.update(current_playlists); - /*foreach(PlaylistDetails detail in current_playlists){ + foreach(PlaylistDetails detail in current_playlists){ + debug(" \n \n "); debug( "Playlist Name = %s", detail.name); debug( "Playlist path = %s", detail.path); debug( "Playlist icon path = %s", detail.icon_path); - debug(" \n \n \n \n \n "); - }*/ + debug(" \n \n "); + } } } diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index 3f5519b..ab8ac95 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -1,6 +1,5 @@ /* Copyright 2010 Canonical Ltd. - Authors: Conor Curran @@ -45,7 +44,6 @@ public interface MprisPlayer : Object { public signal void Seeked(int64 new_position); } - // Playlist container public struct PlaylistDetails{ public ObjectPath path; @@ -54,8 +52,18 @@ public struct PlaylistDetails{ } [DBus (name = "org.mpris.MediaPlayer2.Playlists")] + // TODO: API criticisms -// get playlists should be able to be async => pass in struct to be populated or pass in callback +// Get_playlists should be able to be async => pass in callback pointer +// Lacking the ability to query the current playlist (should be asyncable) +// - needed to keep client and servers in sync +// => get_current_playlist -> +// Should return PlaylistDetails struct with each field nil if there is no active playlist. +// Otherwise a populated PlaylistDetails +// should be asyncable. +// => Need to be able to query get_playlist using ordered by last modified. +// => Need a signal to inform that the active playlist has changed + public interface MprisPlaylists : Object { //properties public abstract string[] Orderings{owned get; set;} @@ -63,8 +71,8 @@ public interface MprisPlaylists : Object { //methods public abstract async void ActivatePlaylist(ObjectPath playlist_id) throws IOError; - public abstract PlaylistDetails[] GetPlaylists ( uint32 index, - uint32 max_count, - string order, - bool reverse_order ) throws IOError; + public abstract PlaylistDetails[] GetPlaylists ( uint32 index, + uint32 max_count, + string order, + bool reverse_order ) throws IOError; } \ No newline at end of file diff --git a/src/player-controller.vala b/src/player-controller.vala index b9e275f..450ecd6 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -141,6 +141,10 @@ public class PlayerController : GLib.Object this.custom_items[widget_order.METADATA].populated(MetadataMenuitem.attributes_format())); this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, true); + this.custom_items[widget_order.PLAYLISTS].property_set_bool(MENUITEM_PROP_VISIBLE, + true); + this.custom_items[widget_order.PLAYLISTS].property_set_bool ( MENUITEM_PROP_ENABLED, + true ); } private void construct_widgets() @@ -160,12 +164,18 @@ public class PlayerController : GLib.Object TransportMenuitem transport_item = new TransportMenuitem(this); this.custom_items.add(transport_item); - // Playlist item + // Playlist item PlaylistsMenuitem playlist_menuitem = new PlaylistsMenuitem(this); this.custom_items.add(playlist_menuitem); foreach(PlayerItem item in this.custom_items){ - root_menu.child_add_position(item, this.menu_offset + this.custom_items.index_of(item)); + if (this.custom_items.index_of(item) != 4) { + root_menu.child_add_position(item, this.menu_offset + this.custom_items.index_of(item)); + } + else{ + PlaylistsMenuitem playlists_menuitem = item as PlaylistsMenuitem; + root_menu.child_add_position(playlists_menuitem.root_item, this.menu_offset + this.custom_items.index_of(item)); + } } } @@ -188,11 +198,11 @@ public class PlayerController : GLib.Object if(this.mpris_bridge.connected() == true){ this.update_state(state.CONNECTED); TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem; - title.toggle_active_triangle(true); - this.mpris_bridge.initial_update(); + title.toggle_active_triangle(true); + this.mpris_bridge.initial_update(); } else{ this.update_state(state.DISCONNECTED); } - } + } } diff --git a/src/player-item.vala b/src/player-item.vala index c80a17d..75f673b 100644 --- a/src/player-item.vala +++ b/src/player-item.vala @@ -28,7 +28,7 @@ public class PlayerItem : Dbusmenu.Menuitem public PlayerItem(string type) { - Object(item_type: type); + Object(item_type: type); } construct { @@ -54,7 +54,7 @@ public class PlayerItem : Dbusmenu.Menuitem if(data == null){ debug("PlayerItem::Update -> The hashtable was null - just leave it!"); return; - } + } foreach(string property in attributes){ string[] input_keys = property.split("-"); diff --git a/src/playlists-menu-item.vala b/src/playlists-menu-item.vala index 8106600..4b81e48 100644 --- a/src/playlists-menu-item.vala +++ b/src/playlists-menu-item.vala @@ -23,18 +23,39 @@ using Gee; public class PlaylistsMenuitem : PlayerItem { + + public Menuitem root_item; public PlaylistsMenuitem ( PlayerController parent ) { Object ( item_type: MENUITEM_TYPE, owner: parent ); } + construct{ + this.property_set ( MENUITEM_PROP_LABEL, "Choose Playlist"); + this.root_item = new Menuitem(); + this.root_item.property_set ( MENUITEM_PROP_LABEL, "Choose Playlist" ); + } - public void update (PlaylistDetails[] playlists) + public new void update (PlaylistDetails[] playlists) { - foreach ( PlaylistDetail detail in playlists ){ - + foreach ( PlaylistDetails detail in playlists ){ + Dbusmenu.Menuitem menuitem = new Menuitem(); + menuitem.property_set (MENUITEM_PROP_LABEL, detail.name); + menuitem.property_set (MENUITEM_PROP_ICON_NAME, "source-smart-playlist"); + menuitem.property_set_bool (MENUITEM_PROP_VISIBLE, true); + menuitem.property_set_bool (MENUITEM_PROP_ENABLED, true); + + menuitem.item_activated.connect(() => { + submenu_item_activated (menuitem.id );}); + + this.root_item.child_append( menuitem ); } } - + + private void submenu_item_activated (int menu_item_id) + { + debug("item %i was activated", menu_item_id); + } + public static HashSet attributes_format() { HashSet attrs = new HashSet(); -- cgit v1.2.3 From 93190886959bfa16b835794a4a12a9a945e7777e Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 10 Dec 2010 15:36:44 +0000 Subject: proposed extension proven and observations gathered --- src/mpris2-controller.vala | 14 ++++++++++++++ src/mpris2-interfaces.vala | 2 -- src/playlists-menu-item.vala | 14 +++++++++----- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 0bd5562..94e82d5 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -180,4 +180,18 @@ public class Mpris2Controller : GLib.Object this.mpris2_root.Raise.begin(); } } + + public void activate_playlist (ObjectPath path) + { + if(this.playlists == null){ + warning("playlists mpris instance is null !"); + return; + } + try{ + this.playlists.ActivatePlaylist.begin(path); + } + catch(IOError e){ + debug("Could not activate playlist %s because %s", (string)path, e.message); + } + } } \ No newline at end of file diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index ab8ac95..160f454 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -55,8 +55,6 @@ public struct PlaylistDetails{ // TODO: API criticisms // Get_playlists should be able to be async => pass in callback pointer -// Lacking the ability to query the current playlist (should be asyncable) -// - needed to keep client and servers in sync // => get_current_playlist -> // Should return PlaylistDetails struct with each field nil if there is no active playlist. // Otherwise a populated PlaylistDetails diff --git a/src/playlists-menu-item.vala b/src/playlists-menu-item.vala index 4b81e48..f9d681e 100644 --- a/src/playlists-menu-item.vala +++ b/src/playlists-menu-item.vala @@ -23,14 +23,14 @@ using Gee; public class PlaylistsMenuitem : PlayerItem { - + private HashMap current_playlists; public Menuitem root_item; public PlaylistsMenuitem ( PlayerController parent ) { Object ( item_type: MENUITEM_TYPE, owner: parent ); } construct{ - this.property_set ( MENUITEM_PROP_LABEL, "Choose Playlist"); + this.current_playlists = new HashMap(); this.root_item = new Menuitem(); this.root_item.property_set ( MENUITEM_PROP_LABEL, "Choose Playlist" ); } @@ -43,17 +43,21 @@ public class PlaylistsMenuitem : PlayerItem menuitem.property_set (MENUITEM_PROP_ICON_NAME, "source-smart-playlist"); menuitem.property_set_bool (MENUITEM_PROP_VISIBLE, true); menuitem.property_set_bool (MENUITEM_PROP_ENABLED, true); - + this.current_playlists.set( menuitem.id, detail ); menuitem.item_activated.connect(() => { submenu_item_activated (menuitem.id );}); - this.root_item.child_append( menuitem ); } } private void submenu_item_activated (int menu_item_id) { - debug("item %i was activated", menu_item_id); + if(!this.current_playlists.has_key(menu_item_id)){ + warning( "item %i was activated but we don't have a corresponding playlist", + menu_item_id ); + return; + } + this.owner.mpris_bridge.activate_playlist ( this.current_playlists[menu_item_id].path ); } public static HashSet attributes_format() -- cgit v1.2.3 From 032797fd7a92bc8a4fd979ddc12cacb0918ca73b Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 17 Dec 2010 12:48:03 +0000 Subject: proved active-playlist prop use-case --- src/mpris2-controller.vala | 26 +++++++++++++++++++++++--- src/mpris2-interfaces.vala | 18 +++++++----------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 94e82d5..d6f27ec 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -18,9 +18,8 @@ with this program. If not, see . */ using Dbusmenu; - [DBus (name = "org.freedesktop.DBus.Properties")] - public interface FreeDesktopProperties : Object{ +public interface FreeDesktopProperties : Object{ public signal void PropertiesChanged (string source, HashTable changed_properties, string[] invalid ); } @@ -91,6 +90,11 @@ public class Mpris2Controller : GLib.Object metadata.property_set_bool ( MENUITEM_PROP_VISIBLE, metadata.populated(MetadataMenuitem.attributes_format())); } + Variant? playlist_v = changed_properties.lookup("ActivePlaylist"); + if ( playlist_v != null ){ + debug (" WE HAVE PLAYLIST CHANGE EVENT DETECTED "); + this.fetch_active_playlist(); + } } private GLib.HashTable? clean_metadata() @@ -131,7 +135,7 @@ public class Mpris2Controller : GLib.Object GLib.HashTable? cleaned_metadata = this.clean_metadata(); this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, MetadataMenuitem.attributes_format()); - this.fetch_playlists(); + this.fetch_playlists(); } public void transport_update(TransportMenuitem.action command) @@ -169,6 +173,22 @@ public class Mpris2Controller : GLib.Object } } + public void fetch_active_playlist() + { + if (this.playlists == null && this.playlists.ActivePlaylist.valid == true){ + warning("Playlists object is null and we have an active playlist"); + return; + } + + PlaylistDetails active_details = this.playlists.ActivePlaylist.active_playlist; + debug(" \n \n "); + debug( "Active Playlist Name = %s", active_details.name); + debug( "Active Playlist path = %s", active_details.path); + debug( "Active Playlist icon path = %s", active_details.icon_path); + debug(" \n \n "); + } + + public bool connected() { return (this.player != null && this.mpris2_root != null); diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index 160f454..578b6c8 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -50,23 +50,19 @@ public struct PlaylistDetails{ public string name; public string icon_path; } +// Active playlist property container +public struct ActivePlaylistContainer{ + public bool valid; + public PlaylistDetails active_playlist; +} [DBus (name = "org.mpris.MediaPlayer2.Playlists")] - -// TODO: API criticisms -// Get_playlists should be able to be async => pass in callback pointer -// => get_current_playlist -> -// Should return PlaylistDetails struct with each field nil if there is no active playlist. -// Otherwise a populated PlaylistDetails -// should be asyncable. -// => Need to be able to query get_playlist using ordered by last modified. -// => Need a signal to inform that the active playlist has changed - public interface MprisPlaylists : Object { //properties public abstract string[] Orderings{owned get; set;} public abstract uint32 PlaylistCount{owned get; set;} - + public abstract ActivePlaylistContainer ActivePlaylist {owned get; set;} + //methods public abstract async void ActivatePlaylist(ObjectPath playlist_id) throws IOError; public abstract PlaylistDetails[] GetPlaylists ( uint32 index, -- cgit v1.2.3 From bc927c2284c55ca8a30146ae905a76aa08f26fa1 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 20 Dec 2010 16:55:31 +0000 Subject: implemented suggested optional playlist mechanism --- src/mpris2-controller.vala | 7 ++++--- src/mpris2-interfaces.vala | 2 -- src/player-item.vala | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 58a1906..4990b38 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -102,9 +102,10 @@ public class Mpris2Controller : GLib.Object public bool playlist_support() { - // awaiting spec updates - // return this.mpris2_root.HasPlaylists; - return true; + if (this.playlists == null) return false; + uint32? count = this.playlists.PlaylistCount; + if ( count == null || count <= 0 ) return false; + return true; } private bool ensure_correct_playback_status(){ diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index 4f01c4c..a731de8 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -21,8 +21,6 @@ with this program. If not, see . public interface MprisRoot : Object { // properties public abstract bool HasTracklist{owned get; set;} - //waiting for MPRIS approval - //public abstract bool HasPlaylist{owned get; set;} public abstract bool CanQuit{owned get; set;} public abstract bool CanRaise{owned get; set;} public abstract string Identity{owned get; set;} diff --git a/src/player-item.vala b/src/player-item.vala index 75f673b..f883a1e 100644 --- a/src/player-item.vala +++ b/src/player-item.vala @@ -28,7 +28,7 @@ public class PlayerItem : Dbusmenu.Menuitem public PlayerItem(string type) { - Object(item_type: type); + Object(item_type: type); } construct { -- cgit v1.2.3 From c8c7681e7b9e2995d29fa58c931aa09e451c4fee Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 20 Dec 2010 18:02:50 +0000 Subject: playlists working --- src/mpris2-controller.vala | 2 +- src/mpris2-interfaces.vala | 1 + src/player-controller.vala | 10 ++++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 4990b38..35dc4e4 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -100,7 +100,7 @@ public class Mpris2Controller : GLib.Object } } - public bool playlist_support() + public bool playlists_support_exist() { if (this.playlists == null) return false; uint32? count = this.playlists.PlaylistCount; diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index a731de8..88610e6 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -50,6 +50,7 @@ public struct PlaylistDetails{ public string name; public string icon_path; } + // Active playlist property container public struct ActivePlaylistContainer{ public bool valid; diff --git a/src/player-controller.vala b/src/player-controller.vala index 24fd090..638c44d 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -131,21 +131,23 @@ public class PlayerController : GLib.Object public void update_layout() { + PlaylistsMenuitem playlists_menuitem = this.custom_items[widget_order.PLAYLISTS] as PlaylistsMenuitem; + if(this.current_state != state.CONNECTED){ this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, false); this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, false); - this.custom_items[widget_order.PLAYLISTS].property_set_bool ( MENUITEM_PROP_ENABLED, - false ); + playlists_menuitem.root_item.property_set_bool ( MENUITEM_PROP_VISIBLE, + false ); return; } this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, this.custom_items[widget_order.METADATA].populated(MetadataMenuitem.attributes_format())); this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, true); - this.custom_items[widget_order.PLAYLISTS].property_set_bool(MENUITEM_PROP_VISIBLE, - true); + playlists_menuitem.root_item.property_set_bool ( MENUITEM_PROP_VISIBLE, + this.mpris_bridge.playlists_support_exist() ); } private void construct_widgets() -- cgit v1.2.3 From 4843ae15f1ce4111c03b0fc24f5a8989d0619697 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 21 Dec 2010 14:53:56 +0000 Subject: playlists ready to go into trunk --- src/mpris2-controller.vala | 27 +++++++-------------------- src/music-player-bridge.vala | 2 +- src/playlists-menu-item.vala | 13 ++++++++++++- src/sound-service.c | 4 ++-- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 35dc4e4..5f98541 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -97,6 +97,7 @@ public class Mpris2Controller : GLib.Object Variant? playlist_v = changed_properties.lookup("ActivePlaylist"); if ( playlist_v != null ){ this.fetch_active_playlist(); + //Timeout.add ( 200, fetch_active_playlist ); } } @@ -154,6 +155,7 @@ public class Mpris2Controller : GLib.Object this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, MetadataMenuitem.attributes_format()); this.fetch_playlists(); + this.fetch_active_playlist(); } public void transport_update(TransportMenuitem.action command) @@ -172,10 +174,8 @@ public class Mpris2Controller : GLib.Object public void fetch_playlists() { - if (this.playlists == null){ - warning("Playlists object is null"); - return; - } + if (this.playlists == null) return; + PlaylistDetails[] current_playlists = this.playlists.GetPlaylists(0, 10, "Alphabetical", @@ -184,30 +184,17 @@ public class Mpris2Controller : GLib.Object debug( "Size of the playlist array = %i", current_playlists.length ); PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; playlists_item.update(current_playlists); - /*foreach(PlaylistDetails detail in current_playlists){ - debug(" \n \n "); - debug( "Playlist Name = %s", detail.name); - debug( "Playlist path = %s", detail.path); - debug( "Playlist icon path = %s", detail.icon_path); - debug(" \n \n "); - }*/ } + return; } - public void fetch_active_playlist() + private void fetch_active_playlist() { - if (this.playlists == null && this.playlists.ActivePlaylist.valid == true){ + if (this.playlists == null && this.playlists.ActivePlaylist.valid == false){ warning("Playlists object is null or we don't have an active playlist"); - return; } PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; playlists_item.update_active_playlist ( this.playlists.ActivePlaylist.details ); - /*debug(" \n \n "); - debug( "Active Playlist Name = %s", active_details.name); - debug( "Active Playlist path = %s", active_details.path); - debug( "Active Playlist icon path = %s", active_details.icon_path); - debug(" \n \n "); - */ } diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 239a40b..de8609d 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -76,7 +76,7 @@ public class MusicPlayerBridge : GLib.Object } } - public void client_has_become_available ( string desktop, string dbus_name ) + public void client_has_become_available ( string desktop, string dbus_name ) { if (desktop == null || desktop == ""){ warning("Client %s attempting to register without desktop entry being set on the mpris root", diff --git a/src/playlists-menu-item.vala b/src/playlists-menu-item.vala index 30ffdc7..024839c 100644 --- a/src/playlists-menu-item.vala +++ b/src/playlists-menu-item.vala @@ -38,6 +38,7 @@ public class PlaylistsMenuitem : PlayerItem public new void update (PlaylistDetails[] playlists) { foreach ( PlaylistDetails detail in playlists ){ + if (this.already_observed(detail)) continue; Dbusmenu.Menuitem menuitem = new Menuitem(); menuitem.property_set (MENUITEM_PROP_LABEL, detail.name); menuitem.property_set (MENUITEM_PROP_ICON_NAME, "source-smart-playlist"); @@ -50,9 +51,19 @@ public class PlaylistsMenuitem : PlayerItem } } + private bool already_observed (PlaylistDetails new_detail) + { + foreach ( PlaylistDetails detail in this.current_playlists.values ){ + if (new_detail.path == detail.path) return true; + } + return false; + } + public void update_active_playlist(PlaylistDetails detail) { - this.root_item.property_set ( MENUITEM_PROP_LABEL, detail.name ); + var update = detail.name; + if ( update == "" ) update = "Choose Playlist"; + this.root_item.property_set ( MENUITEM_PROP_LABEL, update ); } private void submenu_item_activated (int menu_item_id) diff --git a/src/sound-service.c b/src/sound-service.c index defcb94..98f1881 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - //close_pulse_activites(); - //g_main_loop_quit(mainloop); + close_pulse_activites(); + g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From a004703346a865a716538bd4128c5613548618c0 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 21 Dec 2010 17:37:16 +0000 Subject: icon colour change for banshee fixed bug #692648 --- src/title-widget.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/title-widget.c b/src/title-widget.c index cbdf28e..c3ef6a3 100644 --- a/src/title-widget.c +++ b/src/title-widget.c @@ -92,7 +92,8 @@ title_widget_set_icon(TitleWidget *self) GString* app_panel = g_string_new ( g_utf8_strdown ( dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_TITLE_MENUITEM_NAME), -1 )); GtkWidget * icon = NULL; - + g_debug ("banshee icon name = %s", app_panel->str); + // Not ideal but apparently we want the banshee icon to be the greyscale one // and any others to be the icon from the desktop file => colour. if ( g_string_equal ( banshee_string, app_panel ) == TRUE && @@ -161,10 +162,7 @@ title_widget_property_update(DbusmenuMenuitem* item, gchar* property, else if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_ICON, property) == 0){ g_debug("changing the icon data on the title - %s", g_value_get_string(value)); - GtkWidget * icon = gtk_image_new_from_icon_name(g_value_get_string(value), - GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mitem), GTK_WIDGET(icon)); - + title_widget_set_icon (mitem); } } -- cgit v1.2.3 From 4aa3c531119fec777e63bdb3fe953b6a35d5ffae Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 21 Dec 2010 17:46:06 +0000 Subject: remove the trace --- src/title-widget.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/title-widget.c b/src/title-widget.c index c3ef6a3..08b4b81 100644 --- a/src/title-widget.c +++ b/src/title-widget.c @@ -92,7 +92,6 @@ title_widget_set_icon(TitleWidget *self) GString* app_panel = g_string_new ( g_utf8_strdown ( dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_TITLE_MENUITEM_NAME), -1 )); GtkWidget * icon = NULL; - g_debug ("banshee icon name = %s", app_panel->str); // Not ideal but apparently we want the banshee icon to be the greyscale one // and any others to be the icon from the desktop file => colour. @@ -154,14 +153,11 @@ title_widget_property_update(DbusmenuMenuitem* item, gchar* property, { g_return_if_fail (IS_TITLE_WIDGET (userdata)); TitleWidget* mitem = TITLE_WIDGET(userdata); - g_debug("PROPERTY UPDATE FOR THE TITLE"); if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){ gtk_menu_item_set_label (GTK_MENU_ITEM(mitem), g_value_get_string(value)); } else if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_ICON, property) == 0){ - g_debug("changing the icon data on the title - %s", - g_value_get_string(value)); title_widget_set_icon (mitem); } } -- cgit v1.2.3 From 74028a3c0df6fba7ab407f3e6e69c199e7c7d240 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 22 Dec 2010 16:43:17 +0000 Subject: protect against a rogue null cairo contect in the draw method --- src/transport-widget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/transport-widget.c b/src/transport-widget.c index d9c499d..d7f4b75 100644 --- a/src/transport-widget.c +++ b/src/transport-widget.c @@ -4,6 +4,7 @@ Copyright 2010 Canonical Ltd. Authors: Conor Curran Mirco Müller + Andrea Cimitan 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 @@ -1156,6 +1157,7 @@ static void draw (GtkWidget* button, cairo_t *cr) { g_return_if_fail(IS_TRANSPORT_WIDGET(button)); + g_return_if_fail( cr != NULL ); TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); cairo_surface_t* surf = NULL; -- cgit v1.2.3 From b10ee23e9b0720af7d24a1f7c77f7b5809c5fb5e Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 23 Dec 2010 16:37:20 +0000 Subject: sorted the desktop file loading --- src/music-player-bridge.vala | 58 +++++++++++++++++++++----------------------- src/sound-service.c | 4 +-- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index de8609d..cfbd670 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -27,7 +27,6 @@ public class MusicPlayerBridge : GLib.Object private Dbusmenu.Menuitem root_menu; private HashMap registered_clients; private Mpris2Watcher watcher; - private const string DESKTOP_PREFIX = "/usr/share/applications/"; private Settings settings; public MusicPlayerBridge() @@ -49,17 +48,17 @@ public class MusicPlayerBridge : GLib.Object { foreach ( string desktop in this.settings_manager.fetch_interested()){ debug ( "interested client found : %s", desktop ); - string path = DESKTOP_PREFIX.concat ( desktop.concat( ".desktop" ) ); - AppInfo? app_info = create_app_info ( path ); + AppInfo? app_info = create_app_info ( desktop.concat( ".desktop" ) ); if ( app_info == null ){ - warning ( "Could not create app_info for path %s \n Getting out of here ", path); + warning ( "Could not create app_info for path %s \n Getting out of here ", + desktop ); continue; } - var mpris_key = determine_key ( path ); + var mpris_key = determine_key ( desktop ); PlayerController ctrl = new PlayerController ( this.root_menu, app_info, null, - this.fetch_icon_name(path), + this.fetch_icon_name(desktop), calculate_menu_position(), PlayerController.state.OFFLINE ); this.registered_clients.set(mpris_key, ctrl); @@ -84,21 +83,21 @@ public class MusicPlayerBridge : GLib.Object return; } debug ( "client_has_become_available %s", desktop ); - string path = DESKTOP_PREFIX.concat ( desktop.concat( ".desktop" ) ); - AppInfo? app_info = create_app_info ( path ); + AppInfo? app_info = create_app_info ( desktop.concat( ".desktop" ) ); if ( app_info == null ){ - warning ( "Could not create app_info for path %s \n Getting out of here ", path); + warning ( "Could not create app_info for path %s \n Getting out of here ", + desktop ); return; } - var mpris_key = determine_key ( path ); + var mpris_key = determine_key ( desktop ); // Are we sure clients will appear like this with the new registration method in place. if ( this.registered_clients.has_key (mpris_key) == false ){ debug("New client has registered that we have not seen before: %s", dbus_name ); PlayerController ctrl = new PlayerController ( this.root_menu, app_info, dbus_name, - this.fetch_icon_name(path), + this.fetch_icon_name(desktop), this.calculate_menu_position(), PlayerController.state.READY ); this.registered_clients.set ( mpris_key, ctrl ); @@ -135,22 +134,24 @@ public class MusicPlayerBridge : GLib.Object this.watcher.client_disappeared += this.client_has_vanished; } - private static AppInfo? create_app_info ( string path ) + private static AppInfo? create_app_info ( string desktop ) { - DesktopAppInfo info = new DesktopAppInfo.from_filename ( path ) ; - if ( path == null || info == null ){ - warning ( "Could not create a desktopappinfo instance from app: %s", path ); + DesktopAppInfo info = new DesktopAppInfo ( desktop ) ; + if ( desktop == null || info == null ){ + warning ( "Could not create a desktopappinfo instance from app: %s", desktop ); return null; } GLib.AppInfo app_info = info as GLib.AppInfo; return app_info; } - private static string? fetch_icon_name(string desktop_path) + private static string? fetch_icon_name(string desktop) { + // We know the appinfo is good because it was loaded in the previous reg step. + DesktopAppInfo info = new DesktopAppInfo ( desktop.concat( ".desktop" ) ) ; KeyFile desktop_keyfile = new KeyFile (); try{ - desktop_keyfile.load_from_file (desktop_path, KeyFileFlags.NONE); + desktop_keyfile.load_from_file (info.get_filename(), KeyFileFlags.NONE); } catch(GLib.FileError error){ warning("Error loading keyfile - FileError"); @@ -172,24 +173,19 @@ public class MusicPlayerBridge : GLib.Object } /* - Messy but necessary method to consolidate desktop filesnames and mpris dbus names - into the one single word string (used as the key in the players hash). + Messy but necessary method to consolidate desktop filesnames and mpris dbus + names into the one single word string (used as the key in the players hash). So this means that we can determine the key for the players_hash from the - dbus interface name or the desktop file name. + dbus interface name or the desktop file name, at startup offline/online and + shutdown. */ - private static string? determine_key(owned string path) + private static string? determine_key(owned string desktop_or_interface) { - var tokens = path.split( "/" ); - if ( tokens.length < 2 ){ - // try to split on "." - tokens = path.split("."); - if ( tokens.length < 2 ){ - // don't know what this is - return null; - } + var result = desktop_or_interface; + var tokens = desktop_or_interface.split( "." ); + if ( tokens.length > 1 ){ + result = tokens[tokens.length - 1]; } - var filename = tokens[tokens.length - 1]; - var result = filename.split(".")[0]; var temp = result.split("-"); if (temp.length > 1){ result = temp[0]; diff --git a/src/sound-service.c b/src/sound-service.c index 98f1881..defcb94 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From 93c4b258085b77b569755fcaa238f4cfdd23176e Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 23 Dec 2010 19:33:42 +0000 Subject: caught a bug to do with writing to gsettings --- src/settings-manager.vala | 19 ++++++++++++++----- src/sound-service.c | 4 ++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/settings-manager.vala b/src/settings-manager.vala index 05db430..f7bb3b6 100644 --- a/src/settings-manager.vala +++ b/src/settings-manager.vala @@ -27,7 +27,7 @@ public class SettingsManager : GLib.Object } construct{ this.settings = new Settings ("com.canonical.indicators.sound"); - settings.changed["blacklisted-media-players"].connect (on_blacklist_event); + this.settings.changed["blacklisted-media-players"].connect (on_blacklist_event); } public string[] fetch_blacklist() @@ -40,12 +40,21 @@ public class SettingsManager : GLib.Object return this.settings.get_strv ("interested-media-players"); } - public bool add_interested(string app_desktop_name) + public void clear_list() { - string[] already_interested = fetch_interested(); + this.settings.reset("interested-media-players"); + } + + public void add_interested(string app_desktop_name) + { + var already_interested = fetch_interested(); + foreach ( var s in already_interested){ + if ( s == app_desktop_name ) return; + } already_interested += (app_desktop_name); - return this.settings.set_strv( "interested-media-players", - already_interested ); + this.settings.set_strv( "interested-media-players", + already_interested ); + this.settings.apply(); } private void on_blacklist_event() diff --git a/src/sound-service.c b/src/sound-service.c index defcb94..98f1881 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - //close_pulse_activites(); - //g_main_loop_quit(mainloop); + close_pulse_activites(); + g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From f9afcd6bddae52bad5c5d8e7179fe360fcbf6de2 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 4 Jan 2011 15:16:04 +0000 Subject: removed the need for a name instance variable on the player controller obj, now always use the name set in app info --- src/player-controller.vala | 13 ++++++++----- src/title-menu-item.vala | 3 +-- src/transport-menu-item.vala | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/player-controller.vala b/src/player-controller.vala index 638c44d..58e3b47 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -44,7 +44,7 @@ public class PlayerController : GLib.Object public int current_state = state.OFFLINE; private Dbusmenu.Menuitem root_menu; - public string name { get; set;} + //public string name { get; set;} public string dbus_name { get; set;} public ArrayList custom_items; public Mpris2Controller mpris_bridge; @@ -62,7 +62,7 @@ public class PlayerController : GLib.Object this.root_menu = root; this.app_info = app; this.dbus_name = dbus_name; - this.name = format_player_name(this.app_info.get_name()); + //this.name = this.app_info.get_name(); this.icon_name = icon_name; this.custom_items = new ArrayList(); this.current_state = initial_state; @@ -74,7 +74,8 @@ public class PlayerController : GLib.Object public void update_state(state new_state) { - debug("update_state - player controller %s : new state %i", this.name, new_state); + debug("update_state - player controller %s : new state %i", this.app_info.get_name(), + new_state); this.current_state = new_state; this.update_layout(); } @@ -93,13 +94,14 @@ public class PlayerController : GLib.Object */ public void instantiate() { - debug("instantiate in player controller for %s", this.name); + debug("instantiate in player controller for %s", this.app_info.get_name() ); try{ this.app_info.launch(null, null); this.update_state(state.INSTANTIATING); } catch(GLib.Error error){ - warning("Failed to launch app %s with error message: %s", this.name, error.message); + warning("Failed to launch app %s with error message: %s", this.app_info.get_name(), + error.message ); } } @@ -181,6 +183,7 @@ public class PlayerController : GLib.Object } } } + private static string format_player_name(owned string app_info_name) { diff --git a/src/title-menu-item.vala b/src/title-menu-item.vala index d782e84..0b99ae3 100644 --- a/src/title-menu-item.vala +++ b/src/title-menu-item.vala @@ -26,8 +26,7 @@ public class TitleMenuitem : PlayerItem public TitleMenuitem(PlayerController parent) { Object(item_type: MENUITEM_TYPE, owner: parent); - this.property_set(MENUITEM_NAME, parent.name); - debug("title init - icon name = %s", parent.icon_name); + this.property_set(MENUITEM_NAME, parent.app_info.get_name()); this.property_set(MENUITEM_ICON, parent.icon_name); this.property_set_bool(MENUITEM_RUNNING, false); } diff --git a/src/transport-menu-item.vala b/src/transport-menu-item.vala index 57eb67b..0e4e6ee 100644 --- a/src/transport-menu-item.vala +++ b/src/transport-menu-item.vala @@ -51,7 +51,7 @@ public class TransportMenuitem : PlayerItem { int input = input_value.get_int(); debug("handle_event with value %s", input.to_string()); - debug("transport owner name = %s", this.owner.name); + debug("transport owner name = %s", this.owner.app_info.get_name()); this.owner.mpris_bridge.transport_update((action)input); } -- cgit v1.2.3 From 3e5682245ec0200831de249d6b625f3b4e21d91d Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 4 Jan 2011 17:40:15 +0000 Subject: remove redundant member variable --- src/music-player-bridge.vala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index cfbd670..2d112cd 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -27,7 +27,6 @@ public class MusicPlayerBridge : GLib.Object private Dbusmenu.Menuitem root_menu; private HashMap registered_clients; private Mpris2Watcher watcher; - private Settings settings; public MusicPlayerBridge() { -- cgit v1.2.3 From a19ea02da69b3b7c0d810716fe40eed9b7e86c63 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 4 Jan 2011 18:00:49 +0000 Subject: tidied deps --- Makefile.am | 2 +- configure.ac | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 70e69c1..466806a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ SUBDIRS = \ tests \ po -EXTRA_DIST = autogen.sh vapi/common-defs.vapi vapi/Indicate-0.2.vapi +EXTRA_DIST = autogen.sh vapi/common-defs.vapi DISTCHECK_CONFIGURE_FLAGS = --enable-localinstall diff --git a/configure.ac b/configure.ac index 88ffe6d..c42354e 100644 --- a/configure.ac +++ b/configure.ac @@ -46,14 +46,16 @@ AC_SUBST(APPLET_CFLAGS) AC_SUBST(APPLET_LIBS) -PKG_CHECK_MODULES(PULSEAUDIO, libpulse-mainloop-glib >= $PULSE_AUDIO_REQUIRED_VERSION) +PKG_CHECK_MODULES(PULSEAUDIO, libpulse-mainloop-glib >= $PULSE_AUDIO_REQUIRED_VERSION + gio-unix-2.0) AC_SUBST(PULSEAUDIO_CFLAGS) AC_SUBST(PULSEAUDIO_LIBS) PKG_CHECK_MODULES(SOUNDSERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION indicator >= $INDICATOR_REQUIRED_VERSION indicate >= $INDICATE_REQUIRED_VERSION - gee-1.0) + gee-1.0 + gio-unix-2.0) AC_SUBST(SOUNDSERVICE_CFLAGS) AC_SUBST(SOUNDERVICE_LIBS) -- cgit v1.2.3 From d9c023fd1ba9e5630755634d7f0e983081cbc195 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 5 Jan 2011 12:41:18 +0000 Subject: blacklisting in place --- src/settings-manager.vala | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/settings-manager.vala b/src/settings-manager.vala index f7bb3b6..57b4487 100644 --- a/src/settings-manager.vala +++ b/src/settings-manager.vala @@ -35,9 +35,16 @@ public class SettingsManager : GLib.Object return this.settings.get_strv ("blacklisted-media-players"); } - public string[] fetch_interested() + public ArrayList fetch_interested() { - return this.settings.get_strv ("interested-media-players"); + var blacklisted = this.settings.get_strv ("blacklisted-media-players"); + var interested = this.settings.get_strv ("interested-media-players"); + var list = new ArrayList(); + foreach(var s in interested){ + if ( s in blacklisted ) continue; + list.add(s); + } + return list; } public void clear_list() @@ -47,7 +54,7 @@ public class SettingsManager : GLib.Object public void add_interested(string app_desktop_name) { - var already_interested = fetch_interested(); + var already_interested = this.settings.get_strv ("interested-media-players"); foreach ( var s in already_interested){ if ( s == app_desktop_name ) return; } -- cgit v1.2.3 From f43f3cc7f9f5d762bff2dcd7062cafe554581e20 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 5 Jan 2011 12:56:02 +0000 Subject: block start ups that are blacklisted --- src/music-player-bridge.vala | 7 ++++++- src/sound-service.c | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 2d112cd..7a56ede 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -81,6 +81,11 @@ public class MusicPlayerBridge : GLib.Object dbus_name); return; } + if (desktop in this.settings_manager.fetch_blacklist()) { + debug ("Client %s attempting to register but it has been blacklisted", + desktop); + } + debug ( "client_has_become_available %s", desktop ); AppInfo? app_info = create_app_info ( desktop.concat( ".desktop" ) ); if ( app_info == null ){ @@ -117,7 +122,7 @@ public class MusicPlayerBridge : GLib.Object if (root_menu != null){ debug("attempt to remove %s", mpris_root_interface); var mpris_key = determine_key ( mpris_root_interface ); - if ( mpris_key != null ){ + if ( mpris_key != null && this.registered_clients.has_key(mpris_key)){ registered_clients[mpris_key].hibernate(); debug("Successively offlined client %s", mpris_key); } diff --git a/src/sound-service.c b/src/sound-service.c index 98f1881..defcb94 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From b8e5c4267c5c5db7889b18441a2fc733dd48cbdd Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 5 Jan 2011 16:06:52 +0000 Subject: blacklisting working plus bug fixed --- src/music-player-bridge.vala | 1 + src/player-controller.vala | 5 ++--- src/sound-service.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 7a56ede..c7391cf 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -141,6 +141,7 @@ public class MusicPlayerBridge : GLib.Object private static AppInfo? create_app_info ( string desktop ) { DesktopAppInfo info = new DesktopAppInfo ( desktop ) ; + if ( desktop == null || info == null ){ warning ( "Could not create a desktopappinfo instance from app: %s", desktop ); return null; diff --git a/src/player-controller.vala b/src/player-controller.vala index 58e3b47..3922ecf 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -44,7 +44,6 @@ public class PlayerController : GLib.Object public int current_state = state.OFFLINE; private Dbusmenu.Menuitem root_menu; - //public string name { get; set;} public string dbus_name { get; set;} public ArrayList custom_items; public Mpris2Controller mpris_bridge; @@ -62,7 +61,6 @@ public class PlayerController : GLib.Object this.root_menu = root; this.app_info = app; this.dbus_name = dbus_name; - //this.name = this.app_info.get_name(); this.icon_name = icon_name; this.custom_items = new ArrayList(); this.current_state = initial_state; @@ -128,7 +126,8 @@ public class PlayerController : GLib.Object this.custom_items[widget_order.TRANSPORT].reset(TransportMenuitem.attributes_format()); this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem; - title.toggle_active_triangle(false); + title.toggle_active_triangle(false); + this.mpris_bridge = null; } public void update_layout() diff --git a/src/sound-service.c b/src/sound-service.c index defcb94..98f1881 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - //close_pulse_activites(); - //g_main_loop_quit(mainloop); + close_pulse_activites(); + g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From ce996a8b02131d9711cc3dee67f6c3844e55b8e8 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 6 Jan 2011 14:24:55 +0000 Subject: bumped rev no in prep for release --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index c42354e..c9227cd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ -AC_INIT(indicator-sound, 0.5.3, conor.curran@canonical.com) +AC_INIT(indicator-sound, 0.5.4, conor.curran@canonical.com) AC_PREREQ(2.53) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(indicator-sound, 0.5.3) +AM_INIT_AUTOMAKE(indicator-sound, 0.5.4) AM_MAINTAINER_MODE -- cgit v1.2.3 From 9f10c1e5b7a7ceac671d23cdfef2176d4ac8e74d Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Sun, 9 Jan 2011 08:14:43 +0000 Subject: interface introspection underway@ --- configure.ac | 3 +- src/Makefile.am | 3 +- src/mpris2-controller.vala | 26 ++++++++-------- src/mpris2-watcher.vala | 70 ++++++++++++++++++++++++++++++++++++++++---- src/music-player-bridge.vala | 6 ++-- src/sound-service.c | 4 +-- 6 files changed, 88 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index c9227cd..928ffff 100644 --- a/configure.ac +++ b/configure.ac @@ -55,7 +55,8 @@ PKG_CHECK_MODULES(SOUNDSERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION indicator >= $INDICATOR_REQUIRED_VERSION indicate >= $INDICATE_REQUIRED_VERSION gee-1.0 - gio-unix-2.0) + gio-unix-2.0 + libxml-2.0) AC_SUBST(SOUNDSERVICE_CFLAGS) AC_SUBST(SOUNDERVICE_LIBS) diff --git a/src/Makefile.am b/src/Makefile.am index 82830e1..57f52d4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,7 +81,8 @@ music_bridge_VALAFLAGS = \ --pkg common-defs \ --pkg gio-2.0 \ --pkg gio-unix-2.0 \ - --pkg gdk-pixbuf-2.0 + --pkg gdk-pixbuf-2.0 \ + --pkg libxml-2.0 $(MAINTAINER_VALAFLAGS) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 5f98541..7b512a3 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -53,7 +53,6 @@ public class Mpris2Controller : GLib.Object this.playlists = Bus.get_proxy_sync ( BusType.SESSION, this.owner.dbus_name, "/org/mpris/MediaPlayer2" ); - this.properties_interface = Bus.get_proxy_sync ( BusType.SESSION, "org.freedesktop.Properties.PropertiesChanged", "/org/mpris/MediaPlayer2" ); @@ -95,9 +94,8 @@ public class Mpris2Controller : GLib.Object metadata.populated(MetadataMenuitem.attributes_format())); } Variant? playlist_v = changed_properties.lookup("ActivePlaylist"); - if ( playlist_v != null ){ + if ( playlist_v != null && this.playlists_support_exist() ){ this.fetch_active_playlist(); - //Timeout.add ( 200, fetch_active_playlist ); } } @@ -154,8 +152,12 @@ public class Mpris2Controller : GLib.Object GLib.HashTable? cleaned_metadata = this.clean_metadata(); this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, MetadataMenuitem.attributes_format()); - this.fetch_playlists(); - this.fetch_active_playlist(); + + /*if ( playlists_support_exist() == true ){ + debug ("it thinks that there is a valid playlist interface"); + this.fetch_playlists(); + this.fetch_active_playlist(); + }*/ } public void transport_update(TransportMenuitem.action command) @@ -174,8 +176,6 @@ public class Mpris2Controller : GLib.Object public void fetch_playlists() { - if (this.playlists == null) return; - PlaylistDetails[] current_playlists = this.playlists.GetPlaylists(0, 10, "Alphabetical", @@ -189,9 +189,9 @@ public class Mpris2Controller : GLib.Object } private void fetch_active_playlist() - { - if (this.playlists == null && this.playlists.ActivePlaylist.valid == false){ - warning("Playlists object is null or we don't have an active playlist"); + { + if (this.playlists.ActivePlaylist.valid == false){ + debug("We don't have an active playlist"); } PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; playlists_item.update_active_playlist ( this.playlists.ActivePlaylist.details ); @@ -212,10 +212,10 @@ public class Mpris2Controller : GLib.Object public void activate_playlist (ObjectPath path) { - if(this.playlists == null){ - warning("playlists mpris instance is null !"); - return; + if ( playlists_support_exist() == false ){ + return; } + try{ this.playlists.ActivatePlaylist.begin(path); } diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 7814975..f572ab7 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +using Xml; + [DBus (name = "org.freedesktop.DBus")] public interface FreeDesktopObject: Object { public abstract async string[] list_names() throws IOError; @@ -25,6 +27,16 @@ public interface FreeDesktopObject: Object { string new_owner ); } +[DBus (name = "org.freedesktop.DBus.Introspectable")] +public interface FreeDesktopIntrospectable: Object { + public abstract string introspect() throws IOError; +} + +public errordomain XmlError { + FILE_NOT_FOUND, + XML_DOCUMENT_EMPTY +} + public class Mpris2Watcher : GLib.Object { private const string FREEDESKTOP_SERVICE = "org.freedesktop.DBus"; @@ -33,14 +45,14 @@ public class Mpris2Watcher : GLib.Object private const string MPRIS_MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2"; FreeDesktopObject fdesktop_obj; - + public signal void client_appeared ( string desktop_file_name, string dbus_name ); public signal void client_disappeared ( string dbus_name ); public Mpris2Watcher () { } - + construct { try { @@ -76,21 +88,69 @@ public class Mpris2Watcher : GLib.Object } } - private MprisRoot? create_mpris_root(string name){ + private MprisRoot? create_mpris_root ( string name ){ MprisRoot mpris2_root = null; if ( name.has_prefix (MPRIS_PREFIX) ){ try { mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, - name, - MPRIS_MEDIA_PLAYER_PATH ); + name, + MPRIS_MEDIA_PLAYER_PATH ); } catch (IOError e){ warning( "Mpris2watcher could not create a root interface: %s", e.message ); } } + this.supports_playlists(name); return mpris2_root; } + + private bool supports_playlists ( string name ) + { + FreeDesktopIntrospectable introspectable; + try { + introspectable = Bus.get_proxy_sync ( BusType.SESSION, + name, + MPRIS_MEDIA_PLAYER_PATH ); + var results = introspectable.introspect(); + return this.parse_interfaces (results); + } + catch (IOError e){ + warning( "Could not create an introspectable object: %s", + e.message ); + } + return false; + } + + private bool parse_interfaces( string interface_info ) + { + //parse the document from path + debug ("attempting to parse %s", interface_info); + Xml.Doc* xml_doc = Parser.parse_doc (interface_info); + if (xml_doc == null) { + warning ("Mpris2Watcher - parse-interfaces - failed to instantiate xml doc"); + return false; + } + //get the root node. notice the dereferencing operator -> instead of . + Xml.Node* root_node = xml_doc->get_root_element (); + if (root_node == null) { + //free the document manually before throwing because the garbage collector can't work on pointers + delete xml_doc; + warning ("Mpris2Watcher - the interface info xml is empty"); + return false; + } + + //let's parse those nodes + for (Xml.Node* iter = root_node->children; iter != null; iter = iter->next) { + //spaces btw. tags are also nodes, discard them + if (iter->type != ElementType.ELEMENT_NODE) + continue; + string node_name = iter->name; //get the node's name + debug ( "this dbus object has interface %s ", node_name ); + } + delete xml_doc; + return false; + } // At startup check to see if there are clients up that we are interested in // More relevant for development and daemon's like mpd. diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index c7391cf..10c333a 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -82,8 +82,9 @@ public class MusicPlayerBridge : GLib.Object return; } if (desktop in this.settings_manager.fetch_blacklist()) { - debug ("Client %s attempting to register but it has been blacklisted", + debug ("Client %s attempting to register but I'm afraid it is blacklisted", desktop); + return; } debug ( "client_has_become_available %s", desktop ); @@ -118,7 +119,8 @@ public class MusicPlayerBridge : GLib.Object public void client_has_vanished ( string mpris_root_interface ) { - debug("MusicPlayerBridge -> on_server_removed with value %s", mpris_root_interface); + debug("MusicPlayerBridge -> client with dbus interface %s has vanished", + mpris_root_interface ); if (root_menu != null){ debug("attempt to remove %s", mpris_root_interface); var mpris_key = determine_key ( mpris_root_interface ); diff --git a/src/sound-service.c b/src/sound-service.c index 98f1881..defcb94 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From 9dc6c636a4ae4c117afa2973c7dc32c72d22abd0 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Sun, 9 Jan 2011 09:22:16 +0000 Subject: introspection happening nicely --- src/mpris2-watcher.vala | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index f572ab7..fa4207a 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -77,13 +77,14 @@ public class Mpris2Watcher : GLib.Object MprisRoot? mpris2_root = this.create_mpris_root(name); if (mpris2_root == null) return; - + if (previous_owner != "" && current_owner == "") { debug ("Client '%s' gone down", name); client_disappeared (name); } else if (previous_owner == "" && current_owner != "") { debug ("Client '%s' has appeared", name); + bool use_playlists = this.supports_playlists ( name ); client_appeared (mpris2_root.DesktopEntry, name); } } @@ -101,7 +102,6 @@ public class Mpris2Watcher : GLib.Object e.message ); } } - this.supports_playlists(name); return mpris2_root; } @@ -125,6 +125,7 @@ public class Mpris2Watcher : GLib.Object private bool parse_interfaces( string interface_info ) { //parse the document from path + bool result = false; debug ("attempting to parse %s", interface_info); Xml.Doc* xml_doc = Parser.parse_doc (interface_info); if (xml_doc == null) { @@ -143,13 +144,19 @@ public class Mpris2Watcher : GLib.Object //let's parse those nodes for (Xml.Node* iter = root_node->children; iter != null; iter = iter->next) { //spaces btw. tags are also nodes, discard them - if (iter->type != ElementType.ELEMENT_NODE) - continue; - string node_name = iter->name; //get the node's name - debug ( "this dbus object has interface %s ", node_name ); + if (iter->type != ElementType.ELEMENT_NODE){ + continue; + } + Xml.Attr* attributes = iter->properties; //get the node's name + string interface_name = attributes->children->content; + debug ( "this dbus object has interface %s ", interface_name ); + if ( interface_name == MPRIS_PREFIX.concat("Playlists")){ + result = true; + } + delete attributes; } delete xml_doc; - return false; + return result; } // At startup check to see if there are clients up that we are interested in -- cgit v1.2.3 From 6599f962aacdb311322305234d3746ac27533f5e Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Sun, 9 Jan 2011 14:20:41 +0000 Subject: found the way around banshee dbus peculiar --- src/mpris2-controller.vala | 34 ++++++++------------ src/mpris2-watcher.vala | 76 +++++++++++++++++++++++--------------------- src/music-player-bridge.vala | 11 +++++-- src/player-controller.vala | 19 +++++++---- src/sound-service.c | 4 +-- 5 files changed, 76 insertions(+), 68 deletions(-) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 7b512a3..c43f5fe 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -50,9 +50,11 @@ public class Mpris2Controller : GLib.Object this.player = Bus.get_proxy_sync ( BusType.SESSION, this.owner.dbus_name, "/org/mpris/MediaPlayer2" ); - this.playlists = Bus.get_proxy_sync ( BusType.SESSION, - this.owner.dbus_name, - "/org/mpris/MediaPlayer2" ); + if ( this.owner.use_playlists == true ){ + this.playlists = Bus.get_proxy_sync ( BusType.SESSION, + this.owner.dbus_name, + "/org/mpris/MediaPlayer2" ); + } this.properties_interface = Bus.get_proxy_sync ( BusType.SESSION, "org.freedesktop.Properties.PropertiesChanged", "/org/mpris/MediaPlayer2" ); @@ -94,18 +96,10 @@ public class Mpris2Controller : GLib.Object metadata.populated(MetadataMenuitem.attributes_format())); } Variant? playlist_v = changed_properties.lookup("ActivePlaylist"); - if ( playlist_v != null && this.playlists_support_exist() ){ + if ( playlist_v != null && this.owner.use_playlists == true ){ this.fetch_active_playlist(); } } - - public bool playlists_support_exist() - { - if (this.playlists == null) return false; - uint32? count = this.playlists.PlaylistCount; - if ( count == null || count <= 0 ) return false; - return true; - } private bool ensure_correct_playback_status(){ debug("TEST playback status = %s", this.player.PlaybackStatus); @@ -153,11 +147,11 @@ public class Mpris2Controller : GLib.Object this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, MetadataMenuitem.attributes_format()); - /*if ( playlists_support_exist() == true ){ + if ( this.owner.use_playlists == true ){ debug ("it thinks that there is a valid playlist interface"); this.fetch_playlists(); this.fetch_active_playlist(); - }*/ + } } public void transport_update(TransportMenuitem.action command) @@ -185,6 +179,10 @@ public class Mpris2Controller : GLib.Object PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; playlists_item.update(current_playlists); } + else{ + warning(" Playlists are on but its returning no current_playlists" ); + this.owner.use_playlists = false; + } return; } @@ -202,7 +200,7 @@ public class Mpris2Controller : GLib.Object { return (this.player != null && this.mpris2_root != null); } - + public void expose() { if(this.connected() == true){ @@ -212,15 +210,11 @@ public class Mpris2Controller : GLib.Object public void activate_playlist (ObjectPath path) { - if ( playlists_support_exist() == false ){ - return; - } - try{ this.playlists.ActivatePlaylist.begin(path); } catch(IOError e){ debug("Could not activate playlist %s because %s", (string)path, e.message); } - } + } } \ No newline at end of file diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index fa4207a..b30aa88 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -29,7 +29,7 @@ public interface FreeDesktopObject: Object { [DBus (name = "org.freedesktop.DBus.Introspectable")] public interface FreeDesktopIntrospectable: Object { - public abstract string introspect() throws IOError; + public abstract string Introspect() throws IOError; } public errordomain XmlError { @@ -45,8 +45,11 @@ public class Mpris2Watcher : GLib.Object private const string MPRIS_MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2"; FreeDesktopObject fdesktop_obj; - - public signal void client_appeared ( string desktop_file_name, string dbus_name ); + FreeDesktopIntrospectable introspectable; + + public signal void client_appeared ( string desktop_file_name, + string dbus_name, + bool use_playlists ); public signal void client_disappeared ( string dbus_name ); public Mpris2Watcher () @@ -69,6 +72,29 @@ public class Mpris2Watcher : GLib.Object } } + // At startup check to see if there are clients up that we are interested in + // More relevant for development and daemon's like mpd. + private async void check_for_active_clients() + { + string[] interfaces; + try{ + interfaces = yield this.fdesktop_obj.list_names(); + } + catch ( IOError e) { + warning( "Mpris2watcher could fetch active interfaces at startup: %s", + e.message ); + return; + } + foreach (var address in interfaces) { + if (address.has_prefix (MPRIS_PREFIX)){ + MprisRoot? mpris2_root = this.create_mpris_root(address); + if (mpris2_root == null) return; + bool use_playlists = this.supports_playlists ( address ); + client_appeared (mpris2_root.DesktopEntry, address, use_playlists); + } + } + } + private void name_changes_detected ( FreeDesktopObject dbus_obj, string name, string previous_owner, @@ -84,8 +110,8 @@ public class Mpris2Watcher : GLib.Object } else if (previous_owner == "" && current_owner != "") { debug ("Client '%s' has appeared", name); - bool use_playlists = this.supports_playlists ( name ); - client_appeared (mpris2_root.DesktopEntry, name); + bool use_playlists = this.supports_playlists ( name ); + client_appeared (mpris2_root.DesktopEntry, name, false/*use_playlists*/); } } @@ -107,13 +133,15 @@ public class Mpris2Watcher : GLib.Object private bool supports_playlists ( string name ) { - FreeDesktopIntrospectable introspectable; try { - introspectable = Bus.get_proxy_sync ( BusType.SESSION, - name, - MPRIS_MEDIA_PLAYER_PATH ); - var results = introspectable.introspect(); - return this.parse_interfaces (results); + debug( "name = %s", name); + this.introspectable = Bus.get_proxy_sync ( BusType.SESSION, + name, + MPRIS_MEDIA_PLAYER_PATH, + GLib.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES); + + var results = introspectable.Introspect(); + return this.parse_interfaces (results); } catch (IOError e){ warning( "Could not create an introspectable object: %s", @@ -126,7 +154,6 @@ public class Mpris2Watcher : GLib.Object { //parse the document from path bool result = false; - debug ("attempting to parse %s", interface_info); Xml.Doc* xml_doc = Parser.parse_doc (interface_info); if (xml_doc == null) { warning ("Mpris2Watcher - parse-interfaces - failed to instantiate xml doc"); @@ -153,31 +180,8 @@ public class Mpris2Watcher : GLib.Object if ( interface_name == MPRIS_PREFIX.concat("Playlists")){ result = true; } - delete attributes; } delete xml_doc; return result; - } - - // At startup check to see if there are clients up that we are interested in - // More relevant for development and daemon's like mpd. - private async void check_for_active_clients() - { - string[] interfaces; - try{ - interfaces = yield this.fdesktop_obj.list_names(); - } - catch ( IOError e) { - warning( "Mpris2watcher could fetch active interfaces at startup: %s", - e.message ); - return; - } - foreach (var address in interfaces) { - if (address.has_prefix (MPRIS_PREFIX)){ - MprisRoot? mpris2_root = this.create_mpris_root(address); - if (mpris2_root == null) return; - client_appeared (mpris2_root.DesktopEntry, address); - } - } - } + } } \ No newline at end of file diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 10c333a..7587684 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -59,8 +59,9 @@ public class MusicPlayerBridge : GLib.Object null, this.fetch_icon_name(desktop), calculate_menu_position(), + null, PlayerController.state.OFFLINE ); - this.registered_clients.set(mpris_key, ctrl); + this.registered_clients.set(mpris_key, ctrl); } } @@ -74,7 +75,9 @@ public class MusicPlayerBridge : GLib.Object } } - public void client_has_become_available ( string desktop, string dbus_name ) + public void client_has_become_available ( string desktop, + string dbus_name, + bool use_playlists ) { if (desktop == null || desktop == ""){ warning("Client %s attempting to register without desktop entry being set on the mpris root", @@ -104,6 +107,7 @@ public class MusicPlayerBridge : GLib.Object dbus_name, this.fetch_icon_name(desktop), this.calculate_menu_position(), + use_playlists, PlayerController.state.READY ); this.registered_clients.set ( mpris_key, ctrl ); debug ( "Have not seen this %s before, new controller created.", desktop ); @@ -111,6 +115,7 @@ public class MusicPlayerBridge : GLib.Object debug ( "application added to the interested list" ); } else{ + this.registered_clients[mpris_key].use_playlists = use_playlists; this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); this.registered_clients[mpris_key].activate ( dbus_name ); debug("Application has already registered - awaken the hibernation: %s \n", dbus_name ); @@ -130,7 +135,7 @@ public class MusicPlayerBridge : GLib.Object } } } - + public void set_root_menu_item ( Dbusmenu.Menuitem menu ) { this.root_menu = menu; diff --git a/src/player-controller.vala b/src/player-controller.vala index 3922ecf..adefb65 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -45,19 +45,22 @@ public class PlayerController : GLib.Object private Dbusmenu.Menuitem root_menu; public string dbus_name { get; set;} - public ArrayList custom_items; + public ArrayList custom_items; public Mpris2Controller mpris_bridge; public AppInfo? app_info { get; set;} public int menu_offset { get; set;} public string icon_name { get; set; } - + public bool? use_playlists; + public PlayerController(Dbusmenu.Menuitem root, GLib.AppInfo app, string? dbus_name, string icon_name, int offset, + bool? use_playlists, state initial_state) { + this.use_playlists = use_playlists; this.root_menu = root; this.app_info = app; this.dbus_name = dbus_name; @@ -67,7 +70,7 @@ public class PlayerController : GLib.Object this.menu_offset = offset; this.construct_widgets(); this.establish_mpris_connection(); - this.update_layout(); + this.update_layout(); } public void update_state(state new_state) @@ -81,7 +84,7 @@ public class PlayerController : GLib.Object public void activate( string dbus_name ) { this.dbus_name = dbus_name; - this.establish_mpris_connection(); + this.establish_mpris_connection(); } /* @@ -109,6 +112,9 @@ public class PlayerController : GLib.Object debug("establish_mpris_connection - Not ready to connect"); return; } + debug ( " establish mpris connection - use playlists value = %s ", + this.use_playlists.to_string() ); + this.mpris_bridge = new Mpris2Controller(this); this.determine_state(); } @@ -148,7 +154,7 @@ public class PlayerController : GLib.Object this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE, true); playlists_menuitem.root_item.property_set_bool ( MENUITEM_PROP_VISIBLE, - this.mpris_bridge.playlists_support_exist() ); + this.use_playlists ); } private void construct_widgets() @@ -181,9 +187,8 @@ public class PlayerController : GLib.Object root_menu.child_add_position(playlists_menuitem.root_item, this.menu_offset + this.custom_items.index_of(item)); } } - } + } - private static string format_player_name(owned string app_info_name) { string result = app_info_name.down().strip(); diff --git a/src/sound-service.c b/src/sound-service.c index defcb94..98f1881 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - //close_pulse_activites(); - //g_main_loop_quit(mainloop); + close_pulse_activites(); + g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From d34f1878510f6f23a0e238e359d0e057f2991908 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Sun, 9 Jan 2011 14:30:40 +0000 Subject: commit on the pain caused by that banshe mpris peculiarity --- src/mpris2-watcher.vala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index b30aa88..9ef9b2f 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -111,7 +111,7 @@ public class Mpris2Watcher : GLib.Object else if (previous_owner == "" && current_owner != "") { debug ("Client '%s' has appeared", name); bool use_playlists = this.supports_playlists ( name ); - client_appeared (mpris2_root.DesktopEntry, name, false/*use_playlists*/); + client_appeared (mpris2_root.DesktopEntry, name, use_playlists); } } @@ -134,7 +134,14 @@ public class Mpris2Watcher : GLib.Object private bool supports_playlists ( string name ) { try { - debug( "name = %s", name); + /* The dbusproxy flag parameter is needed to ensure Banshee does not + blow up. I suspect the issue is that if you + try to instantiate a dbus object which does not have any properties + associated with it, gdbus will attempt to fetch the properties (this is + in the documentation) but the banshee mpris dbus object more than likely + causes a crash because it doesn't check for the presence of properties + before attempting to access them. + */ this.introspectable = Bus.get_proxy_sync ( BusType.SESSION, name, MPRIS_MEDIA_PLAYER_PATH, -- cgit v1.2.3 From 07197b0c4a8153ad65daecf920d0e0d51b1bebbc Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Sun, 9 Jan 2011 15:05:33 +0000 Subject: nice refactor or mpris code --- src/Makefile.am | 1 + src/freedesktop-interfaces.vala | 41 +++++++++++++++++++++++++++++++++++++++++ src/mpris2-controller.vala | 2 +- src/mpris2-interfaces.vala | 4 +++- src/mpris2-watcher.vala | 35 ++++++----------------------------- src/sound-service.c | 4 ++-- 6 files changed, 54 insertions(+), 33 deletions(-) create mode 100644 src/freedesktop-interfaces.vala diff --git a/src/Makefile.am b/src/Makefile.am index 57f52d4..7fe7e0f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,6 +66,7 @@ music_bridge_VALASOURCES = \ player-item.vala \ settings-manager.vala \ playlists-menu-item.vala \ + freedesktop-interfaces.vala \ fetch-file.vala diff --git a/src/freedesktop-interfaces.vala b/src/freedesktop-interfaces.vala new file mode 100644 index 0000000..3e5d832 --- /dev/null +++ b/src/freedesktop-interfaces.vala @@ -0,0 +1,41 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +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 . +*/ + +[DBus (name = "org.freedesktop.DBus")] +public interface FreeDesktopObject: Object { + public abstract async string[] list_names() throws IOError; + public abstract signal void name_owner_changed ( string name, + string old_owner, + string new_owner ); +} + +[DBus (name = "org.freedesktop.DBus.Introspectable")] +public interface FreeDesktopIntrospectable: Object { + public abstract string Introspect() throws IOError; +} + +public errordomain XmlError { + FILE_NOT_FOUND, + XML_DOCUMENT_EMPTY +} + +const string FREEDESKTOP_SERVICE = "org.freedesktop.DBus"; +const string FREEDESKTOP_OBJECT = "/org/freedesktop/DBus"; + + diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index c43f5fe..66da069 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -71,7 +71,7 @@ public class Mpris2Controller : GLib.Object { debug("properties-changed for interface %s and owner %s", interface_source, this.owner.dbus_name); if ( changed_properties == null || - interface_source.has_prefix ( Mpris2Watcher.MPRIS_PREFIX ) == false ){ + interface_source.has_prefix ( MPRIS_PREFIX ) == false ){ warning("Property-changed hash is null or this is an interface that doesn't concerns us"); return; } diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index 88610e6..9d0b8c9 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -16,6 +16,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +const string MPRIS_PREFIX = "org.mpris.MediaPlayer2."; +const string MPRIS_MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2"; [DBus (name = "org.mpris.MediaPlayer2")] public interface MprisRoot : Object { @@ -24,7 +26,7 @@ public interface MprisRoot : Object { public abstract bool CanQuit{owned get; set;} public abstract bool CanRaise{owned get; set;} public abstract string Identity{owned get; set;} - public abstract string DesktopEntry{owned get; set;} + public abstract string DesktopEntry{owned get; set;} // methods public abstract async void Quit() throws IOError; public abstract async void Raise() throws IOError; diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 9ef9b2f..c20b04b 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -19,33 +19,9 @@ with this program. If not, see . using Xml; -[DBus (name = "org.freedesktop.DBus")] -public interface FreeDesktopObject: Object { - public abstract async string[] list_names() throws IOError; - public abstract signal void name_owner_changed ( string name, - string old_owner, - string new_owner ); -} - -[DBus (name = "org.freedesktop.DBus.Introspectable")] -public interface FreeDesktopIntrospectable: Object { - public abstract string Introspect() throws IOError; -} - -public errordomain XmlError { - FILE_NOT_FOUND, - XML_DOCUMENT_EMPTY -} - public class Mpris2Watcher : GLib.Object { - private const string FREEDESKTOP_SERVICE = "org.freedesktop.DBus"; - private const string FREEDESKTOP_OBJECT = "/org/freedesktop/DBus"; - public const string MPRIS_PREFIX = "org.mpris.MediaPlayer2."; - private const string MPRIS_MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2"; - FreeDesktopObject fdesktop_obj; - FreeDesktopIntrospectable introspectable; public signal void client_appeared ( string desktop_file_name, string dbus_name, @@ -133,6 +109,8 @@ public class Mpris2Watcher : GLib.Object private bool supports_playlists ( string name ) { + FreeDesktopIntrospectable introspectable; + try { /* The dbusproxy flag parameter is needed to ensure Banshee does not blow up. I suspect the issue is that if you @@ -142,11 +120,10 @@ public class Mpris2Watcher : GLib.Object causes a crash because it doesn't check for the presence of properties before attempting to access them. */ - this.introspectable = Bus.get_proxy_sync ( BusType.SESSION, - name, - MPRIS_MEDIA_PLAYER_PATH, - GLib.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES); - + introspectable = Bus.get_proxy_sync ( BusType.SESSION, + name, + MPRIS_MEDIA_PLAYER_PATH, + GLib.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES); var results = introspectable.Introspect(); return this.parse_interfaces (results); } diff --git a/src/sound-service.c b/src/sound-service.c index 98f1881..defcb94 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From 33e8e6c2ac125ba3806032ea3ef730bd5c782ac8 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Sun, 9 Jan 2011 15:30:29 +0000 Subject: more refactoring --- src/freedesktop-interfaces.vala | 6 ++++++ src/mpris2-controller.vala | 9 +-------- src/sound-service.c | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/freedesktop-interfaces.vala b/src/freedesktop-interfaces.vala index 3e5d832..4d75044 100644 --- a/src/freedesktop-interfaces.vala +++ b/src/freedesktop-interfaces.vala @@ -30,6 +30,12 @@ public interface FreeDesktopIntrospectable: Object { public abstract string Introspect() throws IOError; } +[DBus (name = "org.freedesktop.DBus.Properties")] +public interface FreeDesktopProperties : Object{ + public signal void PropertiesChanged (string source, HashTable changed_properties, + string[] invalid ); +} + public errordomain XmlError { FILE_NOT_FOUND, XML_DOCUMENT_EMPTY diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 66da069..fc61c12 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -18,12 +18,6 @@ with this program. If not, see . */ using Dbusmenu; -[DBus (name = "org.freedesktop.DBus.Properties")] -public interface FreeDesktopProperties : Object{ - public signal void PropertiesChanged (string source, HashTable changed_properties, - string[] invalid ); -} - /* This class will entirely replace mpris-controller.vala hence why there is no point in trying to get encorporate both into the same object model. @@ -148,9 +142,8 @@ public class Mpris2Controller : GLib.Object MetadataMenuitem.attributes_format()); if ( this.owner.use_playlists == true ){ - debug ("it thinks that there is a valid playlist interface"); this.fetch_playlists(); - this.fetch_active_playlist(); + this.fetch_active_playlist(); } } diff --git a/src/sound-service.c b/src/sound-service.c index defcb94..98f1881 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - //close_pulse_activites(); - //g_main_loop_quit(mainloop); + close_pulse_activites(); + g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3 From 714c7c49776e8a341254a3e4297b465d181206cd Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Sun, 9 Jan 2011 16:33:07 +0000 Subject: prep for new release --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 928ffff..1297120 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ -AC_INIT(indicator-sound, 0.5.4, conor.curran@canonical.com) +AC_INIT(indicator-sound, 0.5.5, conor.curran@canonical.com) AC_PREREQ(2.53) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(indicator-sound, 0.5.4) +AM_INIT_AUTOMAKE(indicator-sound, 0.5.5) AM_MAINTAINER_MODE -- cgit v1.2.3