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,
|
ResetBindings,
|
||||||
ShowShortcut(usize, String),
|
ShowShortcut(usize, String),
|
||||||
SubmitBinding(usize),
|
SubmitBinding(usize),
|
||||||
|
TabPressed,
|
||||||
Inhibited(bool),
|
Inhibited(bool),
|
||||||
ProtocolUnavailable,
|
ProtocolUnavailable,
|
||||||
ModifiersChanged(Modifiers),
|
ModifiersChanged(Modifiers),
|
||||||
|
|
@ -545,6 +546,23 @@ impl Model {
|
||||||
shortcut.input = shortcut.pending.to_string();
|
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, _, _) => {
|
ShortcutMessage::KeyReleased(keycode, _, _) => {
|
||||||
if let Some((short_id, id)) = self.shortcut_context.zip(self.editing)
|
if let Some((short_id, id)) = self.shortcut_context.zip(self.editing)
|
||||||
&& let Some(model) = self.shortcut_models.get_mut(short_id)
|
&& let Some(model) = self.shortcut_models.get_mut(short_id)
|
||||||
|
|
@ -557,8 +575,9 @@ impl Model {
|
||||||
if shortcut.pending.modifiers
|
if shortcut.pending.modifiers
|
||||||
!= cosmic_settings_config::shortcuts::Modifiers::new()
|
!= cosmic_settings_config::shortcuts::Modifiers::new()
|
||||||
|| shortcut.pending.key.is_some_and(|key| {
|
|| shortcut.pending.key.is_some_and(|key| {
|
||||||
key.is_misc_function_key()
|
!cosmic_settings_config::shortcuts::is_forbidden_unmodified_keysym(
|
||||||
|| matches!(key.raw(), 0x10080001..=0x1008FFFF)
|
key,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
shortcut.input = shortcut.pending.to_string();
|
shortcut.input = shortcut.pending.to_string();
|
||||||
|
|
@ -629,8 +648,7 @@ impl Model {
|
||||||
if matches!(
|
if matches!(
|
||||||
key,
|
key,
|
||||||
Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift)
|
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;
|
return None;
|
||||||
}
|
}
|
||||||
cosmic::iced_winit::conversion::physical_to_scancode(physical_key)
|
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_input(move |text| ShortcutMessage::InputBinding(bind_id, text))
|
||||||
.on_unfocus(ShortcutMessage::SubmitBinding(bind_id))
|
.on_unfocus(ShortcutMessage::SubmitBinding(bind_id))
|
||||||
.on_submit(move |_| 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])
|
.padding([0, space_xs])
|
||||||
.id(shortcut.id.clone())
|
.id(shortcut.id.clone())
|
||||||
.into();
|
.into();
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ pub enum Message {
|
||||||
Shortcut(ShortcutMessage),
|
Shortcut(ShortcutMessage),
|
||||||
/// Open the add shortcut context drawer
|
/// Open the add shortcut context drawer
|
||||||
ShortcutContext,
|
ShortcutContext,
|
||||||
|
TabPressed,
|
||||||
ModifiersChanged(Modifiers),
|
ModifiersChanged(Modifiers),
|
||||||
KeyReleased(u32, Key, Location),
|
KeyReleased(u32, Key, Location),
|
||||||
KeyPressed(u32, Key, Location, Modifiers),
|
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, _, _) => {
|
Message::KeyReleased(keycode, _, _) => {
|
||||||
// if the currently selected shortcut matches, finish selecting shortcut
|
// if the currently selected shortcut matches, finish selecting shortcut
|
||||||
if self.add_shortcut.editing.is_some()
|
if self.add_shortcut.editing.is_some()
|
||||||
|
|
@ -310,7 +331,7 @@ impl Page {
|
||||||
&& self.add_shortcut.binding.modifiers
|
&& self.add_shortcut.binding.modifiers
|
||||||
!= cosmic_settings_config::shortcuts::Modifiers::new()
|
!= cosmic_settings_config::shortcuts::Modifiers::new()
|
||||||
|| self.add_shortcut.binding.key.is_some_and(|key| {
|
|| 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
|
// XX for now avoid applying the keycode
|
||||||
|
|
@ -452,6 +473,7 @@ impl Page {
|
||||||
.select_on_focus(true)
|
.select_on_focus(true)
|
||||||
.on_input(move |input| Message::KeyInput(id, input))
|
.on_input(move |input| Message::KeyInput(id, input))
|
||||||
.on_submit(|_| Message::AddKeybinding)
|
.on_submit(|_| Message::AddKeybinding)
|
||||||
|
.on_tab(Message::TabPressed) // capture Tab to prevent focus navigation
|
||||||
.padding([0, 12])
|
.padding([0, 12])
|
||||||
.id(widget_id.clone())
|
.id(widget_id.clone())
|
||||||
.apply(widget::container)
|
.apply(widget::container)
|
||||||
|
|
@ -599,8 +621,7 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
if matches!(
|
if matches!(
|
||||||
key,
|
key,
|
||||||
Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift)
|
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;
|
return None;
|
||||||
}
|
}
|
||||||
cosmic::iced_winit::conversion::physical_to_scancode(physical_key).map(
|
cosmic::iced_winit::conversion::physical_to_scancode(physical_key).map(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue