From 89466547b9547e0786e3919acab787f669798443 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 9 Feb 2015 14:05:39 -0600 Subject: Putting an interface in for volume control --- src/service.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/service.vala') diff --git a/src/service.vala b/src/service.vala index b07f267..b435726 100644 --- a/src/service.vala +++ b/src/service.vala @@ -32,7 +32,7 @@ public class IndicatorSound.Service: Object { this.settings.bind ("visible", this, "visible", SettingsBindFlags.GET); this.notify["visible"].connect ( () => this.update_root_icon () ); - this.volume_control = new VolumeControl (); + this.volume_control = new VolumeControlPulse (); /* If we're on the greeter, don't export */ if (GLib.Environment.get_user_name() != "lightdm") { -- cgit v1.2.3 From 330b0347282f3e6de77cfe58176ad764495676ec Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 9 Feb 2015 14:08:01 -0600 Subject: Make it so that we can inject the volume control object into the service --- src/service.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/service.vala') diff --git a/src/service.vala b/src/service.vala index b435726..c63f5c0 100644 --- a/src/service.vala +++ b/src/service.vala @@ -18,7 +18,7 @@ */ public class IndicatorSound.Service: Object { - public Service (MediaPlayerList playerlist) { + public Service (MediaPlayerList playerlist, VolumeControl volume) { sync_notification = new Notify.Notification(_("Volume"), "", "audio-volume-muted"); this.notification_server_watch = GLib.Bus.watch_name(GLib.BusType.SESSION, "org.freedesktop.Notifications", @@ -32,7 +32,7 @@ public class IndicatorSound.Service: Object { this.settings.bind ("visible", this, "visible", SettingsBindFlags.GET); this.notify["visible"].connect ( () => this.update_root_icon () ); - this.volume_control = new VolumeControlPulse (); + this.volume_control = volume; /* If we're on the greeter, don't export */ if (GLib.Environment.get_user_name() != "lightdm") { -- cgit v1.2.3 From 043af330ce48ea89d820e50c1f915ac9a9b278c6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 9 Feb 2015 16:35:05 -0600 Subject: Make it so that the accounts service object is made outside of the service object --- src/service.vala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/service.vala') diff --git a/src/service.vala b/src/service.vala index c63f5c0..c6f318b 100644 --- a/src/service.vala +++ b/src/service.vala @@ -18,7 +18,7 @@ */ public class IndicatorSound.Service: Object { - public Service (MediaPlayerList playerlist, VolumeControl volume) { + public Service (MediaPlayerList playerlist, VolumeControl volume, AccountsServiceUser? accounts) { sync_notification = new Notify.Notification(_("Volume"), "", "audio-volume-muted"); this.notification_server_watch = GLib.Bus.watch_name(GLib.BusType.SESSION, "org.freedesktop.Notifications", @@ -34,10 +34,9 @@ public class IndicatorSound.Service: Object { this.volume_control = volume; + this.accounts_service = accounts; /* If we're on the greeter, don't export */ - if (GLib.Environment.get_user_name() != "lightdm") { - this.accounts_service = new AccountsServiceUser(); - + if (this.accounts_service != null) { this.accounts_service.notify["showDataOnGreeter"].connect(() => { this.export_to_accounts_service = this.accounts_service.showDataOnGreeter; eventually_update_player_actions(); -- cgit v1.2.3 From 72bbb7eaaf6985840c86cba9e8b07aebe841c3e8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 9 Feb 2015 22:42:26 -0600 Subject: Make it so that we unexport actions when destroying the object --- src/service.vala | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/service.vala') diff --git a/src/service.vala b/src/service.vala index c6f318b..da3bf09 100644 --- a/src/service.vala +++ b/src/service.vala @@ -101,6 +101,11 @@ public class IndicatorSound.Service: Object { GLib.Bus.unwatch_name(this.notification_server_watch); this.notification_server_watch = 0; } + + if (this.export_actions != 0) { + bus.unexport_action_group(this.export_actions); + this.export_actions = 0; + } } bool greeter_show_track () { @@ -480,9 +485,14 @@ public class IndicatorSound.Service: Object { return high_volume_action; } + DBusConnection? bus = null; + uint export_actions = 0; + void bus_acquired (DBusConnection connection, string name) { + bus = connection; + try { - connection.export_action_group ("/com/canonical/indicator/sound", this.actions); + export_actions = connection.export_action_group ("/com/canonical/indicator/sound", this.actions); } catch (Error e) { critical ("%s", e.message); } -- cgit v1.2.3 From 10d44ff66a7efb25cd2f69300ed04e97b084034f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 11 Feb 2015 15:47:12 -0600 Subject: Pulling the mainloop out of the service object --- src/service.vala | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) (limited to 'src/service.vala') diff --git a/src/service.vala b/src/service.vala index da3bf09..4711867 100644 --- a/src/service.vala +++ b/src/service.vala @@ -18,7 +18,11 @@ */ public class IndicatorSound.Service: Object { - public Service (MediaPlayerList playerlist, VolumeControl volume, AccountsServiceUser? accounts) { + Cancellable cancel; + + public Service (MainLoop inloop, MediaPlayerList playerlist, VolumeControl volume, AccountsServiceUser? accounts) { + loop = inloop; + sync_notification = new Notify.Notification(_("Volume"), "", "audio-volume-muted"); this.notification_server_watch = GLib.Bus.watch_name(GLib.BusType.SESSION, "org.freedesktop.Notifications", @@ -89,9 +93,17 @@ public class IndicatorSound.Service: Object { } } }); + + Bus.own_name (BusType.SESSION, "com.canonical.indicator.sound", BusNameOwnerFlags.NONE, + this.bus_acquired, null, this.name_lost); } ~Service() { + debug("Destroying Service Object"); + + cancel.cancel(); + clear_acts_player(); + if (this.sound_was_blocked_timeout_id > 0) { Source.remove (this.sound_was_blocked_timeout_id); this.sound_was_blocked_timeout_id = 0; @@ -119,30 +131,6 @@ public class IndicatorSound.Service: Object { this.accounts_service.player = null; } - public int run () { - if (this.loop != null) { - warning ("service is already running"); - return 1; - } - - Bus.own_name (BusType.SESSION, "com.canonical.indicator.sound", BusNameOwnerFlags.NONE, - this.bus_acquired, null, this.name_lost); - - this.loop = new MainLoop (null, false); - - GLib.Unix.signal_add(GLib.ProcessSignal.TERM, () => { - debug("SIGTERM recieved, stopping our mainloop"); - this.loop.quit(); - return false; - }); - - this.loop.run (); - - clear_acts_player(); - - return 0; - } - public bool visible { get; set; } public bool allow_amplified_volume { @@ -488,19 +476,23 @@ public class IndicatorSound.Service: Object { DBusConnection? bus = null; uint export_actions = 0; - void bus_acquired (DBusConnection connection, string name) { + void bus_acquired (DBusConnection? connection, string name) { + if (connection == null) + return; + bus = connection; try { - export_actions = connection.export_action_group ("/com/canonical/indicator/sound", this.actions); + export_actions = bus.export_action_group ("/com/canonical/indicator/sound", this.actions); } catch (Error e) { critical ("%s", e.message); } - this.menus.@foreach ( (profile, menu) => menu.export (connection, @"/com/canonical/indicator/sound/$profile")); + return; + this.menus.@foreach ( (profile, menu) => menu.export (bus, @"/com/canonical/indicator/sound/$profile")); } - void name_lost (DBusConnection connection, string name) { + void name_lost (DBusConnection? connection, string name) { this.loop.quit (); } -- cgit v1.2.3 From 180bc45d31558eb19761e07f71beb8d58054c3dc Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 11 Feb 2015 18:37:51 -0600 Subject: Make it so that Vala stops generating circular references --- src/service.vala | 93 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 45 deletions(-) (limited to 'src/service.vala') diff --git a/src/service.vala b/src/service.vala index 4711867..7ab0c9c 100644 --- a/src/service.vala +++ b/src/service.vala @@ -18,17 +18,29 @@ */ public class IndicatorSound.Service: Object { - Cancellable cancel; + DBusConnection bus; + DBusProxy notification_proxy; - public Service (MainLoop inloop, MediaPlayerList playerlist, VolumeControl volume, AccountsServiceUser? accounts) { - loop = inloop; + public Service (MediaPlayerList playerlist, VolumeControl volume, AccountsServiceUser? accounts) { + try { + bus = Bus.get_sync(GLib.BusType.SESSION); + } catch (GLib.Error e) { + error("Unable to get DBus session bus: %s", e.message); + } sync_notification = new Notify.Notification(_("Volume"), "", "audio-volume-muted"); - this.notification_server_watch = GLib.Bus.watch_name(GLib.BusType.SESSION, - "org.freedesktop.Notifications", - GLib.BusNameWatcherFlags.NONE, - () => { check_sync_notification = false; }, - () => { check_sync_notification = false; }); + try { + this.notification_proxy = new DBusProxy.for_bus_sync(GLib.BusType.SESSION, + DBusProxyFlags.DO_NOT_LOAD_PROPERTIES | DBusProxyFlags.DO_NOT_CONNECT_SIGNALS | DBusProxyFlags.DO_NOT_AUTO_START, + null, /* interface info */ + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + null); + this.notification_proxy.notify["g-name-owner"].connect ( () => { check_sync_notification = false; } ); + } catch (GLib.Error e) { + error("Unable to build notification proxy: %s", e.message); + } this.settings = new Settings ("com.canonical.indicator.sound"); this.sharedsettings = new Settings ("com.ubuntu.sound"); @@ -94,16 +106,26 @@ public class IndicatorSound.Service: Object { } }); - Bus.own_name (BusType.SESSION, "com.canonical.indicator.sound", BusNameOwnerFlags.NONE, - this.bus_acquired, null, this.name_lost); + /* Everything is built, let's put it on the bus */ + try { + export_actions = bus.export_action_group ("/com/canonical/indicator/sound", this.actions); + } catch (Error e) { + critical ("%s", e.message); + } + + this.menus.@foreach ( (profile, menu) => menu.export (bus, @"/com/canonical/indicator/sound/$profile")); } ~Service() { debug("Destroying Service Object"); - cancel.cancel(); clear_acts_player(); + if (this.player_action_update_id > 0) { + Source.remove (this.player_action_update_id); + this.player_action_update_id = 0; + } + if (this.sound_was_blocked_timeout_id > 0) { Source.remove (this.sound_was_blocked_timeout_id); this.sound_was_blocked_timeout_id = 0; @@ -163,7 +185,6 @@ public class IndicatorSound.Service: Object { { "indicator-shown", null, null, "@b false", null }, }; - MainLoop loop; SimpleActionGroup actions; HashTable menus; Settings settings; @@ -333,13 +354,14 @@ public class IndicatorSound.Service: Object { } } + SimpleAction silent_action; Action create_silent_mode_action () { bool silentNow = false; if (this.accounts_service != null) { silentNow = this.accounts_service.silentMode; } - var silent_action = new SimpleAction.stateful ("silent-mode", null, new Variant.boolean (silentNow)); + silent_action = new SimpleAction.stateful ("silent-mode", null, new Variant.boolean (silentNow)); /* If we're not dealing with accounts service, we'll just always be out of silent mode and that's cool. */ @@ -363,8 +385,9 @@ public class IndicatorSound.Service: Object { return silent_action; } + SimpleAction mute_action; Action create_mute_action () { - var mute_action = new SimpleAction.stateful ("mute", null, new Variant.boolean (this.volume_control.mute)); + mute_action = new SimpleAction.stateful ("mute", null, new Variant.boolean (this.volume_control.mute)); mute_action.activate.connect ( (action, param) => { action.change_state (new Variant.boolean (!action.get_state ().get_boolean ())); @@ -407,6 +430,7 @@ public class IndicatorSound.Service: Object { return mute_action; } + SimpleAction volume_action; Action create_volume_action () { /* The action's state is between be in [0.0, 1.0] instead of [0.0, * max_volume], so that we don't need to update the slider menu item @@ -417,7 +441,7 @@ public class IndicatorSound.Service: Object { double volume = this.volume_control.volume / this.max_volume; - var volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, new Variant.double (volume)); + volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, new Variant.double (volume)); volume_action.change_state.connect ( (action, val) => { double v = val.get_double () * this.max_volume; @@ -432,10 +456,8 @@ public class IndicatorSound.Service: Object { }); this.volume_control.notify["volume"].connect (() => { - var vol_action = this.actions.lookup_action ("volume") as SimpleAction; - /* Normalize volume, because the volume action's state is [0.0, 1.0], see create_volume_action() */ - vol_action.set_state (new Variant.double (this.volume_control.volume / this.max_volume)); + volume_action.set_state (new Variant.double (this.volume_control.volume / this.max_volume)); this.update_root_icon (); this.update_sync_notification (); @@ -446,24 +468,26 @@ public class IndicatorSound.Service: Object { return volume_action; } + SimpleAction mic_volume_action; Action create_mic_volume_action () { - var volume_action = new SimpleAction.stateful ("mic-volume", null, new Variant.double (this.volume_control.mic_volume)); + mic_volume_action = new SimpleAction.stateful ("mic-volume", null, new Variant.double (this.volume_control.mic_volume)); - volume_action.change_state.connect ( (action, val) => { + mic_volume_action.change_state.connect ( (action, val) => { volume_control.mic_volume = val.get_double (); }); this.volume_control.notify["mic-volume"].connect ( () => { - volume_action.set_state (new Variant.double (this.volume_control.mic_volume)); + mic_volume_action.set_state (new Variant.double (this.volume_control.mic_volume)); }); - this.volume_control.bind_property ("ready", volume_action, "enabled", BindingFlags.SYNC_CREATE); + this.volume_control.bind_property ("ready", mic_volume_action, "enabled", BindingFlags.SYNC_CREATE); - return volume_action; + return mic_volume_action; } + SimpleAction high_volume_action; Action create_high_volume_action () { - var high_volume_action = new SimpleAction.stateful("high-volume", null, new Variant.boolean (this.volume_control.high_volume)); + high_volume_action = new SimpleAction.stateful("high-volume", null, new Variant.boolean (this.volume_control.high_volume)); this.volume_control.notify["high-volume"].connect( () => { high_volume_action.set_state(new Variant.boolean (this.volume_control.high_volume)); @@ -473,29 +497,8 @@ public class IndicatorSound.Service: Object { return high_volume_action; } - DBusConnection? bus = null; uint export_actions = 0; - void bus_acquired (DBusConnection? connection, string name) { - if (connection == null) - return; - - bus = connection; - - try { - export_actions = bus.export_action_group ("/com/canonical/indicator/sound", this.actions); - } catch (Error e) { - critical ("%s", e.message); - } - - return; - this.menus.@foreach ( (profile, menu) => menu.export (bus, @"/com/canonical/indicator/sound/$profile")); - } - - void name_lost (DBusConnection? connection, string name) { - this.loop.quit (); - } - Variant action_state_for_player (MediaPlayer player, bool show_track = true) { var builder = new VariantBuilder (new VariantType ("a{sv}")); builder.add ("{sv}", "running", new Variant ("b", player.is_running)); -- cgit v1.2.3 From d1000c6d613b4cd26bd9ab3d890c3dee295f86a8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 13 Feb 2015 12:47:47 -0600 Subject: Adding a test for notification servers coming on and off the bus, and fixing the code for it --- src/service.vala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/service.vala') diff --git a/src/service.vala b/src/service.vala index 7ab0c9c..0b03b6e 100644 --- a/src/service.vala +++ b/src/service.vala @@ -33,11 +33,11 @@ public class IndicatorSound.Service: Object { this.notification_proxy = new DBusProxy.for_bus_sync(GLib.BusType.SESSION, DBusProxyFlags.DO_NOT_LOAD_PROPERTIES | DBusProxyFlags.DO_NOT_CONNECT_SIGNALS | DBusProxyFlags.DO_NOT_AUTO_START, null, /* interface info */ - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", + "org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", null); - this.notification_proxy.notify["g-name-owner"].connect ( () => { check_sync_notification = false; } ); + this.notification_proxy.notify["g-name-owner"].connect ( () => { debug("Notifications name owner changed"); check_sync_notification = false; } ); } catch (GLib.Error e) { error("Unable to build notification proxy: %s", e.message); } @@ -288,6 +288,7 @@ public class IndicatorSound.Service: Object { void update_sync_notification () { if (!check_sync_notification) { + support_sync_notification = false; List caps = Notify.get_server_caps (); if (caps.find_custom ("x-canonical-private-synchronous", strcmp) != null) { support_sync_notification = true; -- cgit v1.2.3 From eb8a797c9e7ce01e3345edc20db1486764c84d08 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 13 Feb 2015 13:48:31 -0600 Subject: Block notifications in the volume event instead of in the notification one so that high volume warnings can get through --- src/service.vala | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'src/service.vala') diff --git a/src/service.vala b/src/service.vala index 0b03b6e..14a49da 100644 --- a/src/service.vala +++ b/src/service.vala @@ -299,21 +299,6 @@ public class IndicatorSound.Service: Object { if (!support_sync_notification) return; - /* Update our volume and output */ - var oldoutput = this.last_output_notification; - this.last_output_notification = this.volume_control.stream; - - var oldvolume = this.last_volume_notification; - this.last_volume_notification = volume_control.volume; - - /* Suppress notifications of volume changes if it is because the - output stream changed. */ - if (oldoutput != this.last_output_notification) - return; - /* Supress updates that don't change the value */ - if (GLib.Math.fabs(oldvolume - this.last_volume_notification) < 0.01) - return; - var shown_action = actions.lookup_action ("indicator-shown") as SimpleAction; if (shown_action != null && shown_action.get_state().get_boolean()) return; @@ -461,6 +446,22 @@ public class IndicatorSound.Service: Object { volume_action.set_state (new Variant.double (this.volume_control.volume / this.max_volume)); this.update_root_icon (); + + /* Update our volume and output */ + var oldoutput = this.last_output_notification; + this.last_output_notification = this.volume_control.stream; + + var oldvolume = this.last_volume_notification; + this.last_volume_notification = volume_control.volume; + + /* Suppress notifications of volume changes if it is because the + output stream changed. */ + if (oldoutput != this.last_output_notification) + return; + /* Supress updates that don't change the value */ + if (GLib.Math.fabs(oldvolume - this.last_volume_notification) < 0.01) + return; + this.update_sync_notification (); }); -- cgit v1.2.3