From b28b736697f5d0bb94a9f099570da7769ec6afd4 Mon Sep 17 00:00:00 2001 From: Fabio Lenherr / DashieTM Date: Sun, 19 Nov 2023 02:31:41 +0100 Subject: [PATCH] fix: Load audio listener properly --- Cargo.toml | 2 +- src/components/base/utils.rs | 35 +++++- src/components/bluetooth/bluetoothBox.rs | 110 +++++++++++------- src/components/bluetooth/bluetoothBoxImpl.rs | 13 ++- src/components/bluetooth/bluetoothEntry.rs | 94 ++++++++++++--- .../bluetooth/bluetoothEntryImpl.rs | 4 + src/components/input/sourceBox.rs | 57 ++++++--- src/components/input/sourceBoxImpl.rs | 6 + src/components/output/sinkBox.rs | 12 +- src/components/window/handleSidebarClick.rs | 51 ++++---- src/resources/resetAudioInput.ui | 84 +++++++++++++ src/resources/resetAudioOutput.ui | 2 +- src/resources/resetBluetoothEntry.ui | 36 ++++-- src/resources/resetUI.cmb | 77 ++++++++++-- 14 files changed, 440 insertions(+), 143 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a51490f..f193e4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ description = "A wip universal Linux settings application." [dependencies] reset_daemon = "0.1.8" -ReSet-Lib = "0.3.4" +ReSet-Lib = "0.3.5" adw = { version = "0.5.3", package = "libadwaita", features = ["v1_4"] } dbus = "0.9.7" gtk = { version = "0.7.3", package = "gtk4", features = ["v4_12"] } diff --git a/src/components/base/utils.rs b/src/components/base/utils.rs index bbd1a1b..0cb42f5 100644 --- a/src/components/base/utils.rs +++ b/src/components/base/utils.rs @@ -1,5 +1,8 @@ use std::{ - sync::{atomic::{AtomicBool, Ordering}, Arc}, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, thread, time::Duration, }; @@ -15,7 +18,10 @@ use ReSet_Lib::{ signals::GetVal, }; -use crate::components::{input::sourceBox::{SourceBox, start_input_box_listener}, output::sinkBox::{SinkBox, start_output_box_listener}}; +use crate::components::{ + input::sourceBox::{start_input_box_listener, SourceBox}, + output::sinkBox::{start_output_box_listener, SinkBox}, +}; #[derive(Default)] pub struct Listeners { @@ -41,6 +47,14 @@ impl Listeners { proxy.method_call("org.xetibo.ReSet", "StopNetworkListener", ()); }); } + + pub fn stop_audio_listener(&self) { + self.pulse_listener.store(false, Ordering::SeqCst); + } + + pub fn stop_bluetooth_listener(&self) { + self.bluetooth_listener.store(false, Ordering::SeqCst); + } } #[derive(Debug)] @@ -367,20 +381,29 @@ impl GetVal<(u32,)> for OutputStreamRemoved { } } -pub fn start_event_listener(listeners: Arc, sink_box: Option>,source_box: Option>) { +pub fn start_audio_listener( + listeners: Arc, + sink_box: Option>, + source_box: Option>, +) { gio::spawn_blocking(move || { let mut conn = Connection::new_session().unwrap(); + if listeners.pulse_listener.load(Ordering::SeqCst) { + return; + } if sink_box.is_some() { - conn = start_output_box_listener(conn, listeners.clone(), sink_box.unwrap()); + conn = start_output_box_listener(conn, sink_box.unwrap()); } if source_box.is_some() { - conn = start_input_box_listener(conn, listeners.clone(), source_box.unwrap()); + conn = start_input_box_listener(conn, source_box.unwrap()); } + listeners.pulse_listener.store(true, Ordering::SeqCst); + println!("starting audio listener"); loop { let _ = conn.process(Duration::from_millis(1000)); - if !listeners.network_listener.load(Ordering::SeqCst) { + if !listeners.pulse_listener.load(Ordering::SeqCst) { println!("stopping audio listener"); break; } diff --git a/src/components/bluetooth/bluetoothBox.rs b/src/components/bluetooth/bluetoothBox.rs index 0aaf6f3..c389dc2 100644 --- a/src/components/bluetooth/bluetoothBox.rs +++ b/src/components/bluetooth/bluetoothBox.rs @@ -1,7 +1,7 @@ use std::sync::atomic::Ordering; use std::sync::Arc; use std::thread; -use std::time::Duration; +use std::time::{Duration, SystemTime}; use adw::glib; use adw::glib::Object; @@ -49,45 +49,47 @@ impl BluetoothBox { } pub fn scanForDevices(&self) { - let selfImp = self.imp(); - let mut wifiEntries = selfImp.availableDevices.borrow_mut(); - wifiEntries.push(ListEntry::new(&BluetoothEntry::new( - DeviceTypes::Mouse, - "ina mouse", - ))); - wifiEntries.push(ListEntry::new(&BluetoothEntry::new( - DeviceTypes::Keyboard, - "inaboard", - ))); - wifiEntries.push(ListEntry::new(&BluetoothEntry::new( - DeviceTypes::Controller, - "ina controller", - ))); - wifiEntries.push(ListEntry::new(&BluetoothEntry::new( - DeviceTypes::Controller, - "ina best waifu", - ))); - - for wifiEntry in wifiEntries.iter() { - selfImp.resetBluetoothAvailableDevices.append(wifiEntry); - } + // let selfImp = self.imp(); + // let mut wifiEntries = selfImp.availableDevices.borrow_mut(); + // wifiEntries.push(ListEntry::new(&BluetoothEntry::new( + // DeviceTypes::Mouse, + // "ina mouse", + // ))); + // wifiEntries.push(ListEntry::new(&BluetoothEntry::new( + // DeviceTypes::Keyboard, + // "inaboard", + // ))); + // wifiEntries.push(ListEntry::new(&BluetoothEntry::new( + // DeviceTypes::Controller, + // "ina controller", + // ))); + // wifiEntries.push( + // ListEntry::new(&BluetoothEntry::new( + // DeviceTypes::Controller, + // "ina best waifu", + // )) + // ); + // + // for wifiEntry in wifiEntries.iter() { + // selfImp.resetBluetoothAvailableDevices.append(wifiEntry); + // } } pub fn addConnectedDevices(&self) { - let selfImp = self.imp(); - let mut wifiEntries = selfImp.connectedDevices.borrow_mut(); - wifiEntries.push(ListEntry::new(&BluetoothEntry::new( - DeviceTypes::Mouse, - "why are we still here?", - ))); - wifiEntries.push(ListEntry::new(&BluetoothEntry::new( - DeviceTypes::Keyboard, - "just to suffer?", - ))); - - for wifiEntry in wifiEntries.iter() { - selfImp.resetBluetoothConnectedDevices.append(wifiEntry); - } + // let selfImp = self.imp(); + // let mut wifiEntries = selfImp.connectedDevices.borrow_mut(); + // wifiEntries.push(ListEntry::new(&BluetoothEntry::new( + // DeviceTypes::Mouse, + // "why are we still here?", + // ))); + // wifiEntries.push(ListEntry::new(&BluetoothEntry::new( + // DeviceTypes::Keyboard, + // "just to suffer?", + // ))); + // + // for wifiEntry in wifiEntries.iter() { + // selfImp.resetBluetoothConnectedDevices.append(wifiEntry); + // } } } @@ -104,7 +106,7 @@ pub fn start_bluetooth_listener(listeners: Arc, bluetooth_box: Arc = - proxy.method_call("org.xetibo.ReSet", "StartBluetoothSearch", (5000,)); + proxy.method_call("org.xetibo.ReSet", "StartBluetoothSearch", (10000,)); let device_added = BluetoothDeviceAdded::match_rule( Some(&"org.xetibo.ReSet".into()), Some(&Path::from("/org/xetibo/ReSet")), @@ -117,14 +119,21 @@ pub fn start_bluetooth_listener(listeners: Arc, bluetooth_box: Arc, bluetooth_box: Arc, bluetooth_box: Arc Duration::from_millis(5000) + { + glib::spawn_future(async move { + glib::idle_add_once(move || { + let imp = loop_box.imp(); + imp.resetBluetoothConnectedDevices.remove_all(); + }); + }); println!("stopping bluetooth listener"); break; } @@ -162,4 +185,3 @@ pub fn start_bluetooth_listener(listeners: Arc, bluetooth_box: Arc, #[template_child] pub resetBluetoothMainTab: TemplateChild, - pub availableDevices: RefCell>, - pub connectedDevices: RefCell>, + pub availableDevices: RefCell, (Arc, Arc)>>, + pub connectedDevices: RefCell, (Arc, Arc)>>, } #[glib::object_subclass] diff --git a/src/components/bluetooth/bluetoothEntry.rs b/src/components/bluetooth/bluetoothEntry.rs index 83d3e03..744f406 100644 --- a/src/components/bluetooth/bluetoothEntry.rs +++ b/src/components/bluetooth/bluetoothEntry.rs @@ -1,8 +1,16 @@ +use std::time::Duration; + +use crate::components::bluetooth::bluetoothEntryImpl; +use crate::components::bluetooth::bluetoothEntryImpl::DeviceTypes; use adw::glib; use adw::glib::Object; use adw::subclass::prelude::ObjectSubclassIsExt; -use crate::components::bluetooth::bluetoothEntryImpl; -use crate::components::bluetooth::bluetoothEntryImpl::DeviceTypes; +use dbus::blocking::Connection; +use dbus::{Error, Path}; +use glib::clone; +use gtk::prelude::WidgetExt; +use gtk::{gio, GestureClick}; +use ReSet_Lib::bluetooth::bluetooth::BluetoothDevice; glib::wrapper! { pub struct BluetoothEntry(ObjectSubclass) @@ -11,21 +19,75 @@ glib::wrapper! { } impl BluetoothEntry { - pub fn new(deviceType: DeviceTypes, name: &str) -> Self { + pub fn new(device: BluetoothDevice) -> Self { let entry: BluetoothEntry = Object::builder().build(); let entryImp = entry.imp(); - entryImp.resetBluetoothLabel.get().set_text(name); - entryImp.resetBluetoothDeviceType.get().set_from_icon_name(match deviceType { - DeviceTypes::Mouse => Some("input-mouse-symbolic"), - DeviceTypes::Keyboard => Some("input-keyboard-symbolic"), - DeviceTypes::Headset => Some("output-headset-symbolic"), - DeviceTypes::Controller => Some("input-gaming-symbolic"), - DeviceTypes::None => Some("text-x-generic-symbolic") // no generic bluetooth device icon found - }); - { - let mut wifiName = entryImp.deviceName.borrow_mut(); - *wifiName = String::from(name); - } + entryImp.resetBluetoothLabel.get().set_text(&device.name); + entryImp.resetBluetoothAddress.get().set_text(&device.address); + // entryImp + // .resetBluetoothDeviceType + // .get() + // .set_from_icon_name(match deviceType { + // DeviceTypes::Mouse => Some("input-mouse-symbolic"), + // DeviceTypes::Keyboard => Some("input-keyboard-symbolic"), + // DeviceTypes::Headset => Some("output-headset-symbolic"), + // DeviceTypes::Controller => Some("input-gaming-symbolic"), + // DeviceTypes::None => Some("text-x-generic-symbolic"), // no generic bluetooth device icon found + // }); + let gesture = GestureClick::new(); + let connected = false; + // TODO implement this connected + entryImp.device.replace(device); + gesture.connect_released(clone!(@weak entryImp => move |_, _, _, _| { + let device = entryImp.device.borrow_mut(); + if connected { + disconnect_from_device(device.path.clone()); + } else if device.paired { + connect_to_device(device.path.clone()); + } else { + pair_with_device(device.path.clone()); + } + })); + entry.add_controller(gesture); entry } -} \ No newline at end of file +} + +fn connect_to_device(path: Path<'static>) { + gio::spawn_blocking(move || { + let conn = Connection::new_session().unwrap(); + let proxy = conn.with_proxy( + "org.xetibo.ReSet", + "/org/xetibo/ReSet", + Duration::from_millis(1000), + ); + let _: Result<(bool,), Error> = + proxy.method_call("org.xetibo.ReSet", "ConnectToBluetoothDevice", (path,)); + }); +} + +fn pair_with_device(path: Path<'static>) { + gio::spawn_blocking(move || { + let conn = Connection::new_session().unwrap(); + let proxy = conn.with_proxy( + "org.xetibo.ReSet", + "/org/xetibo/ReSet", + Duration::from_millis(1000), + ); + let _: Result<(bool,), Error> = + proxy.method_call("org.xetibo.ReSet", "PairWithBluetoothDevice", (path,)); + }); +} + +fn disconnect_from_device(path: Path<'static>) { + gio::spawn_blocking(move || { + let conn = Connection::new_session().unwrap(); + let proxy = conn.with_proxy( + "org.xetibo.ReSet", + "/org/xetibo/ReSet", + Duration::from_millis(1000), + ); + let _: Result<(bool,), Error> = + proxy.method_call("org.xetibo.ReSet", "DisconnectFromBluetoothDevice", (path,)); + }); +} diff --git a/src/components/bluetooth/bluetoothEntryImpl.rs b/src/components/bluetooth/bluetoothEntryImpl.rs index 3b87336..ab70163 100644 --- a/src/components/bluetooth/bluetoothEntryImpl.rs +++ b/src/components/bluetooth/bluetoothEntryImpl.rs @@ -1,4 +1,5 @@ use std::cell::RefCell; +use ReSet_Lib::bluetooth::bluetooth::BluetoothDevice; use gtk::{Button, CompositeTemplate, glib, Image, Label}; use gtk::subclass::prelude::*; use crate::components::bluetooth::bluetoothEntry; @@ -21,8 +22,11 @@ pub struct BluetoothEntry { #[template_child] pub resetBluetoothLabel: TemplateChild