Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rawscreen and AlternateScreen should disable Ctrl+C signal on windows console #214

Closed
3kyro opened this issue Sep 13, 2019 · 1 comment
Closed

Comments

@3kyro
Copy link

3kyro commented Sep 13, 2019

Or maybe just provide a method to enable/disable the SIGINT signal and just treat it as other keyboard events. Currently pressing Ctrl+C in a windows terminal immediately terminates the process, making for example a feature similar to nodejs' press Ctrl+C twice to exit.

Below my failed attempt to come up with a PR for this:

By following the CTRL+C and CTRL+BREAK Signals in widows console documentation, it appears that one should:

  1. use the SetConsoleMode function to disable the ENABLE_PROCESSED_INPUT flag or
  2. call SetConsoleCtrlHandler with NULL and True as arguments.

For option 1:

RawModeCommand seems to be where we should look

pub struct RawModeCommand {
    mask: DWORD,
}
use self::wincon::{ENABLE_LINE_INPUT, ENABLE_WRAP_AT_EOL_OUTPUT};
impl RawModeCommand {
    pub fn new() -> Self {
        RawModeCommand {
            mask: ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_LINE_INPUT,
        }
    }
}

impl RawModeCommand {
    /// Enables raw mode.
    pub fn enable(&mut self) -> io::Result<()> {
        let console_mode = ConsoleMode::new()?;

        let dw_mode = console_mode.mode()?;

        let new_mode = dw_mode & !self.mask;

        console_mode.set_mode(new_mode)?;

        Ok(())
    }

    /// Disables raw mode.
    pub fn disable(&self) -> io::Result<()> {
        let console_mode = ConsoleMode::new()?;

        let dw_mode = console_mode.mode()?;

        let new_mode = dw_mode | self.mask;

        console_mode.set_mode(new_mode)?;

        return Ok(());
    }
}

Disabling ENABLE_PROCESS_INPUT 0x0001 will not work because the handle needs to be an input handle and not a output handle as is the case each time a ConsoleMode instance is created.

A note: ENABLE_LINE_INPUT and ENABLE_WRAP_AT_EOL_OUTPUT are both 0x0002 and so mask: ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_LINE_INPUT, could be just
mask: ENABLE_WRAP_AT_EOL_OUTPUT,

  1. SetConsoleCtrlHandler takes as arguments an Option type and an i32 and should be set to NULL and true respectively. Creating a method for ConsoleMode such as:

pub fn set_ctrl_handler(&self) { unsafe { SetConsoleCtrlHandler(None, 1); } }
and calling it on initialization does not work as well.

@TimonPost TimonPost mentioned this issue Sep 23, 2019
1 task
@TimonPost
Copy link
Member

Can be closed in favor for #250

december1981 pushed a commit to december1981/crossterm that referenced this issue Oct 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants