fix indicator icon update by implement blocking update handler

This commit is contained in:
yggverse 2025-03-18 17:18:47 +02:00
parent a2f307f315
commit e91930a9d9
2 changed files with 38 additions and 23 deletions

View file

@ -404,3 +404,18 @@ fn home(entry: &Entry) -> Option<Uri> {
None None
} }
} }
/// Update request text with indicator icon without given signal emission
fn update_blocked(
profile: &Profile,
entry: &Entry,
signal_handler_id: &gtk::glib::SignalHandlerId,
text: &str,
) {
use gtk::prelude::ObjectExt;
entry.block_signal(signal_handler_id);
entry.set_text(text);
entry.select_region(0, -1);
update_primary_icon(entry, profile);
entry.unblock_signal(signal_handler_id);
}

View file

@ -13,7 +13,7 @@ use gtk::{
prelude::{Cast, CastNone}, prelude::{Cast, CastNone},
}, },
glib::{GString, SignalHandlerId}, glib::{GString, SignalHandlerId},
prelude::{EditableExt, EntryExt, ListItemExt, WidgetExt}, prelude::{EntryExt, ListItemExt, WidgetExt},
}; };
pub use item::Item; pub use item::Item;
use sourceview::prelude::ListModelExt; use sourceview::prelude::ListModelExt;
@ -23,7 +23,7 @@ pub struct Suggestion {
list_store: ListStore, list_store: ListStore,
list_view: ListView, list_view: ListView,
single_selection: SingleSelection, single_selection: SingleSelection,
request: Entry, entry: Entry,
profile: Arc<Profile>, profile: Arc<Profile>,
popover: Popover, popover: Popover,
pub signal_handler_id: Rc<RefCell<Option<SignalHandlerId>>>, pub signal_handler_id: Rc<RefCell<Option<SignalHandlerId>>>,
@ -33,7 +33,7 @@ impl Suggestion {
// Constructors // Constructors
/// Create new `Self` /// Create new `Self`
pub fn build(profile: &Arc<Profile>, request: &Entry) -> Self { pub fn build(profile: &Arc<Profile>, entry: &Entry) -> Self {
let signal_handler_id = Rc::new(RefCell::new(None)); let signal_handler_id = Rc::new(RefCell::new(None));
let list_store = ListStore::new::<Item>(); let list_store = ListStore::new::<Item>();
let single_selection = { let single_selection = {
@ -42,18 +42,18 @@ impl Suggestion {
.autoselect(false) .autoselect(false)
.build(); .build();
ss.connect_selected_notify({ ss.connect_selected_notify({
let request = request.clone(); let e = entry.clone();
let p = profile.clone();
let signal_handler_id = signal_handler_id.clone(); let signal_handler_id = signal_handler_id.clone();
move |this| { move |this| {
if let Some(selected_item) = this.selected_item() { if let Some(selected_item) = this.selected_item() {
use gtk::prelude::ObjectExt;
if let Some(signal_handler_id) = signal_handler_id.borrow().as_ref() { if let Some(signal_handler_id) = signal_handler_id.borrow().as_ref() {
request.block_signal(signal_handler_id); super::update_blocked(
} &p,
request.set_text(&selected_item.downcast_ref::<Item>().unwrap().request()); &e,
request.select_region(0, -1); signal_handler_id,
if let Some(signal_handler_id) = signal_handler_id.borrow().as_ref() { &selected_item.downcast_ref::<Item>().unwrap().request(),
request.unblock_signal(signal_handler_id); );
} }
} // @TODO find signal to handle selected item only } // @TODO find signal to handle selected item only
} }
@ -105,21 +105,21 @@ impl Suggestion {
.button(gtk::gdk::BUTTON_PRIMARY) .button(gtk::gdk::BUTTON_PRIMARY)
.build(); .build();
c.connect_released({ c.connect_released({
let request = request.clone(); let e = entry.clone();
move |_, _, _, _| request.emit_activate() move |_, _, _, _| e.emit_activate()
}); });
c c
}); });
lv.connect_activate({ lv.connect_activate({
let request = request.clone(); let e = entry.clone();
move |_, _| request.emit_activate() move |_, _| e.emit_activate()
}); });
list_view_css_patch(&lv); list_view_css_patch(&lv);
lv lv
}; };
Self { Self {
profile: profile.clone(), profile: profile.clone(),
request: request.clone(), entry: entry.clone(),
popover: { popover: {
let p = Popover::builder() let p = Popover::builder()
.autohide(false) .autohide(false)
@ -138,17 +138,17 @@ impl Suggestion {
) )
.has_arrow(false) .has_arrow(false)
.build(); .build();
p.set_parent(request); p.set_parent(entry);
p.set_offset( p.set_offset(
request entry
.compute_point(request, &gtk::graphene::Point::zero()) .compute_point(entry, &gtk::graphene::Point::zero())
.unwrap() .unwrap()
.x() as i32, .x() as i32,
6, 6,
); );
p.connect_realize({ p.connect_realize({
let request = request.clone(); let e = entry.clone();
move |this| this.set_width_request(request.width() + 18) move |this| this.set_width_request(e.width() + 18)
}); });
p p
}, },
@ -164,8 +164,8 @@ impl Suggestion {
pub fn update(&self, limit: Option<usize>) { pub fn update(&self, limit: Option<usize>) {
use gtk::prelude::EditableExt; use gtk::prelude::EditableExt;
use itertools::Itertools; use itertools::Itertools;
if self.request.text_length() > 0 { if self.entry.text_length() > 0 {
let query = self.request.text(); let query = self.entry.text();
let popover = self.popover.clone(); let popover = self.popover.clone();
let list_store = self.list_store.clone(); let list_store = self.list_store.clone();
let profile = self.profile.clone(); let profile = self.profile.clone();