fix(input): better handling of keyboard focus and highlighting of shortcuts

This commit is contained in:
Ashley Wulber 2025-09-17 18:28:14 -04:00 committed by Ashley Wulber
parent 320d9e25d4
commit a02bf88626
3 changed files with 43 additions and 22 deletions

30
Cargo.lock generated
View file

@ -1529,7 +1529,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-config" name = "cosmic-config"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"atomicwrites", "atomicwrites",
"cosmic-config-derive", "cosmic-config-derive",
@ -1550,7 +1550,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-config-derive" name = "cosmic-config-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.106", "syn 2.0.106",
@ -1871,7 +1871,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-theme" name = "cosmic-theme"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"almost", "almost",
"cosmic-config", "cosmic-config",
@ -3299,7 +3299,7 @@ dependencies = [
[[package]] [[package]]
name = "iced" name = "iced"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"dnd", "dnd",
"iced_accessibility", "iced_accessibility",
@ -3317,7 +3317,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_accessibility" name = "iced_accessibility"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_winit", "accesskit_winit",
@ -3326,7 +3326,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_core" name = "iced_core"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags 2.9.4",
"bytes", "bytes",
@ -3351,7 +3351,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_futures" name = "iced_futures"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"futures", "futures",
"iced_core", "iced_core",
@ -3377,7 +3377,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_graphics" name = "iced_graphics"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"bitflags 2.9.4", "bitflags 2.9.4",
"bytemuck", "bytemuck",
@ -3399,7 +3399,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_renderer" name = "iced_renderer"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"iced_graphics", "iced_graphics",
"iced_tiny_skia", "iced_tiny_skia",
@ -3411,7 +3411,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_runtime" name = "iced_runtime"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"bytes", "bytes",
"cosmic-client-toolkit", "cosmic-client-toolkit",
@ -3427,7 +3427,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_tiny_skia" name = "iced_tiny_skia"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"cosmic-text", "cosmic-text",
@ -3443,7 +3443,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_wgpu" name = "iced_wgpu"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"as-raw-xcb-connection", "as-raw-xcb-connection",
"bitflags 2.9.4", "bitflags 2.9.4",
@ -3474,7 +3474,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_widget" name = "iced_widget"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
@ -3494,7 +3494,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_winit" name = "iced_winit"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
@ -4550,7 +4550,7 @@ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]] [[package]]
name = "libcosmic" name = "libcosmic"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#0e797b244043ee86610113d547950204258dea83" source = "git+https://github.com/pop-os/libcosmic//?branch=more-input-changes#53f9f463d4cc03b396aee7d27d9d6640af7d1640"
dependencies = [ dependencies = [
"apply", "apply",
"ashpd 0.12.0", "ashpd 0.12.0",

View file

@ -526,9 +526,13 @@ impl Model {
if modifiers.logo() { if modifiers.logo() {
cfg_modifiers = cfg_modifiers.logo() cfg_modifiers = cfg_modifiers.logo()
} }
shortcut.pending.modifiers = cfg_modifiers; let old =
std::mem::replace(&mut shortcut.pending.modifiers, cfg_modifiers);
if shortcut.pending.keycode.is_none() && modifiers.is_empty() { if shortcut.pending.keycode.is_none()
&& modifiers.is_empty()
&& (old.alt || old.ctrl || old.shift || old.logo)
{
self.editing = None; self.editing = None;
shortcut.reset(); shortcut.reset();
return Task::batch(vec![ return Task::batch(vec![
@ -557,7 +561,8 @@ impl Model {
shortcut.binding.keycode = None; shortcut.binding.keycode = None;
return Task::batch(vec![ return Task::batch(vec![
iced_winit::platform_specific::commands::keyboard_shortcuts_inhibit::inhibit_shortcuts(false).discard(), iced_winit::platform_specific::commands::keyboard_shortcuts_inhibit::inhibit_shortcuts(false).discard(),
self.submit_binding(id) self.submit_binding(id),
cosmic::widget::text_input::focus(self.add_keybindings_button_id.clone()),
]); ]);
} }
@ -625,6 +630,9 @@ impl Model {
Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift) Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift)
) { ) {
return None; return None;
} else if 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) cosmic::iced_winit::conversion::physical_to_scancode(physical_key)
.map(|code| ShortcutMessage::KeyPressed(code, key, location, modifiers)) .map(|code| ShortcutMessage::KeyPressed(code, key, location, modifiers))

View file

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
// //
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration;
use super::{ShortcutBinding, ShortcutMessage, ShortcutModel}; use super::{ShortcutBinding, ShortcutMessage, ShortcutModel};
@ -219,10 +220,15 @@ impl Page {
} }
Message::ShortcutContext => { Message::ShortcutContext => {
let name_id = self.name_id.clone();
self.add_shortcut.enable(); self.add_shortcut.enable();
return Task::batch(vec![ return Task::batch(vec![
cosmic::task::message(crate::app::Message::OpenContextDrawer(self.entity)), cosmic::task::message(crate::app::Message::OpenContextDrawer(self.entity)),
widget::text_input::focus(self.name_id.clone()), // XX hack: wait a bit before focusing the input to avoid it being ignored before it exists
cosmic::task::future(async move {
tokio::time::sleep(Duration::from_millis(10)).await;
})
.then(move |_: ()| widget::text_input::focus(name_id.clone())),
]); ]);
} }
@ -241,9 +247,13 @@ impl Page {
if modifiers.logo() { if modifiers.logo() {
cfg_modifiers = cfg_modifiers.logo() cfg_modifiers = cfg_modifiers.logo()
} }
self.add_shortcut.binding.modifiers = cfg_modifiers; let old =
std::mem::replace(&mut self.add_shortcut.binding.modifiers, cfg_modifiers);
if self.add_shortcut.binding.keycode.is_none() && modifiers.is_empty() { if self.add_shortcut.binding.keycode.is_none()
&& modifiers.is_empty()
&& (old.alt || old.ctrl || old.shift || old.logo)
{
self.add_shortcut = Default::default(); self.add_shortcut = Default::default();
self.add_shortcut = Default::default(); self.add_shortcut = Default::default();
_ = self.model.on_enter(); _ = self.model.on_enter();
@ -411,9 +421,9 @@ impl Page {
) )
.on_focus(Message::KeyEditing(id, true)) .on_focus(Message::KeyEditing(id, true))
.select_on_focus(true) .select_on_focus(true)
.padding([0, 12])
.on_input(move |input| Message::KeyInput(id, input)) .on_input(move |input| Message::KeyInput(id, input))
.on_submit(|_| Message::AddKeybinding) .on_submit(|_| Message::AddKeybinding)
.padding([0, 12])
.id(widget_id.clone()) .id(widget_id.clone())
.apply(widget::container) .apply(widget::container)
.padding([8, 24]); .padding([8, 24]);
@ -552,6 +562,9 @@ impl page::Page<crate::pages::Message> for Page {
Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift) Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift)
) { ) {
return None; return None;
} else if 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( cosmic::iced_winit::conversion::physical_to_scancode(physical_key).map(
|code| { |code| {