Separate configuration for Wayland and X11 sessions

This commit is contained in:
Aleksei Bavshin 2023-06-04 01:26:28 -07:00 committed by Antoine POPINEAU
parent 8c08eb78ce
commit 389e73ea21
4 changed files with 51 additions and 29 deletions

View File

@ -11,7 +11,9 @@ Options:
-h, --help show this usage information
-v, --version print version information
-c, --cmd COMMAND command to run
-s, --sessions DIRS colon-separated list of session paths
-s, --sessions DIRS colon-separated list of Wayland session paths
-x, --xsessions DIRS
colon-separated list of X11 session paths
-w, --width WIDTH width of the main prompt (default: 80)
-i, --issue show the host's issue file
-g, --greeting GREETING

View File

@ -21,9 +21,12 @@ tuigreet - A graphical console greeter for greetd
overridden by manual selection within *tuigreet*.
*-s, --sessions DIR1[:DIR2]...*
Location of desktop-files to be used as session definitions. By default,
sessions are fetched from */usr/share/xsessions* and
*/usr/share/wayland-sessions*.
Location of desktop-files to be used as Wayland session definitions. By
default, Wayland sessions are fetched from */usr/share/wayland-sessions*.
*-x, --xsessions DIR1[:DIR2]...*
Location of desktop-files to be used as X11 session definitions. By
default, X11 sessions are fetched from */usr/share/xsessions*.
*-w, --width COLS*
Number of columns the main prompt area should take on the screen.

View File

@ -4,6 +4,7 @@ use std::{
env,
error::Error,
fmt::{self, Display},
path::PathBuf,
process,
sync::Arc,
};
@ -99,7 +100,7 @@ pub struct Greeter {
pub selected_user: usize,
pub command: Option<String>,
pub new_command: String,
pub sessions_path: Option<String>,
pub session_paths: Vec<(PathBuf, SessionType)>,
pub sessions: Vec<Session>,
pub selected_session: usize,
@ -287,7 +288,8 @@ impl Greeter {
opts.optflag("h", "help", "show this usage information");
opts.optflag("v", "version", "print version information");
opts.optopt("c", "cmd", "command to run", "COMMAND");
opts.optopt("s", "sessions", "colon-separated list of session paths", "DIRS");
opts.optopt("s", "sessions", "colon-separated list of Wayland session paths", "DIRS");
opts.optopt("x", "xsessions", "colon-separated list of X11 session paths", "DIRS");
opts.optopt("w", "width", "width of the main prompt (default: 80)", "WIDTH");
opts.optflag("i", "issue", "show the host's issue file");
opts.optopt("g", "greeting", "show custom text above login prompt", "GREETING");
@ -392,7 +394,13 @@ impl Greeter {
self.greeting = self.option("greeting");
self.command = self.option("cmd");
self.sessions_path = self.option("sessions");
if let Some(dirs) = self.option("sessions") {
self.session_paths.extend(env::split_paths(&dirs).map(|dir| (dir, SessionType::Wayland)));
}
if let Some(dirs) = self.option("xsessions") {
self.session_paths.extend(env::split_paths(&dirs).map(|dir| (dir, SessionType::X11)));
}
if self.config().opt_present("issue") {
self.greeting = get_issue();

View File

@ -8,12 +8,11 @@ use std::{
};
use ini::Ini;
use lazy_static::lazy_static;
use nix::sys::utsname;
use crate::{Greeter, Session, SessionType};
const X_SESSIONS: &str = "/usr/share/xsessions";
const WAYLAND_SESSIONS: &str = "/usr/share/wayland-sessions";
const LAST_USER_USERNAME: &str = "/var/cache/tuigreet/lastuser";
const LAST_USER_NAME: &str = "/var/cache/tuigreet/lastuser-name";
const LAST_SESSION: &str = "/var/cache/tuigreet/lastsession";
@ -21,6 +20,18 @@ const LAST_SESSION: &str = "/var/cache/tuigreet/lastsession";
const DEFAULT_MIN_UID: u16 = 1000;
const DEFAULT_MAX_UID: u16 = 60000;
lazy_static! {
static ref XDG_DATA_DIRS: Vec<PathBuf> = {
let value = env::var("XDG_DATA_DIRS").unwrap_or("/usr/local/share:/usr/share".to_string());
env::split_paths(&value).filter(|p| p.is_absolute()).collect()
};
static ref DEFAULT_SESSION_PATHS: Vec<(PathBuf, SessionType)> = XDG_DATA_DIRS
.iter()
.map(|p| (p.join("wayland-sessions"), SessionType::Wayland))
.chain(XDG_DATA_DIRS.iter().map(|p| (p.join("xsessions"), SessionType::X11)))
.collect();
}
pub fn get_hostname() -> String {
match utsname::uname() {
Ok(uts) => uts.nodename().to_str().unwrap_or("").to_string(),
@ -180,32 +191,30 @@ pub fn get_min_max_uids(min_uid: Option<u16>, max_uid: Option<u16>) -> (u16, u16
}
pub fn get_sessions(greeter: &Greeter) -> Result<Vec<Session>, Box<dyn Error>> {
let sessions = match greeter.sessions_path {
Some(ref dirs) => env::split_paths(&dirs).collect(),
None => vec![PathBuf::from(X_SESSIONS), PathBuf::from(WAYLAND_SESSIONS)],
let paths = if greeter.session_paths.is_empty() {
DEFAULT_SESSION_PATHS.as_ref()
} else {
&greeter.session_paths
};
let mut files = sessions
.iter()
.flat_map(fs::read_dir)
.flat_map(|directory| directory.flat_map(|entry| entry.map(|entry| load_desktop_file(entry.path()))).flatten())
.collect::<Vec<_>>();
let mut files = match &greeter.command {
Some(command) => vec![Session {
name: command.clone(),
command: command.clone(),
session_type: SessionType::default(),
}],
_ => vec![],
};
if let Some(command) = &greeter.command {
files.insert(
0,
Session {
name: command.clone(),
command: command.clone(),
session_type: SessionType::default(),
},
);
for (path, session_type) in paths.iter() {
if let Ok(entries) = fs::read_dir(path) {
files.extend(entries.flat_map(|entry| entry.map(|entry| load_desktop_file(entry.path(), *session_type))).flatten());
}
}
Ok(files)
}
fn load_desktop_file<P>(path: P) -> Result<Session, Box<dyn Error>>
fn load_desktop_file<P>(path: P, session_type: SessionType) -> Result<Session, Box<dyn Error>>
where
P: AsRef<Path>,
{
@ -218,7 +227,7 @@ where
Ok(Session {
name: name.to_string(),
command: exec.to_string(),
session_type: SessionType::default(),
session_type,
})
}