From a02bf886261eeaa04f0b65532aff7159432eba21 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 17 Sep 2025 18:28:14 -0400 Subject: [PATCH] fix(input): better handling of keyboard focus and highlighting of shortcuts --- Cargo.lock | 30 +++++++++---------- .../pages/input/keyboard/shortcuts/common.rs | 14 +++++++-- .../pages/input/keyboard/shortcuts/custom.rs | 21 ++++++++++--- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d3d5bf..330a0a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1529,7 +1529,7 @@ dependencies = [ [[package]] name = "cosmic-config" 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 = [ "atomicwrites", "cosmic-config-derive", @@ -1550,7 +1550,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" 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 = [ "quote", "syn 2.0.106", @@ -1871,7 +1871,7 @@ dependencies = [ [[package]] name = "cosmic-theme" 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 = [ "almost", "cosmic-config", @@ -3299,7 +3299,7 @@ dependencies = [ [[package]] name = "iced" 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 = [ "dnd", "iced_accessibility", @@ -3317,7 +3317,7 @@ dependencies = [ [[package]] name = "iced_accessibility" 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 = [ "accesskit", "accesskit_winit", @@ -3326,7 +3326,7 @@ dependencies = [ [[package]] name = "iced_core" 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 = [ "bitflags 2.9.4", "bytes", @@ -3351,7 +3351,7 @@ dependencies = [ [[package]] name = "iced_futures" 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 = [ "futures", "iced_core", @@ -3377,7 +3377,7 @@ dependencies = [ [[package]] name = "iced_graphics" 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 = [ "bitflags 2.9.4", "bytemuck", @@ -3399,7 +3399,7 @@ dependencies = [ [[package]] name = "iced_renderer" 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 = [ "iced_graphics", "iced_tiny_skia", @@ -3411,7 +3411,7 @@ dependencies = [ [[package]] name = "iced_runtime" 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 = [ "bytes", "cosmic-client-toolkit", @@ -3427,7 +3427,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" 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 = [ "bytemuck", "cosmic-text", @@ -3443,7 +3443,7 @@ dependencies = [ [[package]] name = "iced_wgpu" 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 = [ "as-raw-xcb-connection", "bitflags 2.9.4", @@ -3474,7 +3474,7 @@ dependencies = [ [[package]] name = "iced_widget" 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 = [ "cosmic-client-toolkit", "dnd", @@ -3494,7 +3494,7 @@ dependencies = [ [[package]] name = "iced_winit" 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 = [ "cosmic-client-toolkit", "dnd", @@ -4550,7 +4550,7 @@ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libcosmic" 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 = [ "apply", "ashpd 0.12.0", diff --git a/cosmic-settings/src/pages/input/keyboard/shortcuts/common.rs b/cosmic-settings/src/pages/input/keyboard/shortcuts/common.rs index b062caa..530841b 100644 --- a/cosmic-settings/src/pages/input/keyboard/shortcuts/common.rs +++ b/cosmic-settings/src/pages/input/keyboard/shortcuts/common.rs @@ -526,9 +526,13 @@ impl Model { if 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; shortcut.reset(); return Task::batch(vec![ @@ -557,7 +561,8 @@ impl Model { shortcut.binding.keycode = None; return Task::batch(vec![ 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) ) { 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(|code| ShortcutMessage::KeyPressed(code, key, location, modifiers)) diff --git a/cosmic-settings/src/pages/input/keyboard/shortcuts/custom.rs b/cosmic-settings/src/pages/input/keyboard/shortcuts/custom.rs index 1068038..02ebe11 100644 --- a/cosmic-settings/src/pages/input/keyboard/shortcuts/custom.rs +++ b/cosmic-settings/src/pages/input/keyboard/shortcuts/custom.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only // use std::str::FromStr; +use std::time::Duration; use super::{ShortcutBinding, ShortcutMessage, ShortcutModel}; @@ -219,10 +220,15 @@ impl Page { } Message::ShortcutContext => { + let name_id = self.name_id.clone(); self.add_shortcut.enable(); return Task::batch(vec![ 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() { 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.model.on_enter(); @@ -411,9 +421,9 @@ impl Page { ) .on_focus(Message::KeyEditing(id, true)) .select_on_focus(true) - .padding([0, 12]) .on_input(move |input| Message::KeyInput(id, input)) .on_submit(|_| Message::AddKeybinding) + .padding([0, 12]) .id(widget_id.clone()) .apply(widget::container) .padding([8, 24]); @@ -552,6 +562,9 @@ impl page::Page for Page { Key::Named(Named::Super | Named::Alt | Named::Control | Named::Shift) ) { 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( |code| {