Implement key bind reset
This commit is contained in:
parent
6752b9a434
commit
1b980df309
5 changed files with 93 additions and 53 deletions
|
|
@ -63,33 +63,33 @@ show-headerbar = Show header
|
||||||
show-header-description = Reveal the header from the right-click menu.
|
show-header-description = Reveal the header from the right-click menu.
|
||||||
|
|
||||||
### Keyboard shortcuts
|
### Keyboard shortcuts
|
||||||
type-to-search = Type to search...
|
add-another-keybinding = Add another keybinding
|
||||||
keyboard-shortcuts = Keyboard shortcuts
|
|
||||||
menu-keyboard-shortcuts = Keyboard shortcuts...
|
|
||||||
customize-shortcuts = Customize shortcuts
|
|
||||||
shortcut-capture-hint = Press new shortcut, or Esc to cancel
|
|
||||||
cancel = Cancel
|
cancel = Cancel
|
||||||
replace = Replace
|
close-window = Close window
|
||||||
shortcut-replace-title = Replace shortcut?
|
|
||||||
shortcut-replace-body = { $binding } is already assigned to { $existing }. Replace it with { $new_action }?
|
|
||||||
no-shortcuts = No shortcuts
|
|
||||||
add-shortcut = + Add
|
|
||||||
shortcut-group-clipboard = Clipboard
|
|
||||||
shortcut-group-tabs = Tabs
|
|
||||||
shortcut-group-window = Window
|
|
||||||
shortcut-group-zoom = Zoom
|
|
||||||
shortcut-group-other = Other
|
|
||||||
unbind = Unbind
|
|
||||||
copy-or-sigint = Copy or SIGINT
|
copy-or-sigint = Copy or SIGINT
|
||||||
paste-primary = Paste primary
|
focus-pane-down = Focus pane down
|
||||||
focus-pane-left = Focus pane left
|
focus-pane-left = Focus pane left
|
||||||
focus-pane-right = Focus pane right
|
focus-pane-right = Focus pane right
|
||||||
focus-pane-up = Focus pane up
|
focus-pane-up = Focus pane up
|
||||||
focus-pane-down = Focus pane down
|
keyboard-shortcuts = Keyboard shortcuts
|
||||||
toggle-fullscreen = Toggle fullscreen
|
menu-keyboard-shortcuts = Keyboard shortcuts...
|
||||||
close-window = Close window
|
no-shortcuts = No shortcuts
|
||||||
password-manager = Password manager
|
password-manager = Password manager
|
||||||
|
paste-primary = Paste primary
|
||||||
|
replace = Replace
|
||||||
|
reset-to-default = Reset to default
|
||||||
|
shortcut-capture-hint = Press new shortcut, or Esc to cancel
|
||||||
|
shortcut-group-clipboard = Clipboard
|
||||||
|
shortcut-group-other = Other
|
||||||
|
shortcut-group-tabs = Tabs
|
||||||
|
shortcut-group-window = Window
|
||||||
|
shortcut-group-zoom = Zoom
|
||||||
|
shortcut-replace-body = { $binding } is already assigned to { $existing }. Replace it with { $new_action }?
|
||||||
|
shortcut-replace-title = Replace shortcut?
|
||||||
tab-activate = Activate tab { $number }
|
tab-activate = Activate tab { $number }
|
||||||
|
toggle-fullscreen = Toggle fullscreen
|
||||||
|
type-to-search = Type to search...
|
||||||
|
unbind = Unbind
|
||||||
|
|
||||||
# Find
|
# Find
|
||||||
find-placeholder = Find...
|
find-placeholder = Find...
|
||||||
|
|
|
||||||
10
res/icons/edit-undo-symbolic.svg
Normal file
10
res/icons/edit-undo-symbolic.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_409_3702)">
|
||||||
|
<path d="M7 2L2 5L7 8V6H10C11.68 6 13 7.32 13 9C13 10.68 11.68 12 10 12L6 12.004C5.73478 12.004 5.48043 12.1094 5.29289 12.2969C5.10536 12.4844 5 12.7388 5 13.004C5 13.2692 5.10536 13.5236 5.29289 13.7111C5.48043 13.8987 5.73478 14.004 6 14.004L10 14C12.753 13.997 15 11.753 15 9C15 6.247 12.753 4 10 4H7V2Z" fill="#232323"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_409_3702">
|
||||||
|
<rect width="16" height="16" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 573 B |
|
|
@ -33,6 +33,7 @@ impl IconCache {
|
||||||
bundle!("dialog-error-symbolic", 16);
|
bundle!("dialog-error-symbolic", 16);
|
||||||
bundle!("edit-clear-symbolic", 16);
|
bundle!("edit-clear-symbolic", 16);
|
||||||
bundle!("edit-delete-symbolic", 16);
|
bundle!("edit-delete-symbolic", 16);
|
||||||
|
bundle!("edit-undo-symbolic", 16);
|
||||||
bundle!("list-add-symbolic", 16);
|
bundle!("list-add-symbolic", 16);
|
||||||
bundle!("go-down-symbolic", 16);
|
bundle!("go-down-symbolic", 16);
|
||||||
bundle!("go-up-symbolic", 16);
|
bundle!("go-up-symbolic", 16);
|
||||||
|
|
|
||||||
44
src/main.rs
44
src/main.rs
|
|
@ -163,10 +163,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let shortcuts_config = shortcuts::ShortcutsConfig {
|
let shortcuts_config = shortcuts::ShortcutsConfig::new(config.shortcuts_custom.clone());
|
||||||
defaults: shortcuts::Shortcuts::default(),
|
|
||||||
custom: config.shortcuts_custom.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let startup_options = if let Some(shell_program) = shell_program_opt {
|
let startup_options = if let Some(shell_program) = shell_program_opt {
|
||||||
let options = tty::Options {
|
let options = tty::Options {
|
||||||
|
|
@ -382,6 +379,7 @@ pub enum Message {
|
||||||
ShortcutConflictCancel,
|
ShortcutConflictCancel,
|
||||||
ShortcutConflictReplace,
|
ShortcutConflictReplace,
|
||||||
ShortcutRemove(shortcuts::Binding, shortcuts::BindingSource),
|
ShortcutRemove(shortcuts::Binding, shortcuts::BindingSource),
|
||||||
|
ShortcutReset(shortcuts::KeyBindAction),
|
||||||
ShortcutSearch(String),
|
ShortcutSearch(String),
|
||||||
MouseEnter(pane_grid::Pane),
|
MouseEnter(pane_grid::Pane),
|
||||||
Opacity(u8),
|
Opacity(u8),
|
||||||
|
|
@ -1003,16 +1001,28 @@ impl App {
|
||||||
}
|
}
|
||||||
found_actions = true;
|
found_actions = true;
|
||||||
|
|
||||||
let bindings = self.shortcuts_config.bindings_for_action(action);
|
let (bindings, changed) = self.shortcuts_config.bindings_for_action(action);
|
||||||
|
|
||||||
|
let mut buttons = widget::row::with_capacity(2);
|
||||||
|
if changed {
|
||||||
|
buttons = buttons.push(widget::tooltip(
|
||||||
|
widget::button::custom(icon_cache_get("edit-undo-symbolic", 16))
|
||||||
|
.class(style::Button::Icon)
|
||||||
|
.on_press(Message::ShortcutReset(action)),
|
||||||
|
widget::text::body(fl!("reset-to-default")),
|
||||||
|
widget::tooltip::Position::Top,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
buttons = buttons.push(widget::tooltip(
|
||||||
|
widget::button::custom(icon_cache_get("list-add-symbolic", 16))
|
||||||
|
.class(style::Button::Icon)
|
||||||
|
.on_press(Message::ShortcutCaptureStart(action)),
|
||||||
|
widget::text::body(fl!("add-another-keybinding")),
|
||||||
|
widget::tooltip::Position::Top,
|
||||||
|
));
|
||||||
|
|
||||||
list = list.list_item_padding(pad_m);
|
list = list.list_item_padding(pad_m);
|
||||||
list = list.add(
|
list = list.add(widget::settings::item::builder(action_label).control(buttons));
|
||||||
widget::settings::item::builder(action_label).control(
|
|
||||||
widget::button::custom(icon_cache_get("list-add-symbolic", 16))
|
|
||||||
.class(style::Button::Icon)
|
|
||||||
.on_press(Message::ShortcutCaptureStart(action)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
list = list.divider_padding(div_m);
|
list = list.divider_padding(div_m);
|
||||||
|
|
||||||
if bindings.is_empty() {
|
if bindings.is_empty() {
|
||||||
|
|
@ -2090,10 +2100,8 @@ impl Application for App {
|
||||||
//TODO: update syntax theme by clearing tabs, only if needed
|
//TODO: update syntax theme by clearing tabs, only if needed
|
||||||
self.config = config;
|
self.config = config;
|
||||||
if shortcuts_changed {
|
if shortcuts_changed {
|
||||||
self.shortcuts_config = shortcuts::ShortcutsConfig {
|
self.shortcuts_config =
|
||||||
defaults: shortcuts::Shortcuts::default(),
|
shortcuts::ShortcutsConfig::new(self.config.shortcuts_custom.clone());
|
||||||
custom: self.config.shortcuts_custom.clone(),
|
|
||||||
};
|
|
||||||
self.key_binds = key_binds(&self.shortcuts_config);
|
self.key_binds = key_binds(&self.shortcuts_config);
|
||||||
}
|
}
|
||||||
return self.update_config();
|
return self.update_config();
|
||||||
|
|
@ -2431,6 +2439,10 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
self.save_shortcuts_custom();
|
self.save_shortcuts_custom();
|
||||||
}
|
}
|
||||||
|
Message::ShortcutReset(reset_action) => {
|
||||||
|
self.shortcuts_config.reset_action(reset_action);
|
||||||
|
self.save_shortcuts_custom();
|
||||||
|
}
|
||||||
Message::ShortcutSearch(search) => {
|
Message::ShortcutSearch(search) => {
|
||||||
self.shortcut_search_focus.set(true);
|
self.shortcut_search_focus.set(true);
|
||||||
self.shortcut_search_regex = None;
|
self.shortcut_search_regex = None;
|
||||||
|
|
|
||||||
|
|
@ -163,38 +163,47 @@ pub struct ResolvedBinding {
|
||||||
pub source: BindingSource,
|
pub source: BindingSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||||
pub struct ShortcutsConfig {
|
pub struct ShortcutsConfig {
|
||||||
pub defaults: Shortcuts,
|
defaults: Shortcuts,
|
||||||
pub custom: Shortcuts,
|
pub custom: Shortcuts,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShortcutsConfig {
|
impl ShortcutsConfig {
|
||||||
|
pub fn new(custom: Shortcuts) -> Self {
|
||||||
|
Self {
|
||||||
|
defaults: fallback_shortcuts(),
|
||||||
|
custom,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn key_binds(&self) -> HashMap<KeyBind, Action> {
|
pub fn key_binds(&self) -> HashMap<KeyBind, Action> {
|
||||||
let mut binds = HashMap::new();
|
let mut binds = HashMap::new();
|
||||||
let defaults = self.defaults_or_fallback();
|
insert_shortcuts(&self.defaults, &mut binds, false);
|
||||||
insert_shortcuts(&defaults, &mut binds, false);
|
|
||||||
insert_shortcuts(&self.custom, &mut binds, true);
|
insert_shortcuts(&self.custom, &mut binds, true);
|
||||||
binds
|
binds
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bindings_for_action(&self, action: KeyBindAction) -> Vec<ResolvedBinding> {
|
pub fn bindings_for_action(&self, action: KeyBindAction) -> (Vec<ResolvedBinding>, bool) {
|
||||||
let mut bindings = Vec::new();
|
let mut bindings = Vec::new();
|
||||||
let defaults = self.defaults_or_fallback();
|
|
||||||
|
|
||||||
for (binding, default_action) in &defaults.0 {
|
let mut changed = false;
|
||||||
|
for (binding, default_action) in &self.defaults.0 {
|
||||||
if *default_action != action {
|
if *default_action != action {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.custom.0.get(binding) {
|
match self.custom.0.get(binding) {
|
||||||
Some(KeyBindAction::Unbind) => (),
|
Some(KeyBindAction::Unbind) => {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
Some(custom_action) => {
|
Some(custom_action) => {
|
||||||
if *custom_action == action {
|
if *custom_action == action {
|
||||||
bindings.push(ResolvedBinding {
|
bindings.push(ResolvedBinding {
|
||||||
binding: binding.clone(),
|
binding: binding.clone(),
|
||||||
source: BindingSource::Custom,
|
source: BindingSource::Custom,
|
||||||
});
|
});
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => bindings.push(ResolvedBinding {
|
None => bindings.push(ResolvedBinding {
|
||||||
|
|
@ -212,10 +221,11 @@ impl ShortcutsConfig {
|
||||||
binding: binding.clone(),
|
binding: binding.clone(),
|
||||||
source: BindingSource::Custom,
|
source: BindingSource::Custom,
|
||||||
});
|
});
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bindings
|
(bindings, changed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action_for_binding(&self, binding: &Binding) -> Option<KeyBindAction> {
|
pub fn action_for_binding(&self, binding: &Binding) -> Option<KeyBindAction> {
|
||||||
|
|
@ -226,16 +236,23 @@ impl ShortcutsConfig {
|
||||||
return Some(*action);
|
return Some(*action);
|
||||||
}
|
}
|
||||||
|
|
||||||
let defaults = self.defaults_or_fallback();
|
self.defaults.0.get(binding).copied()
|
||||||
defaults.0.get(binding).copied()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn defaults_or_fallback(&self) -> Shortcuts {
|
pub fn reset_action(&mut self, reset_action: KeyBindAction) {
|
||||||
if self.defaults.0.is_empty() {
|
self.custom.0.retain(|binding, action| {
|
||||||
fallback_shortcuts()
|
if *action == reset_action {
|
||||||
} else {
|
// Remove any matching bindings
|
||||||
self.defaults.clone()
|
return false;
|
||||||
}
|
}
|
||||||
|
if let Some(default_action) = self.defaults.0.get(binding) {
|
||||||
|
if *default_action == reset_action {
|
||||||
|
// Remove binding that overrode a default
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue