Ricky Kresslein

Listening for Keystrokes in Iced

2024-06-23

Recently I was working on an app in Iced (the Rust GUI framework) and I needed to listen for keystrokes to do something when a certain key or key-combination was pressed. It was incredibly difficult to find proper documentation on doing this, so here is how I finally managed it. The listening is done in the subscription function.

fn subscription(&self) -> iced::Subscription<Self::Message> {
	fn handle_hotkey(key: keyboard::Key, _modifiers: keyboard::Modifiers) -> Option<Message> {
			match key.as_ref() {
				keyboard::Key::Character("y") => Some(Message::MessageToCall),
				keyboard::Key::Character("n") => Some(Message::OtherMessageToCall),
				_ => None,
			}
	}

	keyboard::on_key_press(handle_hotkey)
}

If you want to listen for a key with a modifier (as in, the user held control, shift, etc. when pressing the key) you can do the following:

fn subscription(&self) -> iced::Subscription<Self::Message> {
	fn handle_hotkey(key: keyboard::Key, modifiers: keyboard::Modifiers) -> Option<Message> {
		match (key.as_ref(), modifiers) {
			(keyboard::Key::Character("y"), keyboard::Modifiers::SHIFT) => {
				Some(Message::MessageToCall)
			}
				_ => None,
		}
	}

	keyboard::on_key_press(handle_hotkey)
}

If you want to listen for both modified and unmodified keys, here is what I came up with:

fn subscription(&self) -> iced::Subscription<Self::Message> {
	fn handle_hotkey(key: keyboard::Key, modifiers: keyboard::Modifiers) -> Option<Message> {
		if modifiers.is_empty() {
			match key.as_ref() {
				keyboard::Key::Character("y") => Some(Message::MessageToCall),
				keyboard::Key::Character("n") => Some(Message::OtherMessageToCall),
				_ => None,
			}
		} else {
			match (key.as_ref(), modifiers) {
				(keyboard::Key::Character("y"), keyboard::Modifiers::SHIFT) => {
					Some(Message::ModifiedMessageToCall)
				}
				_ => None,
			}
		}
	}

	keyboard::on_key_press(handle_hotkey)
}

That should be all there is to it. I love Iced, but I do hope the documentation improves soon. Shoot me an email if you have any questions.