image_view: Fix carousel scrolling when loading files in same dir
With https://gitlab.gnome.org/GNOME/libadwaita/-/merge_requests/652 merged we no longer crash when loading files from the same directory. Now that we don't crash, we've exposed a logic error: we were changing the state of the carousel while scrolling through it, which ends with the carousel in a weird state. This commit delays clearing and refilling the carousel until after the `page-changed` signal is emitted.
This commit is contained in:
parent
8679734a43
commit
20c336b17f
1 changed files with 70 additions and 48 deletions
|
|
@ -54,6 +54,8 @@ mod imp {
|
||||||
|
|
||||||
pub model: RefCell<Option<LpFileModel>>,
|
pub model: RefCell<Option<LpFileModel>>,
|
||||||
pub current_model_index: Cell<u32>,
|
pub current_model_index: Cell<u32>,
|
||||||
|
|
||||||
|
pub scrolling: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
|
@ -229,7 +231,6 @@ impl LpImageView {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let guard = carousel.freeze_notify();
|
|
||||||
let page = LpImagePage::from_file(file);
|
let page = LpImagePage::from_file(file);
|
||||||
|
|
||||||
if new_index > current_index {
|
if new_index > current_index {
|
||||||
|
|
@ -238,14 +239,13 @@ impl LpImageView {
|
||||||
carousel.prepend(&page);
|
carousel.prepend(&page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set a flag and scroll to the page. Our `page-changed` signal handler
|
||||||
|
// will handle clearing and refilling the carousel. This is so we're
|
||||||
|
// not changing the state of the carousel while it's scrolling to the
|
||||||
|
// new page.
|
||||||
|
log::debug!("Scrolling to page for {new_index}");
|
||||||
|
imp.scrolling.set(true);
|
||||||
carousel.scroll_to(&page, true);
|
carousel.scroll_to(&page, true);
|
||||||
|
|
||||||
// Clear everything on either side, then refill
|
|
||||||
self.clear_carousel(true);
|
|
||||||
self.fill_carousel(model, new_index);
|
|
||||||
self.update_action_state(model, new_index);
|
|
||||||
|
|
||||||
drop(guard);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fills the carousel with items on either side of the given `index` of `model`
|
// Fills the carousel with items on either side of the given `index` of `model`
|
||||||
|
|
@ -265,6 +265,7 @@ impl LpImageView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::debug!("Carousel filled, current file at index {index}");
|
||||||
imp.current_model_index.set(index);
|
imp.current_model_index.set(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -309,6 +310,28 @@ impl LpImageView {
|
||||||
let prev_index = imp.current_model_index.get();
|
let prev_index = imp.current_model_index.get();
|
||||||
|
|
||||||
if model_index != prev_index {
|
if model_index != prev_index {
|
||||||
|
if imp.scrolling.get() {
|
||||||
|
log::debug!("Scrolling finished, refilling carousel");
|
||||||
|
imp.scrolling.set(false);
|
||||||
|
// We need to clear the carousel (excluding the current page)
|
||||||
|
// and refill the page buffer.
|
||||||
|
self.clear_carousel(true);
|
||||||
|
self.fill_carousel(model, model_index);
|
||||||
|
self.update_action_state(model, model_index);
|
||||||
|
} else {
|
||||||
|
self.update_page_buffer(model, carousel, model_index, prev_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_page_buffer(
|
||||||
|
&self,
|
||||||
|
model: &LpFileModel,
|
||||||
|
carousel: &adw::Carousel,
|
||||||
|
model_index: u32,
|
||||||
|
prev_index: u32,
|
||||||
|
) {
|
||||||
|
let imp = self.imp();
|
||||||
self.update_action_state(model, model_index);
|
self.update_action_state(model, model_index);
|
||||||
|
|
||||||
// We've moved forward
|
// We've moved forward
|
||||||
|
|
@ -351,7 +374,6 @@ impl LpImageView {
|
||||||
|
|
||||||
imp.current_model_index.set(model_index);
|
imp.current_model_index.set(model_index);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn get_fullscreen_icon(&self, fullscreened: bool) -> &'static str {
|
fn get_fullscreen_icon(&self, fullscreened: bool) -> &'static str {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue