Compare commits
2 Commits
cdfba07802
...
v0.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 4fa0dd0ead | |||
| 658328b39b |
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "moongreet"
|
name = "moongreet"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "A greetd greeter for Wayland with GTK4 and Layer Shell"
|
description = "A greetd greeter for Wayland with GTK4 and Layer Shell"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
+12
-4
@@ -47,14 +47,16 @@ fn split_shell_words(s: &str) -> Option<Vec<String>> {
|
|||||||
}
|
}
|
||||||
'\\' if in_double => {
|
'\\' if in_double => {
|
||||||
// In double quotes, backslash escapes the next char
|
// In double quotes, backslash escapes the next char
|
||||||
if let Some(next) = chars.next() {
|
match chars.next() {
|
||||||
current.push(next);
|
Some(next) => current.push(next),
|
||||||
|
None => return None, // Trailing backslash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'\\' if !in_single && !in_double => {
|
'\\' if !in_single && !in_double => {
|
||||||
// Outside quotes, backslash escapes the next char
|
// Outside quotes, backslash escapes the next char
|
||||||
if let Some(next) = chars.next() {
|
match chars.next() {
|
||||||
current.push(next);
|
Some(next) => current.push(next),
|
||||||
|
None => return None, // Trailing backslash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c if c.is_whitespace() && !in_single && !in_double => {
|
c if c.is_whitespace() && !in_single && !in_double => {
|
||||||
@@ -1189,6 +1191,12 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shell_words_trailing_backslash() {
|
||||||
|
assert_eq!(split_shell_words(r"foo\"), None);
|
||||||
|
assert_eq!(split_shell_words(r#""foo\"#), None);
|
||||||
|
}
|
||||||
|
|
||||||
// -- login_worker tests --
|
// -- login_worker tests --
|
||||||
// These use a real Unix socket pair via UnixListener to simulate greetd.
|
// These use a real Unix socket pair via UnixListener to simulate greetd.
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -54,12 +54,17 @@ fn activate(app: >k::Application) {
|
|||||||
let config = config::load_config(None);
|
let config = config::load_config(None);
|
||||||
let bg_path = config::resolve_background_path(&config);
|
let bg_path = config::resolve_background_path(&config);
|
||||||
|
|
||||||
|
let use_layer_shell = std::env::var("MOONGREET_NO_LAYER_SHELL").is_err();
|
||||||
|
|
||||||
// Main greeter window (login UI) — compositor picks focused monitor
|
// Main greeter window (login UI) — compositor picks focused monitor
|
||||||
let greeter_window = greeter::create_greeter_window(&bg_path, &config, app);
|
let greeter_window = greeter::create_greeter_window(&bg_path, &config, app);
|
||||||
|
if use_layer_shell {
|
||||||
setup_layer_shell(&greeter_window, true);
|
setup_layer_shell(&greeter_window, true);
|
||||||
|
}
|
||||||
greeter_window.present();
|
greeter_window.present();
|
||||||
|
|
||||||
// Wallpaper-only windows on all monitors
|
// Wallpaper-only windows on all monitors (only with layer shell)
|
||||||
|
if use_layer_shell {
|
||||||
let monitors = display.monitors();
|
let monitors = display.monitors();
|
||||||
for i in 0..monitors.n_items() {
|
for i in 0..monitors.n_items() {
|
||||||
if let Some(monitor) = monitors
|
if let Some(monitor) = monitors
|
||||||
@@ -73,6 +78,7 @@ fn activate(app: >k::Application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn setup_logging() {
|
fn setup_logging() {
|
||||||
let mut builder = env_logger::Builder::from_default_env();
|
let mut builder = env_logger::Builder::from_default_env();
|
||||||
|
|||||||
+13
-2
@@ -30,12 +30,12 @@ pub struct User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
/// Return the display name (GECOS if available, otherwise username).
|
/// Return the display name (first GECOS subfield if available, otherwise username).
|
||||||
pub fn display_name(&self) -> &str {
|
pub fn display_name(&self) -> &str {
|
||||||
if self.gecos.is_empty() {
|
if self.gecos.is_empty() {
|
||||||
&self.username
|
&self.username
|
||||||
} else {
|
} else {
|
||||||
&self.gecos
|
self.gecos.split(',').next().unwrap_or(&self.username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,6 +150,17 @@ mod tests {
|
|||||||
assert_eq!(users[0].home, PathBuf::from("/home/testuser"));
|
assert_eq!(users[0].home, PathBuf::from("/home/testuser"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn gecos_subfield_trimmed() {
|
||||||
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
let path = make_passwd(
|
||||||
|
dir.path(),
|
||||||
|
"testuser:x:1000:1000:Test User,Room 123,555-1234:/home/testuser:/bin/bash\n",
|
||||||
|
);
|
||||||
|
let users = get_users(Some(&path));
|
||||||
|
assert_eq!(users[0].display_name(), "Test User");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn skip_system_users() {
|
fn skip_system_users() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user