diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/dbus-shared-names.h | 22 | ||||
-rw-r--r-- | src/familiar-players-db.vala | 24 | ||||
-rw-r--r-- | src/indicator-sound.c | 4 | ||||
-rw-r--r-- | src/metadata-menu-item.vala | 6 | ||||
-rw-r--r-- | src/metadata-widget.c | 10 | ||||
-rw-r--r-- | src/mpris2-controller.vala | 57 | ||||
-rw-r--r-- | src/mpris2-interfaces.vala | 4 | ||||
-rw-r--r-- | src/mpris2-watcher.vala | 66 | ||||
-rw-r--r-- | src/music-player-bridge.vala | 142 | ||||
-rw-r--r-- | src/player-controller.vala | 25 | ||||
-rw-r--r-- | src/playlists-menu-item.vala | 5 | ||||
-rw-r--r-- | src/pulse-manager.c | 4 | ||||
-rw-r--r-- | src/settings-manager.vala | 55 | ||||
-rw-r--r-- | src/sound-service-dbus.c | 1 | ||||
-rw-r--r-- | src/sound-service.xml | 4 |
16 files changed, 270 insertions, 161 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 214507b..82830e1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,8 +64,8 @@ music_bridge_VALASOURCES = \ mpris2-watcher.vala \ mpris2-controller.vala \ player-item.vala \ + settings-manager.vala \ playlists-menu-item.vala \ - familiar-players-db.vala \ fetch-file.vala diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h index 3062ac5..9d1e875 100644 --- a/src/dbus-shared-names.h +++ b/src/dbus-shared-names.h @@ -25,24 +25,10 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #ifndef __DBUS_SHARED_NAMES_H__ #define __DBUS_SHARED_NAMES_H__ 1 -#define INDICATOR_STATUS_DBUS_NAME "org.ayatana.indicator.status" -#define INDICATOR_STATUS_DBUS_OBJECT "/org/ayatana/indicator/status/menu" -#define INDICATOR_STATUS_SERVICE_DBUS_OBJECT "/org/ayatana/indicator/status/service" -#define INDICATOR_STATUS_SERVICE_DBUS_INTERFACE "org.ayatana.indicator.status.service" - -#define INDICATOR_USERS_DBUS_NAME "org.ayatana.indicator.users" -#define INDICATOR_USERS_DBUS_OBJECT "/org/ayatana/indicator/users/menu" -#define INDICATOR_USERS_SERVICE_DBUS_OBJECT "/org/gnome/DisplayManager/UserManager" -#define INDICATOR_USERS_SERVICE_DBUS_INTERFACE "org.gnome.DisplayManager.UserManager" - -#define INDICATOR_SESSION_DBUS_NAME "org.ayatana.indicator.session" -#define INDICATOR_SESSION_DBUS_OBJECT "/org/ayatana/indicator/session/menu" -#define INDICATOR_SESSION_DBUS_VERSION 0 - -#define INDICATOR_SOUND_DBUS_NAME "org.ayatana.indicator.sound" -#define INDICATOR_SOUND_DBUS_OBJECT "/org/ayatana/indicator/sound/menu" -#define INDICATOR_SOUND_SERVICE_DBUS_OBJECT "/org/ayatana/indicator/sound/service" -#define INDICATOR_SOUND_SERVICE_DBUS_INTERFACE "org.ayatana.indicator.sound" +#define INDICATOR_SOUND_DBUS_NAME "com.canonical.indicators.sound" +#define INDICATOR_SOUND_DBUS_OBJECT "/com/canonical/indicators/sound/menu" +#define INDICATOR_SOUND_SERVICE_DBUS_OBJECT "/com/canonical/indicators/sound/service" +#define INDICATOR_SOUND_SERVICE_DBUS_INTERFACE "com.canonical.indicators.sound" #define INDICATOR_SOUND_DBUS_VERSION 0 #endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/familiar-players-db.vala b/src/familiar-players-db.vala index 7012b5a..96d690a 100644 --- a/src/familiar-players-db.vala +++ b/src/familiar-players-db.vala @@ -160,29 +160,5 @@ public class FamiliarPlayersDB : GLib.Object return this.players_DB.keys; } - public static string? fetch_icon_name(string desktop_path) - { - KeyFile desktop_keyfile = new KeyFile (); - try{ - desktop_keyfile.load_from_file (desktop_path, KeyFileFlags.NONE); - } - catch(GLib.FileError error){ - warning("Error loading keyfile - FileError"); - return null; - } - catch(GLib.KeyFileError error){ - warning("Error loading keyfile - KeyFileError"); - return null; - } - - try{ - return desktop_keyfile.get_string (KeyFileDesktop.GROUP, - KeyFileDesktop.KEY_ICON); - } - catch(GLib.KeyFileError error){ - warning("Error trying to fetch the icon name from the keyfile"); - return null; - } - } }
\ No newline at end of file diff --git a/src/indicator-sound.c b/src/indicator-sound.c index d5cc54c..34f5ed9 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -561,7 +561,7 @@ fetch_sink_availability_from_dbus(IndicatorSound* self) GError * error = NULL; gboolean * available_input; available_input = g_new0(gboolean, 1); - org_ayatana_indicator_sound_get_sink_availability(sound_dbus_proxy, available_input, &error); + com_canonical_indicators_sound_get_sink_availability(sound_dbus_proxy, available_input, &error); if (error != NULL) { g_warning("Unable to fetch AVAILABILITY at indicator start up: %s", error->message); g_error_free(error); @@ -593,7 +593,7 @@ fetch_mute_value_from_dbus() GError * error = NULL; gboolean *mute_input; mute_input = g_new0(gboolean, 1); - org_ayatana_indicator_sound_get_sink_mute(sound_dbus_proxy, mute_input, &error); + com_canonical_indicators_sound_get_sink_mute(sound_dbus_proxy, mute_input, &error); if (error != NULL) { g_warning("Unable to fetch MUTE at indicator start up: %s", error->message); g_error_free(error); diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala index e84e902..741bb9f 100644 --- a/src/metadata-menu-item.vala +++ b/src/metadata-menu-item.vala @@ -99,10 +99,10 @@ public class MetadataMenuitem : PlayerItem { File art_file = File.new_for_uri(uri); if(art_file.is_native() == true){ - string path; + string path; try{ - path = Filename.from_uri(uri.strip()); - this.property_set(prop, path); + path = Filename.from_uri ( uri.strip() ); + this.property_set ( prop, path ); } catch(ConvertError e){ warning("Problem converting URI %s to file path", diff --git a/src/metadata-widget.c b/src/metadata-widget.c index 1e2c891..191e134 100644 --- a/src/metadata-widget.c +++ b/src/metadata-widget.c @@ -194,21 +194,23 @@ metadata_image_expose (GtkWidget *metadata, GdkEventExpose *event, gpointer user if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE || priv->theme_change_occured == TRUE){ priv->theme_change_occured = FALSE; - GdkPixbuf* pixbuf; - pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, NULL); + GdkPixbuf* orig_pixbuf; + orig_pixbuf = gdk_pixbuf_new_from_file(priv->image_path->str, NULL); //g_debug("metadata_load_new_image -> pixbuf from %s", // priv->image_path->str); - if(GDK_IS_PIXBUF(pixbuf) == FALSE){ + if(GDK_IS_PIXBUF(orig_pixbuf) == FALSE){ //g_debug("problem loading the downloaded image just use the placeholder instead"); draw_album_art_placeholder(metadata); return TRUE; } - pixbuf = gdk_pixbuf_scale_simple(pixbuf,60, 60, GDK_INTERP_BILINEAR); + GdkPixbuf* pixbuf; + pixbuf = gdk_pixbuf_scale_simple(orig_pixbuf,60, 60, GDK_INTERP_BILINEAR); gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); g_string_erase(priv->old_image_path, 0, -1); g_string_overwrite(priv->old_image_path, 0, priv->image_path->str); g_object_unref(pixbuf); + g_object_unref(orig_pixbuf); } return FALSE; } diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index d6f27ec..58a1906 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -30,7 +30,6 @@ public interface FreeDesktopProperties : Object{ */ 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;} @@ -46,19 +45,19 @@ public class Mpris2Controller : GLib.Object construct{ try { this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, - root_interface.concat(".").concat(this.owner.mpris_name), - "/org/mpris/MediaPlayer2"); + this.owner.dbus_name, + "/org/mpris/MediaPlayer2" ); this.player = Bus.get_proxy_sync ( BusType.SESSION, - root_interface.concat(".").concat(this.owner.mpris_name), + this.owner.dbus_name, "/org/mpris/MediaPlayer2" ); this.playlists = Bus.get_proxy_sync ( BusType.SESSION, - root_interface.concat(".").concat(this.owner.mpris_name), + this.owner.dbus_name, "/org/mpris/MediaPlayer2" ); this.properties_interface = Bus.get_proxy_sync ( BusType.SESSION, "org.freedesktop.Properties.PropertiesChanged", - "/org/mpris/MediaPlayer2" ); - this.properties_interface.PropertiesChanged += property_changed_cb; + "/org/mpris/MediaPlayer2" ); + this.properties_interface.PropertiesChanged.connect ( property_changed_cb ); } catch (IOError e) { error("Problems connecting to the session bus - %s", e.message); @@ -69,14 +68,19 @@ public class Mpris2Controller : GLib.Object HashTable<string, Variant?> changed_properties, string[] invalid ) { - debug("properties-changed for interface %s and owner %s", interface_source, this.owner.mpris_name); - if(changed_properties == null || interface_source.has_prefix(this.root_interface) == false ){ + 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 ){ warning("Property-changed hash is null or this is an interface that doesn't concerns us"); return; } Variant? play_v = changed_properties.lookup("PlaybackStatus"); if(play_v != null){ + // Race condition sometimes appears with the playback status + // 200ms timeout ensures we have the correct playback status at all times. string state = this.player.PlaybackStatus; + //debug("in the property update and the playback status = %s and update = %s", state, (string)play_v); + Timeout.add ( 200, ensure_correct_playback_status ); TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(state); (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); } @@ -84,7 +88,7 @@ public class Mpris2Controller : GLib.Object if(meta_v != null){ GLib.HashTable<string, Variant?> changed_updates = clean_metadata(); PlayerItem metadata = this.owner.custom_items[PlayerController.widget_order.METADATA]; - metadata.reset( MetadataMenuitem.attributes_format()); + metadata.reset ( MetadataMenuitem.attributes_format()); metadata.update ( changed_updates, MetadataMenuitem.attributes_format()); metadata.property_set_bool ( MENUITEM_PROP_VISIBLE, @@ -92,11 +96,24 @@ public class Mpris2Controller : GLib.Object } Variant? playlist_v = changed_properties.lookup("ActivePlaylist"); if ( playlist_v != null ){ - debug (" WE HAVE PLAYLIST CHANGE EVENT DETECTED "); this.fetch_active_playlist(); } } + public bool playlist_support() + { + // awaiting spec updates + // return this.mpris2_root.HasPlaylists; + return true; + } + + private bool ensure_correct_playback_status(){ + debug("TEST playback status = %s", this.player.PlaybackStatus); + TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(this.player.PlaybackStatus); + (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); + return false; + } + private GLib.HashTable<string, Variant?>? clean_metadata() { GLib.HashTable<string, Variant?> changed_updates = this.player.Metadata; @@ -158,34 +175,38 @@ public class Mpris2Controller : GLib.Object warning("Playlists object is null"); return; } - PlaylistDetails[] current_playlists = this.playlists.GetPlaylists(0, 10, "Alphabetical", false); + 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){ + /*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 "); - } + }*/ } } 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"); + warning("Playlists object is null or we don't have an active playlist"); return; } - - PlaylistDetails active_details = this.playlists.ActivePlaylist.active_playlist; - debug(" \n \n "); + 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/mpris2-interfaces.vala b/src/mpris2-interfaces.vala index 578b6c8..4f01c4c 100644 --- a/src/mpris2-interfaces.vala +++ b/src/mpris2-interfaces.vala @@ -21,6 +21,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>. 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;} @@ -53,7 +55,7 @@ public struct PlaylistDetails{ // Active playlist property container public struct ActivePlaylistContainer{ public bool valid; - public PlaylistDetails active_playlist; + public PlaylistDetails details; } [DBus (name = "org.mpris.MediaPlayer2.Playlists")] diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 1cf8baa..7814975 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -19,22 +19,23 @@ with this program. If not, see <http://www.gnu.org/licenses/>. [DBus (name = "org.freedesktop.DBus")] public interface FreeDesktopObject: Object { - public abstract signal void name_owner_changed (string name, - string old_owner, - string new_owner); + public abstract async string[] list_names() throws IOError; + public abstract signal void name_owner_changed ( string name, + string old_owner, + string new_owner ); } public class Mpris2Watcher : GLib.Object { private const string FREEDESKTOP_SERVICE = "org.freedesktop.DBus"; private const string FREEDESKTOP_OBJECT = "/org/freedesktop/DBus"; - private const string MPRIS_PREFIX = "org.mpris.MediaPlayer2."; + public const string MPRIS_PREFIX = "org.mpris.MediaPlayer2."; private const string MPRIS_MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2"; FreeDesktopObject fdesktop_obj; - public signal void client_appeared ( string desktop_name ); - public signal void client_disappeared ( string mpris_root_interface ); + public signal void client_appeared ( string desktop_file_name, string dbus_name ); + public signal void client_disappeared ( string dbus_name ); public Mpris2Watcher () { @@ -48,6 +49,7 @@ public class Mpris2Watcher : GLib.Object FREEDESKTOP_OBJECT, DBusProxyFlags.DO_NOT_LOAD_PROPERTIES ); this.fdesktop_obj.name_owner_changed.connect (this.name_changes_detected); + this.check_for_active_clients.begin(); } catch ( IOError e ){ warning( "Mpris2watcher could not set up a watch for mpris clients appearing on the bus: %s", @@ -58,8 +60,24 @@ public class Mpris2Watcher : GLib.Object private void name_changes_detected ( FreeDesktopObject dbus_obj, string name, string previous_owner, - string current_owner ) { - MprisRoot mpris2_root; + string current_owner ) + { + 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); + client_appeared (mpris2_root.DesktopEntry, 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, @@ -69,16 +87,30 @@ public class Mpris2Watcher : GLib.Object catch (IOError e){ warning( "Mpris2watcher could not create a root interface: %s", e.message ); - 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); - client_appeared (mpris2_root.DesktopEntry); } } + return mpris2_root; } + + // 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 5133770..239a40b 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -23,46 +23,49 @@ using GLib; public class MusicPlayerBridge : GLib.Object { + private SettingsManager settings_manager; private Dbusmenu.Menuitem root_menu; private HashMap<string, PlayerController> registered_clients; - private FamiliarPlayersDB playersDB; private Mpris2Watcher watcher; private const string DESKTOP_PREFIX = "/usr/share/applications/"; - + private Settings settings; + public MusicPlayerBridge() { - playersDB = new FamiliarPlayersDB(); - registered_clients = new HashMap<string, PlayerController> (); } - private void try_to_add_inactive_familiar_clients(){ - foreach(string app in this.playersDB.records()){ - if(app == null){ - warning("App string in keyfile is null therefore moving on to next player"); - continue; - } - - debug("attempting to make an app info from %s", app); - - DesktopAppInfo info = new DesktopAppInfo.from_filename(app); + construct{ + this.registered_clients = new HashMap<string, PlayerController> (); + this.settings_manager = new SettingsManager(); + this.settings_manager.blacklist_updates.connect ( this.on_blacklist_update ); + } + + private void on_blacklist_update ( string[] blacklist ) + { + debug("some blacklist update"); + } - if(info == null){ - warning("Could not create a desktopappinfo instance from app,: %s , moving on to the next client", app); + private void try_to_add_inactive_familiar_clients() + { + 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 ); + if ( app_info == null ){ + warning ( "Could not create app_info for path %s \n Getting out of here ", path); continue; } - - GLib.AppInfo app_info = info as GLib.AppInfo; - var mpris_key = determine_key ( app ); - PlayerController ctrl = new PlayerController(this.root_menu, - app_info, - mpris_key, - playersDB.fetch_icon_name(app), - calculate_menu_position(), - PlayerController.state.OFFLINE); - this.registered_clients.set(mpris_key, ctrl); - } + var mpris_key = determine_key ( path ); + PlayerController ctrl = new PlayerController ( this.root_menu, + app_info, + null, + this.fetch_icon_name(path), + calculate_menu_position(), + PlayerController.state.OFFLINE ); + this.registered_clients.set(mpris_key, ctrl); + } } - + private int calculate_menu_position() { if(this.registered_clients.size == 0){ @@ -73,20 +76,15 @@ public class MusicPlayerBridge : GLib.Object } } - /*public void on_server_added(Indicate.ListenerServer object, string type) + public void client_has_become_available ( string desktop, string dbus_name ) { - debug("MusicPlayerBridge -> on_server_added with value %s", type); - if(server_is_not_of_interest(type)) return; - if ( this.root_menu != null ){ - listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback; - this.listener.server_get_desktop(object, cb, this); + if (desktop == null || desktop == ""){ + warning("Client %s attempting to register without desktop entry being set on the mpris root", + dbus_name); + return; } - }*/ - - public void client_has_become_available ( string desktop_file_name ) - { - debug ( "client_has_become_available %s", desktop_file_name ); - string path = DESKTOP_PREFIX.concat ( desktop_file_name.concat( ".desktop" ) ); + debug ( "client_has_become_available %s", desktop ); + string path = DESKTOP_PREFIX.concat ( desktop.concat( ".desktop" ) ); AppInfo? app_info = create_app_info ( path ); if ( app_info == null ){ warning ( "Could not create app_info for path %s \n Getting out of here ", path); @@ -94,25 +92,26 @@ public class MusicPlayerBridge : GLib.Object } var mpris_key = determine_key ( path ); - - if ( this.playersDB.already_familiar ( path ) == false ){ - debug("New client has registered that we have not seen before: %s", desktop_file_name ); - this.playersDB.insert ( path ); + // 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, - mpris_key, - playersDB.fetch_icon_name(path), + dbus_name, + this.fetch_icon_name(path), this.calculate_menu_position(), PlayerController.state.READY ); - this.registered_clients.set ( mpris_key, ctrl ); - debug ( "successfully created appinfo and instance from path and set it on the respective instance" ); - } - else{ - this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); - this.registered_clients[mpris_key].activate ( ); - debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path); - } + this.registered_clients.set ( mpris_key, ctrl ); + debug ( "Have not seen this %s before, new controller created.", desktop ); + this.settings_manager.add_interested ( desktop ); + debug ( "application added to the interested list" ); } + else{ + 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 ); + } + } public void client_has_vanished ( string mpris_root_interface ) { @@ -127,7 +126,7 @@ public class MusicPlayerBridge : GLib.Object } } - public void set_root_menu_item(Dbusmenu.Menuitem menu) + public void set_root_menu_item ( Dbusmenu.Menuitem menu ) { this.root_menu = menu; this.try_to_add_inactive_familiar_clients(); @@ -136,7 +135,7 @@ public class MusicPlayerBridge : GLib.Object this.watcher.client_disappeared += this.client_has_vanished; } - public static AppInfo? create_app_info ( string path ) + private static AppInfo? create_app_info ( string path ) { DesktopAppInfo info = new DesktopAppInfo.from_filename ( path ) ; if ( path == null || info == null ){ @@ -146,7 +145,38 @@ public class MusicPlayerBridge : GLib.Object GLib.AppInfo app_info = info as GLib.AppInfo; return app_info; } + + private static string? fetch_icon_name(string desktop_path) + { + KeyFile desktop_keyfile = new KeyFile (); + try{ + desktop_keyfile.load_from_file (desktop_path, KeyFileFlags.NONE); + } + catch(GLib.FileError error){ + warning("Error loading keyfile - FileError"); + return null; + } + catch(GLib.KeyFileError error){ + warning("Error loading keyfile - KeyFileError"); + return null; + } + + try{ + return desktop_keyfile.get_string (KeyFileDesktop.GROUP, + KeyFileDesktop.KEY_ICON); + } + catch(GLib.KeyFileError error){ + warning("Error trying to fetch the icon name from the keyfile"); + return null; + } + } + /* + 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. + */ private static string? determine_key(owned string path) { var tokens = path.split( "/" ); diff --git a/src/player-controller.vala b/src/player-controller.vala index 450ecd6..24fd090 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -45,7 +45,7 @@ public class PlayerController : GLib.Object private Dbusmenu.Menuitem root_menu; public string name { get; set;} - public string mpris_name { get; set;} + public string dbus_name { get; set;} public ArrayList<PlayerItem> custom_items; public Mpris2Controller mpris_bridge; public AppInfo? app_info { get; set;} @@ -54,21 +54,21 @@ public class PlayerController : GLib.Object public PlayerController(Dbusmenu.Menuitem root, GLib.AppInfo app, - string mpris_name, + string? dbus_name, string icon_name, int offset, state initial_state) { this.root_menu = root; this.app_info = app; + this.dbus_name = dbus_name; this.name = format_player_name(this.app_info.get_name()); - this.mpris_name = mpris_name; this.icon_name = icon_name; this.custom_items = new ArrayList<PlayerItem>(); this.current_state = initial_state; this.menu_offset = offset; - construct_widgets(); - establish_mpris_connection(); + this.construct_widgets(); + this.establish_mpris_connection(); this.update_layout(); } @@ -79,8 +79,9 @@ public class PlayerController : GLib.Object this.update_layout(); } - public void activate() + public void activate( string dbus_name ) { + this.dbus_name = dbus_name; this.establish_mpris_connection(); } @@ -104,7 +105,7 @@ public class PlayerController : GLib.Object private void establish_mpris_connection() { - if(this.current_state != state.READY){ + if(this.current_state != state.READY || this.dbus_name == null ){ debug("establish_mpris_connection - Not ready to connect"); return; } @@ -135,6 +136,8 @@ public class PlayerController : GLib.Object 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 ); return; } this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, @@ -143,8 +146,6 @@ public class PlayerController : GLib.Object 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() @@ -177,7 +178,7 @@ 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) { @@ -188,12 +189,12 @@ public class PlayerController : GLib.Object } if(result.length > 1){ result = result.up(1).concat(result.slice(1, result.length)); - debug("PlayerController->format_player_name - : %s", result); } + debug("PlayerController->format_player_name - : %s", result); return result; } - public void determine_state() + private void determine_state() { if(this.mpris_bridge.connected() == true){ this.update_state(state.CONNECTED); diff --git a/src/playlists-menu-item.vala b/src/playlists-menu-item.vala index f9d681e..30ffdc7 100644 --- a/src/playlists-menu-item.vala +++ b/src/playlists-menu-item.vala @@ -49,6 +49,11 @@ public class PlaylistsMenuitem : PlayerItem this.root_item.child_append( menuitem ); } } + + public void update_active_playlist(PlaylistDetails detail) + { + this.root_item.property_set ( MENUITEM_PROP_LABEL, detail.name ); + } private void submenu_item_activated (int menu_item_id) { diff --git a/src/pulse-manager.c b/src/pulse-manager.c index b002094..4443044 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -65,7 +65,7 @@ void establish_pulse_activities(SoundServiceDbus *service) pa_main_loop = pa_glib_mainloop_new(g_main_context_default()); g_assert(pa_main_loop); pulse_context = pa_context_new(pa_glib_mainloop_get_api(pa_main_loop), - "ayatana.indicator.sound"); + "com.canonical.indicators.sound"); g_assert(pulse_context); sink_hash = g_hash_table_new_full(g_direct_hash, @@ -103,7 +103,7 @@ reconnect_to_pulse() sink_hash = NULL; } pulse_context = pa_context_new( pa_glib_mainloop_get_api( pa_main_loop ), - "ayatana.indicator.sound" ); + "com.canonical.indicators.sound" ); g_assert(pulse_context); sink_hash = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, diff --git a/src/settings-manager.vala b/src/settings-manager.vala new file mode 100644 index 0000000..05db430 --- /dev/null +++ b/src/settings-manager.vala @@ -0,0 +1,55 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +using Gee; + +public class SettingsManager : GLib.Object +{ + private Settings settings; + public signal void blacklist_updates ( string[] new_blacklist ); + + public SettingsManager ( ){ + } + construct{ + this.settings = new Settings ("com.canonical.indicators.sound"); + settings.changed["blacklisted-media-players"].connect (on_blacklist_event); + } + + public string[] fetch_blacklist() + { + return this.settings.get_strv ("blacklisted-media-players"); + } + + public string[] fetch_interested() + { + return this.settings.get_strv ("interested-media-players"); + } + + public bool add_interested(string app_desktop_name) + { + string[] already_interested = fetch_interested(); + already_interested += (app_desktop_name); + return this.settings.set_strv( "interested-media-players", + already_interested ); + } + + private void on_blacklist_event() + { + this.blacklist_updates(this.settings.get_strv ("blacklisted-media-players")); + } +}
\ No newline at end of file diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index d553285..0760247 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -42,7 +42,6 @@ struct _SoundServiceDbusPrivate { gboolean sink_availability; }; - /* Signals */ enum { SINK_INPUT_WHILE_MUTED, diff --git a/src/sound-service.xml b/src/sound-service.xml index ee19ceb..a552d52 100644 --- a/src/sound-service.xml +++ b/src/sound-service.xml @@ -1,6 +1,6 @@ <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> -<node name="/org/ayatana/indicator/sound"> - <interface name="org.ayatana.indicator.sound"> +<node name="/com/canonical/indicators/sound"> + <interface name="com.canonical.indicators.sound"> <method name = "GetSinkMute"> <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="sound_service_dbus_get_sink_mute"/> <arg type='b' name='mute_input' direction="out"/> |