feat(keyboard): add numlock configuration

This commit is contained in:
Paul Daniel Faria 2025-02-17 08:29:54 -08:00 • committed by Michael Murphy
parent b2101e41a8
commit 8c87db2235
2 changed files with 81 additions and 1 deletions

View file

@ -13,7 +13,7 @@ use cosmic::{
widget::{self, button, container, icon, radio, row, settings, ListColumn}, widget::{self, button, container, icon, radio, row, settings, ListColumn},
Apply, Element, Task, Apply, Element, Task,
}; };
use cosmic_comp_config::XkbConfig; use cosmic_comp_config::{KeyboardConfig, NumlockState, XkbConfig};
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use itertools::Itertools; use itertools::Itertools;
use slab::Slab; use slab::Slab;
@ -58,6 +58,7 @@ pub enum Message {
ExpandInputSourcePopover(Option<DefaultKey>), ExpandInputSourcePopover(Option<DefaultKey>),
InputSourceSearch(String), InputSourceSearch(String),
OpenSpecialCharacterContext(SpecialKey), OpenSpecialCharacterContext(SpecialKey),
OpenNumlockContext,
ShowInputSourcesContext, ShowInputSourcesContext,
SourceAdd(DefaultKey), SourceAdd(DefaultKey),
SourceContext(SourceContext), SourceContext(SourceContext),
@ -65,6 +66,7 @@ pub enum Message {
SetRepeatKeysDelay(u32), SetRepeatKeysDelay(u32),
SetRepeatKeysRate(u32), SetRepeatKeysRate(u32),
SetShowExtendedInputSources(bool), SetShowExtendedInputSources(bool),
SetNumlockState(NumlockState),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -102,6 +104,7 @@ pub struct Page {
context: Option<Context>, context: Option<Context>,
input_source_search: String, input_source_search: String,
xkb: XkbConfig, xkb: XkbConfig,
keyboard_config: KeyboardConfig,
keyboard_layouts: SlotMap<DefaultKey, (Locale, Variant, Description, LayoutSource)>, keyboard_layouts: SlotMap<DefaultKey, (Locale, Variant, Description, LayoutSource)>,
active_layouts: Vec<DefaultKey>, active_layouts: Vec<DefaultKey>,
expanded_source_popover: Option<DefaultKey>, expanded_source_popover: Option<DefaultKey>,
@ -120,6 +123,7 @@ impl Default for Page {
keyboard_layouts: SlotMap::new(), keyboard_layouts: SlotMap::new(),
active_layouts: Vec::new(), active_layouts: Vec::new(),
xkb: XkbConfig::default(), xkb: XkbConfig::default(),
keyboard_config: KeyboardConfig::default(),
input_source_search: String::new(), input_source_search: String::new(),
show_extended_input_sources: false, show_extended_input_sources: false,
config, config,
@ -130,6 +134,7 @@ impl Default for Page {
enum Context { enum Context {
ShowInputSourcesContext, ShowInputSourcesContext,
SpecialCharacter(SpecialKey), SpecialCharacter(SpecialKey),
NumlockState,
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -279,6 +284,7 @@ impl page::Page<crate::pages::Message> for Page {
sections.insert(special_character_entry()), sections.insert(special_character_entry()),
sections.insert(keyboard_shortcuts()), sections.insert(keyboard_shortcuts()),
sections.insert(keyboard_typing_assist()), sections.insert(keyboard_typing_assist()),
sections.insert(keyboard_num_lock()),
]) ])
} }
@ -295,6 +301,10 @@ impl page::Page<crate::pages::Message> for Page {
.special_character_key_view(special_key) .special_character_key_view(special_key)
.map(crate::pages::Message::Keyboard) .map(crate::pages::Message::Keyboard)
.apply(Some), .apply(Some),
Some(Context::NumlockState) => self
.numlock_state_view()
.map(crate::pages::Message::Keyboard)
.apply(Some),
None => None, None => None,
} }
@ -302,6 +312,7 @@ impl page::Page<crate::pages::Message> for Page {
fn on_enter(&mut self) -> Task<crate::pages::Message> { fn on_enter(&mut self) -> Task<crate::pages::Message> {
self.xkb = super::get_config(&self.config, "xkb_config"); self.xkb = super::get_config(&self.config, "xkb_config");
self.keyboard_config = super::get_config(&self.config, "keyboard_config");
match ( match (
xkb_data::keyboard_layouts(), xkb_data::keyboard_layouts(),
xkb_data::extra_keyboard_layouts(), xkb_data::extra_keyboard_layouts(),
@ -490,6 +501,14 @@ impl Page {
)); ));
} }
Message::OpenNumlockContext => {
self.context = Some(Context::NumlockState);
return cosmic::task::message(crate::app::Message::OpenContextDrawer(
self.entity,
fl!("keyboard-numlock-boot", "set").into(),
));
}
Message::SpecialCharacterSelect(id) => { Message::SpecialCharacterSelect(id) => {
if let Some(Context::SpecialCharacter(special_key)) = self.context { if let Some(Context::SpecialCharacter(special_key)) = self.context {
let options = self.xkb.options.as_deref().unwrap_or_default(); let options = self.xkb.options.as_deref().unwrap_or_default();
@ -518,6 +537,12 @@ impl Page {
Message::SetShowExtendedInputSources(value) => { Message::SetShowExtendedInputSources(value) => {
self.show_extended_input_sources = value; self.show_extended_input_sources = value;
} }
Message::SetNumlockState(numlock_state) => {
self.keyboard_config.numlock_state = numlock_state;
if let Err(err) = self.config.set("keyboard_config", &self.keyboard_config) {
tracing::error!(?err, "Failed to set config 'keyboard_config'");
}
}
} }
Task::none() Task::none()
@ -613,6 +638,32 @@ impl Page {
cosmic::widget::container(list).padding(24).into() cosmic::widget::container(list).padding(24).into()
} }
fn numlock_state_view(&self) -> cosmic::Element<'_, Message> {
let current = self.keyboard_config.numlock_state;
let options = [
(fl!("keyboard-numlock-boot", "off"), NumlockState::BootOff),
(fl!("keyboard-numlock-boot", "on"), NumlockState::BootOn),
(
fl!("keyboard-numlock-boot", "last-boot"),
NumlockState::LastBoot,
),
];
let mut list = cosmic::widget::list_column();
for (desc, state) in options {
list = list.add(settings::item_row(vec![radio(
cosmic::widget::text(desc),
Some(state),
Some(Some(current)),
|_| Message::SetNumlockState(state),
)
.width(Length::Fill)
.into()]));
}
cosmic::widget::container(list).padding(24).into()
}
fn update_xkb_config(&mut self) { fn update_xkb_config(&mut self) {
let result = update_xkb_config( let result = update_xkb_config(
&self.config, &self.config,
@ -792,6 +843,28 @@ fn keyboard_typing_assist() -> Section<crate::pages::Message> {
}) })
} }
fn keyboard_num_lock() -> Section<crate::pages::Message> {
let mut descriptions = Slab::new();
let boot_state = descriptions.insert(fl!("keyboard-numlock-boot", "boot-state"));
Section::default()
.title(fl!("keyboard-numlock-boot"))
.descriptions(descriptions)
.view::<Page>(move |_binder, _page, section| {
let descriptions = &section.descriptions;
settings::section()
.title(&section.title)
.add(crate::widget::go_next_item(
&descriptions[boot_state],
Message::OpenNumlockContext,
))
.apply(cosmic::Element::from)
.map(crate::pages::Message::Keyboard)
})
}
fn update_xkb_config( fn update_xkb_config(
config: &cosmic_config::Config, config: &cosmic_config::Config,
xkb: &mut XkbConfig, xkb: &mut XkbConfig,

View file

@ -550,6 +550,13 @@ keyboard-typing-assist = Typing
.repeat-rate = Repeat rate .repeat-rate = Repeat rate
.repeat-delay = Repeat delay .repeat-delay = Repeat delay
keyboard-numlock-boot = Numlock
.boot-state = State on boot
.last-boot = Last boot
.on = On
.off = Off
.set = Set numlock boot state
added = Added added = Added
type-to-search = Type to search... type-to-search = Type to search...
show-extended-input-sources = Show extended input sources show-extended-input-sources = Show extended input sources