Implement reactive-rendering for text_input

... and fix the redraw queue logic in `iced_winit`.
This commit is contained in:
Héctor Ramón Jiménez 2024-10-22 02:50:46 +02:00
parent 3ba7c71e3f
commit 52490397d6
No known key found for this signature in database
GPG key ID: 4C07CEC81AFA161F
4 changed files with 201 additions and 88 deletions

View file

@ -691,7 +691,6 @@ async fn run_instance<P, C>(
let mut ui_caches = FxHashMap::default();
let mut user_interfaces = ManuallyDrop::new(FxHashMap::default());
let mut clipboard = Clipboard::unconnected();
let mut redraw_queue = Vec::new();
debug.startup_finished();
@ -769,17 +768,12 @@ async fn run_instance<P, C>(
) => {
let now = Instant::now();
while let Some((target, id)) =
redraw_queue.last().copied()
{
if target > now {
break;
}
let _ = redraw_queue.pop();
if let Some(window) = window_manager.get_mut(id) {
window.raw.request_redraw();
for (_id, window) in window_manager.iter_mut() {
if let Some(redraw_at) = window.redraw_at {
if redraw_at <= now {
window.raw.request_redraw();
window.redraw_at = None;
}
}
}
}
@ -878,7 +872,7 @@ async fn run_instance<P, C>(
window.raw.request_redraw();
}
window::RedrawRequest::At(at) => {
redraw_queue.push((at, id));
window.redraw_at = Some(at);
}
}
}
@ -1039,7 +1033,10 @@ async fn run_instance<P, C>(
}
}
event::Event::AboutToWait => {
if events.is_empty() && messages.is_empty() {
if events.is_empty()
&& messages.is_empty()
&& window_manager.is_idle()
{
continue;
}
@ -1085,7 +1082,7 @@ async fn run_instance<P, C>(
window.raw.request_redraw();
}
window::RedrawRequest::At(at) => {
redraw_queue.push((at, id));
window.redraw_at = Some(at);
}
},
user_interface::State::Outdated => {
@ -1160,24 +1157,15 @@ async fn run_instance<P, C>(
}
}
if !redraw_queue.is_empty() {
// The queue should be fairly short, so we can
// simply sort all of the time.
redraw_queue.sort_by(
|(target_a, _), (target_b, _)| {
target_a.cmp(target_b).reverse()
},
);
let (target, _id) = redraw_queue
.last()
.copied()
.expect("Redraw queue is not empty");
if let Some(redraw_at) = window_manager.redraw_at() {
let _ =
control_sender.start_send(Control::ChangeFlow(
ControlFlow::WaitUntil(target),
ControlFlow::WaitUntil(redraw_at),
));
} else {
let _ = control_sender.start_send(
Control::ChangeFlow(ControlFlow::Wait),
);
}
}
_ => {}

View file

@ -1,4 +1,5 @@
use crate::core::mouse;
use crate::core::time::Instant;
use crate::core::window::Id;
use crate::core::{Point, Size};
use crate::graphics::Compositor;
@ -62,6 +63,7 @@ where
surface,
renderer,
mouse_interaction: mouse::Interaction::None,
redraw_at: None,
},
);
@ -74,6 +76,19 @@ where
self.entries.is_empty()
}
pub fn is_idle(&self) -> bool {
self.entries
.values()
.any(|window| window.redraw_at.is_some())
}
pub fn redraw_at(&self) -> Option<Instant> {
self.entries
.values()
.filter_map(|window| window.redraw_at)
.min()
}
pub fn first(&self) -> Option<&Window<P, C>> {
self.entries.first_key_value().map(|(_id, window)| window)
}
@ -138,6 +153,7 @@ where
pub mouse_interaction: mouse::Interaction,
pub surface: C::Surface,
pub renderer: P::Renderer,
pub redraw_at: Option<Instant>,
}
impl<P, C> Window<P, C>