mirror of
https://github.com/Xetibo/ReSet.git
synced 2025-04-04 13:02:01 +02:00
fix: Update default sink and source after setting it
This commit is contained in:
parent
d3bc2edf88
commit
049a846c36
|
@ -808,14 +808,14 @@
|
|||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/mio/mio-0.8.10.crate",
|
||||
"sha256": "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09",
|
||||
"dest": "cargo/vendor/mio-0.8.10"
|
||||
"url": "https://static.crates.io/crates/mio/mio-0.8.9.crate",
|
||||
"sha256": "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0",
|
||||
"dest": "cargo/vendor/mio-0.8.9"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/mio-0.8.10",
|
||||
"contents": "{\"package\": \"3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/mio-0.8.9",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
|
@ -873,14 +873,14 @@
|
|||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/once_cell/once_cell-1.19.0.crate",
|
||||
"sha256": "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92",
|
||||
"dest": "cargo/vendor/once_cell-1.19.0"
|
||||
"url": "https://static.crates.io/crates/once_cell/once_cell-1.18.0.crate",
|
||||
"sha256": "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d",
|
||||
"dest": "cargo/vendor/once_cell-1.18.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/once_cell-1.19.0",
|
||||
"contents": "{\"package\": \"dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/once_cell-1.18.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
|
@ -964,14 +964,14 @@
|
|||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/proc-macro-crate/proc-macro-crate-2.0.1.crate",
|
||||
"sha256": "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a",
|
||||
"dest": "cargo/vendor/proc-macro-crate-2.0.1"
|
||||
"url": "https://static.crates.io/crates/proc-macro-crate/proc-macro-crate-2.0.0.crate",
|
||||
"sha256": "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8",
|
||||
"dest": "cargo/vendor/proc-macro-crate-2.0.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/proc-macro-crate-2.0.1",
|
||||
"contents": "{\"package\": \"7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/proc-macro-crate-2.0.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
|
@ -1302,27 +1302,27 @@
|
|||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/toml/toml-0.8.2.crate",
|
||||
"sha256": "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d",
|
||||
"dest": "cargo/vendor/toml-0.8.2"
|
||||
"url": "https://static.crates.io/crates/toml/toml-0.8.8.crate",
|
||||
"sha256": "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35",
|
||||
"dest": "cargo/vendor/toml-0.8.8"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml-0.8.2",
|
||||
"contents": "{\"package\": \"a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml-0.8.8",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/toml_datetime/toml_datetime-0.6.3.crate",
|
||||
"sha256": "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b",
|
||||
"dest": "cargo/vendor/toml_datetime-0.6.3"
|
||||
"url": "https://static.crates.io/crates/toml_datetime/toml_datetime-0.6.5.crate",
|
||||
"sha256": "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1",
|
||||
"dest": "cargo/vendor/toml_datetime-0.6.5"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_datetime-0.6.3",
|
||||
"contents": "{\"package\": \"3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_datetime-0.6.5",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
|
@ -1341,14 +1341,27 @@
|
|||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/toml_edit/toml_edit-0.20.2.crate",
|
||||
"sha256": "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338",
|
||||
"dest": "cargo/vendor/toml_edit-0.20.2"
|
||||
"url": "https://static.crates.io/crates/toml_edit/toml_edit-0.20.7.crate",
|
||||
"sha256": "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81",
|
||||
"dest": "cargo/vendor/toml_edit-0.20.7"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_edit-0.20.2",
|
||||
"contents": "{\"package\": \"70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_edit-0.20.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/toml_edit/toml_edit-0.21.0.crate",
|
||||
"sha256": "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03",
|
||||
"dest": "cargo/vendor/toml_edit-0.21.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_edit-0.21.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
|
@ -1562,14 +1575,14 @@
|
|||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/winnow/winnow-0.5.26.crate",
|
||||
"sha256": "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff",
|
||||
"dest": "cargo/vendor/winnow-0.5.26"
|
||||
"url": "https://static.crates.io/crates/winnow/winnow-0.5.19.crate",
|
||||
"sha256": "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b",
|
||||
"dest": "cargo/vendor/winnow-0.5.19"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/winnow-0.5.26",
|
||||
"contents": "{\"package\": \"829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/winnow-0.5.19",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -23,6 +23,18 @@ use crate::components::{
|
|||
output::sink_box::{start_output_box_listener, SinkBox},
|
||||
};
|
||||
|
||||
#[derive(Default, PartialEq, Eq)]
|
||||
pub enum Position {
|
||||
Connectivity,
|
||||
Wifi,
|
||||
Bluetooth,
|
||||
Audio,
|
||||
AudioOutput,
|
||||
AudioInput,
|
||||
#[default]
|
||||
Home,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Listeners {
|
||||
pub wifi_disabled: AtomicBool,
|
||||
|
@ -405,11 +417,9 @@ pub fn start_audio_listener(
|
|||
|
||||
listeners.pulse_listener.store(true, Ordering::SeqCst);
|
||||
|
||||
println!("starting audio listener");
|
||||
loop {
|
||||
let _ = conn.process(Duration::from_millis(1000));
|
||||
if !listeners.pulse_listener.load(Ordering::SeqCst) {
|
||||
println!("stopping audio listener");
|
||||
stop_dbus_audio_listener(conn);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,13 @@ unsafe impl Sync for SourceBox {}
|
|||
|
||||
impl SourceBox {
|
||||
pub fn new() -> Self {
|
||||
Object::builder().build()
|
||||
let obj: Self = Object::builder().build();
|
||||
{
|
||||
let imp = obj.imp();
|
||||
let mut model_index = imp.reset_model_index.write().unwrap();
|
||||
*model_index = 0;
|
||||
}
|
||||
obj
|
||||
}
|
||||
|
||||
pub fn setup_callbacks(&self) {
|
||||
|
@ -85,68 +91,70 @@ impl Default for SourceBox {
|
|||
|
||||
pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||
gio::spawn_blocking(move || {
|
||||
let output_box_imp = input_box.imp();
|
||||
let sources = get_sources();
|
||||
{
|
||||
let list = output_box_imp.reset_model_list.write().unwrap();
|
||||
let mut map = output_box_imp.reset_source_map.write().unwrap();
|
||||
let mut model_index = output_box_imp.reset_model_index.write().unwrap();
|
||||
let input_box_imp = input_box.imp();
|
||||
let list = input_box_imp.reset_model_list.write().unwrap();
|
||||
let mut map = input_box_imp.reset_source_map.write().unwrap();
|
||||
let mut model_index = input_box_imp.reset_model_index.write().unwrap();
|
||||
input_box_imp
|
||||
.reset_default_source
|
||||
.replace(get_default_source());
|
||||
for (i, source) in (0_u32..).zip(sources.iter()) {
|
||||
list.append(&source.alias);
|
||||
map.insert(source.alias.clone(), (source.index, i, source.name.clone()));
|
||||
*model_index += 1;
|
||||
}
|
||||
}
|
||||
output_box_imp
|
||||
.reset_default_source
|
||||
.replace(get_default_source());
|
||||
|
||||
populate_outputstreams(input_box.clone());
|
||||
populate_cards(input_box.clone());
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box_ref_slider = input_box.clone();
|
||||
let output_box_ref_mute = input_box.clone();
|
||||
let output_box_ref = input_box.clone();
|
||||
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 output_box_imp = output_box_ref.imp();
|
||||
let default_sink = output_box_imp.reset_default_source.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() + "%";
|
||||
output_box_imp.reset_volume_percentage.set_text(&percentage);
|
||||
output_box_imp.reset_volume_slider.set_value(*volume as f64);
|
||||
let mut list = output_box_imp.reset_source_list.write().unwrap();
|
||||
for stream in sources {
|
||||
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 output_box_imp.reset_default_source.borrow().name == stream.name {
|
||||
if input_box_imp.reset_default_source.borrow().name == source.name {
|
||||
is_default = true;
|
||||
}
|
||||
let source_entry = Arc::new(SourceEntry::new(
|
||||
is_default,
|
||||
output_box_imp.reset_default_check_button.clone(),
|
||||
stream,
|
||||
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));
|
||||
output_box_imp.reset_sources.append(&*entry);
|
||||
input_box_imp.reset_sources.append(&*entry);
|
||||
}
|
||||
let list = output_box_imp.reset_model_list.read().unwrap();
|
||||
output_box_imp.reset_source_dropdown.set_model(Some(&*list));
|
||||
let map = output_box_imp.reset_source_map.read().unwrap();
|
||||
let name = output_box_imp.reset_default_source.borrow();
|
||||
let list = input_box_imp.reset_model_list.read().unwrap();
|
||||
input_box_imp.reset_source_dropdown.set_model(Some(&*list));
|
||||
let map = input_box_imp.reset_source_map.read().unwrap();
|
||||
let name = input_box_imp.reset_default_source.borrow();
|
||||
if let Some(index) = map.get(&name.alias) {
|
||||
output_box_imp.reset_source_dropdown.set_selected(index.1);
|
||||
input_box_imp.reset_source_dropdown.set_selected(index.1);
|
||||
}
|
||||
output_box_imp
|
||||
.reset_source_dropdown
|
||||
.connect_selected_notify(clone!(@weak output_box_imp => move |dropdown| {
|
||||
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;
|
||||
|
@ -155,20 +163,27 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
|||
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
||||
let selected = selected.string().to_string();
|
||||
|
||||
let source = output_box_imp.reset_source_map.read().unwrap();
|
||||
let source = input_box_imp.reset_source_map.read().unwrap();
|
||||
let source = source.get(&selected);
|
||||
if source.is_none() {
|
||||
return;
|
||||
}
|
||||
let sink = Arc::new(source.unwrap().2.clone());
|
||||
set_default_source(sink);
|
||||
}));
|
||||
let source = Arc::new(source.unwrap().2.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);
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
output_box_ref
|
||||
input_box_ref
|
||||
.imp()
|
||||
.reset_volume_slider
|
||||
.connect_change_value(move |_, _, value| {
|
||||
let imp = output_box_ref_slider.imp();
|
||||
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);
|
||||
|
@ -188,27 +203,64 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
|||
Propagation::Proceed
|
||||
});
|
||||
|
||||
output_box_ref
|
||||
input_box_ref
|
||||
.imp()
|
||||
.reset_source_mute
|
||||
.connect_clicked(move |_| {
|
||||
let imp = output_box_ref_mute.imp();
|
||||
let mut stream = imp.reset_default_source.borrow_mut();
|
||||
stream.muted = !stream.muted;
|
||||
if stream.muted {
|
||||
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(stream.index, stream.muted);
|
||||
toggle_source_mute(source.index, source.muted);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pub fn refresh_default_source(new_source: Source, input_box: Arc<SourceBox>, entry: bool) {
|
||||
let volume = *new_source.volume.first().unwrap_or(&0_u32);
|
||||
let fraction = (volume as f64 / 655.36).round();
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let imp = input_box.imp();
|
||||
if !entry {
|
||||
let list = imp.reset_source_list.read().unwrap();
|
||||
let entry = list.get(&new_source.index);
|
||||
if entry.is_none() {
|
||||
return;
|
||||
}
|
||||
let entry_imp = entry.unwrap().1.imp();
|
||||
entry_imp.reset_selected_source.set_active(true);
|
||||
} else {
|
||||
let map = imp.reset_source_map.read().unwrap();
|
||||
let entry = map.get(&new_source.alias);
|
||||
if entry.is_none() {
|
||||
return;
|
||||
}
|
||||
imp.reset_source_dropdown.set_selected(entry.unwrap().1);
|
||||
}
|
||||
imp.reset_volume_percentage.set_text(&percentage);
|
||||
imp.reset_volume_slider.set_value(volume as f64);
|
||||
if new_source.muted {
|
||||
imp.reset_source_mute
|
||||
.set_icon_name("microphone-disabled-symbolic");
|
||||
} else {
|
||||
imp.reset_source_mute
|
||||
.set_icon_name("audio-input-microphone-symbolic");
|
||||
}
|
||||
imp.reset_default_source.replace(new_source);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pub fn populate_outputstreams(input_box: Arc<SourceBox>) {
|
||||
let input_box_ref = input_box.clone();
|
||||
|
||||
|
@ -234,11 +286,11 @@ pub fn populate_outputstreams(input_box: Arc<SourceBox>) {
|
|||
|
||||
pub fn populate_cards(input_box: Arc<SourceBox>) {
|
||||
gio::spawn_blocking(move || {
|
||||
let output_box_ref = input_box.clone();
|
||||
let input_box_ref = input_box.clone();
|
||||
let cards = get_cards();
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let imp = output_box_ref.imp();
|
||||
let imp = input_box_ref.imp();
|
||||
for card in cards {
|
||||
imp.reset_cards.add(&CardEntry::new(card));
|
||||
}
|
||||
|
@ -365,29 +417,30 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
|||
let source_box = source_added_box.clone();
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box = source_box.clone();
|
||||
let output_box_imp = output_box.imp();
|
||||
let mut list = output_box_imp.reset_source_list.write().unwrap();
|
||||
let input_box = source_box.clone();
|
||||
let input_box_imp = input_box.imp();
|
||||
let mut list = input_box_imp.reset_source_list.write().unwrap();
|
||||
let source_index = ir.source.index;
|
||||
let alias = ir.source.alias.clone();
|
||||
let name = ir.source.name.clone();
|
||||
let mut is_default = false;
|
||||
if output_box_imp.reset_default_source.borrow().name == ir.source.name {
|
||||
if input_box_imp.reset_default_source.borrow().name == ir.source.name {
|
||||
is_default = true;
|
||||
}
|
||||
let source_entry = Arc::new(SourceEntry::new(
|
||||
is_default,
|
||||
output_box_imp.reset_default_check_button.clone(),
|
||||
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);
|
||||
list.insert(source_index, (entry.clone(), source_clone, alias.clone()));
|
||||
output_box_imp.reset_sources.append(&*entry);
|
||||
let mut map = output_box_imp.reset_source_map.write().unwrap();
|
||||
let mut index = output_box_imp.reset_model_index.write().unwrap();
|
||||
output_box_imp
|
||||
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();
|
||||
input_box_imp
|
||||
.reset_model_list
|
||||
.write()
|
||||
.unwrap()
|
||||
|
@ -407,29 +460,26 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
|||
let source_box = source_removed_box.clone();
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box = source_box.clone();
|
||||
let output_box_imp = output_box.imp();
|
||||
let mut list = output_box_imp.reset_source_list.write().unwrap();
|
||||
let entry = list.get(&ir.index);
|
||||
let input_box = source_box.clone();
|
||||
let input_box_imp = input_box.imp();
|
||||
let mut list = input_box_imp.reset_source_list.write().unwrap();
|
||||
let entry = list.remove(&ir.index);
|
||||
if entry.is_none() {
|
||||
return;
|
||||
}
|
||||
output_box_imp.reset_sources.remove(&*entry.unwrap().0);
|
||||
list.remove(&ir.index);
|
||||
let alias = list.remove(&ir.index);
|
||||
if alias.is_none() {
|
||||
return;
|
||||
}
|
||||
let mut map = output_box_imp.reset_source_map.write().unwrap();
|
||||
let entry_index = map.remove(&alias.unwrap().2);
|
||||
input_box_imp
|
||||
.reset_sources
|
||||
.remove(&*entry.clone().unwrap().0);
|
||||
let mut map = input_box_imp.reset_source_map.write().unwrap();
|
||||
let entry_index = map.remove(&entry.unwrap().2);
|
||||
if let Some(entry_index) = entry_index {
|
||||
output_box_imp
|
||||
input_box_imp
|
||||
.reset_model_list
|
||||
.write()
|
||||
.unwrap()
|
||||
.remove(entry_index.1);
|
||||
}
|
||||
let mut index = output_box_imp.reset_model_index.write().unwrap();
|
||||
let mut index = input_box_imp.reset_model_index.write().unwrap();
|
||||
if *index != 0 {
|
||||
*index -= 1;
|
||||
}
|
||||
|
@ -447,30 +497,31 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
|||
let default_source = get_default_source_name();
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box = source_box.clone();
|
||||
let output_box_imp = output_box.imp();
|
||||
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 = output_box_imp.reset_source_list.read().unwrap();
|
||||
|
||||
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 {
|
||||
output_box_imp.reset_volume_percentage.set_text(&percentage);
|
||||
output_box_imp.reset_volume_slider.set_value(*volume as f64);
|
||||
output_box_imp
|
||||
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 {
|
||||
output_box_imp
|
||||
input_box_imp
|
||||
.reset_source_mute
|
||||
.set_icon_name("microphone-disabled-symbolic");
|
||||
} else {
|
||||
output_box_imp
|
||||
input_box_imp
|
||||
.reset_source_mute
|
||||
.set_icon_name("audio-input-microphone-symbolic");
|
||||
}
|
||||
|
@ -502,16 +553,15 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
|||
let source_box = output_stream_added_box.clone();
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box = source_box.clone();
|
||||
let output_box_imp = output_box.imp();
|
||||
let mut list = output_box_imp.reset_output_stream_list.write().unwrap();
|
||||
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(output_box.clone(), ir.stream));
|
||||
let output_stream_clone = output_stream.clone();
|
||||
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));
|
||||
output_box_imp.reset_output_streams.append(&*entry);
|
||||
list.insert(index, (entry.clone(), output_stream.clone()));
|
||||
input_box_imp.reset_output_streams.append(&*entry);
|
||||
});
|
||||
});
|
||||
true
|
||||
|
@ -537,11 +587,11 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
|||
let source_box = output_stream_changed_box.clone();
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box = source_box.clone();
|
||||
let output_box_imp = output_box.imp();
|
||||
let input_box = source_box.clone();
|
||||
let input_box_imp = input_box.imp();
|
||||
let entry: Arc<OutputStreamEntry>;
|
||||
{
|
||||
let list = output_box_imp.reset_output_stream_list.read().unwrap();
|
||||
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;
|
||||
|
@ -563,7 +613,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
|||
let percentage = (fraction).to_string() + "%";
|
||||
imp.reset_volume_percentage.set_text(&percentage);
|
||||
imp.reset_volume_slider.set_value(*volume as f64);
|
||||
let map = output_box_imp.reset_source_map.read().unwrap();
|
||||
let map = input_box_imp.reset_source_map.read().unwrap();
|
||||
if let Some(index) = map.get(&alias) {
|
||||
imp.reset_source_selection.set_selected(index.1);
|
||||
}
|
||||
|
@ -583,14 +633,14 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
|||
let source_box = output_stream_removed_box.clone();
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box = source_box.clone();
|
||||
let output_box_imp = output_box.imp();
|
||||
let mut list = output_box_imp.reset_output_stream_list.write().unwrap();
|
||||
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;
|
||||
}
|
||||
output_box_imp
|
||||
input_box_imp
|
||||
.reset_output_streams
|
||||
.remove(&*entry.unwrap().0);
|
||||
});
|
||||
|
|
|
@ -11,6 +11,7 @@ use glib::{clone, Propagation};
|
|||
use gtk::{gio, CheckButton};
|
||||
use re_set_lib::audio::audio_structures::Source;
|
||||
|
||||
use super::source_box::{refresh_default_source, SourceBox};
|
||||
use super::source_entry_impl;
|
||||
|
||||
glib::wrapper! {
|
||||
|
@ -23,26 +24,31 @@ unsafe impl Send for SourceEntry {}
|
|||
unsafe impl Sync for SourceEntry {}
|
||||
|
||||
impl SourceEntry {
|
||||
pub fn new(is_default: bool, check_group: Arc<CheckButton>, stream: Source) -> Self {
|
||||
pub fn new(
|
||||
is_default: bool,
|
||||
check_group: Arc<CheckButton>,
|
||||
source: Source,
|
||||
input_box: Arc<SourceBox>,
|
||||
) -> Self {
|
||||
let obj: Self = Object::builder().build();
|
||||
// TODO use event callback for progress bar -> this is the "im speaking" indicator
|
||||
{
|
||||
let imp = obj.imp();
|
||||
imp.reset_source_name
|
||||
.set_title(stream.alias.clone().as_str());
|
||||
let name = Arc::new(stream.name.clone());
|
||||
let volume = stream.volume.first().unwrap_or(&0_u32);
|
||||
.set_title(source.alias.clone().as_str());
|
||||
let name = Arc::new(source.name.clone());
|
||||
let volume = source.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);
|
||||
imp.stream.replace(stream);
|
||||
imp.source.replace(source);
|
||||
imp.reset_volume_slider.connect_change_value(
|
||||
clone!(@weak imp => @default-return Propagation::Stop, move |_, _, value| {
|
||||
let fraction = (value / 655.36).round();
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
imp.reset_volume_percentage.set_text(&percentage);
|
||||
let source = imp.stream.borrow();
|
||||
let source = imp.source.borrow();
|
||||
let index = source.index;
|
||||
let channels = source.channels;
|
||||
{
|
||||
|
@ -65,23 +71,30 @@ impl SourceEntry {
|
|||
imp.reset_selected_source.set_active(false);
|
||||
}
|
||||
imp.reset_selected_source.connect_toggled(move |button| {
|
||||
let input_box = input_box.clone();
|
||||
if button.is_active() {
|
||||
set_default_source(name.clone());
|
||||
let name = name.clone();
|
||||
gio::spawn_blocking(move || {
|
||||
let result = set_default_source(name);
|
||||
if result.is_none() {
|
||||
return;
|
||||
}
|
||||
refresh_default_source(result.unwrap(), input_box, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
imp.reset_source_mute
|
||||
.connect_clicked(clone!(@weak imp => move |_| {
|
||||
let stream = imp.stream.clone();
|
||||
let mut stream = stream.borrow_mut();
|
||||
stream.muted = !stream.muted;
|
||||
if stream.muted {
|
||||
let mut source = imp.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(stream.index, stream.muted);
|
||||
toggle_source_mute(source.index, source.muted);
|
||||
}));
|
||||
}
|
||||
obj
|
||||
|
@ -127,22 +140,20 @@ pub fn toggle_source_mute(index: u32, muted: bool) -> bool {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn set_default_source(name: Arc<String>) -> bool {
|
||||
gio::spawn_blocking(move || {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.Xetibo.ReSetDaemon",
|
||||
"/org/Xetibo/ReSetDaemon",
|
||||
Duration::from_millis(1000),
|
||||
);
|
||||
let _: Result<(), Error> =
|
||||
proxy.method_call("org.Xetibo.ReSetAudio", "SetDefaultSink", (name.as_str(),));
|
||||
// if res.is_err() {
|
||||
// return;
|
||||
// }
|
||||
// handle change
|
||||
});
|
||||
true
|
||||
pub fn set_default_source(name: Arc<String>) -> Option<Source> {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.Xetibo.ReSetDaemon",
|
||||
"/org/Xetibo/ReSetDaemon",
|
||||
Duration::from_millis(1000),
|
||||
);
|
||||
let res: Result<(Source,), Error> = proxy.method_call(
|
||||
"org.Xetibo.ReSetAudio",
|
||||
"SetDefaultSource",
|
||||
(name.as_str(),),
|
||||
);
|
||||
if res.is_err() {
|
||||
return None;
|
||||
}
|
||||
Some(res.unwrap().0)
|
||||
}
|
||||
|
||||
// TODO propagate error from dbus
|
||||
|
|
|
@ -25,7 +25,7 @@ pub struct SourceEntry {
|
|||
pub reset_volume_percentage: TemplateChild<Label>,
|
||||
#[template_child]
|
||||
pub reset_volume_meter: TemplateChild<ProgressBar>,
|
||||
pub stream: Arc<RefCell<Source>>,
|
||||
pub source: Arc<RefCell<Source>>,
|
||||
pub volume_time_stamp: RefCell<Option<SystemTime>>,
|
||||
}
|
||||
|
||||
|
|
0
src/components/output/audio_box.rs
Normal file
0
src/components/output/audio_box.rs
Normal file
|
@ -4,3 +4,4 @@ pub mod sink_box;
|
|||
pub mod sink_box_impl;
|
||||
pub mod sink_entry;
|
||||
pub mod sink_entry_impl;
|
||||
pub mod audio_box;
|
||||
|
|
|
@ -65,7 +65,6 @@ impl SinkBox {
|
|||
self_imp
|
||||
.reset_cards_row
|
||||
.set_action_target_value(Some(&Variant::from("profileConfiguration")));
|
||||
self_imp.reset_cards_row.connect_action_name_notify(|_| {});
|
||||
|
||||
self_imp.reset_input_stream_button.set_activatable(true);
|
||||
self_imp
|
||||
|
@ -92,12 +91,11 @@ impl Default for SinkBox {
|
|||
|
||||
pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
||||
gio::spawn_blocking(move || {
|
||||
let output_box_ref = output_box.clone();
|
||||
let sinks = get_sinks();
|
||||
{
|
||||
let output_box_imp = output_box.imp();
|
||||
let mut map = output_box_imp.reset_sink_map.write().unwrap();
|
||||
let list = output_box_imp.reset_model_list.write().unwrap();
|
||||
let mut map = output_box_imp.reset_sink_map.write().unwrap();
|
||||
let mut model_index = output_box_imp.reset_model_index.write().unwrap();
|
||||
output_box_imp
|
||||
.reset_default_sink
|
||||
|
@ -112,8 +110,10 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
|||
populate_cards(output_box.clone());
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let output_box_ref_select = output_box.clone();
|
||||
let output_box_ref_slider = output_box.clone();
|
||||
let output_box_ref_mute = output_box.clone();
|
||||
let output_box_ref = output_box.clone();
|
||||
{
|
||||
let output_box_imp = output_box_ref.imp();
|
||||
let default_sink = output_box_imp.reset_default_sink.clone();
|
||||
|
@ -136,6 +136,7 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
|||
is_default,
|
||||
output_box_imp.reset_default_check_button.clone(),
|
||||
sink,
|
||||
output_box.clone(),
|
||||
));
|
||||
let sink_clone = sink_entry.clone();
|
||||
let entry = Arc::new(ListEntry::new(&*sink_entry));
|
||||
|
@ -147,13 +148,12 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
|||
output_box_imp.reset_sink_dropdown.set_model(Some(&*list));
|
||||
let map = output_box_imp.reset_sink_map.read().unwrap();
|
||||
let name = output_box_imp.reset_default_sink.borrow();
|
||||
let name = &name.alias;
|
||||
let index = map.get(name);
|
||||
if let Some(index) = index {
|
||||
if let Some(index) = map.get(&name.alias) {
|
||||
output_box_imp.reset_sink_dropdown.set_selected(index.1);
|
||||
}
|
||||
output_box_imp.reset_sink_dropdown.connect_selected_notify(
|
||||
clone!(@weak output_box_imp => move |dropdown| {
|
||||
let output_box_ref = output_box_ref_select.clone();
|
||||
let selected = dropdown.selected_item();
|
||||
if selected.is_none() {
|
||||
return;
|
||||
|
@ -167,8 +167,15 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
|||
if sink.is_none() {
|
||||
return;
|
||||
}
|
||||
let sink = Arc::new(sink.unwrap().2.clone());
|
||||
set_default_sink(sink);
|
||||
let new_sink_name = Arc::new(sink.unwrap().2.clone());
|
||||
gio::spawn_blocking(move || {
|
||||
let result = set_default_sink(new_sink_name);
|
||||
if result.is_none() {
|
||||
return;
|
||||
}
|
||||
let new_sink = result.unwrap();
|
||||
refresh_default_sink(new_sink, output_box_ref, false);
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -216,6 +223,43 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn refresh_default_sink(new_sink: Sink, output_box: Arc<SinkBox>, entry: bool) {
|
||||
let volume = *new_sink.volume.first().unwrap_or(&0_u32);
|
||||
let fraction = (volume as f64 / 655.36).round();
|
||||
let percentage = (fraction).to_string() + "%";
|
||||
glib::spawn_future(async move {
|
||||
glib::idle_add_once(move || {
|
||||
let imp = output_box.imp();
|
||||
if !entry {
|
||||
let list = imp.reset_sink_list.read().unwrap();
|
||||
let entry = list.get(&new_sink.index);
|
||||
if entry.is_none() {
|
||||
return;
|
||||
}
|
||||
let entry_imp = entry.unwrap().1.imp();
|
||||
entry_imp.reset_selected_sink.set_active(true);
|
||||
} else {
|
||||
let map = imp.reset_sink_map.read().unwrap();
|
||||
let entry = map.get(&new_sink.alias);
|
||||
if entry.is_none() {
|
||||
return;
|
||||
}
|
||||
imp.reset_sink_dropdown.set_selected(entry.unwrap().1);
|
||||
}
|
||||
imp.reset_volume_percentage.set_text(&percentage);
|
||||
imp.reset_volume_slider.set_value(volume as f64);
|
||||
if new_sink.muted {
|
||||
imp.reset_sink_mute
|
||||
.set_icon_name("audio-volume-muted-symbolic");
|
||||
} else {
|
||||
imp.reset_sink_mute
|
||||
.set_icon_name("audio-volume-high-symbolic");
|
||||
}
|
||||
imp.reset_default_sink.replace(new_sink);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pub fn populate_inputstreams(output_box: Arc<SinkBox>) {
|
||||
let output_box_ref = output_box.clone();
|
||||
|
||||
|
@ -283,6 +327,21 @@ fn get_sinks() -> Vec<Sink> {
|
|||
res.unwrap().0
|
||||
}
|
||||
|
||||
fn get_cards() -> Vec<Card> {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.Xetibo.ReSetDaemon",
|
||||
"/org/Xetibo/ReSetDaemon",
|
||||
Duration::from_millis(1000),
|
||||
);
|
||||
let res: Result<(Vec<Card>,), Error> =
|
||||
proxy.method_call("org.Xetibo.ReSetAudio", "ListCards", ());
|
||||
if res.is_err() {
|
||||
return Vec::new();
|
||||
}
|
||||
res.unwrap().0
|
||||
}
|
||||
|
||||
fn get_default_sink_name() -> String {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
|
@ -313,21 +372,6 @@ fn get_default_sink() -> Sink {
|
|||
res.unwrap().0
|
||||
}
|
||||
|
||||
fn get_cards() -> Vec<Card> {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.Xetibo.ReSetDaemon",
|
||||
"/org/Xetibo/ReSetDaemon",
|
||||
Duration::from_millis(1000),
|
||||
);
|
||||
let res: Result<(Vec<Card>,), Error> =
|
||||
proxy.method_call("org.Xetibo.ReSetAudio", "ListCards", ());
|
||||
if res.is_err() {
|
||||
return Vec::new();
|
||||
}
|
||||
res.unwrap().0
|
||||
}
|
||||
|
||||
pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Connection {
|
||||
let sink_added = SinkAdded::match_rule(
|
||||
Some(&"org.Xetibo.ReSetDaemon".into()),
|
||||
|
@ -385,6 +429,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
|||
is_default,
|
||||
output_box_imp.reset_default_check_button.clone(),
|
||||
ir.sink,
|
||||
output_box.clone(),
|
||||
));
|
||||
let sink_clone = sink_entry.clone();
|
||||
let entry = Arc::new(ListEntry::new(&*sink_entry));
|
||||
|
@ -416,17 +461,15 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
|||
let output_box = sink_box.clone();
|
||||
let output_box_imp = output_box.imp();
|
||||
let mut list = output_box_imp.reset_sink_list.write().unwrap();
|
||||
let entry = list.get(&ir.index);
|
||||
let entry = list.remove(&ir.index);
|
||||
if entry.is_none() {
|
||||
return;
|
||||
}
|
||||
output_box_imp.reset_sinks.remove(&*entry.unwrap().0);
|
||||
let alias = list.remove(&ir.index);
|
||||
if alias.is_none() {
|
||||
return;
|
||||
}
|
||||
output_box_imp
|
||||
.reset_sinks
|
||||
.remove(&*entry.clone().unwrap().0);
|
||||
let mut map = output_box_imp.reset_sink_map.write().unwrap();
|
||||
let entry_index = map.remove(&alias.unwrap().2);
|
||||
let entry_index = map.remove(&entry.unwrap().2);
|
||||
if let Some(entry_index) = entry_index {
|
||||
output_box_imp
|
||||
.reset_model_list
|
||||
|
@ -529,8 +572,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
|||
let alias: String;
|
||||
{
|
||||
let sink_list = imp.reset_sink_list.read().unwrap();
|
||||
let alias_opt = sink_list.get(&ir.stream.sink_index);
|
||||
if let Some(alias_opt) = alias_opt {
|
||||
if let Some(alias_opt) = sink_list.get(&ir.stream.sink_index) {
|
||||
alias = alias_opt.2.clone();
|
||||
} else {
|
||||
alias = String::from("");
|
||||
|
@ -566,8 +608,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
|||
imp.reset_volume_percentage.set_text(&percentage);
|
||||
imp.reset_volume_slider.set_value(*volume as f64);
|
||||
let map = output_box_imp.reset_sink_map.read().unwrap();
|
||||
let index = map.get(&alias);
|
||||
if let Some(index) = index {
|
||||
if let Some(index) = map.get(&alias) {
|
||||
imp.reset_sink_selection.set_selected(index.1);
|
||||
}
|
||||
});
|
||||
|
@ -586,14 +627,13 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
|||
let output_box = sink_box.clone();
|
||||
let output_box_imp = output_box.imp();
|
||||
let mut list = output_box_imp.reset_input_stream_list.write().unwrap();
|
||||
let entry = list.get(&ir.index);
|
||||
let entry = list.remove(&ir.index);
|
||||
if entry.is_none() {
|
||||
return;
|
||||
}
|
||||
output_box_imp
|
||||
.reset_input_streams
|
||||
.remove(&*entry.unwrap().0);
|
||||
list.remove(&ir.index);
|
||||
});
|
||||
});
|
||||
true
|
||||
|
|
|
@ -16,6 +16,8 @@ use super::sink_entry::SinkEntry;
|
|||
|
||||
type SinkEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<SinkEntry>, String)>>>;
|
||||
type InputStreamEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<InputStreamEntry>)>>>;
|
||||
// key is model name -> alias, first u32 is the index of the sink, the second the index in the model list and the third is
|
||||
// the detailed name
|
||||
type SinkMap = Arc<RwLock<HashMap<String, (u32, u32, String)>>>;
|
||||
|
||||
#[derive(Default, CompositeTemplate)]
|
||||
|
@ -51,8 +53,6 @@ pub struct SinkBox {
|
|||
pub reset_input_stream_list: InputStreamEntryMap,
|
||||
pub reset_model_list: Arc<RwLock<StringList>>,
|
||||
pub reset_model_index: Arc<RwLock<u32>>,
|
||||
// first u32 is the index of the sink, the second the index in the model list and the third is
|
||||
// the full name
|
||||
pub reset_sink_map: SinkMap,
|
||||
pub volume_time_stamp: RefCell<Option<SystemTime>>,
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use glib::{clone, Propagation};
|
|||
use gtk::{gio, CheckButton};
|
||||
use re_set_lib::audio::audio_structures::Sink;
|
||||
|
||||
use super::sink_box::{refresh_default_sink, SinkBox};
|
||||
use super::sink_entry_impl;
|
||||
|
||||
glib::wrapper! {
|
||||
|
@ -23,7 +24,12 @@ unsafe impl Send for SinkEntry {}
|
|||
unsafe impl Sync for SinkEntry {}
|
||||
|
||||
impl SinkEntry {
|
||||
pub fn new(is_default: bool, check_group: Arc<CheckButton>, stream: Sink) -> Self {
|
||||
pub fn new(
|
||||
is_default: bool,
|
||||
check_group: Arc<CheckButton>,
|
||||
stream: Sink,
|
||||
output_box: Arc<SinkBox>,
|
||||
) -> Self {
|
||||
let obj: Self = Object::builder().build();
|
||||
// TODO use event callback for progress bar -> this is the "im speaking" indicator
|
||||
{
|
||||
|
@ -62,8 +68,16 @@ impl SinkEntry {
|
|||
imp.reset_selected_sink.set_active(false);
|
||||
}
|
||||
imp.reset_selected_sink.connect_toggled(move |button| {
|
||||
let output_box_ref = output_box.clone();
|
||||
if button.is_active() {
|
||||
set_default_sink(name.clone());
|
||||
let name = name.clone();
|
||||
gio::spawn_blocking(move || {
|
||||
let result = set_default_sink(name);
|
||||
if result.is_none() {
|
||||
return;
|
||||
}
|
||||
refresh_default_sink(result.unwrap(), output_box_ref, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
imp.reset_sink_mute
|
||||
|
@ -124,21 +138,17 @@ pub fn toggle_sink_mute(index: u32, muted: bool) -> bool {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn set_default_sink(name: Arc<String>) {
|
||||
gio::spawn_blocking(move || {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.Xetibo.ReSetDaemon",
|
||||
"/org/Xetibo/ReSetDaemon",
|
||||
Duration::from_millis(1000),
|
||||
);
|
||||
let _: Result<(), Error> =
|
||||
proxy.method_call("org.Xetibo.ReSetAudio", "SetDefaultSink", (name.as_str(),));
|
||||
// if res.is_err() {
|
||||
// return;
|
||||
// }
|
||||
// handle change
|
||||
});
|
||||
pub fn set_default_sink(name: Arc<String>) -> Option<Sink> {
|
||||
let conn = Connection::new_session().unwrap();
|
||||
let proxy = conn.with_proxy(
|
||||
"org.Xetibo.ReSetDaemon",
|
||||
"/org/Xetibo/ReSetDaemon",
|
||||
Duration::from_millis(1000),
|
||||
);
|
||||
let res: Result<(Sink,), Error> =
|
||||
proxy.method_call("org.Xetibo.ReSetAudio", "SetDefaultSink", (name.as_str(),));
|
||||
if res.is_err() {
|
||||
return None;
|
||||
}
|
||||
Some(res.unwrap().0)
|
||||
}
|
||||
|
||||
// TODO propagate error from dbus
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use gtk::prelude::FrameExt;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::components::base::setting_box::SettingBox;
|
||||
use crate::components::base::utils::{start_audio_listener, Listeners};
|
||||
use crate::components::base::utils::{start_audio_listener, Listeners, Position};
|
||||
use crate::components::bluetooth::bluetooth_box::{
|
||||
populate_conntected_bluetooth_devices, start_bluetooth_listener, BluetoothBox,
|
||||
};
|
||||
|
@ -14,9 +16,11 @@ use crate::components::wifi::wifi_box::{
|
|||
use gtk::prelude::WidgetExt;
|
||||
use gtk::{Align, FlowBox, FlowBoxChild, Frame};
|
||||
|
||||
pub const HANDLE_CONNECTIVITY_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||
listeners.stop_audio_listener();
|
||||
pub const HANDLE_CONNECTIVITY_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Connectivity) {
|
||||
return;
|
||||
}
|
||||
let wifi_box = WifiBox::new(listeners.clone());
|
||||
start_event_listener(listeners.clone(), wifi_box.clone());
|
||||
show_stored_connections(wifi_box.clone());
|
||||
|
@ -24,7 +28,7 @@ pub const HANDLE_CONNECTIVITY_CLICK: fn(Arc<Listeners>, FlowBox) =
|
|||
let wifi_frame = wrap_in_flow_box_child(SettingBox::new(&*wifi_box));
|
||||
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
||||
populate_conntected_bluetooth_devices(bluetooth_box.clone());
|
||||
start_bluetooth_listener(listeners.clone(), bluetooth_box.clone());
|
||||
start_bluetooth_listener(listeners, bluetooth_box.clone());
|
||||
let bluetooth_frame = wrap_in_flow_box_child(SettingBox::new(&*bluetooth_box));
|
||||
reset_main.remove_all();
|
||||
reset_main.insert(&wifi_frame, -1);
|
||||
|
@ -32,12 +36,13 @@ pub const HANDLE_CONNECTIVITY_CLICK: fn(Arc<Listeners>, FlowBox) =
|
|||
reset_main.set_max_children_per_line(2);
|
||||
};
|
||||
|
||||
pub const HANDLE_WIFI_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||
listeners.stop_audio_listener();
|
||||
listeners.stop_bluetooth_listener();
|
||||
pub const HANDLE_WIFI_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Wifi) {
|
||||
return;
|
||||
}
|
||||
let wifi_box = WifiBox::new(listeners.clone());
|
||||
start_event_listener(listeners.clone(), wifi_box.clone());
|
||||
start_event_listener(listeners, wifi_box.clone());
|
||||
show_stored_connections(wifi_box.clone());
|
||||
scan_for_wifi(wifi_box.clone());
|
||||
let wifi_frame = wrap_in_flow_box_child(SettingBox::new(&*wifi_box));
|
||||
|
@ -46,12 +51,13 @@ pub const HANDLE_WIFI_CLICK: fn(Arc<Listeners>, FlowBox) =
|
|||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
|
||||
pub const HANDLE_BLUETOOTH_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||
listeners.stop_network_listener();
|
||||
listeners.stop_audio_listener();
|
||||
pub const HANDLE_BLUETOOTH_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Bluetooth) {
|
||||
return;
|
||||
}
|
||||
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
||||
start_bluetooth_listener(listeners.clone(), bluetooth_box.clone());
|
||||
start_bluetooth_listener(listeners, bluetooth_box.clone());
|
||||
populate_conntected_bluetooth_devices(bluetooth_box.clone());
|
||||
let bluetooth_frame = wrap_in_flow_box_child(SettingBox::new(&*bluetooth_box));
|
||||
reset_main.remove_all();
|
||||
|
@ -59,33 +65,35 @@ pub const HANDLE_BLUETOOTH_CLICK: fn(Arc<Listeners>, FlowBox) =
|
|||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
|
||||
pub const HANDLE_AUDIO_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||
listeners.stop_network_listener();
|
||||
listeners.stop_bluetooth_listener();
|
||||
pub const HANDLE_AUDIO_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::Audio) {
|
||||
return;
|
||||
}
|
||||
let audio_output = Arc::new(SinkBox::new());
|
||||
let audio_input = Arc::new(SourceBox::new());
|
||||
start_audio_listener(
|
||||
listeners.clone(),
|
||||
listeners,
|
||||
Some(audio_output.clone()),
|
||||
Some(audio_input.clone()),
|
||||
);
|
||||
populate_sinks(audio_output.clone());
|
||||
let audio_frame = wrap_in_flow_box_child(SettingBox::new(&*audio_output));
|
||||
populate_sources(audio_input.clone());
|
||||
let sink_frame = wrap_in_flow_box_child(SettingBox::new(&*audio_output));
|
||||
let source_frame = wrap_in_flow_box_child(SettingBox::new(&*audio_input));
|
||||
reset_main.remove_all();
|
||||
reset_main.insert(&audio_frame, -1);
|
||||
reset_main.insert(&sink_frame, -1);
|
||||
reset_main.insert(&source_frame, -1);
|
||||
reset_main.set_max_children_per_line(2);
|
||||
};
|
||||
|
||||
pub const HANDLE_VOLUME_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||
listeners.stop_network_listener();
|
||||
listeners.stop_bluetooth_listener();
|
||||
pub const HANDLE_VOLUME_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::AudioOutput) {
|
||||
return;
|
||||
}
|
||||
let audio_output = Arc::new(SinkBox::new());
|
||||
start_audio_listener(listeners.clone(), Some(audio_output.clone()), None);
|
||||
start_audio_listener(listeners, Some(audio_output.clone()), None);
|
||||
populate_sinks(audio_output.clone());
|
||||
let audio_frame = wrap_in_flow_box_child(SettingBox::new(&*audio_output));
|
||||
reset_main.remove_all();
|
||||
|
@ -93,12 +101,13 @@ pub const HANDLE_VOLUME_CLICK: fn(Arc<Listeners>, FlowBox) =
|
|||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
|
||||
pub const HANDLE_MICROPHONE_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||
listeners.stop_network_listener();
|
||||
listeners.stop_bluetooth_listener();
|
||||
pub const HANDLE_MICROPHONE_CLICK: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners.clone(), position, Position::AudioInput) {
|
||||
return;
|
||||
}
|
||||
let audio_input = Arc::new(SourceBox::new());
|
||||
start_audio_listener(listeners.clone(), None, Some(audio_input.clone()));
|
||||
start_audio_listener(listeners, None, Some(audio_input.clone()));
|
||||
populate_sources(audio_input.clone());
|
||||
let source_frame = wrap_in_flow_box_child(SettingBox::new(&*audio_input));
|
||||
reset_main.remove_all();
|
||||
|
@ -106,11 +115,11 @@ pub const HANDLE_MICROPHONE_CLICK: fn(Arc<Listeners>, FlowBox) =
|
|||
reset_main.set_max_children_per_line(1);
|
||||
};
|
||||
|
||||
pub const HANDLE_HOME: fn(Arc<Listeners>, FlowBox) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||
listeners.stop_network_listener();
|
||||
listeners.stop_audio_listener();
|
||||
listeners.stop_bluetooth_listener();
|
||||
pub const HANDLE_HOME: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>) =
|
||||
|listeners: Arc<Listeners>, reset_main: FlowBox, position: Rc<RefCell<Position>>| {
|
||||
if handle_init(listeners, position, Position::Home) {
|
||||
return;
|
||||
}
|
||||
reset_main.remove_all();
|
||||
};
|
||||
|
||||
|
@ -125,6 +134,24 @@ fn wrap_in_flow_box_child(widget: SettingBox) -> FlowBoxChild {
|
|||
.build()
|
||||
}
|
||||
|
||||
fn handle_init(
|
||||
listeners: Arc<Listeners>,
|
||||
position: Rc<RefCell<Position>>,
|
||||
clicked_position: Position,
|
||||
) -> bool {
|
||||
{
|
||||
let mut pos_borrow = position.borrow_mut();
|
||||
if *pos_borrow == clicked_position {
|
||||
return true;
|
||||
}
|
||||
*pos_borrow = clicked_position;
|
||||
}
|
||||
listeners.stop_network_listener();
|
||||
listeners.stop_audio_listener();
|
||||
listeners.stop_bluetooth_listener();
|
||||
false
|
||||
}
|
||||
|
||||
// for future implementations
|
||||
// pub const HANDLE_VPN_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||
// |listeners: Arc<Listeners>, resetMain: FlowBox| {
|
||||
|
|
|
@ -45,7 +45,7 @@ impl ReSetWindow {
|
|||
clone!(@ weak self_imp as flowbox => move |_, y| {
|
||||
let result = y.downcast_ref::<SidebarEntry>().unwrap();
|
||||
let click_event = result.imp().on_click_event.borrow().on_click_event;
|
||||
(click_event)(flowbox.listeners.clone(), flowbox.reset_main.get());
|
||||
(click_event)(flowbox.listeners.clone(), flowbox.reset_main.get(), flowbox.position.clone());
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use adw::glib::StaticTypeExt;
|
||||
|
@ -9,7 +10,7 @@ use gtk::prelude::WidgetExt;
|
|||
use gtk::subclass::prelude::*;
|
||||
use gtk::{glib, Button, CompositeTemplate, FlowBox, ListBox, PopoverMenu, SearchEntry};
|
||||
|
||||
use crate::components::base::utils::Listeners;
|
||||
use crate::components::base::utils::{Listeners, Position};
|
||||
use crate::components::wifi::wifi_box::WifiBox;
|
||||
use crate::components::window::reset_window;
|
||||
use crate::components::window::sidebar_entry::SidebarEntry;
|
||||
|
@ -41,6 +42,7 @@ pub struct ReSetWindow {
|
|||
pub reset_shortcuts_button: TemplateChild<Button>,
|
||||
pub sidebar_entries: RefCell<Vec<(SidebarEntry, Vec<SidebarEntry>)>>,
|
||||
pub listeners: Arc<Listeners>,
|
||||
pub position: Rc<RefCell<Position>>,
|
||||
}
|
||||
|
||||
unsafe impl Send for ReSetWindow {}
|
||||
|
@ -83,7 +85,7 @@ impl WidgetImpl for ReSetWindow {
|
|||
self.reset_main.set_margin_end(60);
|
||||
} else {
|
||||
let div = (width - 540) / 2;
|
||||
if div > 1 {
|
||||
if div > 1 {
|
||||
self.reset_main.set_margin_start(div);
|
||||
self.reset_main.set_margin_end(div);
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::components::base::utils::Listeners;
|
||||
use crate::components::base::utils::{Listeners, Position};
|
||||
use crate::components::window::sidebar_entry_impl;
|
||||
use crate::components::window::sidebar_entry_impl::{Categories, SidebarAction};
|
||||
use adw::subclass::prelude::ObjectSubclassIsExt;
|
||||
|
@ -20,7 +22,7 @@ impl SidebarEntry {
|
|||
icon_name: &str,
|
||||
category: Categories,
|
||||
is_subcategory: bool,
|
||||
click_event: fn(Arc<Listeners>, FlowBox),
|
||||
click_event: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>),
|
||||
) -> Self {
|
||||
let entry: SidebarEntry = Object::builder().build();
|
||||
let entry_imp = entry.imp();
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use glib::subclass::InitializingObject;
|
||||
use gtk::subclass::prelude::*;
|
||||
use gtk::{glib, CompositeTemplate, FlowBox, Image, Label, ListBoxRow};
|
||||
|
||||
use crate::components::base::utils::Listeners;
|
||||
use crate::components::base::utils::{Listeners, Position};
|
||||
use crate::components::window::handle_sidebar_click::HANDLE_HOME;
|
||||
use crate::components::window::sidebar_entry;
|
||||
|
||||
|
@ -32,7 +33,7 @@ pub struct SidebarEntry {
|
|||
}
|
||||
|
||||
pub struct SidebarAction {
|
||||
pub on_click_event: fn(Arc<Listeners>, FlowBox),
|
||||
pub on_click_event: fn(Arc<Listeners>, FlowBox, Rc<RefCell<Position>>),
|
||||
}
|
||||
|
||||
impl Default for SidebarAction {
|
||||
|
|
Loading…
Reference in a new issue