How to map Control S to a Keyboard Event?

I know how to use a shift modifier with a key (like below). But is there a way to add letters, like ‘s’ to a key::Named::Control?

I would like to add a Control S for Message::Save on forms.

  Message::Event(event) => match event {
                Event::Keyboard(keyboard::Event::KeyPressed {
                    key: keyboard::Key::Named(key::Named::Tab),
                    modifiers,
                    ..
                }) => {
                    if modifiers.shift() {
                        widget::focus_previous()
                    } else {
                        widget::focus_next()
                    }
                }

Is there a way to do that in iced? For now I have tried it with Ctrl+Alt … but ideally it would be Ctrl+S.

      Message::Event(event) => match event {
               //.. 
            Event::Keyboard(keyboard::Event::KeyPressed {
                    key: keyboard::Key::Named(key::Named::Control),
                    modifiers,
                    ..
                }) => {
                    if modifiers.alt() {
                        // Here I want to run a task Message::Save

                        Task::perform(..., Message::Save)
                    } else {
                        Task::none()
                    }
                }

        }


Thank you in advance!

You need to match against Key::Character instead of Key::Named.

1 Like

Thanks! @lufte !

Now I got to the following:

  Event::Keyboard(keyboard::Event::KeyPressed {
                    key: keyboard::Key::Character(character_pressed),
                    modified_key,
                    ..
                }) => {
                    let control_s: SmolStr = "s".into();
                    if character_pressed == control_s {
                        // do something serious
                        Task::none()
                    } else {
                        Task::none()
                    }
                }

Where can I find the keymapping for control-s or how should I approach this?

I converted “s”.into Smolstr but that is just for “s”. And I need Control s. Any ideas?

Do I have look at keycodes?
/usr/share/ibus/keymaps

keycode 29 = Control_L
keycode 42 = Shift_L
keycode 54 = Shift_R
keycode 56 = Alt_L
keycode 97 = Control_R
keycode 100 = Alt_R
keycode 125 = Super_L
keycode 126 = Super_R
keycode 127 = Menu

keycode 46 = c addupper

Thank you in advance!
Alex

You match the modifiers separately, using the modifiers field of the KeyPressed event. Putting it all together, it would look like this:

match event {
    iced::Event::Keyboard(iced::keyboard::Event::KeyPressed {
        key: iced::keyboard::Key::Character(c),
        modifiers: iced::keyboard::Modifiers::CONTROL,
        ..
    }) if c == "s" => { // You could test for `c.to_lowercase() == "s"` if you care for both cases
        // Ctrl+s was pressed
    },

@lufte but don’t I first need to listen for Control key, and then listen for s. I want to listen Control + s. Not s and then a modifier key (it also said that Control can’t be a modifier key). :frowning:

Ah, no, you don’t need to keep track of whether the modifier keys were pressed (and not released!) before or not; Iced does that for you and can inform you if they are pressed (through the modifiers field) when another key is pressed.

My example is reacting to a key press of the letter s if, and only if, the Ctrl key is also pressed (with no other modifiers).

I made a mistake in my code though, I used Modifiers::SHIFT when I meant Modifiers::CONTROL. It’s fixed now.

1 Like

I guess I would do this with subscription.

impl App {
    /* Rest of your app logic, view, update etc. */

    pub fn update(&mut self, message: Message) -> Task<Message> {
        match message {
            Message::Save => // Handle your save logic
        }
    }

    // When CTRL + S pressed, fires Message::Save message
    pub fn subscription(&self) -> iced::Subscription<Message> {
       iced::Subscription::batch([iced::keyboard::on_key_press(|k, m| match (k, m) {
            (iced::keyboard::Key::Character('s'), iced::keyboard::Modifiers::CTRL) => {
                Some(Message::Save)
            }
            _ => None,
        })])
    }
}
1 Like

@NandeMD Thanks!!! Will try.

1 Like