fix: use more permissive denylist for bare shortcut key validation
This commit is contained in:
parent
98fc3d5952
commit
18ff4d01de
3 changed files with 414 additions and 496 deletions
856
Cargo.lock
generated
856
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -29,6 +29,7 @@ pub enum ShortcutMessage {
|
|||
ResetBindings,
|
||||
ShowShortcut(usize, String),
|
||||
SubmitBinding(usize),
|
||||
TabPressed,
|
||||
Inhibited(bool),
|
||||
ProtocolUnavailable,
|
||||
ModifiersChanged(Modifiers),
|
||||
|
|
@ -545,6 +546,23 @@ impl Model {
|
|||
shortcut.input = shortcut.pending.to_string();
|
||||
}
|
||||
}
|
||||
// libcosmic requires we set on_tab() and manually process here
|
||||
// otherwise it'll consume the tab key event for navigation
|
||||
ShortcutMessage::TabPressed => {
|
||||
if let Some((short_id, id)) = self.shortcut_context.zip(self.editing)
|
||||
&& let Some(model) = self.shortcut_models.get_mut(short_id)
|
||||
&& let Some(shortcut) = model.bindings.get_mut(id)
|
||||
{
|
||||
shortcut.pending.key = Some(xkeysym::Keysym::Tab);
|
||||
shortcut.pending.keycode = None;
|
||||
shortcut.input = shortcut.pending.to_string();
|
||||
return Task::batch(vec![
|
||||
iced_winit::platform_specific::commands::keyboard_shortcuts_inhibit::inhibit_shortcuts(false).discard(),
|
||||
self.submit_binding(id),
|
||||
cosmic::widget::text_input::focus(self.add_keybindings_button_id.clone()),
|
||||
]);
|
||||
}
|
||||
}
|
||||
ShortcutMessage::KeyReleased(keycode, _, _) => {
|
||||
if let Some((short_id, id)) = self.shortcut_context.zip(self.editing)
|
||||
&& let Some(model) = self.shortcut_models.get_mut(short_id)
|
||||
|
|
@ -557,8 +575,9 @@ impl Model {
|
|||
if shortcut.pending.modifiers
|
||||
!= cosmic_settings_config::shortcuts::Modifiers::new()
|
||||
|| shortcut.pending.key.is_some_and(|key| {
|
||||
key.is_misc_function_key()
|
||||
|| matches!(key.raw(), 0x10080001..=0x1008FFFF)
|
||||
!cosmic_settings_config::shortcuts::is_forbidden_unmodified_keysym(
|
||||
key,
|
||||
)
|
||||
})
|
||||
{
|
||||
shortcut.input = shortcut.pending.to_string();
|
||||
|
|
@ -629,8 +648,7 @@ impl Model {
|
|||
if matches!(
|
||||
key,
|
||||
Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift)
|
||||
) || matches!((&key, modifiers), (Key::Named(Named::Tab), modifiers) if modifiers.is_empty() || modifiers == Modifiers::SHIFT)
|
||||
{
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
cosmic::iced_winit::conversion::physical_to_scancode(physical_key)
|
||||
|
|
@ -788,6 +806,7 @@ fn context_drawer<'a>(
|
|||
.on_input(move |text| ShortcutMessage::InputBinding(bind_id, text))
|
||||
.on_unfocus(ShortcutMessage::SubmitBinding(bind_id))
|
||||
.on_submit(move |_| ShortcutMessage::SubmitBinding(bind_id))
|
||||
.on_tab(ShortcutMessage::TabPressed) // capture Tab to prevent focus navigation
|
||||
.padding([0, space_xs])
|
||||
.id(shortcut.id.clone())
|
||||
.into();
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ pub enum Message {
|
|||
Shortcut(ShortcutMessage),
|
||||
/// Open the add shortcut context drawer
|
||||
ShortcutContext,
|
||||
TabPressed,
|
||||
ModifiersChanged(Modifiers),
|
||||
KeyReleased(u32, Key, Location),
|
||||
KeyPressed(u32, Key, Location, Modifiers),
|
||||
|
|
@ -297,6 +298,26 @@ impl Page {
|
|||
}
|
||||
}
|
||||
}
|
||||
// libcosmic requires we set on_tab() and manually process here
|
||||
// otherwise it'll consume the tab key event for navigation
|
||||
Message::TabPressed => {
|
||||
if self.add_shortcut.editing.is_some() && self.add_shortcut.active {
|
||||
self.add_shortcut.binding.key = Some(xkeysym::Keysym::Tab);
|
||||
self.add_shortcut.binding.keycode = Some(0);
|
||||
if let Some(k) = self
|
||||
.add_shortcut
|
||||
.keys
|
||||
.get_mut(self.add_shortcut.editing.unwrap())
|
||||
{
|
||||
k.0 = self.add_shortcut.binding.to_string();
|
||||
}
|
||||
return self.update(Message::KeyReleased(
|
||||
0,
|
||||
Key::Named(Named::Tab),
|
||||
Location::Standard,
|
||||
));
|
||||
}
|
||||
}
|
||||
Message::KeyReleased(keycode, _, _) => {
|
||||
// if the currently selected shortcut matches, finish selecting shortcut
|
||||
if self.add_shortcut.editing.is_some()
|
||||
|
|
@ -310,7 +331,7 @@ impl Page {
|
|||
&& self.add_shortcut.binding.modifiers
|
||||
!= cosmic_settings_config::shortcuts::Modifiers::new()
|
||||
|| self.add_shortcut.binding.key.is_some_and(|key| {
|
||||
key.is_misc_function_key() || matches!(key.raw(), 0x10080001..=0x1008FFFF)
|
||||
!cosmic_settings_config::shortcuts::is_forbidden_unmodified_keysym(key)
|
||||
})
|
||||
{
|
||||
// XX for now avoid applying the keycode
|
||||
|
|
@ -452,6 +473,7 @@ impl Page {
|
|||
.select_on_focus(true)
|
||||
.on_input(move |input| Message::KeyInput(id, input))
|
||||
.on_submit(|_| Message::AddKeybinding)
|
||||
.on_tab(Message::TabPressed) // capture Tab to prevent focus navigation
|
||||
.padding([0, 12])
|
||||
.id(widget_id.clone())
|
||||
.apply(widget::container)
|
||||
|
|
@ -599,8 +621,7 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
if matches!(
|
||||
key,
|
||||
Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift)
|
||||
) || matches!((&key, modifiers), (Key::Named(Named::Tab), modifiers) if modifiers.is_empty() || modifiers == Modifiers::SHIFT)
|
||||
{
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
cosmic::iced_winit::conversion::physical_to_scancode(physical_key).map(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue