fix focus

This commit is contained in:
Alexander Mohr 2025-05-03 01:39:26 +02:00
parent bdbe3c49cd
commit 54354c298f
2 changed files with 73 additions and 31 deletions

View file

@ -4,9 +4,6 @@ use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use crate::config::{Anchor, Config, MatchMethod, WrapMode};
use crate::desktop::known_image_extension_regex_pattern;
use crate::{config, desktop};
use anyhow::anyhow; use anyhow::anyhow;
use crossbeam::channel; use crossbeam::channel;
use crossbeam::channel::Sender; use crossbeam::channel::Sender;
@ -29,6 +26,10 @@ use gtk4_layer_shell::{Edge, KeyboardMode, LayerShell};
use log; use log;
use regex::Regex; use regex::Regex;
use crate::config::{Anchor, Config, MatchMethod, WrapMode};
use crate::desktop::known_image_extension_regex_pattern;
use crate::{config, desktop};
type ArcMenuMap<T> = Arc<Mutex<HashMap<FlowBoxChild, MenuItem<T>>>>; type ArcMenuMap<T> = Arc<Mutex<HashMap<FlowBoxChild, MenuItem<T>>>>;
type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T> + Send>>; type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T> + Send>>;
type MenuItemSender<T> = Sender<Result<MenuItem<T>, anyhow::Error>>; type MenuItemSender<T> = Sender<Result<MenuItem<T>, anyhow::Error>>;
@ -374,7 +375,6 @@ fn build_ui_from_menu_items<T: Clone + 'static>(
let query = ui_clone.search.text(); let query = ui_clone.search.text();
let menus = &mut *lock; let menus = &mut *lock;
set_menu_visibility_for_search(&query, menus, &meta_clone.config); set_menu_visibility_for_search(&query, menus, &meta_clone.config);
select_first_visible_child(&*lock, &ui_clone.main_box);
} }
let items_sort = ArcMenuMap::clone(&ui_clone.menu_rows); let items_sort = ArcMenuMap::clone(&ui_clone.menu_rows);
@ -383,6 +383,10 @@ fn build_ui_from_menu_items<T: Clone + 'static>(
}); });
if done { if done {
let mut lock = ui_clone.menu_rows.lock().unwrap();
let menus = &mut *lock;
select_first_visible_child(menus, &ui_clone.main_box);
log::debug!("Created menu items in {:?}", start.elapsed()); log::debug!("Created menu items in {:?}", start.elapsed());
ControlFlow::Break ControlFlow::Break
} else { } else {
@ -417,10 +421,6 @@ fn handle_key_press<T: Clone + 'static>(
let mut lock = ui.menu_rows.lock().unwrap(); let mut lock = ui.menu_rows.lock().unwrap();
let menus = &mut *lock; let menus = &mut *lock;
set_menu_visibility_for_search(query, menus, &meta.config); set_menu_visibility_for_search(query, menus, &meta.config);
for (fb, item) in lock.iter() {
fb.set_visible(item.visible);
}
select_first_visible_child(&*lock, &ui.main_box); select_first_visible_child(&*lock, &ui.main_box);
}; };
@ -450,9 +450,10 @@ fn handle_key_press<T: Clone + 'static>(
let mut query = ui.search.text().to_string(); let mut query = ui.search.text().to_string();
if !query.is_empty() { if !query.is_empty() {
query.pop(); query.pop();
ui.search.set_text(&query);
update_view_from_provider(&query);
} }
ui.search.set_text(&query);
update_view_from_provider(&query);
} }
Key::Tab => { Key::Tab => {
if let Some(fb) = ui.main_box.selected_children().first() { if let Some(fb) = ui.main_box.selected_children().first() {
@ -461,22 +462,27 @@ fn handle_key_press<T: Clone + 'static>(
if let Some(expander) = expander { if let Some(expander) = expander {
expander.set_expanded(true); expander.set_expanded(true);
} else { } else {
let lock = ui.menu_rows.lock().unwrap(); let opt_changed = {
let menu_item = lock.get(fb); let lock = ui.menu_rows.lock().unwrap();
if let Some(menu_item) = menu_item { let menu_item = lock.get(fb);
let (changed, items) = meta menu_item.map(|menu_item| {
.item_provider (
.lock() meta.item_provider
.unwrap() .lock()
.get_sub_elements(menu_item); .unwrap()
.get_sub_elements(menu_item),
menu_item.label.clone(),
)
})
};
let items = items.unwrap_or_default(); if let Some(changed) = opt_changed {
if changed { let items = changed.0.1.unwrap_or_default();
if changed.0.0 {
build_ui_from_menu_items(ui, meta, items); build_ui_from_menu_items(ui, meta, items);
} }
let query = menu_item.label.clone(); let query = changed.1;
ui.search.set_text(&query); ui.search.set_text(&query);
update_view(&query); update_view(&query);
} }
@ -775,6 +781,7 @@ fn create_menu_row<T: Clone + 'static>(
element_to_add: &MenuItem<T>, element_to_add: &MenuItem<T>,
) -> Widget { ) -> Widget {
let row = ListBoxRow::new(); let row = ListBoxRow::new();
row.set_focusable(true);
row.set_hexpand(true); row.set_hexpand(true);
row.set_halign(Align::Fill); row.set_halign(Align::Fill);
row.set_widget_name("row"); row.set_widget_name("row");
@ -927,6 +934,8 @@ fn select_first_visible_child<T: Clone>(
if let Some(child) = flow_box.child_at_index(i_32) { if let Some(child) = flow_box.child_at_index(i_32) {
if child.is_visible() { if child.is_visible() {
flow_box.select_child(&child); flow_box.select_child(&child);
child.grab_focus();
child.activate();
return; return;
} }
} }

View file

@ -553,6 +553,7 @@ struct AutoItemProvider {
file: FileItemProvider<AutoRunType>, file: FileItemProvider<AutoRunType>,
math: MathProvider<AutoRunType>, math: MathProvider<AutoRunType>,
ssh: SshProvider<AutoRunType>, ssh: SshProvider<AutoRunType>,
last_mode: Option<AutoRunType>,
} }
impl AutoItemProvider { impl AutoItemProvider {
@ -562,6 +563,22 @@ impl AutoItemProvider {
file: FileItemProvider::new(AutoRunType::File), file: FileItemProvider::new(AutoRunType::File),
math: MathProvider::new(AutoRunType::Math), math: MathProvider::new(AutoRunType::Math),
ssh: SshProvider::new(AutoRunType::Ssh), ssh: SshProvider::new(AutoRunType::Ssh),
last_mode: None,
}
}
fn default_auto_elements(
&mut self,
search_opt: Option<&str>,
) -> (bool, Vec<MenuItem<AutoRunType>>) {
// return ssh and drun items
let (changed, mut items) = self.drun.get_elements(search_opt);
items.append(&mut self.ssh.get_elements(search_opt).1);
if self.last_mode == Some(AutoRunType::DRun) {
(changed, items)
} else {
self.last_mode = Some(AutoRunType::DRun);
(true, items)
} }
} }
} }
@ -571,26 +588,42 @@ impl ItemProvider<AutoRunType> for AutoItemProvider {
if let Some(search) = search_opt { if let Some(search) = search_opt {
let trimmed_search = search.trim(); let trimmed_search = search.trim();
if trimmed_search.is_empty() { if trimmed_search.is_empty() {
self.drun.get_elements(search_opt) let (_changed, items) = self.default_auto_elements(search_opt);
(true, items)
} else if MathProvider::<AutoRunType>::contains_math_functions_or_starts_with_number( } else if MathProvider::<AutoRunType>::contains_math_functions_or_starts_with_number(
trimmed_search, trimmed_search,
) { ) {
self.math.get_elements(search_opt) // math mode handling
let (changed, items) = self.math.get_elements(search_opt);
if self.last_mode == Some(AutoRunType::Math) {
return (changed, items);
}
self.last_mode = Some(AutoRunType::Math);
return (true, items);
} else if trimmed_search.starts_with('$') } else if trimmed_search.starts_with('$')
|| trimmed_search.starts_with('/') || trimmed_search.starts_with('/')
|| trimmed_search.starts_with('~') || trimmed_search.starts_with('~')
{ {
self.file.get_elements(search_opt) // file mode handling
let (changed, items) = self.file.get_elements(search_opt);
if self.last_mode == Some(AutoRunType::File) {
return (changed, items);
}
self.last_mode = Some(AutoRunType::File);
return (true, items);
} else if trimmed_search.starts_with("ssh") { } else if trimmed_search.starts_with("ssh") {
self.ssh.get_elements(search_opt) // file mode handling
let (changed, items) = self.ssh.get_elements(search_opt);
if self.last_mode == Some(AutoRunType::Ssh) {
return (changed, items);
}
self.last_mode = Some(AutoRunType::Ssh);
return (true, items);
} else { } else {
// return ssh and drun items self.default_auto_elements(search_opt)
let (changed, mut drun) = self.drun.get_elements(search_opt);
drun.append(&mut self.ssh.get_elements(search_opt).1);
(changed, drun)
} }
} else { } else {
self.drun.get_elements(search_opt) self.default_auto_elements(search_opt)
} }
} }