diff --git a/cosmic-settings/src/pages/bluetooth/mod.rs b/cosmic-settings/src/pages/bluetooth/mod.rs index a3f9555a..5145cf9e 100644 --- a/cosmic-settings/src/pages/bluetooth/mod.rs +++ b/cosmic-settings/src/pages/bluetooth/mod.rs @@ -47,6 +47,8 @@ pub struct Page { selected_adapter: Option, heading: String, devices: HashMap, + // Set to true when the org.bluez dbus service is unknown. + bluez_service_unknown: bool, popup_setting: bool, popup_device: Option, subscription: Option>, @@ -157,6 +159,7 @@ pub enum Message { tokio::sync::mpsc::Sender, ), DBusError(String), + DBusServiceUnknown, DeviceFailed(OwnedObjectPath), DisconnectDevice(OwnedObjectPath), ForgetDevice(OwnedObjectPath), @@ -491,6 +494,9 @@ impl Page { Message::DBusError(why) => { tracing::error!("dbus connection failed. {why}"); } + Message::DBusServiceUnknown => { + self.bluez_service_unknown = true; + } }; cosmic::Task::none() } @@ -575,6 +581,14 @@ fn status() -> Section { .show_while::(|page| !page.adapters.is_empty()) .view::(move |_binder, page, section| { let descriptions = §ion.descriptions; + + if page.bluez_service_unknown { + return widget::text::body( + "The org.bluez DBus service could not be activated. Is bluez installed?", + ) + .apply(Element::from); + } + let status = page .get_selected_adapter() .map_or(page.active, |(_, adapter)| adapter.enabled); diff --git a/cosmic-settings/src/pages/bluetooth/subscription.rs b/cosmic-settings/src/pages/bluetooth/subscription.rs index 1a9d85e4..0baaa291 100644 --- a/cosmic-settings/src/pages/bluetooth/subscription.rs +++ b/cosmic-settings/src/pages/bluetooth/subscription.rs @@ -7,7 +7,7 @@ use std::pin::Pin; use bluez_zbus::BluetoothDevice; use cosmic::iced::futures::{SinkExt, StreamExt}; use futures::{channel::mpsc, stream::FusedStream}; -use zbus::zvariant::OwnedObjectPath; +use zbus::{fdo, zvariant::OwnedObjectPath}; enum DevicePropertyWatcherTask { Add(OwnedObjectPath), @@ -201,14 +201,26 @@ pub async fn watch( }.await; if let Err(why) = result { - tracing::error!("failed to watch bluetooth event: {why}"); - if let Err(why) = tx + _ = tx .send(bluetooth::Message::DBusError(why.to_string())) - .await - { - tracing::error!("failed to communicate error to app: {why}"); + .await; + + tracing::error!("failed to watch bluetooth event: {why}."); + + // Exit if the dbus service is not found. + if let zbus::Error::FDO(fdo_error) = why { + match *fdo_error { + fdo::Error::ServiceUnknown(_) => { + tracing::error!( + "The org.bluez dbus service is unknown. Is the bluez service installed and activatable?" + ); + _ = tx.send(bluetooth::Message::DBusServiceUnknown).await; + return; + } + + _ => (), + } } - tracing::error!("failed to watch bluetooth event: {why}. Restarting..."); } } }