From d19b8a66e26978ff11f61027a5f96efe22167744 Mon Sep 17 00:00:00 2001 From: jtuomi Date: Tue, 14 Apr 2026 21:18:42 +0300 Subject: [PATCH 1/9] feat: keybindings initial implementation --- src/app/keybind.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++ src/app/mod.rs | 3 +++ 2 files changed, 61 insertions(+) create mode 100644 src/app/keybind.rs diff --git a/src/app/keybind.rs b/src/app/keybind.rs new file mode 100644 index 0000000..ca22d79 --- /dev/null +++ b/src/app/keybind.rs @@ -0,0 +1,58 @@ +use crate::app::ContextPage; +use cosmic::iced::keyboard::Key; +use cosmic::iced::keyboard::key::Named; + +/// **Returns** a subscription to key events mapped similarly as GNOME Camera's for now +pub fn key_subscription(mode: CameraMode) -> Subscription { + cosmic::iced::event::listen_raw(|event, _status, _window| { + let Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) = event else { + return None; + }; + + if modifiers.shift { + return match &key { + n => Some(Message::PrevMode()), + _ => None, + }; + } + + if modifiers.ctrl { + return match &key { + a => Some(Message::CyclePhotoAspectRatio()), + c => Some(Message::ToggleColorPicker()), + f => Some(Message::ToggleFormatPicker()), + q => Some(Message::KeyPressed(Key::Named(Named::Q))), + r => Some(Message::ResetAllSettings()), + t => Some(Message::ToggleTheatherMode()), + Named::Plus => Some(Message::ZoomIn()), + Named::Minus => Some(Message::ZoomOut()), + Named::Enter => Some(Message::StartRecordingAfterDelay()), + Named::Space => Some(Message::AbortPhotoTimer()), + Named::Zero => Some(Message::ResetZoom()), + Named::Comma => Some(Message::ToggleContextPage(ContextPage::Settings)), + _ => None, + }; + } + + match &key { + a => Some(Message::ToggleFocusAuto()), + c => Some(Message::ToggleColorPicker()), + e => Some(Message::ToggleExposurePicker()), + f => Some(Message::ToggleFlash()), + g => Some(Message::OpenGallery()), + n => Some(Message::NextMode()), + m => Some(Message::ToggleRecordAudio()), + p => Some(Message::ToggleMotorPicker()), + q => Some(Message::ToggleQrDetection()), + r => Some(Message::ToggleSaveBurstRaw()), + s => Some(Message::SwitchCamera()), + t => Some(Message::ToggleTimelapse()), + u => Some(Message::TheatreToggleUI()), + v => Some(Message::ToggleVirtualCamera()), + Named::F1 => Some(Message::ToggleContextPage(ContextPage::About)), + Named::Enter => Some(Message::ToggleRecording()), + Named::Space => Some(Message::ToggleVideoPlayPause()), + _ => None, + } + }) +} diff --git a/src/app/mod.rs b/src/app/mod.rs index 87e8097..4a5a387 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -39,6 +39,7 @@ mod gallery_primitive; mod gallery_widget; mod handlers; pub mod insights; +mod keybind; mod motor_picker; pub mod qr_overlay; pub mod settings; @@ -1498,6 +1499,8 @@ impl cosmic::Application for AppModel { Subscription::none() }; + let keybind_sub = key_subscription(self.mode); + Subscription::batch([ config_sub, camera_sub, From b53f2a91591f125ae30b721c00421e5a39efa74f Mon Sep 17 00:00:00 2001 From: jtuomi Date: Wed, 15 Apr 2026 16:53:40 +0300 Subject: [PATCH 2/9] fix: making new changes compile --- src/app/keybind.rs | 83 +++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/src/app/keybind.rs b/src/app/keybind.rs index ca22d79..6646e67 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -9,50 +9,49 @@ pub fn key_subscription(mode: CameraMode) -> Subscription { return None; }; - if modifiers.shift { - return match &key { - n => Some(Message::PrevMode()), - _ => None, - }; - } + match &key { - if modifiers.ctrl { - return match &key { - a => Some(Message::CyclePhotoAspectRatio()), - c => Some(Message::ToggleColorPicker()), - f => Some(Message::ToggleFormatPicker()), - q => Some(Message::KeyPressed(Key::Named(Named::Q))), - r => Some(Message::ResetAllSettings()), - t => Some(Message::ToggleTheatherMode()), - Named::Plus => Some(Message::ZoomIn()), - Named::Minus => Some(Message::ZoomOut()), - Named::Enter => Some(Message::StartRecordingAfterDelay()), - Named::Space => Some(Message::AbortPhotoTimer()), - Named::Zero => Some(Message::ResetZoom()), - Named::Comma => Some(Message::ToggleContextPage(ContextPage::Settings)), - _ => None, - }; - } + Named::Key(Named::F1) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => Some(Message::ToggleContextPage(ContextPage::About)), + Named::Key(Named::Enter) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() && mode == CameraMode::Video => Some(Message::ToggleRecording()), + Named::Key(Named::Enter) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() && mode == CameraMode::Camera => Some(Message::Capture()), + Named::Key(Named::Enter) if modifiers.control() && !modifiers.logo() && !modifiers.alt() => Some(Message::StartRecordingAfterDelay()), - match &key { - a => Some(Message::ToggleFocusAuto()), - c => Some(Message::ToggleColorPicker()), - e => Some(Message::ToggleExposurePicker()), - f => Some(Message::ToggleFlash()), - g => Some(Message::OpenGallery()), - n => Some(Message::NextMode()), - m => Some(Message::ToggleRecordAudio()), - p => Some(Message::ToggleMotorPicker()), - q => Some(Message::ToggleQrDetection()), - r => Some(Message::ToggleSaveBurstRaw()), - s => Some(Message::SwitchCamera()), - t => Some(Message::ToggleTimelapse()), - u => Some(Message::TheatreToggleUI()), - v => Some(Message::ToggleVirtualCamera()), - Named::F1 => Some(Message::ToggleContextPage(ContextPage::About)), - Named::Enter => Some(Message::ToggleRecording()), - Named::Space => Some(Message::ToggleVideoPlayPause()), - _ => None, + Key::Character(c) if modifiers.control() && !modifiers.logo() && !modifiers.alt() => { + match c.as_str() { + "a" => Some(Message::CyclePhotoAspectRatio()), + "f" => Some(Message::ToggleFormatPicker()), + "q" => Some(Message::Noop), + "r" => Some(Message::ResetAllSettings()), + "t" => Some(Message::ToggleTheatherMode()), + "+" => Some(Message::ZoomIn()), + "-" => Some(Message::ZoomOut()), + " " => Some(Message::AbortPhotoTimer()), + "0" => Some(Message::ResetZoom()), + "," => Some(Message::ToggleContextPage(ContextPage::Settings)), + _ => None, + } + } + + Key::Character(c) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() { + match c.as_str() { + "a" => Some(Message::ToggleFocusAuto()), + "c" => Some(Message::ToggleColorPicker()), + "e" => Some(Message::ToggleExposurePicker()), + "f" => Some(Message::ToggleFlash()), + "g" => Some(Message::OpenGallery()), + "n" => Some(Message::NextMode()), + "m" => Some(Message::ToggleRecordAudio()), + "p" => Some(Message::ToggleMotorPicker()), + "q" => Some(Message::ToggleQrDetection()), + "r" => Some(Message::ToggleSaveBurstRaw()), + "s" => Some(Message::SwitchCamera()), + "t" => Some(Message::ToggleTimelapse()), + "u" => Some(Message::TheatreToggleUI()), + "v" => Some(Message::ToggleVirtualCamera()), + " " => Some(Message::ToggleVideoPlayPause()), + _ => None, + } + } } }) } From 6068080cf171ad0208eaadba6ece92b84a2fe7d5 Mon Sep 17 00:00:00 2001 From: jtuomi Date: Wed, 15 Apr 2026 16:54:14 +0300 Subject: [PATCH 3/9] docs: added a doc comment --- src/app/keybind.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/app/keybind.rs b/src/app/keybind.rs index 6646e67..c409efc 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -1,7 +1,42 @@ +// SPDX-License-Identifier: GPL-3.0-only + +use crate::Message; use crate::app::ContextPage; use cosmic::iced::keyboard::Key; use cosmic::iced::keyboard::key::Named; +/// Keybinding are currently hardcoded as follows: +/// +/// //TODO: HashMap for reconfigurable ones +/// +/// F1 => about +/// Enter => take a picture or start/stop recording video +/// Ctrl + Enter => start recording after delay +/// a => toggles auto focus +/// c => toggles color picker +/// e => toggles exposure picker +/// f => toggles flash +/// g => opens gallery +/// n => next mode +/// m => toggle audio recording or mute/unmute +/// p => toggle motor picker +/// q => toggle QR detection +/// r => toggle save burst RAW +/// s => switches camera +/// t => toggles timelapse +/// u => toggles theatre UI +/// v => toggles virtual camera +/// => toggles play/pause +/// Ctrl + a => cycles aspect ratio +/// Ctrl + f => toggles format picker +/// Ctrl + q => currently noop //TODO: close app +/// Ctrl + r => reset settings +/// Ctrl + t => toggles theatre mode +/// Ctrl + + => zoom in +/// Ctrl + - => zoom out +/// Ctrl + 0 => reset zoom +/// Ctrl + , => opens/closes settings +/// /// **Returns** a subscription to key events mapped similarly as GNOME Camera's for now pub fn key_subscription(mode: CameraMode) -> Subscription { cosmic::iced::event::listen_raw(|event, _status, _window| { From 83cb3df2c8727fea07dd173c8896ada9314a91a3 Mon Sep 17 00:00:00 2001 From: jtuomi Date: Wed, 15 Apr 2026 17:04:47 +0300 Subject: [PATCH 4/9] fix: formatting --- src/app/keybind.rs | 62 ++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/app/keybind.rs b/src/app/keybind.rs index c409efc..0e70d6e 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -5,37 +5,39 @@ use crate::app::ContextPage; use cosmic::iced::keyboard::Key; use cosmic::iced::keyboard::key::Named; +//TODO: HashMap for reconfigurable ones + /// Keybinding are currently hardcoded as follows: /// -/// //TODO: HashMap for reconfigurable ones -/// -/// F1 => about -/// Enter => take a picture or start/stop recording video -/// Ctrl + Enter => start recording after delay -/// a => toggles auto focus -/// c => toggles color picker -/// e => toggles exposure picker -/// f => toggles flash -/// g => opens gallery -/// n => next mode -/// m => toggle audio recording or mute/unmute -/// p => toggle motor picker -/// q => toggle QR detection -/// r => toggle save burst RAW -/// s => switches camera -/// t => toggles timelapse -/// u => toggles theatre UI -/// v => toggles virtual camera -/// => toggles play/pause -/// Ctrl + a => cycles aspect ratio -/// Ctrl + f => toggles format picker -/// Ctrl + q => currently noop //TODO: close app -/// Ctrl + r => reset settings -/// Ctrl + t => toggles theatre mode -/// Ctrl + + => zoom in -/// Ctrl + - => zoom out -/// Ctrl + 0 => reset zoom -/// Ctrl + , => opens/closes settings +/// | Character | Binding | +/// |-----------|---------| +/// | F1 | => about | +/// | Enter | => take a picture or start/stop recording | +/// | Ctrl + Enter |=> start recording after delay | +/// | a | => toggles auto focus | +/// | c | => toggles color picker | +/// | e | => toggles exposure picker | +/// | f | => toggles flash | +/// | g | => opens gallery | +/// | n | => next mode | +/// | m | => toggle audio recording or mute/unmute | +/// | p | => toggle motor picker | +/// | q | => toggle QR detection | +/// | r | => toggle save burst RAW | +/// | s | => switches camera | +/// | t | => toggles timelapse | +/// | u | => toggles theatre UI | +/// | v | => toggles virtual camera | +/// | | => toggles play/pause | +/// | Ctrl + a | => cycles aspect ratio | +/// | Ctrl + f | => toggles format picker | +/// | Ctrl + q | => currently noop //TODO: close app | +/// | Ctrl + r | => reset settings | +/// | Ctrl + t | => toggles theatre mode | +/// | Ctrl + + | => zoom in | +/// | Ctrl + - | => zoom out | +/// | Ctrl + 0 | => reset zoom | +/// | Ctrl + , | => opens/closes settings | /// /// **Returns** a subscription to key events mapped similarly as GNOME Camera's for now pub fn key_subscription(mode: CameraMode) -> Subscription { @@ -86,7 +88,7 @@ pub fn key_subscription(mode: CameraMode) -> Subscription { " " => Some(Message::ToggleVideoPlayPause()), _ => None, } - } + } } }) } From 524439782cab6c687511fcd05934848a1453c857 Mon Sep 17 00:00:00 2001 From: jtuomi Date: Wed, 15 Apr 2026 17:33:21 +0300 Subject: [PATCH 5/9] fix: missing fat arrow --- src/app/keybind.rs | 99 ++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/src/app/keybind.rs b/src/app/keybind.rs index 0e70d6e..ba13f62 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -47,48 +47,69 @@ pub fn key_subscription(mode: CameraMode) -> Subscription { }; match &key { - - Named::Key(Named::F1) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => Some(Message::ToggleContextPage(ContextPage::About)), - Named::Key(Named::Enter) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() && mode == CameraMode::Video => Some(Message::ToggleRecording()), - Named::Key(Named::Enter) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() && mode == CameraMode::Camera => Some(Message::Capture()), - Named::Key(Named::Enter) if modifiers.control() && !modifiers.logo() && !modifiers.alt() => Some(Message::StartRecordingAfterDelay()), + Named::Key(Named::F1) + if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => + { + Some(Message::ToggleContextPage(ContextPage::About)) + } + Named::Key(Named::Enter) + if !modifiers.control() + && !modifiers.logo() + && !modifiers.alt() + && mode == CameraMode::Video => + { + Some(Message::ToggleRecording()) + } + Named::Key(Named::Enter) + if !modifiers.control() + && !modifiers.logo() + && !modifiers.alt() + && mode == CameraMode::Camera => + { + Some(Message::Capture()) + } + Named::Key(Named::Enter) + if modifiers.control() && !modifiers.logo() && !modifiers.alt() => + { + Some(Message::StartRecordingAfterDelay()) + } Key::Character(c) if modifiers.control() && !modifiers.logo() && !modifiers.alt() => { - match c.as_str() { - "a" => Some(Message::CyclePhotoAspectRatio()), - "f" => Some(Message::ToggleFormatPicker()), - "q" => Some(Message::Noop), - "r" => Some(Message::ResetAllSettings()), - "t" => Some(Message::ToggleTheatherMode()), - "+" => Some(Message::ZoomIn()), - "-" => Some(Message::ZoomOut()), - " " => Some(Message::AbortPhotoTimer()), - "0" => Some(Message::ResetZoom()), - "," => Some(Message::ToggleContextPage(ContextPage::Settings)), - _ => None, - } - } + match c.as_str() { + "a" => Some(Message::CyclePhotoAspectRatio()), + "f" => Some(Message::ToggleFormatPicker()), + "q" => Some(Message::Noop), + "r" => Some(Message::ResetAllSettings()), + "t" => Some(Message::ToggleTheatherMode()), + "+" => Some(Message::ZoomIn()), + "-" => Some(Message::ZoomOut()), + " " => Some(Message::AbortPhotoTimer()), + "0" => Some(Message::ResetZoom()), + "," => Some(Message::ToggleContextPage(ContextPage::Settings)), + _ => None, + } + } - Key::Character(c) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() { - match c.as_str() { - "a" => Some(Message::ToggleFocusAuto()), - "c" => Some(Message::ToggleColorPicker()), - "e" => Some(Message::ToggleExposurePicker()), - "f" => Some(Message::ToggleFlash()), - "g" => Some(Message::OpenGallery()), - "n" => Some(Message::NextMode()), - "m" => Some(Message::ToggleRecordAudio()), - "p" => Some(Message::ToggleMotorPicker()), - "q" => Some(Message::ToggleQrDetection()), - "r" => Some(Message::ToggleSaveBurstRaw()), - "s" => Some(Message::SwitchCamera()), - "t" => Some(Message::ToggleTimelapse()), - "u" => Some(Message::TheatreToggleUI()), - "v" => Some(Message::ToggleVirtualCamera()), - " " => Some(Message::ToggleVideoPlayPause()), - _ => None, - } - } + Key::Character(c) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => { + match c.as_str() { + "a" => Some(Message::ToggleFocusAuto()), + "c" => Some(Message::ToggleColorPicker()), + "e" => Some(Message::ToggleExposurePicker()), + "f" => Some(Message::ToggleFlash()), + "g" => Some(Message::OpenGallery()), + "n" => Some(Message::NextMode()), + "m" => Some(Message::ToggleRecordAudio()), + "p" => Some(Message::ToggleMotorPicker()), + "q" => Some(Message::ToggleQrDetection()), + "r" => Some(Message::ToggleSaveBurstRaw()), + "s" => Some(Message::SwitchCamera()), + "t" => Some(Message::ToggleTimelapse()), + "u" => Some(Message::TheatreToggleUI()), + "v" => Some(Message::ToggleVirtualCamera()), + " " => Some(Message::ToggleVideoPlayPause()), + _ => None, + } + } } }) } From 24ae8403c02d29c4a2b15c533ce066e781c5c796 Mon Sep 17 00:00:00 2001 From: jtuomi Date: Wed, 15 Apr 2026 20:33:40 +0300 Subject: [PATCH 6/9] fix: compiler errors --- src/app/keybind.rs | 135 +++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 66 deletions(-) diff --git a/src/app/keybind.rs b/src/app/keybind.rs index ba13f62..1a6c518 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -11,37 +11,41 @@ use cosmic::iced::keyboard::key::Named; /// /// | Character | Binding | /// |-----------|---------| -/// | F1 | => about | -/// | Enter | => take a picture or start/stop recording | +/// | F1 | => about | +/// | Enter | => take a picture or start/stop recording | +/// | a | => toggles auto focus | +/// | c | => toggles color picker | +/// | e | => toggles exposure picker | +/// | f | => toggles flash | +/// | g | => opens gallery | +/// | n | => next mode | +/// | m | => toggle audio recording or mute/unmute | +/// | p | => toggle motor picker | +/// | q | => toggle QR detection | +/// | r | => toggle save burst RAW | +/// | s | => switches camera | +/// | t | => toggles timelapse | +/// | u | => toggles theatre UI | +/// | v | => toggles virtual camera | +/// | | => toggles play/pause | +/// | Ctrl + a | => cycles aspect ratio | +/// | Ctrl + f | => toggles format picker | +/// | Ctrl + q | => currently noop //TODO: close app | +/// | Ctrl + r | => reset settings | +/// | Ctrl + t | => toggles theatre mode | +/// | Ctrl + + | => zoom in | +/// | Ctrl + - | => zoom out | +/// | Ctrl + 0 | => reset zoom | +/// | Ctrl + , | => opens/closes settings | /// | Ctrl + Enter |=> start recording after delay | -/// | a | => toggles auto focus | -/// | c | => toggles color picker | -/// | e | => toggles exposure picker | -/// | f | => toggles flash | -/// | g | => opens gallery | -/// | n | => next mode | -/// | m | => toggle audio recording or mute/unmute | -/// | p | => toggle motor picker | -/// | q | => toggle QR detection | -/// | r | => toggle save burst RAW | -/// | s | => switches camera | -/// | t | => toggles timelapse | -/// | u | => toggles theatre UI | -/// | v | => toggles virtual camera | -/// | | => toggles play/pause | -/// | Ctrl + a | => cycles aspect ratio | -/// | Ctrl + f | => toggles format picker | -/// | Ctrl + q | => currently noop //TODO: close app | -/// | Ctrl + r | => reset settings | -/// | Ctrl + t | => toggles theatre mode | -/// | Ctrl + + | => zoom in | -/// | Ctrl + - | => zoom out | -/// | Ctrl + 0 | => reset zoom | -/// | Ctrl + , | => opens/closes settings | /// /// **Returns** a subscription to key events mapped similarly as GNOME Camera's for now -pub fn key_subscription(mode: CameraMode) -> Subscription { - cosmic::iced::event::listen_raw(|event, _status, _window| { +pub fn key_subscription() -> Subscription { + fn event_to_functionality( + event: cosmic::iced::Event, + _status: cosmic::iced::event::Status, + _window: cosmic::iced::window::Id, + ) -> Option { let Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) = event else { return None; }; @@ -52,39 +56,37 @@ pub fn key_subscription(mode: CameraMode) -> Subscription { { Some(Message::ToggleContextPage(ContextPage::About)) } + // TODO: couldn't capture mode, need to think about it + // Named::Key(Named::Enter) + // if !modifiers.control() + // && !modifiers.logo() + // && !modifiers.alt() + // => + // { + // Some(Message::ToggleRecording()) + // } Named::Key(Named::Enter) - if !modifiers.control() - && !modifiers.logo() - && !modifiers.alt() - && mode == CameraMode::Video => - { - Some(Message::ToggleRecording()) - } - Named::Key(Named::Enter) - if !modifiers.control() - && !modifiers.logo() - && !modifiers.alt() - && mode == CameraMode::Camera => + if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => { - Some(Message::Capture()) + Some(Message::Capture) } Named::Key(Named::Enter) if modifiers.control() && !modifiers.logo() && !modifiers.alt() => { - Some(Message::StartRecordingAfterDelay()) + Some(Message::StartRecordingAfterDelay) } Key::Character(c) if modifiers.control() && !modifiers.logo() && !modifiers.alt() => { match c.as_str() { - "a" => Some(Message::CyclePhotoAspectRatio()), - "f" => Some(Message::ToggleFormatPicker()), + "a" => Some(Message::CyclePhotoAspectRatio), + "f" => Some(Message::ToggleFormatPicker), "q" => Some(Message::Noop), - "r" => Some(Message::ResetAllSettings()), - "t" => Some(Message::ToggleTheatherMode()), - "+" => Some(Message::ZoomIn()), - "-" => Some(Message::ZoomOut()), - " " => Some(Message::AbortPhotoTimer()), - "0" => Some(Message::ResetZoom()), + "r" => Some(Message::ResetAllSettings), + "t" => Some(Message::ToggleTheatherMode), + "+" => Some(Message::ZoomIn), + "-" => Some(Message::ZoomOut), + " " => Some(Message::AbortPhotoTimer), + "0" => Some(Message::ResetZoom), "," => Some(Message::ToggleContextPage(ContextPage::Settings)), _ => None, } @@ -92,24 +94,25 @@ pub fn key_subscription(mode: CameraMode) -> Subscription { Key::Character(c) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => { match c.as_str() { - "a" => Some(Message::ToggleFocusAuto()), - "c" => Some(Message::ToggleColorPicker()), - "e" => Some(Message::ToggleExposurePicker()), - "f" => Some(Message::ToggleFlash()), - "g" => Some(Message::OpenGallery()), - "n" => Some(Message::NextMode()), - "m" => Some(Message::ToggleRecordAudio()), - "p" => Some(Message::ToggleMotorPicker()), - "q" => Some(Message::ToggleQrDetection()), - "r" => Some(Message::ToggleSaveBurstRaw()), - "s" => Some(Message::SwitchCamera()), - "t" => Some(Message::ToggleTimelapse()), - "u" => Some(Message::TheatreToggleUI()), - "v" => Some(Message::ToggleVirtualCamera()), - " " => Some(Message::ToggleVideoPlayPause()), + "a" => Some(Message::ToggleFocusAuto), + "c" => Some(Message::ToggleColorPicker), + "e" => Some(Message::ToggleExposurePicker), + "f" => Some(Message::ToggleFlash), + "g" => Some(Message::OpenGallery), + "n" => Some(Message::NextMode), + "m" => Some(Message::ToggleRecordAudio), + "p" => Some(Message::ToggleMotorPicker), + "q" => Some(Message::ToggleQrDetection), + "r" => Some(Message::ToggleSaveBurstRaw), + "s" => Some(Message::SwitchCamera), + "t" => Some(Message::ToggleTimelapse), + "u" => Some(Message::TheatreToggleUI), + "v" => Some(Message::ToggleVirtualCamera), + " " => Some(Message::ToggleVideoPlayPause), _ => None, } } } - }) + } + cosmic::iced::event::listen_raw(event_to_functionality) } From 6fc4af92fab1d4110cf66feed7b38d6d375b35dc Mon Sep 17 00:00:00 2001 From: jtuomi Date: Wed, 15 Apr 2026 21:56:24 +0300 Subject: [PATCH 7/9] fix: return an enum and added keybind_sub to subs --- src/app/keybind.rs | 14 ++++---------- src/app/mod.rs | 3 ++- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/app/keybind.rs b/src/app/keybind.rs index 1a6c518..58cea71 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only -use crate::Message; use crate::app::ContextPage; +use crate::{Message, Subscription}; +use cosmic::iced::Event; use cosmic::iced::keyboard::Key; use cosmic::iced::keyboard::key::Named; @@ -56,15 +57,8 @@ pub fn key_subscription() -> Subscription { { Some(Message::ToggleContextPage(ContextPage::About)) } + // TODO: couldn't capture mode, need to think about it - // Named::Key(Named::Enter) - // if !modifiers.control() - // && !modifiers.logo() - // && !modifiers.alt() - // => - // { - // Some(Message::ToggleRecording()) - // } Named::Key(Named::Enter) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => { @@ -82,7 +76,7 @@ pub fn key_subscription() -> Subscription { "f" => Some(Message::ToggleFormatPicker), "q" => Some(Message::Noop), "r" => Some(Message::ResetAllSettings), - "t" => Some(Message::ToggleTheatherMode), + "t" => Some(Message::ToggleTheatreMode), "+" => Some(Message::ZoomIn), "-" => Some(Message::ZoomOut), " " => Some(Message::AbortPhotoTimer), diff --git a/src/app/mod.rs b/src/app/mod.rs index 4a5a387..15634da 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1499,7 +1499,7 @@ impl cosmic::Application for AppModel { Subscription::none() }; - let keybind_sub = key_subscription(self.mode); + let keybind_sub = key_subscription(); Subscription::batch([ config_sub, @@ -1513,6 +1513,7 @@ impl cosmic::Application for AppModel { brightness_eval_sub, insights_update_sub, portal_theme_sub, + keybind_sub, ]) } From 61d1c210090a0907184985fe9042b40fa2d60b2c Mon Sep 17 00:00:00 2001 From: jtuomi Date: Wed, 15 Apr 2026 22:11:27 +0300 Subject: [PATCH 8/9] fix: Key::Named not Named::Key import key_subcription --- src/app/keybind.rs | 10 +++++----- src/app/mod.rs | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/app/keybind.rs b/src/app/keybind.rs index 58cea71..11c0c83 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -43,28 +43,28 @@ use cosmic::iced::keyboard::key::Named; /// **Returns** a subscription to key events mapped similarly as GNOME Camera's for now pub fn key_subscription() -> Subscription { fn event_to_functionality( - event: cosmic::iced::Event, + event: Event, _status: cosmic::iced::event::Status, _window: cosmic::iced::window::Id, ) -> Option { - let Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) = event else { + let Event::Keyboard(Event::KeyPressed { key, modifiers, .. }) = event else { return None; }; match &key { - Named::Key(Named::F1) + Key::Named(Named::F1) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => { Some(Message::ToggleContextPage(ContextPage::About)) } // TODO: couldn't capture mode, need to think about it - Named::Key(Named::Enter) + Key::Named(Named::Enter) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => { Some(Message::Capture) } - Named::Key(Named::Enter) + Key::Named(Named::Enter) if modifiers.control() && !modifiers.logo() && !modifiers.alt() => { Some(Message::StartRecordingAfterDelay) diff --git a/src/app/mod.rs b/src/app/mod.rs index 15634da..03b2e8b 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -52,6 +52,7 @@ mod video_widget; mod view; // Re-export public API +use crate::app::keybind::key_subscription; use crate::config::Config; use crate::fl; use cosmic::app::context_drawer; From faa4050d1ab063cf57334d5f1ec5bc3608049fc2 Mon Sep 17 00:00:00 2001 From: jtuomi Date: Wed, 15 Apr 2026 22:22:06 +0300 Subject: [PATCH 9/9] fix: imports and _ in top level match --- src/app/keybind.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/app/keybind.rs b/src/app/keybind.rs index 11c0c83..2dbd950 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only -use crate::app::ContextPage; -use crate::{Message, Subscription}; +use crate::Message; +use crate::app::{ContextPage, Subscription}; use cosmic::iced::Event; +use cosmic::iced::keyboard; use cosmic::iced::keyboard::Key; use cosmic::iced::keyboard::key::Named; @@ -43,11 +44,11 @@ use cosmic::iced::keyboard::key::Named; /// **Returns** a subscription to key events mapped similarly as GNOME Camera's for now pub fn key_subscription() -> Subscription { fn event_to_functionality( - event: Event, + event: cosmic::iced::Event, _status: cosmic::iced::event::Status, _window: cosmic::iced::window::Id, ) -> Option { - let Event::Keyboard(Event::KeyPressed { key, modifiers, .. }) = event else { + let Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) = event else { return None; }; @@ -106,6 +107,7 @@ pub fn key_subscription() -> Subscription { _ => None, } } + _ => None, } } cosmic::iced::event::listen_raw(event_to_functionality)