diff --git a/src/components/input/source_box.rs b/src/components/input/source_box.rs index a1409df..b620b98 100644 --- a/src/components/input/source_box.rs +++ b/src/components/input/source_box.rs @@ -16,7 +16,7 @@ use dbus::blocking::Connection; use dbus::message::SignalArgs; use dbus::{Error, Path}; use glib::subclass::prelude::ObjectSubclassIsExt; -use glib::{clone, Cast, Propagation, Variant}; +use glib::{clone, Cast, ControlFlow, Propagation, Variant}; use gtk::prelude::ActionableExt; use gtk::{gio, StringObject}; @@ -29,6 +29,10 @@ use crate::components::utils::{ }; use super::output_stream_entry::OutputStreamEntry; +use super::source_box_event_handlers::{ + output_stream_added_handler, output_stream_changed_handler, output_stream_removed_handler, + source_added_handler, source_changed_handler, source_removed_handler, +}; use super::source_entry::{set_default_source, toggle_source_mute, SourceEntry}; glib::wrapper! { @@ -111,136 +115,159 @@ pub fn populate_sources(input_box: Arc) { populate_outputstreams(input_box.clone()); populate_cards(input_box.clone()); - glib::spawn_future(async move { - glib::idle_add_once(move || { - let input_box_ref_slider = input_box.clone(); - let input_box_ref_toggle = input_box.clone(); - let input_box_ref_mute = input_box.clone(); - let input_box_ref = input_box.clone(); - { - let input_box_imp = input_box_ref.imp(); - let default_sink = input_box_imp.reset_default_source.clone(); - let source = default_sink.borrow(); + populate_source_information(input_box, sources); + }); +} - if source.muted { - input_box_imp - .reset_source_mute - .set_icon_name("microphone-disabled-symbolic"); - } else { - input_box_imp - .reset_source_mute - .set_icon_name("audio-input-microphone-symbolic"); - } +fn populate_source_information(input_box: Arc, sources: Vec) { + glib::spawn_future(async move { + glib::idle_add_once(move || { + let input_box_ref_slider = input_box.clone(); + let input_box_ref_toggle = input_box.clone(); + let input_box_ref_mute = input_box.clone(); + let input_box_ref = input_box.clone(); + { + let input_box_imp = input_box_ref.imp(); + let default_sink = input_box_imp.reset_default_source.clone(); + let source = default_sink.borrow(); - let volume = source.volume.first().unwrap_or(&0_u32); - let fraction = (*volume as f64 / 655.36).round(); - let percentage = (fraction).to_string() + "%"; - input_box_imp.reset_volume_percentage.set_text(&percentage); - input_box_imp.reset_volume_slider.set_value(*volume as f64); - let mut list = input_box_imp.reset_source_list.write().unwrap(); - for source in sources { - let index = source.index; - let alias = source.alias.clone(); - let mut is_default = false; - if input_box_imp.reset_default_source.borrow().name == source.name { - is_default = true; - } - let source_entry = Arc::new(SourceEntry::new( - is_default, - input_box_imp.reset_default_check_button.clone(), - source, - input_box.clone(), - )); - let source_clone = source_entry.clone(); - let entry = Arc::new(ListEntry::new(&*source_entry)); - entry.set_activatable(false); - list.insert(index, (entry.clone(), source_clone, alias)); - input_box_imp.reset_sources.append(&*entry); - } - let list = input_box_imp.reset_model_list.read().unwrap(); - input_box_imp.reset_source_dropdown.set_model(Some(&*list)); - let name = input_box_imp.reset_default_source.borrow(); - - let index = input_box_imp.reset_model_index.read().unwrap(); - let model_list = input_box_imp.reset_model_list.read().unwrap(); - for entry in 0..*index { - if model_list.string(entry) == Some(name.alias.clone().into()) { - input_box_imp.reset_source_dropdown.set_selected(entry); - break; - } - } - input_box_imp.reset_source_dropdown.connect_selected_notify( - clone!(@weak input_box_imp => move |dropdown| { - let input_box = input_box_ref_toggle.clone(); - let selected = dropdown.selected_item(); - if selected.is_none() { - return; - } - let selected = selected.unwrap(); - let selected = selected.downcast_ref::().unwrap(); - let selected = selected.string().to_string(); - - let source = input_box_imp.reset_source_map.read().unwrap(); - let source = source.get(&selected); - if source.is_none() { - return; - } - let source = Arc::new(source.unwrap().1.clone()); - gio::spawn_blocking(move || { - let result = set_default_source(source); - if result.is_none(){ - return; - } - refresh_default_source(result.unwrap(), input_box.clone(), false); - }); - }), - ); + if source.muted { + input_box_imp + .reset_source_mute + .set_icon_name("microphone-disabled-symbolic"); + } else { + input_box_imp + .reset_source_mute + .set_icon_name("audio-input-microphone-symbolic"); } - input_box_ref - .imp() - .reset_volume_slider - .connect_change_value(move |_, _, value| { - let imp = input_box_ref_slider.imp(); - let fraction = (value / 655.36).round(); - let percentage = (fraction).to_string() + "%"; - imp.reset_volume_percentage.set_text(&percentage); - let source = imp.reset_default_source.borrow(); - let index = source.index; - let channels = source.channels; - { - let mut time = imp.volume_time_stamp.borrow_mut(); - if time.is_some() - && time.unwrap().elapsed().unwrap() < Duration::from_millis(50) - { - return Propagation::Proceed; - } - *time = Some(SystemTime::now()); - } - set_source_volume(value, index, channels); - Propagation::Proceed - }); - input_box_ref - .imp() - .reset_source_mute - .connect_clicked(move |_| { - let imp = input_box_ref_mute.imp(); - let mut source = imp.reset_default_source.borrow_mut(); - source.muted = !source.muted; - if source.muted { - imp.reset_source_mute - .set_icon_name("microphone-disabled-symbolic"); - } else { - imp.reset_source_mute - .set_icon_name("audio-input-microphone-symbolic"); + let volume = source.volume.first().unwrap_or(&0_u32); + let fraction = (*volume as f64 / 655.36).round(); + let percentage = (fraction).to_string() + "%"; + input_box_imp.reset_volume_percentage.set_text(&percentage); + input_box_imp.reset_volume_slider.set_value(*volume as f64); + let mut list = input_box_imp.reset_source_list.write().unwrap(); + for source in sources { + let index = source.index; + let alias = source.alias.clone(); + let mut is_default = false; + if input_box_imp.reset_default_source.borrow().name == source.name { + is_default = true; + } + let source_entry = Arc::new(SourceEntry::new( + is_default, + input_box_imp.reset_default_check_button.clone(), + source, + input_box.clone(), + )); + let source_clone = source_entry.clone(); + let entry = Arc::new(ListEntry::new(&*source_entry)); + entry.set_activatable(false); + list.insert(index, (entry.clone(), source_clone, alias)); + input_box_imp.reset_sources.append(&*entry); + } + let list = input_box_imp.reset_model_list.read().unwrap(); + input_box_imp.reset_source_dropdown.set_model(Some(&*list)); + let name = input_box_imp.reset_default_source.borrow(); + + let index = input_box_imp.reset_model_index.read().unwrap(); + let model_list = input_box_imp.reset_model_list.read().unwrap(); + for entry in 0..*index { + if model_list.string(entry) == Some(name.alias.clone().into()) { + input_box_imp.reset_source_dropdown.set_selected(entry); + break; + } + } + input_box_imp + .reset_source_dropdown + .connect_selected_notify(move |dropdown| { + if let ControlFlow::Break() = + dropdown_handler(input_box_ref_toggle, dropdown, input_box_imp) + { + return; } - toggle_source_mute(source.index, source.muted); }); - }); + } + input_box_ref + .imp() + .reset_volume_slider + .connect_change_value(move |_, _, value| { + volume_slider_handler(input_box_ref_slider, value) + }); + + input_box_ref + .imp() + .reset_source_mute + .connect_clicked(move |_| { + mute_clicked_handler(input_box_ref_mute); + }); }); }); } +fn dropdown_handler( + input_box_ref_toggle: Arc, + dropdown: &adw::ComboRow, + input_box_imp: &source_box_impl::SourceBox, +) -> ControlFlow<()> { + let input_box = input_box_ref_toggle.clone(); + let selected = dropdown.selected_item(); + if selected.is_none() { + return ControlFlow::Break(()); + } + let selected = selected.unwrap(); + let selected = selected.downcast_ref::().unwrap(); + let selected = selected.string().to_string(); + let source = input_box_imp.reset_source_map.read().unwrap(); + let source = source.get(&selected); + if source.is_none() { + return ControlFlow::Break(()); + } + let source = Arc::new(source.unwrap().1.clone()); + gio::spawn_blocking(move || { + let result = set_default_source(source); + if result.is_none() { + return ControlFlow::Break(()); + } + refresh_default_source(result.unwrap(), input_box.clone(), false); + }); + + ControlFlow::Continue(()) +} + +fn volume_slider_handler(input_box_ref_slider: Arc, value: f64) -> Propagation { + let imp = input_box_ref_slider.imp(); + let fraction = (value / 655.36).round(); + let percentage = (fraction).to_string() + "%"; + imp.reset_volume_percentage.set_text(&percentage); + let source = imp.reset_default_source.borrow(); + let index = source.index; + let channels = source.channels; + { + let mut time = imp.volume_time_stamp.borrow_mut(); + if time.is_some() && time.unwrap().elapsed().unwrap() < Duration::from_millis(50) { + return Propagation::Proceed; + } + *time = Some(SystemTime::now()); + } + set_source_volume(value, index, channels); + Propagation::Proceed +} + +fn mute_clicked_handler(input_box_ref_mute: Arc) { + let imp = input_box_ref_mute.imp(); + let mut source = imp.reset_default_source.borrow_mut(); + source.muted = !source.muted; + if source.muted { + imp.reset_source_mute + .set_icon_name("microphone-disabled-symbolic"); + } else { + imp.reset_source_mute + .set_icon_name("audio-input-microphone-symbolic"); + } + toggle_source_mute(source.index, source.muted); +} + pub fn refresh_default_source(new_source: Source, input_box: Arc, entry: bool) { let volume = *new_source.volume.first().unwrap_or(&0_u32); let fraction = (volume as f64 / 655.36).round(); @@ -348,7 +375,7 @@ fn get_cards() -> Vec { res.unwrap().0 } -fn get_default_source_name() -> String { +pub fn get_default_source_name() -> String { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); let res: Result<(String,), Error> = proxy.method_call(AUDIO, "GetDefaultSourceName", ()); @@ -393,93 +420,16 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc) -> let output_stream_changed_box = source_box.clone(); let res = conn.add_match(source_added, move |ir: SourceAdded, _, _| { - let source_box = source_added_box.clone(); - glib::spawn_future(async move { - glib::idle_add_once(move || { - let input_box = source_box.clone(); - let input_box_imp = input_box.imp(); - let source_index = ir.source.index; - let alias = ir.source.alias.clone(); - let name = ir.source.name.clone(); - let mut is_default = false; - if input_box_imp.reset_default_source.borrow().name == ir.source.name { - is_default = true; - } - let source_entry = Arc::new(SourceEntry::new( - is_default, - input_box_imp.reset_default_check_button.clone(), - ir.source, - input_box.clone(), - )); - let source_clone = source_entry.clone(); - let entry = Arc::new(ListEntry::new(&*source_entry)); - entry.set_activatable(false); - let mut list = input_box_imp.reset_source_list.write().unwrap(); - list.insert(source_index, (entry.clone(), source_clone, alias.clone())); - input_box_imp.reset_sources.append(&*entry); - let mut map = input_box_imp.reset_source_map.write().unwrap(); - let mut index = input_box_imp.reset_model_index.write().unwrap(); - let model_list = input_box_imp.reset_model_list.write().unwrap(); - if model_list.string(*index - 1) == Some("Monitor of Dummy Output".into()) { - model_list.append(&alias); - model_list.remove(*index - 1); - map.insert(alias, (source_index, name)); - input_box_imp.reset_source_dropdown.set_selected(0); - } else { - model_list.append(&alias); - map.insert(alias.clone(), (source_index, name)); - if alias == "Monitor of Dummy Output" { - input_box_imp.reset_source_dropdown.set_selected(0); - } - *index += 1; - } - }); - }); - true + source_added_handler(source_box, ir) }); if res.is_err() { + // TODO: handle this with the log/error macro println!("fail on source add event"); return conn; } let res = conn.add_match(source_removed, move |ir: SourceRemoved, _, _| { - let source_box = source_removed_box.clone(); - glib::spawn_future(async move { - glib::idle_add_once(move || { - let input_box = source_box.clone(); - let input_box_imp = input_box.imp(); - let entry: Option<(Arc, Arc, String)>; - { - let mut list = input_box_imp.reset_source_list.write().unwrap(); - entry = list.remove(&ir.index); - if entry.is_none() { - return; - } - } - input_box_imp - .reset_sources - .remove(&*entry.clone().unwrap().0); - let mut map = input_box_imp.reset_source_map.write().unwrap(); - let alias = entry.unwrap().2; - map.remove(&alias); - let mut index = input_box_imp.reset_model_index.write().unwrap(); - let model_list = input_box_imp.reset_model_list.write().unwrap(); - - if *index == 1 { - model_list.append("Monitor of Dummy Output"); - } - for entry in 0..*index { - if model_list.string(entry) == Some(alias.clone().into()) { - model_list.splice(entry, 1, &[]); - break; - } - } - if *index > 1 { - *index -= 1; - } - }); - }); - true + source_removed_handler(source_box, ir) }); if res.is_err() { println!("fail on source remove event"); @@ -487,56 +437,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc) -> } let res = conn.add_match(source_changed, move |ir: SourceChanged, _, _| { - let source_box = source_changed_box.clone(); - let default_source = get_default_source_name(); - glib::spawn_future(async move { - glib::idle_add_once(move || { - let input_box = source_box.clone(); - let input_box_imp = input_box.imp(); - let is_default = ir.source.name == default_source; - let volume = ir.source.volume.first().unwrap_or(&0_u32); - let fraction = (*volume as f64 / 655.36).round(); - let percentage = (fraction).to_string() + "%"; - - let list = input_box_imp.reset_source_list.read().unwrap(); - let entry = list.get(&ir.source.index); - if entry.is_none() { - return; - } - let imp = entry.unwrap().1.imp(); - if is_default { - input_box_imp.reset_volume_percentage.set_text(&percentage); - input_box_imp.reset_volume_slider.set_value(*volume as f64); - input_box_imp - .reset_default_source - .replace(ir.source.clone()); - if ir.source.muted { - input_box_imp - .reset_source_mute - .set_icon_name("microphone-disabled-symbolic"); - } else { - input_box_imp - .reset_source_mute - .set_icon_name("audio-input-microphone-symbolic"); - } - imp.reset_selected_source.set_active(true); - } else { - imp.reset_selected_source.set_active(false); - } - imp.reset_source_name - .set_title(ir.source.alias.clone().as_str()); - imp.reset_volume_percentage.set_text(&percentage); - imp.reset_volume_slider.set_value(*volume as f64); - if ir.source.muted { - imp.reset_source_mute - .set_icon_name("microphone-disabled-symbolic"); - } else { - imp.reset_source_mute - .set_icon_name("audio-input-microphone-symbolic"); - } - }); - }); - true + source_changed_handler(source_box, ir) }); if res.is_err() { println!("fail on source change event"); @@ -544,21 +445,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc) -> } let res = conn.add_match(output_stream_added, move |ir: OutputStreamAdded, _, _| { - let source_box = output_stream_added_box.clone(); - glib::spawn_future(async move { - glib::idle_add_once(move || { - let input_box = source_box.clone(); - let input_box_imp = input_box.imp(); - let mut list = input_box_imp.reset_output_stream_list.write().unwrap(); - let index = ir.stream.index; - let output_stream = Arc::new(OutputStreamEntry::new(input_box.clone(), ir.stream)); - let entry = Arc::new(ListEntry::new(&*output_stream)); - entry.set_activatable(false); - list.insert(index, (entry.clone(), output_stream.clone())); - input_box_imp.reset_output_streams.append(&*entry); - }); - }); - true + output_stream_added_handler(output_stream_added_box, ir) }); if res.is_err() { println!("fail on output stream add event"); @@ -568,56 +455,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc) -> let res = conn.add_match( output_stream_changed, move |ir: OutputStreamChanged, _, _| { - let imp = output_stream_changed_box.imp(); - let alias: String; - { - let source_list = imp.reset_source_list.read().unwrap(); - if let Some(alias_opt) = source_list.get(&ir.stream.source_index) { - alias = alias_opt.2.clone(); - } else { - alias = String::from(""); - } - } - let source_box = output_stream_changed_box.clone(); - glib::spawn_future(async move { - glib::idle_add_once(move || { - let input_box = source_box.clone(); - let input_box_imp = input_box.imp(); - let entry: Arc; - { - let list = input_box_imp.reset_output_stream_list.read().unwrap(); - let entry_opt = list.get(&ir.stream.index); - if entry_opt.is_none() { - return; - } - entry = entry_opt.unwrap().1.clone(); - } - let imp = entry.imp(); - if ir.stream.muted { - imp.reset_source_mute - .set_icon_name("microphone-disabled-symbolic"); - } else { - imp.reset_source_mute - .set_icon_name("audio-input-microphone-symbolic"); - } - let name = ir.stream.application_name.clone() + ": " + ir.stream.name.as_str(); - imp.reset_source_selection.set_title(name.as_str()); - let volume = ir.stream.volume.first().unwrap_or(&0_u32); - let fraction = (*volume as f64 / 655.36).round(); - let percentage = (fraction).to_string() + "%"; - imp.reset_volume_percentage.set_text(&percentage); - imp.reset_volume_slider.set_value(*volume as f64); - let index = input_box_imp.reset_model_index.read().unwrap(); - let model_list = input_box_imp.reset_model_list.read().unwrap(); - for entry in 0..*index { - if model_list.string(entry) == Some(alias.clone().into()) { - imp.reset_source_selection.set_selected(entry); - break; - } - } - }); - }); - true + output_stream_changed_handler(output_stream_changed_box, ir) }, ); if res.is_err() { @@ -628,22 +466,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc) -> let res = conn.add_match( output_stream_removed, move |ir: OutputStreamRemoved, _, _| { - let source_box = output_stream_removed_box.clone(); - glib::spawn_future(async move { - glib::idle_add_once(move || { - let input_box = source_box.clone(); - let input_box_imp = input_box.imp(); - let mut list = input_box_imp.reset_output_stream_list.write().unwrap(); - let entry = list.remove(&ir.index); - if entry.is_none() { - return; - } - input_box_imp - .reset_output_streams - .remove(&*entry.unwrap().0); - }); - }); - true + output_stream_removed_handler(output_stream_removed_box, ir) }, ); if res.is_err() { diff --git a/src/components/input/source_box_event_handlers.rs b/src/components/input/source_box_event_handlers.rs new file mode 100644 index 0000000..73350a0 --- /dev/null +++ b/src/components/input/source_box_event_handlers.rs @@ -0,0 +1,240 @@ +use std::sync::Arc; + +use adw::prelude::{ComboRowExt, PreferencesRowExt}; +use glib::subclass::types::ObjectSubclassIsExt; +use gtk::prelude::{BoxExt, ButtonExt, CheckButtonExt, ListBoxRowExt, RangeExt}; +use re_set_lib::signals::{ + OutputStreamAdded, OutputStreamChanged, OutputStreamRemoved, SourceAdded, SourceChanged, + SourceRemoved, +}; + +use crate::components::base::list_entry::ListEntry; + +use super::{ + output_stream_entry::OutputStreamEntry, + source_box::{get_default_source_name, SourceBox}, + source_entry::SourceEntry, +}; + +pub fn source_added_handler(source_box: Arc, ir: SourceAdded) -> bool { + glib::spawn_future(async move { + glib::idle_add_once(move || { + let input_box = source_box.clone(); + let input_box_imp = input_box.imp(); + let source_index = ir.source.index; + let alias = ir.source.alias.clone(); + let name = ir.source.name.clone(); + let mut is_default = false; + if input_box_imp.reset_default_source.borrow().name == ir.source.name { + is_default = true; + } + let source_entry = Arc::new(SourceEntry::new( + is_default, + input_box_imp.reset_default_check_button.clone(), + ir.source, + input_box.clone(), + )); + let source_clone = source_entry.clone(); + let entry = Arc::new(ListEntry::new(&*source_entry)); + entry.set_activatable(false); + let mut list = input_box_imp.reset_source_list.write().unwrap(); + list.insert(source_index, (entry.clone(), source_clone, alias.clone())); + input_box_imp.reset_sources.append(&*entry); + let mut map = input_box_imp.reset_source_map.write().unwrap(); + let mut index = input_box_imp.reset_model_index.write().unwrap(); + let model_list = input_box_imp.reset_model_list.write().unwrap(); + if model_list.string(*index - 1) == Some("Monitor of Dummy Output".into()) { + model_list.append(&alias); + model_list.remove(*index - 1); + map.insert(alias, (source_index, name)); + input_box_imp.reset_source_dropdown.set_selected(0); + } else { + model_list.append(&alias); + map.insert(alias.clone(), (source_index, name)); + if alias == "Monitor of Dummy Output" { + input_box_imp.reset_source_dropdown.set_selected(0); + } + *index += 1; + } + }); + }); + true +} + +pub fn source_removed_handler(source_box: Arc, ir: SourceRemoved) -> bool { + glib::spawn_future(async move { + glib::idle_add_once(move || { + let input_box = source_box.clone(); + let input_box_imp = input_box.imp(); + let entry: Option<(Arc, Arc, String)>; + { + let mut list = input_box_imp.reset_source_list.write().unwrap(); + entry = list.remove(&ir.index); + if entry.is_none() { + return; + } + } + input_box_imp + .reset_sources + .remove(&*entry.clone().unwrap().0); + let mut map = input_box_imp.reset_source_map.write().unwrap(); + let alias = entry.unwrap().2; + map.remove(&alias); + let mut index = input_box_imp.reset_model_index.write().unwrap(); + let model_list = input_box_imp.reset_model_list.write().unwrap(); + + if *index == 1 { + model_list.append("Monitor of Dummy Output"); + } + for entry in 0..*index { + if model_list.string(entry) == Some(alias.clone().into()) { + model_list.splice(entry, 1, &[]); + break; + } + } + if *index > 1 { + *index -= 1; + } + }); + }); + true +} + +pub fn source_changed_handler(source_box: Arc, ir: SourceChanged) -> bool { + let default_source = get_default_source_name(); + glib::spawn_future(async move { + glib::idle_add_once(move || { + let input_box = source_box.clone(); + let input_box_imp = input_box.imp(); + let is_default = ir.source.name == default_source; + let volume = ir.source.volume.first().unwrap_or(&0_u32); + let fraction = (*volume as f64 / 655.36).round(); + let percentage = (fraction).to_string() + "%"; + + let list = input_box_imp.reset_source_list.read().unwrap(); + let entry = list.get(&ir.source.index); + if entry.is_none() { + return; + } + let imp = entry.unwrap().1.imp(); + if is_default { + input_box_imp.reset_volume_percentage.set_text(&percentage); + input_box_imp.reset_volume_slider.set_value(*volume as f64); + input_box_imp + .reset_default_source + .replace(ir.source.clone()); + if ir.source.muted { + input_box_imp + .reset_source_mute + .set_icon_name("microphone-disabled-symbolic"); + } else { + input_box_imp + .reset_source_mute + .set_icon_name("audio-input-microphone-symbolic"); + } + imp.reset_selected_source.set_active(true); + } else { + imp.reset_selected_source.set_active(false); + } + imp.reset_source_name + .set_title(ir.source.alias.clone().as_str()); + imp.reset_volume_percentage.set_text(&percentage); + imp.reset_volume_slider.set_value(*volume as f64); + if ir.source.muted { + imp.reset_source_mute + .set_icon_name("microphone-disabled-symbolic"); + } else { + imp.reset_source_mute + .set_icon_name("audio-input-microphone-symbolic"); + } + }); + }); + true +} + +pub fn output_stream_added_handler(source_box: Arc, ir: OutputStreamAdded) -> bool { + glib::spawn_future(async move { + glib::idle_add_once(move || { + let input_box = source_box.clone(); + let input_box_imp = input_box.imp(); + let mut list = input_box_imp.reset_output_stream_list.write().unwrap(); + let index = ir.stream.index; + let output_stream = Arc::new(OutputStreamEntry::new(input_box.clone(), ir.stream)); + let entry = Arc::new(ListEntry::new(&*output_stream)); + entry.set_activatable(false); + list.insert(index, (entry.clone(), output_stream.clone())); + input_box_imp.reset_output_streams.append(&*entry); + }); + }); + true +} + +pub fn output_stream_changed_handler(source_box: Arc, ir: OutputStreamChanged) -> bool { + let imp = source_box.imp(); + let alias: String; + { + let source_list = imp.reset_source_list.read().unwrap(); + if let Some(alias_opt) = source_list.get(&ir.stream.source_index) { + alias = alias_opt.2.clone(); + } else { + alias = String::from(""); + } + } + glib::spawn_future(async move { + glib::idle_add_once(move || { + let input_box = source_box.clone(); + let input_box_imp = input_box.imp(); + let entry: Arc; + { + let list = input_box_imp.reset_output_stream_list.read().unwrap(); + let entry_opt = list.get(&ir.stream.index); + if entry_opt.is_none() { + return; + } + entry = entry_opt.unwrap().1.clone(); + } + let imp = entry.imp(); + if ir.stream.muted { + imp.reset_source_mute + .set_icon_name("microphone-disabled-symbolic"); + } else { + imp.reset_source_mute + .set_icon_name("audio-input-microphone-symbolic"); + } + let name = ir.stream.application_name.clone() + ": " + ir.stream.name.as_str(); + imp.reset_source_selection.set_title(name.as_str()); + let volume = ir.stream.volume.first().unwrap_or(&0_u32); + let fraction = (*volume as f64 / 655.36).round(); + let percentage = (fraction).to_string() + "%"; + imp.reset_volume_percentage.set_text(&percentage); + imp.reset_volume_slider.set_value(*volume as f64); + let index = input_box_imp.reset_model_index.read().unwrap(); + let model_list = input_box_imp.reset_model_list.read().unwrap(); + for entry in 0..*index { + if model_list.string(entry) == Some(alias.clone().into()) { + imp.reset_source_selection.set_selected(entry); + break; + } + } + }); + }); + true +} + +pub fn output_stream_removed_handler(source_box: Arc, ir: OutputStreamRemoved) -> bool { + glib::spawn_future(async move { + glib::idle_add_once(move || { + let input_box = source_box.clone(); + let input_box_imp = input_box.imp(); + let mut list = input_box_imp.reset_output_stream_list.write().unwrap(); + let entry = list.remove(&ir.index); + if entry.is_none() { + return; + } + input_box_imp + .reset_output_streams + .remove(&*entry.unwrap().0); + }); + }); + true +} diff --git a/src/components/output/sink_box.rs b/src/components/output/sink_box.rs index 9246c06..87301e1 100644 --- a/src/components/output/sink_box.rs +++ b/src/components/output/sink_box.rs @@ -120,7 +120,7 @@ pub fn populate_sinks(output_box: Arc) { } populate_inputstreams(output_box.clone()); populate_cards(output_box.clone()); - initialize(output_box, sinks); + populate_sink_information(output_box, sinks); }); } @@ -184,7 +184,7 @@ fn mute_handler(output_box_ref_mute: Arc) { toggle_sink_mute(stream.index, stream.muted); } -fn initialize(output_box: Arc, sinks: Vec) { +fn populate_sink_information(output_box: Arc, sinks: Vec) { glib::spawn_future(async move { glib::idle_add_once(move || { let output_box_ref_select = output_box.clone();