fix focus
This commit is contained in:
parent
bdbe3c49cd
commit
54354c298f
2 changed files with 73 additions and 31 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue