diff --git a/src/greeter.rs b/src/greeter.rs index 929459a..b53e4f4 100644 --- a/src/greeter.rs +++ b/src/greeter.rs @@ -280,6 +280,8 @@ pub fn main() -> Result<(), Box> { sessions }; + let logind_available = cfg!(feature = "logind") && crate::logind::is_available(); + let flags = Flags { user_icons: user_datas .iter_mut() @@ -289,6 +291,7 @@ pub fn main() -> Result<(), Box> { sessions, greeter_config, greeter_config_handler, + logind_available, }; let settings = Settings::default().no_main_window(true); @@ -305,6 +308,7 @@ pub struct Flags { sessions: HashMap, Vec)>, greeter_config: CosmicGreeterConfig, greeter_config_handler: Option, + logind_available: bool, } #[derive(Clone, Debug)] @@ -688,7 +692,7 @@ impl App { let accessibility_button = accessibility_dropdown; - let button_row = iced::widget::row![ + let mut button_row = iced::widget::row![ widget::tooltip( accessibility_button, text(fl!("accessibility")), @@ -709,30 +713,32 @@ impl App { text(fl!("session")), widget::tooltip::Position::Top ), - widget::tooltip( - widget::button::custom(widget::icon::from_name("system-suspend-symbolic")) - .padding(12.0) - .on_press(Message::Suspend), - text(fl!("suspend")), - widget::tooltip::Position::Top - ), - widget::tooltip( - widget::button::custom(widget::icon::from_name("system-reboot-symbolic")) - .padding(12.0) - .on_press(Message::Restart), - text(fl!("restart")), - widget::tooltip::Position::Top - ), - widget::tooltip( - widget::button::custom(widget::icon::from_name("system-shutdown-symbolic")) - .padding(12.0) - .on_press(Message::Shutdown), - text(fl!("shutdown")), - widget::tooltip::Position::Top - ) - ] - .padding([16.0, 0.0, 0.0, 0.0]) - .spacing(8.0); + ]; + if self.flags.logind_available { + button_row = button_row + .push(widget::tooltip( + widget::button::custom(widget::icon::from_name("system-suspend-symbolic")) + .padding(12.0) + .on_press(Message::Suspend), + text(fl!("suspend")), + widget::tooltip::Position::Top, + )) + .push(widget::tooltip( + widget::button::custom(widget::icon::from_name("system-reboot-symbolic")) + .padding(12.0) + .on_press(Message::Restart), + text(fl!("restart")), + widget::tooltip::Position::Top, + )) + .push(widget::tooltip( + widget::button::custom(widget::icon::from_name("system-shutdown-symbolic")) + .padding(12.0) + .on_press(Message::Shutdown), + text(fl!("shutdown")), + widget::tooltip::Position::Top, + )); + } + let button_row = button_row.padding([16.0, 0.0, 0.0, 0.0]).spacing(8.0); widget::container(iced::widget::column![ date_time_column, diff --git a/src/locker.rs b/src/locker.rs index 952d00a..d7fd18b 100644 --- a/src/locker.rs +++ b/src/locker.rs @@ -79,6 +79,8 @@ pub fn main(user: pwd::Passwd) -> Result<(), Box> { // We are already the user at this point user_data.load_config_as_user(); + let logind_available = cfg!(feature = "logind") && crate::logind::is_available(); + let flags = Flags { user_icon: user_data .icon_opt @@ -86,6 +88,7 @@ pub fn main(user: pwd::Passwd) -> Result<(), Box> { .map(widget::image::Handle::from_bytes), user_data, lockfile_opt: lockfile_opt(), + logind_available, }; let settings = Settings::default().no_main_window(true); @@ -247,6 +250,7 @@ pub struct Flags { user_data: UserData, user_icon: Option, lockfile_opt: Option, + logind_available: bool, } ///TODO: this is custom code that should be better handled by libcosmic @@ -429,7 +433,7 @@ impl App { } //TODO: implement these buttons - let button_row = iced::widget::row![ + let mut button_row = iced::widget::row![ /*TODO: greeter accessibility options widget::button::custom(widget::icon::from_name( "applications-accessibility-symbolic" @@ -442,16 +446,17 @@ impl App { widget::text(fl!("keyboard-layout")), widget::tooltip::Position::Top ), - widget::tooltip( + ]; + if cfg!(feature = "logind") && self.flags.logind_available { + button_row = button_row.push(widget::tooltip( widget::button::custom(widget::icon::from_name("system-suspend-symbolic")) .padding(12.0) .on_press(Message::Suspend), widget::text(fl!("suspend")), - widget::tooltip::Position::Top - ), - ] - .padding([16.0, 0.0, 0.0, 0.0]) - .spacing(8.0); + widget::tooltip::Position::Top, + )); + } + let button_row = button_row.padding([16.0, 0.0, 0.0, 0.0]).spacing(8.0); widget::container(iced::widget::column![ date_time_column, @@ -679,18 +684,18 @@ impl cosmic::Application for App { authenticating: false, }; - let task = if cfg!(feature = "logind") { + let task = if cfg!(feature = "logind") && app.flags.logind_available { if already_locked { // Recover previously locked state tracing::info!("recovering previous locked state"); app.state = State::Locking; lock() } else { - // When logind feature is used, wait for lock signal + // When logind is available, wait for lock signal Task::none() } } else { - // When logind feature not used, lock immediately + // When logind is not available, lock immediately tracing::info!("locking immediately"); app.state = State::Locking; lock() @@ -1005,11 +1010,11 @@ impl cosmic::Application for App { self.common.window_size.remove(surface_id); commands.push(destroy_lock_surface(*surface_id)); } - if cfg!(feature = "logind") { + if cfg!(feature = "logind") && self.flags.logind_available { return Task::batch(commands); - // When using logind feature, stick around for more lock signals + // When logind is available, stick around for more lock signals } else { - // When not using logind feature, exit immediately after unlocking + // When logind is not available, exit immediately after unlocking //TODO: cleaner method to exit? process::exit(0); } @@ -1212,8 +1217,7 @@ impl cosmic::Application for App { }), ); - #[cfg(feature = "logind")] - { + if cfg!(feature = "logind") && self.flags.logind_available { subscriptions.push(crate::logind::subscription()); } diff --git a/src/logind.rs b/src/logind.rs index c5561f3..74da8e4 100644 --- a/src/logind.rs +++ b/src/logind.rs @@ -13,6 +13,27 @@ use zbus::Connection; use crate::common; use crate::locker::Message; +/// Checks whether logind (either elogind or systemd-logind) is reachable on the system bus. +pub fn is_available() -> bool { + fn ping() -> zbus::Result<()> { + let connection = zbus::blocking::Connection::system()?; + connection.call_method( + Some("org.freedesktop.login1"), + "/org/freedesktop/login1", + Some("org.freedesktop.DBus.Peer"), + "Ping", + &(), + )?; + Ok(()) + } + if let Err(err) = ping() { + tracing::info!("logind not available: {}", err); + false + } else { + true + } +} + pub async fn power_off() -> zbus::Result<()> { let connection = Connection::system().await?; let manager = ManagerProxy::new(&connection).await?;