diff --git a/cosmic-settings/src/app.rs b/cosmic-settings/src/app.rs index 5125824..f32f011 100644 --- a/cosmic-settings/src/app.rs +++ b/cosmic-settings/src/app.rs @@ -384,19 +384,27 @@ impl cosmic::Application for SettingsApp { return page.update(message).map(Into::into); } } - #[cfg(feature = "page-accessibility")] - crate::pages::Message::AccessibilityMagnifier(message) => { - if let Some(page) = self.pages.page_mut::() { - return page.update(self.active_page, message).map(Into::into); - } - } #[cfg(feature = "page-about")] crate::pages::Message::About(message) => { if let Some(page) = self.pages.page_mut::() { return page.update(message).map(Into::into); } } - + #[cfg(feature = "page-accessibility")] + crate::pages::Message::AccessibilityMagnifier(message) => { + if let Some(page) = self.pages.page_mut::() { + return page.update(self.active_page, message).map(Into::into); + } + } + #[cfg(feature = "page-input")] + crate::pages::Message::AccessibilityShortcuts(message) => { + if let Some(page) = self + .pages + .page_mut::() + { + return page.update(message).map(Into::into); + } + } crate::pages::Message::Appearance(message) => { if let Some(page) = self.pages.page_mut::() { return page.update(message).map(Into::into); diff --git a/cosmic-settings/src/pages/input/keyboard/shortcuts/accessibility.rs b/cosmic-settings/src/pages/input/keyboard/shortcuts/accessibility.rs new file mode 100644 index 0000000..a00fc48 --- /dev/null +++ b/cosmic-settings/src/pages/input/keyboard/shortcuts/accessibility.rs @@ -0,0 +1,113 @@ +// Copyright 2024 System76 +// SPDX-License-Identifier: GPL-3.0-only + +use super::{ShortcutMessage, ShortcutModel}; +use cosmic::app::ContextDrawer; +use cosmic::{Element, Task}; +use cosmic_settings_config::shortcuts::Action; +use cosmic_settings_page::{self as page, Section, section}; +use slab::Slab; + +pub struct Page { + model: super::Model, +} + +impl Default for Page { + fn default() -> Self { + Self { + model: super::Model::default().actions(|defaults, keybindings| { + actions().iter().fold(Slab::new(), |mut slab, action| { + slab.insert(ShortcutModel::new(defaults, keybindings, action.clone())); + slab + }) + }), + } + } +} + +impl Page { + pub fn update(&mut self, message: ShortcutMessage) -> Task { + self.model.update(message) + } +} + +impl page::Page for Page { + fn set_id(&mut self, entity: page::Entity) { + self.model.entity = entity; + } + + fn info(&self) -> page::Info { + page::Info::new("accessibility-shortcuts", "input-keyboard-symbolic") + .title(fl!("accessibility")) + } + + fn content( + &self, + sections: &mut slotmap::SlotMap>, + ) -> Option { + Some(vec![sections.insert(shortcuts())]) + } + + fn context_drawer(&self) -> Option> { + self.model + .context_drawer(crate::pages::Message::AccessibilityShortcuts) + } + + fn dialog(&self) -> Option> { + self.model + .dialog() + .map(|el| el.map(crate::pages::Message::AccessibilityShortcuts)) + } + + fn on_context_drawer_close(&mut self) -> Task { + self.model.on_context_drawer_close(); + Task::none() + } + + fn on_enter(&mut self) -> Task { + _ = self.model.on_enter(); + Task::none() + } + + fn on_leave(&mut self) -> Task { + self.model.on_clear(); + cosmic::iced_winit::platform_specific::commands::keyboard_shortcuts_inhibit::inhibit_shortcuts( + false, + ) + .discard() + } + + #[cfg(feature = "wayland")] + fn subscription( + &self, + core: &cosmic::Core, + ) -> cosmic::iced::Subscription { + self.model + .subscription(core) + .map(crate::pages::Message::AccessibilityShortcuts) + } +} + +impl page::AutoBind for Page {} + +#[must_use] +pub const fn actions() -> &'static [Action] { + &[Action::ZoomIn, Action::ZoomOut] +} + +fn shortcuts() -> Section { + let mut descriptions = Slab::new(); + + // Make these searchable in the global settings search. + for action in actions() { + descriptions.insert(super::localize_action(action)); + } + + Section::default() + .descriptions(descriptions) + .view::(move |_binder, page, _section| { + page.model + .view() + .map(crate::pages::Message::AccessibilityShortcuts) + }) +} diff --git a/cosmic-settings/src/pages/input/keyboard/shortcuts/mod.rs b/cosmic-settings/src/pages/input/keyboard/shortcuts/mod.rs index 8e913a8..a0acb37 100644 --- a/cosmic-settings/src/pages/input/keyboard/shortcuts/mod.rs +++ b/cosmic-settings/src/pages/input/keyboard/shortcuts/mod.rs @@ -5,6 +5,7 @@ mod common; pub use common::{Model, ShortcutBinding, ShortcutMessage, ShortcutModel}; +pub mod accessibility; pub mod custom; pub mod manage_windows; pub mod move_window; @@ -42,6 +43,7 @@ pub struct Page { #[derive(Default)] struct Modified { + accessibility: u16, manage_windows: u16, move_windows: u16, nav: u16, @@ -51,6 +53,7 @@ struct Modified { } struct SubPages { + accessibility: page::Entity, custom: page::Entity, manage_window: page::Entity, move_window: page::Entity, @@ -77,6 +80,7 @@ pub enum Message { #[derive(Clone, Copy, Debug)] pub enum Category { + Accessibility, Custom, ManageWindow, MoveWindow, @@ -94,6 +98,7 @@ impl Default for Page { search_model: Model::default(), shortcuts_context: None, sub_pages: SubPages { + accessibility: page::Entity::null(), custom: page::Entity::null(), manage_window: page::Entity::null(), move_window: page::Entity::null(), @@ -174,6 +179,10 @@ impl Page { pub fn update(&mut self, message: Message) -> Task { match message { Message::Category(category) => match category { + Category::Accessibility => { + cosmic::task::message(crate::app::Message::Page(self.sub_pages.accessibility)) + } + Category::Custom => { cosmic::task::message(crate::app::Message::Page(self.sub_pages.custom)) } @@ -240,6 +249,7 @@ impl Page { } match action_category(custom_action) { + Some(Category::Accessibility) => self.modified.accessibility += 1, Some(Category::ManageWindow) => self.modified.manage_windows += 1, Some(Category::MoveWindow) => self.modified.move_windows += 1, Some(Category::Nav) => self.modified.nav += 1, @@ -261,6 +271,7 @@ impl Page { }; match action_category(action) { + Some(Category::Accessibility) => self.modified.accessibility += 1, Some(Category::ManageWindow) => self.modified.manage_windows += 1, Some(Category::MoveWindow) => self.modified.move_windows += 1, Some(Category::Nav) => self.modified.nav += 1, @@ -297,6 +308,7 @@ impl page::AutoBind for Page { fn sub_pages( mut page: cosmic_settings_page::Insert, ) -> cosmic_settings_page::Insert { + let accessibility = page.sub_page_with_id::(); let custom = page.sub_page_with_id::(); let manage_window = page.sub_page_with_id::(); let move_window = page.sub_page_with_id::(); @@ -305,6 +317,7 @@ impl page::AutoBind for Page { let window_tiling = page.sub_page_with_id::(); let model = page.model.page_mut::().unwrap(); + model.sub_pages.accessibility = accessibility; model.sub_pages.custom = custom; model.sub_pages.manage_window = manage_window; model.sub_pages.move_window = move_window; @@ -407,6 +420,7 @@ impl Search { fn shortcuts() -> Section { let mut descriptions = Slab::new(); + let accessibility = descriptions.insert(fl!("accessibility")); let custom_label = descriptions.insert(fl!("custom")); let manage_window_label = descriptions.insert(fl!("manage-windows")); let move_window_label = descriptions.insert(fl!("move-windows")); @@ -430,6 +444,11 @@ fn shortcuts() -> Section { // If the search input is not empty, show the category view, else the search results. let content = if page.search.input.is_empty() { settings::section() + .add(category_item( + Category::Accessibility, + &descriptions[accessibility], + page.modified.accessibility, + )) .add(category_item( Category::ManageWindow, &descriptions[manage_window_label], diff --git a/cosmic-settings/src/pages/mod.rs b/cosmic-settings/src/pages/mod.rs index fb27621..b453932 100644 --- a/cosmic-settings/src/pages/mod.rs +++ b/cosmic-settings/src/pages/mod.rs @@ -31,6 +31,8 @@ pub enum Message { Accessibility(accessibility::Message), #[cfg(feature = "page-accessibility")] AccessibilityMagnifier(accessibility::magnifier::Message), + #[cfg(feature = "page-input")] + AccessibilityShortcuts(input::keyboard::shortcuts::ShortcutMessage), #[cfg(feature = "page-about")] About(system::about::Message), Appearance(desktop::appearance::Message),