Problem with Key events in TUI

⚓ rust    📅 2025-04-24    👤 surdeus    👁️ 2      

surdeus

So ... I recently discovered the Glicol music programming language (glicol.org), and thought it was pretty cool. But the existing implementation is browser-based, and I don't like doing that kind of thing in a browser, so I decided to develop a TUI environment for Glicol. I've done some GUI programming in the past, but this is my first serious attempt to work with the terminal.

My program uses ratatui and tui-textarea with crossterm as a backend. I've created a simple proof-of-concept version, and it sort of works, but I've encountered a problem with keyboard events. I don't think it's actually a bug, but it is behavior that I didn't expect and don't want.

I would like to use the keystroke combinations Ctrl+Enter to evaluate code in the main window, and Ctrl+. to stop playing sound. Of course, it's not absolutely necessary to use these particular keys, but I'd really like to, because (1) they are used in other music programming environments - e.g. in the very popular SuperCollider, and at least one other program I've seen, and (2) they are IMHO quite intuitive.

But it turns out those combinations don't work.

My event handling code looks like this:

    match crossterm::event::read()?.into() {
        Input {
            key: Key::Enter,
            ctrl: true,
            .. 
        } => {
            let code = textarea.lines().join("");
            let _ = tx.send(CtrlReq::Process(code));
        },
        Input {
            key: Key::Char('q' | 'Q'),
            ctrl: true,
            ..
        } => {
            let _ = tx.send(CtrlReq::Stop);
            break;
        },
        Input {
            key: Key::Char('.'),
            ctrl: true,
            ..
        } => {
            let _ = tx.send(CtrlReq::Pause);
        },
        input => {
            log(format!("Input: {:?}", input));
            let _ = textarea.input(input);
        }
    }

I've discovered that for certain keys, including Enter and ., crossterm's KeyEvent struct simply ignores the Ctrl modifier. And I guess that sort of makes sense, since apparently the crossterm keyboard mapping follows the old-school Unix terminal conventions. So, as I said, I guess it's not a bug, but it's not good for my purposes.

Is there any way I can make crossterm read the Ctrl key in combination with Enter and .? Or any other library I could use instead, to get the behavior I want?

4 posts - 4 participants

Read full topic

🏷️ rust_feed