~kennylevinsen/greetd

87e92776543c224676d64316f4519b509c21a0d5 — muradm 2 months ago fba10c1 master
greetd: add terminal switch flag configuration option

This adds "switch" true/false flag in "terminal" section of
configuration file.

Flag controls whether terminal under control should be switched to
when greetd starts. If "switch" set to true, greetd behaves as it
did before, on start vt_setactivate will be called. If "switch" set
to false, and terminal under control by greetd is not currently
active VT, greetd will wait for terminal to become active with
vt_waitactive, which translates to VT_WAITACTIVE ioctl call.

* greetd/src/config/mod.rs: add "switch" flag
* greetd/src/server.rs: add using "switch" flag and waiting for active
* greetd/src/terminal/mod.rs: add vt_waitactive method
* man/greetd-5.scd: mention "switch" configuration option
4 files changed, 58 insertions(+), 11 deletions(-)

M greetd/src/config/mod.rs
M greetd/src/server.rs
M greetd/src/terminal/mod.rs
M man/greetd-5.scd
M greetd/src/config/mod.rs => greetd/src/config/mod.rs +23 -9
@@ 35,6 35,7 @@ pub struct ConfigInternal {
#[derive(Debug, Eq, PartialEq, Default)]
pub struct ConfigTerminal {
    pub vt: VtSelection,
    pub switch: bool,
}

#[derive(Debug, Eq, PartialEq)]


@@ 104,7 105,7 @@ fn parse_old_config(config: &HashMap<&str, HashMap<&str, &str>>) -> Result<Confi
    };

    Ok(ConfigFile {
        terminal: ConfigTerminal { vt },
        terminal: ConfigTerminal { vt, switch: true },
        default_session: ConfigSession {
            user: greeter_user,
            command: greeter,


@@ 165,6 166,11 @@ fn parse_new_config(config: &HashMap<&str, HashMap<&str, &str>>) -> Result<Confi
                        .map_err(|e| format!("could not parse vt number: {}", e))?,
                ),
            },
            switch: section
                .get("switch")
                .unwrap_or(&"true")
                .parse()
                .map_err(|e| format!("could not parse switch: {}", e))?,
        }),
        None => Err("no terminal specified"),
    }?;


@@ 300,7 306,8 @@ greeter_user = \"greeter\"
            config,
            ConfigFile {
                terminal: ConfigTerminal {
                    vt: VtSelection::Specific(1)
                    vt: VtSelection::Specific(1),
                    switch: true,
                },
                default_session: ConfigSession {
                    command: "agreety".to_string(),


@@ 322,7 329,8 @@ greeter = \"agreety\"
            config,
            ConfigFile {
                terminal: ConfigTerminal {
                    vt: VtSelection::Next
                    vt: VtSelection::Next,
                    switch: true,
                },
                default_session: ConfigSession {
                    command: "agreety".to_string(),


@@ 349,7 357,8 @@ command = \"agreety\"
            config,
            ConfigFile {
                terminal: ConfigTerminal {
                    vt: VtSelection::Specific(1)
                    vt: VtSelection::Specific(1),
                    switch: true,
                },
                default_session: ConfigSession {
                    command: "agreety".to_string(),


@@ 376,7 385,8 @@ user = \"john\"
            config,
            ConfigFile {
                terminal: ConfigTerminal {
                    vt: VtSelection::Specific(1)
                    vt: VtSelection::Specific(1),
                    switch: true,
                },
                default_session: ConfigSession {
                    command: "agreety".to_string(),


@@ 406,7 416,8 @@ runfile = \"/path/to/greetd.state\"
            config,
            ConfigFile {
                terminal: ConfigTerminal {
                    vt: VtSelection::Specific(1)
                    vt: VtSelection::Specific(1),
                    switch: true,
                },
                default_session: ConfigSession {
                    command: "agreety".to_string(),


@@ 447,7 458,8 @@ vt = 1
            config,
            ConfigFile {
                terminal: ConfigTerminal {
                    vt: VtSelection::Specific(1)
                    vt: VtSelection::Specific(1),
                    switch: true,
                },
                default_session: ConfigSession {
                    command: "agreety".to_string(),


@@ 469,7 481,8 @@ vt = next
            config,
            ConfigFile {
                terminal: ConfigTerminal {
                    vt: VtSelection::Next
                    vt: VtSelection::Next,
                    switch: true,
                },
                default_session: ConfigSession {
                    command: "agreety".to_string(),


@@ 491,7 504,8 @@ vt = current
            config,
            ConfigFile {
                terminal: ConfigTerminal {
                    vt: VtSelection::Current
                    vt: VtSelection::Current,
                    switch: true,
                },
                default_session: ConfigSession {
                    command: "agreety".to_string(),

M greetd/src/server.rs => greetd/src/server.rs +17 -2
@@ 31,6 31,17 @@ fn reset_vt(term_mode: &TerminalMode) -> Result<(), Error> {
    Ok(())
}

fn wait_vt(term_mode: &TerminalMode) -> Result<(), Error> {
    match term_mode {
        TerminalMode::Terminal { path, vt, .. } => {
            let term = Terminal::open(path)?;
            term.vt_waitactive(*vt)?;
        }
        TerminalMode::Stdin => (),
    }
    Ok(())
}

fn wrap_result<T>(res: Result<T, Error>) -> Response {
    match res {
        Ok(_) => Response::Success,


@@ 145,14 156,14 @@ fn get_tty(config: &Config) -> Result<TerminalMode, Error> {
            TerminalMode::Terminal {
                path: format!("/dev/tty{}", vt),
                vt,
                switch: true,
                switch: config.file.terminal.switch,
            }
        }
        VtSelection::None => TerminalMode::Stdin,
        VtSelection::Specific(vt) => TerminalMode::Terminal {
            path: format!("/dev/tty{}", vt),
            vt,
            switch: true,
            switch: config.file.terminal.switch,
        },
    };
    return Ok(term);


@@ 215,6 226,10 @@ pub async fn main(config: Config) -> Result<(), Error> {

    let term_mode = get_tty(&config)?;

    if !config.file.terminal.switch {
        wait_vt(&term_mode).map_err(|e| format!("unable to wait VT: {}", e))?;
    }

    let ctx = Rc::new(Context::new(
        config.file.default_session.command,
        config.file.default_session.user,

M greetd/src/terminal/mod.rs => greetd/src/terminal/mod.rs +8 -0
@@ 111,6 111,14 @@ impl Terminal {
        Ok(())
    }

    /// Waits for specified VT to become active.
    pub fn vt_waitactive(&self, target_vt: usize) -> Result<(), Error> {
        if let Err(v) = unsafe { ioctl::vt_waitactive(self.fd, target_vt as i32) } {
            return Err(format!("terminal: unable to wait for activation: {}", v).into());
        }
        Ok(())
    }

    /// Set the VT mode to VT_AUTO with everything cleared.
    fn vt_mode_clean(&self) -> Result<(), Error> {
        let mode = ioctl::vt_mode {

M man/greetd-5.scd => man/greetd-5.scd +10 -0
@@ 37,6 37,16 @@ This section contains terminal configuration.

	Use of a specific VT with appropriate conflict avoidance is recommended.

*switch* = true|false
	Whether or not to switch to *vt*.

	If set to false and *vt* is not currently active VT, greetd will wait for
	*vt* to become active, before doing anything including starting greeter.

	If set to true, greetd will switch current VT to *vt*,

	Default is true.

## general

This section contains general configuration that does not fit in other sections