Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ the Roboto font. All screenshots are provided under the
- Allows manual entry of username and session command
- Remembers the last authenticated user
- Automatically selects the last used session per user
- Can also skip selecting the user/session and choose the last user and their
last used session.
- Allows setting environment variables for created sessions
- Supports customizing:
- Background image
Expand Down
3 changes: 3 additions & 0 deletions regreet.sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later

# Whether to skip asking for username and session, and use the last used ones.
skip_selection = false

[background]
# Path to the background image/video
path = "/usr/share/backgrounds/greeter.jpg"
Expand Down
7 changes: 7 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ fn default_greeting_msg() -> String {
/// The configuration struct
#[derive(Default, Deserialize)]
pub struct Config {
#[serde(default)]
skip_selection: bool,

#[serde(default)]
appearance: AppearanceSettings,

Expand Down Expand Up @@ -184,4 +187,8 @@ impl Config {
pub fn get_default_message(&self) -> &str {
&self.appearance.greeting_msg
}

pub fn skip_selection(&self) -> bool {
self.skip_selection
}
}
22 changes: 21 additions & 1 deletion src/gui/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::path::PathBuf;
use relm4::{
AsyncComponentSender,
component::{AsyncComponent, AsyncComponentParts},
gtk::prelude::*,
gtk::{glib::GString, prelude::*},
prelude::*,
};
use tracing::{debug, info, warn};
Expand Down Expand Up @@ -420,6 +420,26 @@ impl AsyncComponent for Greeter {
// Set the default behaviour of pressing the Return key to act like the login button.
root.set_default_widget(Some(&widgets.ui.login_button));

if let Some(user) = model.cache.get_last_user() {
if model.config.skip_selection() && model.cache.has_last_session(user) {
debug!("Skipping user & session selection and using those from the cache");
// Queue up a login event after the Self::Input::UserChanged that will be fired by
// setup_users_sessions (as sender.input queues). This way we avoid any race
// conditions. Use cached values directly instead of extracting from widgets.
let user = user.to_string();
let last_session = model.cache.get_last_session(&user).unwrap().to_string();
sender.input(Self::Input::Login {
input: String::new(),
info: UserSessInfo {
user_id: Some(user.into()),
user_text: GString::new(),
sess_id: Some(last_session.into()),
sess_text: GString::new(),
},
});
}
}

AsyncComponentParts { model, widgets }
}

Expand Down
39 changes: 33 additions & 6 deletions src/gui/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,10 @@ pub struct Greeter {
pub(super) updates: Updates,
/// Is it run as demo
pub(super) demo: bool,

/// The clock widget
pub(super) clock: Controller<Clock>,
/// Has the first click of the login button been handled previously?
first_login_handled: bool,
}

impl Greeter {
Expand Down Expand Up @@ -141,6 +143,7 @@ impl Greeter {
updates,
demo,
clock,
first_login_handled: false,
}
}

Expand Down Expand Up @@ -300,17 +303,34 @@ impl Greeter {
) {
match response {
Response::Success => {
// Authentication was successful and the session may be started.
// This may happen on the first request, in which case logging in
// as the given user requires no authentication.
info!("Successfully logged in; starting session");
self.start_session(sender).await;
if self.config.skip_selection() && !self.first_login_handled {
// This happens when the last logged-in user has no password or any other auth
// set. Since the login button is auto-clicked, it would've otherwise logged
// them in without any possibility of changing the user or session!
warn!("Preventing auto-login for user without auth: cancelling session");
self.cancel_click_handler().await
} else {
// Authentication was successful and the session may be started.
// This may happen on the first request, in which case logging in
// as the given user requires no authentication.
info!("Successfully logged in; starting session");
self.start_session(sender).await
}
return;
}
Response::AuthMessage {
auth_message,
auth_message_type,
} => {
let auto_select_msg = if self.config.skip_selection() && !self.first_login_handled {
self.sess_info
.as_ref()
.and_then(|s| s.sess_id.as_ref())
.map(|s| format!("Auto-selecting session \"{s}\""))
} else {
None
};

match auth_message_type {
AuthMessageType::Secret => {
// Greetd has requested input that should be hidden
Expand All @@ -320,6 +340,9 @@ impl Greeter {
self.updates.set_input(String::new());
self.updates
.set_input_prompt(auth_message.trim_end().to_string());
if let Some(msg) = auto_select_msg {
self.display_info(sender, &msg, "Skipped user/session selection");
}
return;
}
AuthMessageType::Visible => {
Expand All @@ -329,6 +352,9 @@ impl Greeter {
self.updates.set_input(String::new());
self.updates
.set_input_prompt(auth_message.trim_end().to_string());
if let Some(msg) = auto_select_msg {
self.display_info(sender, &msg, "Skipped user/session selection");
}
return;
}
AuthMessageType::Info => {
Expand Down Expand Up @@ -435,6 +461,7 @@ impl Greeter {
self.create_session(sender).await;
}
};
self.first_login_handled = true;
}

/// Send the entered input for logging in.
Expand Down
Loading