diff --git a/src/components/base/error_impl.rs b/src/components/base/error_impl.rs index 5c84083..d337d04 100644 --- a/src/components/base/error_impl.rs +++ b/src/components/base/error_impl.rs @@ -58,6 +58,7 @@ pub fn show_error( parent: Arc, message: &'static str, ) { + // TODO: Add error to log glib::spawn_future(async move { glib::idle_add_once(move || { let mut error = parent.error(); diff --git a/src/components/bluetooth/bluetooth_box.rs b/src/components/bluetooth/bluetooth_box.rs index 5d5197c..fc20e09 100644 --- a/src/components/bluetooth/bluetooth_box.rs +++ b/src/components/bluetooth/bluetooth_box.rs @@ -16,6 +16,7 @@ use gtk::{gio, StringObject}; use re_set_lib::bluetooth::bluetooth_structures::{BluetoothAdapter, BluetoothDevice}; use re_set_lib::signals::{BluetoothDeviceAdded, BluetoothDeviceChanged, BluetoothDeviceRemoved}; +use crate::components::base::error_impl::{show_error, ReSetErrorImpl}; use crate::components::base::utils::Listeners; use crate::components::bluetooth::bluetooth_box_impl; use crate::components::bluetooth::bluetooth_entry::BluetoothEntry; @@ -30,6 +31,14 @@ glib::wrapper! { unsafe impl Send for BluetoothBox {} unsafe impl Sync for BluetoothBox {} +impl ReSetErrorImpl for BluetoothBox { + fn error( + &self, + ) -> >k::subclass::prelude::TemplateChild { + &self.imp().error + } +} + impl BluetoothBox { pub fn new(listeners: Arc) -> Arc { let obj: Arc = Arc::new(Object::builder().build()); @@ -68,14 +77,24 @@ fn setup_callbacks( .store(true, Ordering::SeqCst); }); + let bluetooth_box_discover = bluetooth_box.clone(); imp.reset_bluetooth_discoverable_switch .connect_active_notify(clone!(@weak imp => move |state| { - set_bluetooth_adapter_visibility(imp.reset_current_bluetooth_adapter.borrow().path.clone(), state.is_active()); + set_bluetooth_adapter_visibility( + imp.reset_current_bluetooth_adapter.borrow().path.clone(), + state.is_active(), + bluetooth_box_discover.clone() + ); })); + let bluetooth_box_pairable = bluetooth_box.clone(); imp.reset_bluetooth_pairable_switch .connect_active_notify(clone!(@weak imp => move |state| { - set_bluetooth_adapter_pairability(imp.reset_current_bluetooth_adapter.borrow().path.clone(), state.is_active()); + set_bluetooth_adapter_pairability( + imp.reset_current_bluetooth_adapter.borrow().path.clone(), + state.is_active(), + bluetooth_box_pairable.clone() + ); })); imp.reset_bluetooth_switch.connect_state_set( @@ -110,6 +129,7 @@ fn setup_callbacks( let res = set_adapter_enabled( current_adapter.path.clone(), false, + bluetooth_box_ref.clone() ); if res { current_adapter.powered = false; @@ -129,6 +149,7 @@ fn setup_callbacks( .path .clone(), true, + restart_ref.clone() ) { current_adapter.powered = true; start_bluetooth_listener(restart_listener_ref.clone(), restart_ref.clone()); @@ -145,8 +166,8 @@ pub fn populate_conntected_bluetooth_devices(bluetooth_box: Arc) { // TODO handle saved devices -> they also exist gio::spawn_blocking(move || { let ref_box = bluetooth_box.clone(); - let devices = get_connected_devices(); - let adapters = get_bluetooth_adapters(); + let devices = get_connected_devices(ref_box.clone()); + let adapters = get_bluetooth_adapters(ref_box.clone()); { let imp = bluetooth_box.imp(); let list = imp.reset_model_list.write().unwrap(); @@ -165,6 +186,7 @@ pub fn populate_conntected_bluetooth_devices(bluetooth_box: Arc) { } glib::spawn_future(async move { glib::idle_add_once(move || { + let new_adapter_ref = ref_box.clone(); let imp = ref_box.imp(); let list = imp.reset_model_list.read().unwrap(); @@ -202,14 +224,14 @@ pub fn populate_conntected_bluetooth_devices(bluetooth_box: Arc) { if device.is_none() { return; } - set_bluetooth_adapter(device.unwrap().0.path.clone()); + set_bluetooth_adapter(device.unwrap().0.path.clone(), new_adapter_ref.clone()); }), ); for device in devices { let path = device.path.clone(); let connected = device.connected; - let bluetooth_entry = BluetoothEntry::new(device); + let bluetooth_entry = BluetoothEntry::new(device, ref_box.clone()); imp.available_devices .borrow_mut() .insert(path, bluetooth_entry.clone()); @@ -242,7 +264,10 @@ pub fn start_bluetooth_listener(listeners: Arc, bluetooth_box: Arc = proxy.method_call(BLUETOOTH, "StartBluetoothListener", ()); + let res: Result<(), Error> = proxy.method_call(BLUETOOTH, "StartBluetoothListener", ()); + if res.is_err() { + show_error::(bluetooth_box.clone(), "Failed to start bluetooth listener"); + } imp.reset_bluetooth_available_devices .set_description(Some("Scanning...")); let device_added = @@ -262,7 +287,8 @@ pub fn start_bluetooth_listener(listeners: Arc, bluetooth_box: Arc, bluetooth_box: Arc = + let res: Result<(), Error> = proxy.method_call(BLUETOOTH, "StopBluetoothListener", ()); + if res.is_err() { + show_error::( + bluetooth_box.clone(), + "Failed to stop bluetooth listener", + ); + } loop_box .imp() .reset_bluetooth_available_devices @@ -372,7 +404,13 @@ pub fn start_bluetooth_listener(listeners: Arc, bluetooth_box: Arc = proxy.method_call(BLUETOOTH, "StopBluetoothScan", ()); + let res: Result<(), Error> = proxy.method_call(BLUETOOTH, "StopBluetoothScan", ()); + if res.is_err() { + show_error::( + bluetooth_box.clone(), + "Failed to stop bluetooth listener", + ); + } loop_box .imp() .reset_bluetooth_available_devices @@ -383,8 +421,14 @@ pub fn start_bluetooth_listener(listeners: Arc, bluetooth_box: Arc = + let res: Result<(), Error> = proxy.method_call(BLUETOOTH, "StartBluetoothListener", ()); + if res.is_err() { + show_error::( + bluetooth_box.clone(), + "Failed to start bluetooth listener", + ); + } loop_box .imp() .reset_bluetooth_available_devices @@ -395,58 +439,91 @@ pub fn start_bluetooth_listener(listeners: Arc, bluetooth_box: Arc Vec { +fn get_connected_devices(bluetooth_box: Arc) -> Vec { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); let res: Result<(Vec,), Error> = proxy.method_call(BLUETOOTH, "GetConnectedBluetoothDevices", ()); if res.is_err() { + show_error::( + bluetooth_box.clone(), + "Failed to get connected bluetooth devices", + ); return Vec::new(); } res.unwrap().0 } -fn get_bluetooth_adapters() -> Vec { +fn get_bluetooth_adapters(bluetooth_box: Arc) -> Vec { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); let res: Result<(Vec,), Error> = proxy.method_call(BLUETOOTH, "GetBluetoothAdapters", ()); if res.is_err() { + show_error::(bluetooth_box.clone(), "Failed to get bluetooth adapters"); return Vec::new(); } res.unwrap().0 } -fn set_bluetooth_adapter(path: Path<'static>) { +fn set_bluetooth_adapter(path: Path<'static>, bluetooth_box: Arc) { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(Path<'static>,), Error> = + let res: Result<(Path<'static>,), Error> = proxy.method_call(BLUETOOTH, "SetBluetoothAdapter", (path,)); + if res.is_err() { + show_error::(bluetooth_box.clone(), "Failed to set bluetooth adapter"); + } } -fn set_bluetooth_adapter_visibility(path: Path<'static>, visible: bool) { +fn set_bluetooth_adapter_visibility( + path: Path<'static>, + visible: bool, + bluetooth_box: Arc, +) { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(bool,), Error> = proxy.method_call( + let res: Result<(bool,), Error> = proxy.method_call( BLUETOOTH, "SetBluetoothAdapterDiscoverability", (path, visible), ); + if res.is_err() { + show_error::( + bluetooth_box.clone(), + "Failed to set bluetooth adapter visibility", + ); + } } -fn set_bluetooth_adapter_pairability(path: Path<'static>, visible: bool) { +fn set_bluetooth_adapter_pairability( + path: Path<'static>, + visible: bool, + bluetooth_box: Arc, +) { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(bool,), Error> = + let res: Result<(bool,), Error> = proxy.method_call(BLUETOOTH, "SetBluetoothAdapterPairability", (path, visible)); + if res.is_err() { + show_error::( + bluetooth_box.clone(), + "Failed to set bluetooth adapter pairability", + ); + } } -fn set_adapter_enabled(path: Path<'static>, enabled: bool) -> bool { +fn set_adapter_enabled( + path: Path<'static>, + enabled: bool, + bluetooth_box: Arc, +) -> bool { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); let result: Result<(bool,), Error> = proxy.method_call(BLUETOOTH, "SetBluetoothAdapterEnabled", (path, enabled)); if result.is_err() { + show_error::(bluetooth_box.clone(), "Failed to enable bluetooth adapter"); return false; } result.unwrap().0 diff --git a/src/components/bluetooth/bluetooth_box_impl.rs b/src/components/bluetooth/bluetooth_box_impl.rs index 6c1973d..0d05612 100644 --- a/src/components/bluetooth/bluetooth_box_impl.rs +++ b/src/components/bluetooth/bluetooth_box_impl.rs @@ -9,6 +9,7 @@ use std::collections::HashMap; use std::sync::atomic::AtomicBool; use std::sync::{Arc, RwLock}; +use crate::components::base::error::ReSetError; use crate::components::base::list_entry::ListEntry; use crate::components::bluetooth::bluetooth_box; use crate::components::bluetooth::bluetooth_entry::BluetoothEntry; @@ -36,6 +37,8 @@ pub struct BluetoothBox { pub reset_bluetooth_discoverable_switch: TemplateChild, #[template_child] pub reset_bluetooth_pairable_switch: TemplateChild, + #[template_child] + pub error: TemplateChild, pub available_devices: BluetoothMap, pub connected_devices: BluetoothMap, pub reset_bluetooth_adapters: Arc>>, diff --git a/src/components/bluetooth/bluetooth_entry.rs b/src/components/bluetooth/bluetooth_entry.rs index 3fc04e1..02a943a 100644 --- a/src/components/bluetooth/bluetooth_entry.rs +++ b/src/components/bluetooth/bluetooth_entry.rs @@ -2,8 +2,10 @@ use std::ops::Deref; use std::sync::Arc; use std::time::Duration; +use crate::components::base::error_impl::show_error; use crate::components::bluetooth::bluetooth_entry_impl; use crate::components::utils::{BASE, BLUETOOTH, DBUS_PATH}; +use crate::components::wifi::wifi_box_impl::WifiBox; use adw::glib::Object; use adw::prelude::{ActionRowExt, PreferencesRowExt}; use adw::{glib, ActionRow}; @@ -14,6 +16,8 @@ use gtk::prelude::{ButtonExt, ListBoxRowExt, WidgetExt}; use gtk::{gio, Align, Button, GestureClick, Image, Label}; use re_set_lib::bluetooth::bluetooth_structures::BluetoothDevice; +use super::bluetooth_box::BluetoothBox; + glib::wrapper! { pub struct BluetoothEntry(ObjectSubclass) @extends ActionRow, gtk::Widget, @@ -24,7 +28,7 @@ unsafe impl Send for BluetoothEntry {} unsafe impl Sync for BluetoothEntry {} impl BluetoothEntry { - pub fn new(device: BluetoothDevice) -> Arc { + pub fn new(device: BluetoothDevice, bluetooth_box: Arc) -> Arc { let entry: Arc = Arc::new(Object::builder().build()); let entry_imp = entry.imp(); let entry_ref = entry.clone(); @@ -60,7 +64,7 @@ impl BluetoothEntry { .borrow() .connect_clicked(move |_| { let imp = entry_ref_remove.imp(); - remove_device_pairing(imp.bluetooth_device.borrow().path.clone()); + remove_device_pairing(imp.bluetooth_device.borrow().path.clone(), bluetooth_box.clone()); }); let gesture = GestureClick::new(); // paired is not what we think @@ -147,11 +151,14 @@ fn disconnect_from_device(entry: Arc, path: Path<'static>) { }); } -fn remove_device_pairing(path: Path<'static>) { +fn remove_device_pairing(path: Path<'static>, wifi_box: Arc) { gio::spawn_blocking(move || { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(bool,), Error> = + let res: Result<(bool,), Error> = proxy.method_call(BLUETOOTH, "RemoveDevicePairing", (path,)); + if res.is_err() { + show_error::(wifi_box.clone(), "Failed to remove device pairing"); + } }); } diff --git a/src/components/input/output_stream_entry.rs b/src/components/input/output_stream_entry.rs index 2400c19..ce8a7fb 100644 --- a/src/components/input/output_stream_entry.rs +++ b/src/components/input/output_stream_entry.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use std::time::{Duration, SystemTime}; +use crate::components::base::error_impl::show_error; use crate::components::utils::{ create_dropdown_label_factory, set_combo_row_ellipsis, AUDIO, BASE, DBUS_PATH, }; @@ -30,6 +31,9 @@ impl OutputStreamEntry { pub fn new(source_box: Arc, stream: OutputStream) -> Self { let obj: Self = Object::builder().build(); // TODO use event callback for progress bar -> this is the "im speaking" indicator + let output_box_volume_ref = source_box.clone(); + let output_box_mute_ref = source_box.clone(); + let output_box_source_ref = source_box.clone(); { let index = stream.index; let box_imp = source_box.imp(); @@ -66,7 +70,7 @@ impl OutputStreamEntry { } *time = Some(SystemTime::now()); } - set_outputstream_volume(value, index, channels); + set_outputstream_volume(value, index, channels, output_box_volume_ref.clone()); Propagation::Proceed }), ); @@ -118,7 +122,7 @@ impl OutputStreamEntry { } let stream = stream.unwrap(); let source = source.unwrap().0; - set_source_of_output_stream(stream.index, source); + set_source_of_output_stream(stream.index, source, output_box_source_ref.clone()); }), ); imp.reset_source_mute @@ -139,53 +143,56 @@ impl OutputStreamEntry { imp.reset_source_mute .set_icon_name("audio-input-microphone-symbolic"); } - toggle_output_stream_mute(index, muted); + toggle_output_stream_mute(index, muted, output_box_mute_ref.clone()); })); } obj } } -fn set_outputstream_volume(value: f64, index: u32, channels: u16) -> bool { +fn set_outputstream_volume( + value: f64, + index: u32, + channels: u16, + input_box: Arc, +) -> bool { gio::spawn_blocking(move || { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(), Error> = proxy.method_call( + let res: Result<(), Error> = proxy.method_call( AUDIO, "SetOutputStreamVolume", (index, channels, value as u32), ); - // if res.is_err() { - // return false; - // } - // res.unwrap().0 + if res.is_err() { + show_error::(input_box.clone(), "Failed to set output stream volume"); + } }); true } -fn toggle_output_stream_mute(index: u32, muted: bool) -> bool { +fn toggle_output_stream_mute(index: u32, muted: bool, input_box: Arc) -> bool { gio::spawn_blocking(move || { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(), Error> = proxy.method_call(AUDIO, "SetOutputStreamMute", (index, muted)); - // if res.is_err() { - // return false; - // } - // res.unwrap().0 + let res: Result<(), Error> = + proxy.method_call(AUDIO, "SetOutputStreamMute", (index, muted)); + if res.is_err() { + show_error::(input_box.clone(), "Failed to mute output stream"); + } }); true } -fn set_source_of_output_stream(stream: u32, source: u32) -> bool { +fn set_source_of_output_stream(stream: u32, source: u32, input_box: Arc) -> bool { gio::spawn_blocking(move || { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(bool,), Error> = + let res: Result<(bool,), Error> = proxy.method_call(AUDIO, "SetSourceOfOutputStream", (stream, source)); - // if res.is_err() { - // return false; - // } - // res.unwrap().0 + if res.is_err() { + show_error::(input_box.clone(), "Failed to set source of output stream"); + } }); true } diff --git a/src/components/output/input_stream_entry.rs b/src/components/output/input_stream_entry.rs index 52de3ba..ee235be 100644 --- a/src/components/output/input_stream_entry.rs +++ b/src/components/output/input_stream_entry.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use std::time::{Duration, SystemTime}; +use crate::components::base::error_impl::show_error; use crate::components::utils::{ create_dropdown_label_factory, set_combo_row_ellipsis, AUDIO, BASE, DBUS_PATH, }; @@ -30,6 +31,9 @@ impl InputStreamEntry { pub fn new(sink_box: Arc, stream: InputStream) -> Self { let obj: Self = Object::builder().build(); // TODO use event callback for progress bar -> this is the "im speaking" indicator + let output_box_mute_ref = sink_box.clone(); + let output_box_volume_ref = sink_box.clone(); + let output_box_sink_ref = sink_box.clone(); { let index = stream.sink_index; let box_imp = sink_box.imp(); @@ -75,7 +79,7 @@ impl InputStreamEntry { } *time = Some(SystemTime::now()); } - set_inputstream_volume(value, index, channels); + set_inputstream_volume(value, index, channels, output_box_volume_ref.clone()); Propagation::Proceed }), ); @@ -131,7 +135,7 @@ impl InputStreamEntry { } let stream = stream.unwrap(); let sink = sink.unwrap().0; - set_sink_of_input_stream(stream.index, sink); + set_sink_of_input_stream(stream.index, sink, output_box_sink_ref.clone()); }), ); imp.reset_sink_mute @@ -152,54 +156,55 @@ impl InputStreamEntry { imp.reset_sink_mute .set_icon_name("audio-volume-high-symbolic"); } - toggle_input_stream_mute(index, muted); + toggle_input_stream_mute(index, muted, output_box_mute_ref.clone()); })); } obj } } -fn set_inputstream_volume(value: f64, index: u32, channels: u16) -> bool { +fn set_inputstream_volume( + value: f64, + index: u32, + channels: u16, + output_box: Arc, +) -> bool { gio::spawn_blocking(move || { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(), Error> = proxy.method_call( + let res: Result<(), Error> = proxy.method_call( AUDIO, "SetInputStreamVolume", (index, channels, value as u32), ); - // if res.is_err() { - // return false; - // } - // res.unwrap().0 + if res.is_err() { + show_error::(output_box.clone(), "Failed to set input stream volume"); + } }); true } -fn toggle_input_stream_mute(index: u32, muted: bool) -> bool { +fn toggle_input_stream_mute(index: u32, muted: bool, output_box: Arc) -> bool { gio::spawn_blocking(move || { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(), Error> = proxy.method_call(AUDIO, "SetInputStreamMute", (index, muted)); - // if res.is_err() { - // return false; - // } - // res.unwrap().0 + let res: Result<(), Error> = proxy.method_call(AUDIO, "SetInputStreamMute", (index, muted)); + if res.is_err() { + show_error::(output_box.clone(), "Failed to mute input stream"); + } }); true } -fn set_sink_of_input_stream(stream: u32, sink: u32) -> bool { +fn set_sink_of_input_stream(stream: u32, sink: u32, output_box: Arc) -> bool { gio::spawn_blocking(move || { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(), Error> = proxy.method_call(AUDIO, "SetSinkOfInputStream", (stream, sink)); - // if res.is_err() { - // return false; - // } - // res.unwrap().0 + let res: Result<(), Error> = + proxy.method_call(AUDIO, "SetSinkOfInputStream", (stream, sink)); + if res.is_err() { + show_error::(output_box.clone(), "Failed to set sink of input stream"); + } }); true } - -// TODO propagate error from dbus diff --git a/src/components/wifi/wifi_box.rs b/src/components/wifi/wifi_box.rs index fa5e697..87f1cb4 100644 --- a/src/components/wifi/wifi_box.rs +++ b/src/components/wifi/wifi_box.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use std::time::Duration; +use crate::components::base::error_impl::{show_error, ReSetErrorImpl}; use crate::components::base::utils::Listeners; use crate::components::utils::{set_combo_row_ellipsis, BASE, DBUS_PATH, WIRELESS}; use adw::glib; @@ -38,6 +39,14 @@ type ResultMap = Result<(Vec<(Path<'static>, Vec)>,), Error>; unsafe impl Send for WifiBox {} unsafe impl Sync for WifiBox {} +impl ReSetErrorImpl for WifiBox { + fn error( + &self, + ) -> >k::subclass::prelude::TemplateChild { + &self.imp().error + } +} + impl WifiBox { pub fn new(listeners: Arc) -> Arc { let obj: Arc = Arc::new(Object::builder().build()); @@ -50,6 +59,7 @@ impl WifiBox { fn setup_callbacks(listeners: Arc, wifi_box: Arc) -> Arc { let imp = wifi_box.imp(); let wifibox_ref = wifi_box.clone(); + let wifibox_ref_switch = wifi_box.clone(); imp.reset_switch_initial.set(true); imp.reset_saved_networks.set_activatable(true); imp.reset_saved_networks @@ -66,7 +76,7 @@ fn setup_callbacks(listeners: Arc, wifi_box: Arc) -> Arc, wifi_box: Arc) -> Arc) { let wifibox_ref = wifi_box.clone(); - let _wifibox_ref_listener = wifi_box.clone(); let wifi_entries = wifi_box.imp().wifi_entries.clone(); let wifi_entries_path = wifi_box.imp().wifi_entries_path.clone(); gio::spawn_blocking(move || { - let wifi_status = get_wifi_status(); - let devices = get_wifi_devices(); + let wifi_status = get_wifi_status(wifibox_ref.clone()); + let devices = get_wifi_devices(wifibox_ref.clone()); if devices.is_empty() { return; } - let access_points = get_access_points(); + let access_points = get_access_points(wifibox_ref.clone()); { let imp = wifibox_ref.imp(); let list = imp.reset_model_list.write().unwrap(); @@ -118,7 +127,7 @@ pub fn scan_for_wifi(wifi_box: Arc) { } let wifi_entries = wifi_entries.clone(); let wifi_entries_path = wifi_entries_path.clone(); - dbus_start_network_events(); + dbus_start_network_events(wifibox_ref.clone()); glib::spawn_future(async move { glib::idle_add_once(move || { let mut wifi_entries = wifi_entries.write().unwrap(); @@ -139,6 +148,7 @@ pub fn scan_for_wifi(wifi_box: Arc) { } } + let device_changed_ref = wifibox_ref.clone(); imp.reset_wifi_device.connect_selected_notify( clone!(@weak imp => move |dropdown| { let selected = dropdown.selected_item(); @@ -154,7 +164,7 @@ pub fn scan_for_wifi(wifi_box: Arc) { if device.is_none() { return; } - set_wifi_device(device.unwrap().0.path.clone()); + set_wifi_device(device.unwrap().0.path.clone(), device_changed_ref.clone()); }), ); for access_point in access_points { @@ -178,7 +188,7 @@ pub fn scan_for_wifi(wifi_box: Arc) { pub fn show_stored_connections(wifi_box: Arc) { let wifibox_ref = wifi_box.clone(); gio::spawn_blocking(move || { - let connections = get_stored_connections(); + let connections = get_stored_connections(wifi_box.clone()); glib::spawn_future(async move { glib::idle_add_once(move || { let self_imp = wifibox_ref.imp(); @@ -194,67 +204,80 @@ pub fn show_stored_connections(wifi_box: Arc) { }); } -pub fn dbus_start_network_events() { +pub fn dbus_start_network_events(wifi_box: Arc) { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(), Error> = proxy.method_call(WIRELESS, "StartNetworkListener", ()); + let res: Result<(), Error> = proxy.method_call(WIRELESS, "StartNetworkListener", ()); + if res.is_err() { + show_error::(wifi_box.clone(), "Failed to start Network listener"); + } } -pub fn get_access_points() -> Vec { +pub fn get_access_points(wifi_box: Arc) -> Vec { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); let res: Result<(Vec,), Error> = proxy.method_call(WIRELESS, "ListAccessPoints", ()); if res.is_err() { + show_error::(wifi_box.clone(), "Failed to list access points"); return Vec::new(); } let (access_points,) = res.unwrap(); access_points } -pub fn set_wifi_device(path: Path<'static>) { +pub fn set_wifi_device(path: Path<'static>, wifi_box: Arc) { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(bool,), Error> = proxy.method_call(WIRELESS, "SetWifiDevice", (path,)); + let res: Result<(bool,), Error> = proxy.method_call(WIRELESS, "SetWifiDevice", (path,)); + if res.is_err() { + show_error::(wifi_box.clone(), "Failed to set WiFi devices"); + } } -pub fn get_wifi_devices() -> Vec { +pub fn get_wifi_devices(wifi_box: Arc) -> Vec { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); let res: Result<(Vec,), Error> = proxy.method_call(WIRELESS, "GetAllWifiDevices", ()); if res.is_err() { + show_error::(wifi_box.clone(), "Failed to get WiFi devices"); return Vec::new(); } let (devices,) = res.unwrap(); devices } -pub fn get_wifi_status() -> bool { +pub fn get_wifi_status(wifi_box: Arc) -> bool { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); let res: Result<(bool,), Error> = proxy.method_call(WIRELESS, "GetWifiStatus", ()); if res.is_err() { + show_error::(wifi_box.clone(), "Failed to get WiFi status"); return false; } res.unwrap().0 } -pub fn get_stored_connections() -> Vec<(Path<'static>, Vec)> { +pub fn get_stored_connections(wifi_box: Arc) -> Vec<(Path<'static>, Vec)> { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); let res: ResultMap = proxy.method_call(WIRELESS, "ListStoredConnections", ()); if res.is_err() { + show_error::(wifi_box.clone(), "Failed to list stored connections"); return Vec::new(); } let (connections,) = res.unwrap(); connections } -pub fn set_wifi_enabled(enabled: bool) { +pub fn set_wifi_enabled(enabled: bool, wifi_box: Arc) { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000)); - let _: Result<(bool,), Error> = proxy.method_call(WIRELESS, "SetWifiEnabled", (enabled,)); + let res: Result<(bool,), Error> = proxy.method_call(WIRELESS, "SetWifiEnabled", (enabled,)); + if res.is_err() { + show_error::(wifi_box.clone(), "Failed to enable WiFi"); + } } pub fn start_event_listener(listeners: Arc, wifi_box: Arc) { diff --git a/src/components/wifi/wifi_box_impl.rs b/src/components/wifi/wifi_box_impl.rs index 7e22a41..f6b0530 100644 --- a/src/components/wifi/wifi_box_impl.rs +++ b/src/components/wifi/wifi_box_impl.rs @@ -1,3 +1,4 @@ +use crate::components::base::error::ReSetError; use crate::components::wifi::wifi_box; use adw::{ActionRow, ComboRow, NavigationView, PreferencesGroup}; use dbus::Path; @@ -32,6 +33,8 @@ pub struct WifiBox { pub reset_stored_wifi_list: TemplateChild, #[template_child] pub reset_available_networks: TemplateChild, + #[template_child] + pub error: TemplateChild, pub wifi_entries: Arc, Arc>>>, pub wifi_entries_path: Arc, Arc>>>, pub reset_wifi_devices: Arc>>, diff --git a/src/resources/resetBluetooth.ui b/src/resources/resetBluetooth.ui index 05aa506..c3f9eb7 100644 --- a/src/resources/resetBluetooth.ui +++ b/src/resources/resetBluetooth.ui @@ -144,5 +144,8 @@ + + + diff --git a/src/resources/resetUI.cmb b/src/resources/resetUI.cmb index 8b7f78c..bd8965a 100644 --- a/src/resources/resetUI.cmb +++ b/src/resources/resetUI.cmb @@ -77,6 +77,7 @@ (4,206,"AdwActionRow","reset_available_networks",205,None,None,None,-1,None), (4,207,"GtkImage",None,206,None,None,None,None,None), (4,208,"AdwPreferencesGroup","reset_wifi_list",154,None,None,None,1,None), + (4,209,"resetError","error",7,None,None,None,2,None), (5,12,"AdwActionRow","resetWifiEntry",None,None,None,None,-1,None), (5,13,"resetPopup","reset_wifi_popup",12,None,None,None,None,None), (6,1,"GtkListBoxRow","resetSidebarEntry",None,None,None,None,None,None), @@ -150,6 +151,7 @@ (10,211,"AdwSwitchRow","reset_bluetooth_discoverable_switch",209,None,None,None,-1,None), (10,212,"AdwActionRow","reset_bluetooth_main_tab",208,None,None,None,None,None), (10,213,"GtkImage",None,212,None,None,None,None,None), + (10,214,"resetError","error",1,None,None,None,2,None), (11,1,"AdwActionRow","resetBluetoothEntry",None,None,None,None,None,None), (12,11,"GtkBox","resetAudioInput",None,None,None,None,None,None), (12,12,"GtkLabel",None,11,None,None,None,None,None), diff --git a/src/resources/resetWiFi.ui b/src/resources/resetWiFi.ui index d19af3a..f715411 100644 --- a/src/resources/resetWiFi.ui +++ b/src/resources/resetWiFi.ui @@ -120,5 +120,8 @@ + + +