From 12f92ac59747e9221075dfe8241c56f25857a007 Mon Sep 17 00:00:00 2001 From: Fabio Lenherr / DashieTM Date: Sun, 12 Nov 2023 22:10:15 +0100 Subject: [PATCH 1/4] feat: Implement working signal receiver --- Cargo.toml | 2 +- src/components/wifi/wifiBox.rs | 219 ++++++++++++++++++++++------- src/components/wifi/wifiBoxImpl.rs | 5 +- 3 files changed, 177 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 453c19f..2db6d87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ description = "A wip universal Linux settings application." [dependencies] reset_daemon = "0.1.0" -ReSet-Lib = "0.2.3" +ReSet-Lib = "0.2.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/wifi/wifiBox.rs b/src/components/wifi/wifiBox.rs index 0f27d52..c7c8438 100644 --- a/src/components/wifi/wifiBox.rs +++ b/src/components/wifi/wifiBox.rs @@ -1,6 +1,8 @@ use std::collections::HashMap; +use std::sync::atomic::Ordering; use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::{atomic::AtomicBool, Arc}; +use std::thread; use std::time::Duration; use crate::components::base::listEntry::ListEntry; @@ -8,15 +10,16 @@ use adw::glib; use adw::glib::Object; use adw::prelude::{BoxExt, ListBoxRowExt}; use adw::subclass::prelude::ObjectSubclassIsExt; -use dbus::arg::RefArg; +use dbus::arg::{AppendAll, ReadAll, RefArg}; use dbus::blocking::Connection; use dbus::Error; use dbus::Path; +use gtk::gio; use gtk::glib::Variant; use gtk::prelude::ActionableExt; use ReSet_Lib::network::network::AccessPoint; -use ReSet_Lib::signals::AccessPointAdded; use ReSet_Lib::signals::AccessPointRemoved; +use ReSet_Lib::signals::{AccessPointAdded, GetVal}; use ReSet_Lib::utils::Events; use crate::components::wifi::wifiBoxImpl; @@ -42,72 +45,105 @@ impl WifiBox { pub fn setupCallbacks(&self) { let selfImp = self.imp(); - selfImp.resetSavedNetworks.set_action_name(Some("navigation.push")); - selfImp.resetSavedNetworks.set_action_target_value(Some(&Variant::from("saved"))); + selfImp + .resetSavedNetworks + .set_action_name(Some("navigation.push")); + selfImp + .resetSavedNetworks + .set_action_target_value(Some(&Variant::from("saved"))); - selfImp.resetAvailableNetworks.set_action_name(Some("navigation.pop")); + selfImp + .resetAvailableNetworks + .set_action_name(Some("navigation.pop")); } - - // pub fn donotdisturb() { - // thread::spawn(|| { - // let conn = Connection::new_session().unwrap(); - // let proxy = conn.with_proxy( - // "org.freedesktop.Notifications", - // "/org/freedesktop/Notifications", - // Duration::from_millis(1000), - // ); - // let _: Result<(), Error> = - // proxy.method_call("org.freedesktop.Notifications", "DoNotDisturb", ()); - // }); - // } } pub fn scanForWifi(wifiBox: Arc) { let wifibox_ref = wifiBox.clone(); + let wifibox_ref_listener = wifiBox.clone(); let wifiEntries = wifiBox.imp().wifiEntries.clone(); - glib::spawn_future_local(async move { - let accessPoints = get_access_points().await; + gio::spawn_blocking(move || { + let accessPoints = get_access_points(); + let wifiEntriesListener = wifiEntries.clone(); let wifiEntries = wifiEntries.clone(); { let mut wifiEntries = wifiEntries.lock().unwrap(); for accessPoint in accessPoints { - wifiEntries.push(ListEntry::new(&*WifiEntry::new(accessPoint))); + wifiEntries.push(accessPoint); } } - glib::MainContext::default().spawn_local(async move { + glib::spawn_future(async move { glib::idle_add_once(move || { - let wifiEntries = wifiEntries.lock().unwrap(); + let mut wifiEntries = wifiEntries.lock().unwrap(); let selfImp = wifibox_ref.imp(); - for wifiEntry in wifiEntries.iter() { - selfImp.resetWifiList.append(wifiEntry); + for _ in 0..wifiEntries.len() { + selfImp + .resetWifiList + .append(&ListEntry::new(&*WifiEntry::new( + wifiEntries.pop().unwrap(), + ))); } }); }); + let wifiBoxImpl = wifibox_ref_listener.imp(); + wifiBoxImpl + .listener_active + .store(true, std::sync::atomic::Ordering::SeqCst); + dbus_start_network_events(); let (sender, receiver): ( Sender,)>>, Receiver,)>>, ) = channel(); let sender_ref = Arc::new(sender); - let listener_active = Arc::new(AtomicBool::new(false)); - ReSet_Lib::utils::start_event_listener::< + let res = start_event_listener::< (AccessPoint,), (Path<'static>,), AccessPointAdded, AccessPointRemoved, - >(listener_active, sender_ref); - // handle receiver... - let res = receiver.try_recv(); - if res.is_ok() { - let access_point = res.unwrap(); - match access_point { - Events::AddedEvent(access_point) => { - dbg!(access_point); - } - _ => (), - }; - } else { - println!("no message there :)"); + >( + wifibox_ref_listener.imp().listener_active.clone(), + sender_ref, + ); + if res.is_err() { + println!("Could not connect listener"); + } + loop { + if wifiBoxImpl + .listener_active + .load(std::sync::atomic::Ordering::SeqCst) + == false + { + break; + } + println!("receiving!"); + let res = receiver.recv(); + if res.is_ok() { + let access_point = res.unwrap(); + match access_point { + Events::AddedEvent(access_point) => { + { + let mut wifiEntries = wifiEntriesListener.lock().unwrap(); + println!("got this access point:"); + dbg!(access_point.0.clone()); + wifiEntries.push(access_point.0); + } + let wifiEntriesListener = wifiEntriesListener.clone(); + let wifiBoxImpl = wifibox_ref_listener.clone(); + glib::spawn_future(async move { + glib::idle_add_once(move || { + let mut wifiEntries = wifiEntriesListener.lock().unwrap(); + wifiBoxImpl.imp().resetWifiList.append(&ListEntry::new( + &*WifiEntry::new(wifiEntries.pop().unwrap()), + )); + }); + }); + } + _ => (), + }; + } else { + println!("no message there :)"); + } } }); } @@ -116,8 +152,8 @@ pub fn show_stored_connections(wifiBox: Arc) { let wifibox_ref = wifiBox.clone(); let wifiEntries = wifiBox.imp().savedWifiEntries.clone(); - glib::spawn_future_local(async move { - let connections = get_stored_connections().await; + gio::spawn_blocking(move || { + let connections = get_stored_connections(); let wifiEntries = wifiEntries.clone(); { let mut wifiEntries = wifiEntries.lock().unwrap(); @@ -129,7 +165,7 @@ pub fn show_stored_connections(wifiBox: Arc) { wifiEntries.push(entry); } } - glib::MainContext::default().spawn_local(async move { + glib::spawn_future(async move { glib::idle_add_once(move || { let wifiEntries = wifiEntries.lock().unwrap(); let selfImp = wifibox_ref.imp(); @@ -141,7 +177,17 @@ pub fn show_stored_connections(wifiBox: Arc) { }); } -pub async fn get_access_points() -> Vec { +pub fn dbus_start_network_events() { + let conn = Connection::new_session().unwrap(); + let proxy = conn.with_proxy( + "org.xetibo.ReSet", + "/org/xetibo/ReSet", + Duration::from_millis(1000), + ); + let _: Result<(), Error> = proxy.method_call("org.xetibo.ReSet", "StartNetworkListener", ()); +} + +pub fn get_access_points() -> Vec { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy( "org.xetibo.ReSet", @@ -157,7 +203,7 @@ pub async fn get_access_points() -> Vec { accessPoints } -pub async fn get_stored_connections() -> Vec<(Path<'static>, Vec)> { +pub fn get_stored_connections() -> Vec<(Path<'static>, Vec)> { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy( "org.xetibo.ReSet", @@ -182,8 +228,10 @@ pub fn getConnectionSettings(path: Path<'static>) -> Option { "/org/xetibo/ReSet", Duration::from_millis(1000), ); - let res: Result<(HashMap>>,>,), Error> = - proxy.method_call("org.xetibo.ReSet", "GetConnectionSettings", (path,)); + let res: Result< + (HashMap>>>,), + Error, + > = proxy.method_call("org.xetibo.ReSet", "GetConnectionSettings", (path,)); if res.is_err() { println!("lol not work"); return None; @@ -196,3 +244,80 @@ pub fn getConnectionSettings(path: Path<'static>) -> Option { } Some(res.unwrap()) } + +// temporary, testing this with lib is pain +// + +pub fn start_event_listener< + AddedType: ReadAll + AppendAll + Send + Sync + 'static, + RemovedType: ReadAll + AppendAll + Send + Sync + 'static, + AddedEvent: ReadAll + AppendAll + dbus::message::SignalArgs + GetVal, + RemovedEvent: ReadAll + AppendAll + dbus::message::SignalArgs + GetVal, +>( + active_listener: Arc, + sender: Arc>>, +) -> Result<(), dbus::Error> { + thread::spawn(move || { + let added_sender = sender.clone(); + let removed_sender = sender.clone(); + let conn = Connection::new_session().unwrap(); + let mr = AddedEvent::match_rule( + Some(&"org.xetibo.ReSet".into()), + Some(&Path::from("/org/xetibo/ReSet")), + ) + .static_clone(); + let mrb = RemovedEvent::match_rule( + Some(&"org.xetibo.ReSet".into()), + Some(&Path::from("/org/xetibo/ReSet")), + ) + .static_clone(); + let res = conn.add_match(mr, move |ir: AddedEvent, _, _| { + println!("received added event"); + let res = added_sender.send(Events::AddedEvent(ir.get_value())); + if res.is_err() { + println!("fail on sending added"); + return false; + } + true + }); + if res.is_err() { + println!("fail on add"); + return Err(dbus::Error::new_custom( + "SignalMatchFailed", + "Failed to match signal on ReSet.", + )); + } + let res = conn.add_match(mrb, move |ir: RemovedEvent, _, _| { + println!("received removed event"); + let res = removed_sender.send(Events::RemovedEvent(ir.get_value())); + if res.is_err() { + println!("fail on sending removed"); + return false; + } + true + }); + if res.is_err() { + println!("fail on remove"); + return Err(dbus::Error::new_custom( + "SignalMatchFailed", + "Failed to match signal on ReSet.", + )); + } + active_listener.store(true, Ordering::SeqCst); + println!("starting thread listener"); + loop { + let _ = conn.process(Duration::from_millis(1000))?; + if !active_listener.load(Ordering::SeqCst) { + println!("stopping thread listener"); + break; + } + thread::sleep(Duration::from_millis(1000)); + } + Ok(()) + }); + Ok(()) +} + +pub fn stop_listener(active_listener: Arc) { + active_listener.store(false, Ordering::SeqCst); +} diff --git a/src/components/wifi/wifiBoxImpl.rs b/src/components/wifi/wifiBoxImpl.rs index c0e2dbf..501f41f 100644 --- a/src/components/wifi/wifiBoxImpl.rs +++ b/src/components/wifi/wifiBoxImpl.rs @@ -1,4 +1,6 @@ +use std::sync::atomic::AtomicBool; use std::sync::{Arc, Mutex}; +use ReSet_Lib::network::network::AccessPoint; use gtk::{CompositeTemplate, glib, ListBox, Switch}; use gtk::prelude::*; use gtk::subclass::prelude::*; @@ -23,8 +25,9 @@ pub struct WifiBox { pub resetStoredWifiList: TemplateChild, #[template_child] pub resetAvailableNetworks: TemplateChild, - pub wifiEntries: Arc>>, + pub wifiEntries: Arc>>, pub savedWifiEntries: Arc>>, + pub listener_active: Arc, } unsafe impl Send for WifiBox {} From f5f6246ad14ef006ca2c01b6b3a9feb91dc89138 Mon Sep 17 00:00:00 2001 From: Fabio Lenherr / DashieTM Date: Sun, 12 Nov 2023 23:06:31 +0100 Subject: [PATCH 2/4] feat: Add remove event for wifi entries --- src/components/base/listEntry.rs | 1 + src/components/base/listEntryImpl.rs | 4 +-- src/components/wifi/wifiBox.rs | 52 ++++++++++++++++------------ src/components/wifi/wifiBoxImpl.rs | 4 ++- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/components/base/listEntry.rs b/src/components/base/listEntry.rs index 7bcfaea..e0c1ffd 100644 --- a/src/components/base/listEntry.rs +++ b/src/components/base/listEntry.rs @@ -1,6 +1,7 @@ use crate::components::base::listEntryImpl; use adw::glib; use adw::glib::{IsA, Object}; +use dbus::Path; use gtk::prelude::ListBoxRowExt; use gtk::Widget; diff --git a/src/components/base/listEntryImpl.rs b/src/components/base/listEntryImpl.rs index db0172b..0cb1c74 100644 --- a/src/components/base/listEntryImpl.rs +++ b/src/components/base/listEntryImpl.rs @@ -1,6 +1,6 @@ -use gtk::{CompositeTemplate, glib}; -use gtk::subclass::prelude::*; use crate::components::base::listEntry; +use gtk::subclass::prelude::*; +use gtk::{glib, CompositeTemplate}; #[allow(non_snake_case)] #[derive(Default, CompositeTemplate)] diff --git a/src/components/wifi/wifiBox.rs b/src/components/wifi/wifiBox.rs index c7c8438..94e4ce1 100644 --- a/src/components/wifi/wifiBox.rs +++ b/src/components/wifi/wifiBox.rs @@ -67,22 +67,15 @@ pub fn scanForWifi(wifiBox: Arc) { let accessPoints = get_access_points(); let wifiEntriesListener = wifiEntries.clone(); let wifiEntries = wifiEntries.clone(); - { - let mut wifiEntries = wifiEntries.lock().unwrap(); - for accessPoint in accessPoints { - wifiEntries.push(accessPoint); - } - } glib::spawn_future(async move { glib::idle_add_once(move || { let mut wifiEntries = wifiEntries.lock().unwrap(); let selfImp = wifibox_ref.imp(); - for _ in 0..wifiEntries.len() { - selfImp - .resetWifiList - .append(&ListEntry::new(&*WifiEntry::new( - wifiEntries.pop().unwrap(), - ))); + for accessPoint in accessPoints { + let path = accessPoint.dbus_path.clone(); + let entry = Arc::new(ListEntry::new(&*WifiEntry::new(accessPoint))); + wifiEntries.insert(path, entry.clone()); + selfImp.resetWifiList.append(&*entry); } }); }); @@ -109,6 +102,7 @@ pub fn scanForWifi(wifiBox: Arc) { println!("Could not connect listener"); } loop { + let wifiEntriesListener = wifiEntriesListener.clone(); if wifiBoxImpl .listener_active .load(std::sync::atomic::Ordering::SeqCst) @@ -122,24 +116,38 @@ pub fn scanForWifi(wifiBox: Arc) { let access_point = res.unwrap(); match access_point { Events::AddedEvent(access_point) => { - { - let mut wifiEntries = wifiEntriesListener.lock().unwrap(); - println!("got this access point:"); - dbg!(access_point.0.clone()); - wifiEntries.push(access_point.0); - } let wifiEntriesListener = wifiEntriesListener.clone(); let wifiBoxImpl = wifibox_ref_listener.clone(); glib::spawn_future(async move { glib::idle_add_once(move || { let mut wifiEntries = wifiEntriesListener.lock().unwrap(); - wifiBoxImpl.imp().resetWifiList.append(&ListEntry::new( - &*WifiEntry::new(wifiEntries.pop().unwrap()), - )); + let path = access_point.0.dbus_path.clone(); + if wifiEntries.get(&path).is_some() { + // don't add the entry if it exists, somehow networkmanager + // spams these added things? + // TODO perhaps use ssid? + return; + } + let entry = + Arc::new(ListEntry::new(&*WifiEntry::new(access_point.0))); + wifiEntries.insert(path, entry.clone()); + wifiBoxImpl.imp().resetWifiList.append(&*entry); + }); + }); + } + Events::RemovedEvent(path) => { + let wifiBoxImpl = wifibox_ref_listener.clone(); + glib::spawn_future(async move { + glib::idle_add_once(move || { + let mut wifiEntries = wifiEntriesListener.lock().unwrap(); + let entry = wifiEntries.remove(&path.0); + if entry.is_none() { + return; + } + wifiBoxImpl.imp().resetWifiList.remove(&*entry.unwrap()); }); }); } - _ => (), }; } else { println!("no message there :)"); diff --git a/src/components/wifi/wifiBoxImpl.rs b/src/components/wifi/wifiBoxImpl.rs index 501f41f..b1d46d1 100644 --- a/src/components/wifi/wifiBoxImpl.rs +++ b/src/components/wifi/wifiBoxImpl.rs @@ -1,6 +1,8 @@ +use std::collections::HashMap; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Mutex}; use ReSet_Lib::network::network::AccessPoint; +use dbus::Path; use gtk::{CompositeTemplate, glib, ListBox, Switch}; use gtk::prelude::*; use gtk::subclass::prelude::*; @@ -25,7 +27,7 @@ pub struct WifiBox { pub resetStoredWifiList: TemplateChild, #[template_child] pub resetAvailableNetworks: TemplateChild, - pub wifiEntries: Arc>>, + pub wifiEntries: Arc,Arc>>>, pub savedWifiEntries: Arc>>, pub listener_active: Arc, } From e3b95d75404e9fb69f5ca7ef23fd556b00d01bf6 Mon Sep 17 00:00:00 2001 From: Fabio Lenherr / DashieTM Date: Mon, 13 Nov 2023 10:28:48 +0100 Subject: [PATCH 3/4] feat: Add stop listener --- Cargo.toml | 2 +- src/components/base/mod.rs | 1 + src/components/base/utils.rs | 36 ++++ src/components/wifi/wifiBox.rs | 72 +++---- src/components/wifi/wifiBoxImpl.rs | 3 +- src/components/wifi/wifiEntry.rs | 7 +- src/components/wifi/wifiEntryImpl.rs | 2 - src/components/window/handleSidebarClick.rs | 211 ++++++++++++-------- src/components/window/sidebarEntry.rs | 6 +- src/components/window/sidebarEntryImpl.rs | 7 +- src/components/window/window.rs | 2 +- src/components/window/windowImpl.rs | 4 + src/resources/resetUI.cmb | 5 +- src/resources/resetWifiEntry.ui | 8 +- 14 files changed, 215 insertions(+), 151 deletions(-) create mode 100644 src/components/base/utils.rs diff --git a/Cargo.toml b/Cargo.toml index 2db6d87..9ed48d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ description = "A wip universal Linux settings application." [dependencies] reset_daemon = "0.1.0" -ReSet-Lib = "0.2.5" +ReSet-Lib = "0.2.6" 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/mod.rs b/src/components/base/mod.rs index 628b0b7..0a6703f 100644 --- a/src/components/base/mod.rs +++ b/src/components/base/mod.rs @@ -4,3 +4,4 @@ pub mod listEntry; pub mod listEntryImpl; pub mod popup; pub mod popupImpl; +pub mod utils; diff --git a/src/components/base/utils.rs b/src/components/base/utils.rs new file mode 100644 index 0000000..c920f02 --- /dev/null +++ b/src/components/base/utils.rs @@ -0,0 +1,36 @@ +use std::{ + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + thread, + time::Duration, +}; + +use dbus::{blocking::Connection, Error}; + +#[derive(Default)] +pub struct Listeners { + pub network_listener: AtomicBool, + pub bluetooth_listener: AtomicBool, + pub pulse_listener: AtomicBool, +} + +impl Listeners { + pub fn stop_network_listener(&self) { + if !self.network_listener.load(Ordering::SeqCst) { + return; + } + self.network_listener.store(false, Ordering::SeqCst); + thread::spawn(|| { + 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", "StopNetworkListener", ()); + }); + } +} diff --git a/src/components/wifi/wifiBox.rs b/src/components/wifi/wifiBox.rs index 94e4ce1..70b1a1c 100644 --- a/src/components/wifi/wifiBox.rs +++ b/src/components/wifi/wifiBox.rs @@ -6,6 +6,7 @@ use std::thread; use std::time::Duration; use crate::components::base::listEntry::ListEntry; +use crate::components::base::utils::Listeners; use adw::glib; use adw::glib::Object; use adw::prelude::{BoxExt, ListBoxRowExt}; @@ -58,7 +59,7 @@ impl WifiBox { } } -pub fn scanForWifi(wifiBox: Arc) { +pub fn scanForWifi(listeners: Arc, wifiBox: Arc) { let wifibox_ref = wifiBox.clone(); let wifibox_ref_listener = wifiBox.clone(); let wifiEntries = wifiBox.imp().wifiEntries.clone(); @@ -72,39 +73,36 @@ pub fn scanForWifi(wifiBox: Arc) { let mut wifiEntries = wifiEntries.lock().unwrap(); let selfImp = wifibox_ref.imp(); for accessPoint in accessPoints { - let path = accessPoint.dbus_path.clone(); + let ssid = accessPoint.ssid.clone(); let entry = Arc::new(ListEntry::new(&*WifiEntry::new(accessPoint))); - wifiEntries.insert(path, entry.clone()); + wifiEntries.insert(ssid, entry.clone()); selfImp.resetWifiList.append(&*entry); } }); }); - let wifiBoxImpl = wifibox_ref_listener.imp(); - wifiBoxImpl - .listener_active - .store(true, std::sync::atomic::Ordering::SeqCst); + if listeners.network_listener.load(Ordering::SeqCst) { + return; + } + listeners.network_listener.store(true, Ordering::SeqCst); dbus_start_network_events(); let (sender, receiver): ( - Sender,)>>, - Receiver,)>>, + Sender>, + Receiver>, ) = channel(); let sender_ref = Arc::new(sender); let res = start_event_listener::< (AccessPoint,), - (Path<'static>,), + (AccessPoint,), AccessPointAdded, AccessPointRemoved, - >( - wifibox_ref_listener.imp().listener_active.clone(), - sender_ref, - ); + >(listeners.clone(), sender_ref); if res.is_err() { println!("Could not connect listener"); } loop { let wifiEntriesListener = wifiEntriesListener.clone(); - if wifiBoxImpl - .listener_active + if listeners + .network_listener .load(std::sync::atomic::Ordering::SeqCst) == false { @@ -121,26 +119,23 @@ pub fn scanForWifi(wifiBox: Arc) { glib::spawn_future(async move { glib::idle_add_once(move || { let mut wifiEntries = wifiEntriesListener.lock().unwrap(); - let path = access_point.0.dbus_path.clone(); - if wifiEntries.get(&path).is_some() { - // don't add the entry if it exists, somehow networkmanager - // spams these added things? - // TODO perhaps use ssid? + let ssid = access_point.0.ssid.clone(); + if wifiEntries.get(&ssid).is_some() { return; } let entry = Arc::new(ListEntry::new(&*WifiEntry::new(access_point.0))); - wifiEntries.insert(path, entry.clone()); + wifiEntries.insert(ssid, entry.clone()); wifiBoxImpl.imp().resetWifiList.append(&*entry); }); }); } - Events::RemovedEvent(path) => { + Events::RemovedEvent(access_point) => { let wifiBoxImpl = wifibox_ref_listener.clone(); glib::spawn_future(async move { glib::idle_add_once(move || { let mut wifiEntries = wifiEntriesListener.lock().unwrap(); - let entry = wifiEntries.remove(&path.0); + let entry = wifiEntries.remove(&access_point.0.ssid); if entry.is_none() { return; } @@ -158,27 +153,18 @@ pub fn scanForWifi(wifiBox: Arc) { pub fn show_stored_connections(wifiBox: Arc) { let wifibox_ref = wifiBox.clone(); - let wifiEntries = wifiBox.imp().savedWifiEntries.clone(); - gio::spawn_blocking(move || { let connections = get_stored_connections(); - let wifiEntries = wifiEntries.clone(); - { - let mut wifiEntries = wifiEntries.lock().unwrap(); - for connection in connections { - // TODO include button for settings - let name = &String::from_utf8(connection.1).unwrap_or_else(|_| String::from("")); - let entry = ListEntry::new(&SavedWifiEntry::new(name, connection.0)); - entry.set_activatable(false); - wifiEntries.push(entry); - } - } glib::spawn_future(async move { glib::idle_add_once(move || { - let wifiEntries = wifiEntries.lock().unwrap(); let selfImp = wifibox_ref.imp(); - for wifiEntry in wifiEntries.iter() { - selfImp.resetStoredWifiList.append(wifiEntry); + for connection in connections { + // TODO include button for settings + let name = + &String::from_utf8(connection.1).unwrap_or_else(|_| String::from("")); + let entry = ListEntry::new(&SavedWifiEntry::new(name, connection.0)); + entry.set_activatable(false); + selfImp.resetStoredWifiList.append(&entry); } }); }); @@ -262,7 +248,7 @@ pub fn start_event_listener< AddedEvent: ReadAll + AppendAll + dbus::message::SignalArgs + GetVal, RemovedEvent: ReadAll + AppendAll + dbus::message::SignalArgs + GetVal, >( - active_listener: Arc, + listeners: Arc, sender: Arc>>, ) -> Result<(), dbus::Error> { thread::spawn(move || { @@ -311,11 +297,11 @@ pub fn start_event_listener< "Failed to match signal on ReSet.", )); } - active_listener.store(true, Ordering::SeqCst); + listeners.network_listener.store(true, Ordering::SeqCst); println!("starting thread listener"); loop { let _ = conn.process(Duration::from_millis(1000))?; - if !active_listener.load(Ordering::SeqCst) { + if !listeners.network_listener.load(Ordering::SeqCst) { println!("stopping thread listener"); break; } diff --git a/src/components/wifi/wifiBoxImpl.rs b/src/components/wifi/wifiBoxImpl.rs index b1d46d1..0161872 100644 --- a/src/components/wifi/wifiBoxImpl.rs +++ b/src/components/wifi/wifiBoxImpl.rs @@ -27,9 +27,8 @@ pub struct WifiBox { pub resetStoredWifiList: TemplateChild, #[template_child] pub resetAvailableNetworks: TemplateChild, - pub wifiEntries: Arc,Arc>>>, + pub wifiEntries: Arc,Arc>>>, pub savedWifiEntries: Arc>>, - pub listener_active: Arc, } unsafe impl Send for WifiBox {} diff --git a/src/components/wifi/wifiEntry.rs b/src/components/wifi/wifiEntry.rs index ed29668..1b7724a 100644 --- a/src/components/wifi/wifiEntry.rs +++ b/src/components/wifi/wifiEntry.rs @@ -62,14 +62,11 @@ impl WifiEntry { entryImp.accessPoint.set(access_point); let gesture = GestureClick::new(); if stored { - entryImp - .resetWifiStored - .get() - .set_from_icon_name(Some("document-save-symbolic")); gesture.connect_released(move |_, _, _, _| { click_stored_network(stored_entry.clone()); }); } else { + entryImp.resetWifiEditButton.set_sensitive(false); gesture.connect_released(move |_, _, _, _| { click_new_network(new_entry.clone()); }); @@ -93,11 +90,9 @@ pub fn click_stored_network(entry: Arc) { let root = &entry.root().unwrap(); let root = root.downcast_ref::(); if root.is_none() { - println!("ERROR BRO"); return; } let root = root.unwrap(); - // TODO handle unknown access point -> should be done by having 2 different categories let entryImp = entry.imp(); let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy( diff --git a/src/components/wifi/wifiEntryImpl.rs b/src/components/wifi/wifiEntryImpl.rs index c542bb7..0a1193d 100644 --- a/src/components/wifi/wifiEntryImpl.rs +++ b/src/components/wifi/wifiEntryImpl.rs @@ -20,8 +20,6 @@ pub struct WifiEntry { #[template_child] pub resetWifiConnected: TemplateChild, #[template_child] - pub resetWifiStored: TemplateChild, - #[template_child] pub resetWifiPopup: TemplateChild, pub wifiName: RefCell, pub wifiStrength: RefCell, diff --git a/src/components/window/handleSidebarClick.rs b/src/components/window/handleSidebarClick.rs index 274cc0c..0632fea 100644 --- a/src/components/window/handleSidebarClick.rs +++ b/src/components/window/handleSidebarClick.rs @@ -1,104 +1,151 @@ use gtk::prelude::FrameExt; use std::sync::Arc; +use std::sync::atomic::Ordering; -use crate::components::output::audioBox::AudioBox; use crate::components::base::settingBox::SettingBox; +use crate::components::base::utils::Listeners; use crate::components::bluetooth::bluetoothBox::BluetoothBox; -use crate::components::wifi::wifiBox::{scanForWifi, show_stored_connections, WifiBox}; -use gtk::{FlowBox, Frame, Label,}; -use gtk::prelude::WidgetExt; use crate::components::input::sourceBox; use crate::components::input::sourceBox::SourceBox; +use crate::components::output::audioBox::AudioBox; +use crate::components::wifi::wifiBox::{scanForWifi, show_stored_connections, WifiBox}; +use gtk::prelude::WidgetExt; +use gtk::{FlowBox, Frame, Label}; -pub const HANDLE_CONNECTIVITY_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let wifiBox = Arc::new(WifiBox::new()); - show_stored_connections(wifiBox.clone()); - scanForWifi(wifiBox.clone()); - let wifiFrame = wrapInFrame(SettingBox::new(&*wifiBox)); - let bluetoothFrame = wrapInFrame(SettingBox::new(&BluetoothBox::new())); - resetMain.remove_all(); - resetMain.insert(&wifiFrame, -1); - resetMain.insert(&bluetoothFrame, -1); - resetMain.set_max_children_per_line(2); -}; +pub const HANDLE_CONNECTIVITY_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.pulse_listener.store(false, Ordering::SeqCst); + let wifiBox = Arc::new(WifiBox::new()); + show_stored_connections(wifiBox.clone()); + scanForWifi(listeners.clone(),wifiBox.clone()); + let wifiFrame = wrapInFrame(SettingBox::new(&*wifiBox)); + let bluetoothFrame = wrapInFrame(SettingBox::new(&BluetoothBox::new())); + resetMain.remove_all(); + resetMain.insert(&wifiFrame, -1); + resetMain.insert(&bluetoothFrame, -1); + resetMain.set_max_children_per_line(2); + }; -pub const HANDLE_WIFI_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let wifiBox = Arc::new(WifiBox::new()); - scanForWifi(wifiBox.clone()); - let wifiFrame = wrapInFrame(SettingBox::new(&*wifiBox)); - resetMain.remove_all(); - resetMain.insert(&wifiFrame, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_WIFI_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let wifiBox = Arc::new(WifiBox::new()); + scanForWifi(listeners.clone(),wifiBox.clone()); + let wifiFrame = wrapInFrame(SettingBox::new(&*wifiBox)); + resetMain.remove_all(); + resetMain.insert(&wifiFrame, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_BLUETOOTH_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let bluetoothFrame = wrapInFrame(SettingBox::new(&BluetoothBox::new())); - resetMain.remove_all(); - resetMain.insert(&bluetoothFrame, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_BLUETOOTH_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let bluetoothFrame = wrapInFrame(SettingBox::new(&BluetoothBox::new())); + resetMain.remove_all(); + resetMain.insert(&bluetoothFrame, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_VPN_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let label = Label::new(Some("not implemented yet")); - resetMain.remove_all(); - resetMain.insert(&label, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_VPN_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let label = Label::new(Some("not implemented yet")); + resetMain.remove_all(); + resetMain.insert(&label, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_AUDIO_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let audioFrame = wrapInFrame(SettingBox::new(&AudioBox::new())); - let sourceFrame = wrapInFrame(SettingBox::new(&SourceBox::new())); - resetMain.remove_all(); - resetMain.insert(&audioFrame, -1); - resetMain.insert(&sourceFrame, -1); - resetMain.set_max_children_per_line(2); -}; +pub const HANDLE_AUDIO_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(true, Ordering::SeqCst); + let audioFrame = wrapInFrame(SettingBox::new(&AudioBox::new())); + let sourceFrame = wrapInFrame(SettingBox::new(&SourceBox::new())); + resetMain.remove_all(); + resetMain.insert(&audioFrame, -1); + resetMain.insert(&sourceFrame, -1); + resetMain.set_max_children_per_line(2); + }; -pub const HANDLE_VOLUME_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let audioFrame = wrapInFrame(SettingBox::new(&AudioBox::new())); - resetMain.remove_all(); - resetMain.insert(&audioFrame, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_VOLUME_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let audioFrame = wrapInFrame(SettingBox::new(&AudioBox::new())); + resetMain.remove_all(); + resetMain.insert(&audioFrame, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_MICROPHONE_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let sourceFrame = wrapInFrame(SettingBox::new(&SourceBox::new())); - resetMain.remove_all(); - resetMain.insert(&sourceFrame, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_MICROPHONE_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let sourceFrame = wrapInFrame(SettingBox::new(&SourceBox::new())); + resetMain.remove_all(); + resetMain.insert(&sourceFrame, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_PERIPHERALS_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let label = Label::new(Some("not implemented yet")); - resetMain.remove_all(); - resetMain.insert(&label, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_PERIPHERALS_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let label = Label::new(Some("not implemented yet")); + resetMain.remove_all(); + resetMain.insert(&label, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_MONITOR_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let label = Label::new(Some("not implemented yet")); - resetMain.remove_all(); - resetMain.insert(&label, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_MONITOR_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let label = Label::new(Some("not implemented yet")); + resetMain.remove_all(); + resetMain.insert(&label, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_MOUSE_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let label = Label::new(Some("not implemented yet")); - resetMain.remove_all(); - resetMain.insert(&label, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_MOUSE_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let label = Label::new(Some("not implemented yet")); + resetMain.remove_all(); + resetMain.insert(&label, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_KEYBOARD_CLICK: fn(FlowBox) = |resetMain: FlowBox| { - let label = Label::new(Some("not implemented yet")); - resetMain.remove_all(); - resetMain.insert(&label, -1); - resetMain.set_max_children_per_line(1); -}; +pub const HANDLE_KEYBOARD_CLICK: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + let label = Label::new(Some("not implemented yet")); + resetMain.remove_all(); + resetMain.insert(&label, -1); + resetMain.set_max_children_per_line(1); + }; -pub const HANDLE_HOME: fn(FlowBox) = |resetMain: FlowBox| { - resetMain.remove_all(); -}; +pub const HANDLE_HOME: fn(Arc, FlowBox) = + |listeners: Arc, resetMain: FlowBox| { + listeners.stop_network_listener(); + listeners.network_listener.store(false, Ordering::SeqCst); + listeners.bluetooth_listener.store(false, Ordering::SeqCst); + listeners.pulse_listener.store(false, Ordering::SeqCst); + resetMain.remove_all(); + }; fn wrapInFrame(widget: SettingBox) -> Frame { let frame = Frame::new(None); diff --git a/src/components/window/sidebarEntry.rs b/src/components/window/sidebarEntry.rs index c04e13f..e8b78f9 100644 --- a/src/components/window/sidebarEntry.rs +++ b/src/components/window/sidebarEntry.rs @@ -1,7 +1,11 @@ +use std::sync::Arc; +use std::sync::atomic::AtomicBool; + use adw::subclass::prelude::ObjectSubclassIsExt; use glib::Object; use gtk::{FlowBox, glib}; use gtk::prelude::*; +use crate::components::base::utils::Listeners; use crate::components::window::sidebarEntryImpl; use crate::components::window::sidebarEntryImpl::{Categories, SidebarAction}; @@ -17,7 +21,7 @@ impl SidebarEntry { iconName: &str, category: Categories, isSubcategory: bool, - clickEvent: fn(FlowBox), + clickEvent: fn(Arc, FlowBox), ) -> Self { let entry: SidebarEntry = Object::builder().build(); let entryImp = entry.imp(); diff --git a/src/components/window/sidebarEntryImpl.rs b/src/components/window/sidebarEntryImpl.rs index 3497890..7be22fa 100644 --- a/src/components/window/sidebarEntryImpl.rs +++ b/src/components/window/sidebarEntryImpl.rs @@ -1,9 +1,12 @@ use std::cell::{Cell, RefCell}; +use std::sync::Arc; +use std::sync::atomic::AtomicBool; use glib::subclass::InitializingObject; use gtk::{CompositeTemplate, FlowBox, glib, Image, Label, ListBoxRow}; use gtk::subclass::prelude::*; +use crate::components::base::utils::Listeners; use crate::components::window::handleSidebarClick::HANDLE_HOME; use crate::components::window::sidebarEntry; @@ -32,7 +35,7 @@ pub struct SidebarEntry { #[allow(non_snake_case)] pub struct SidebarAction { - pub onClickEvent: fn(FlowBox), + pub onClickEvent: fn(Arc,FlowBox), } impl Default for SidebarAction { @@ -62,4 +65,4 @@ impl ObjectImpl for SidebarEntry {} impl ListBoxRowImpl for SidebarEntry {} -impl WidgetImpl for SidebarEntry {} \ No newline at end of file +impl WidgetImpl for SidebarEntry {} diff --git a/src/components/window/window.rs b/src/components/window/window.rs index cf2397d..4d18560 100644 --- a/src/components/window/window.rs +++ b/src/components/window/window.rs @@ -45,7 +45,7 @@ impl Window { clone!(@ weak selfImp as flowbox => move |_, y| { let result = y.downcast_ref::().unwrap(); let clickEvent = result.imp().onClickEvent.borrow().onClickEvent; - (clickEvent)(flowbox.resetMain.get()); + (clickEvent)(flowbox.listeners.clone(), flowbox.resetMain.get()); }), ); diff --git a/src/components/window/windowImpl.rs b/src/components/window/windowImpl.rs index eda7bcd..3a578b4 100644 --- a/src/components/window/windowImpl.rs +++ b/src/components/window/windowImpl.rs @@ -1,4 +1,6 @@ use std::cell::RefCell; +use std::sync::Arc; +use std::sync::atomic::AtomicBool; use adw::glib::StaticTypeExt; use adw::subclass::prelude::AdwApplicationWindowImpl; @@ -7,6 +9,7 @@ use glib::subclass::InitializingObject; use gtk::subclass::prelude::*; use gtk::{glib, Box, Button, CompositeTemplate, FlowBox, ListBox, PopoverMenu, SearchEntry}; +use crate::components::base::utils::Listeners; use crate::components::wifi::wifiBox::WifiBox; use crate::components::window::sidebarEntry::SidebarEntry; use crate::components::window::window; @@ -40,6 +43,7 @@ pub struct Window { #[template_child] pub resetShortcutsButton: TemplateChild