Describe the bug
When multiple viewports are open, animations using request_repaint() work only on the active viewport, and requests to update other viewports are ignored.
To Reproduce
I have created a minimal demonstration, which is included below. Compile and run. See how animation works only on window that is clicked.
Replace show_viewport_deferred() on line 41 to show_viewport_immediate() to see expected behaviour.
Expected behavior
Animation to work identically in both windows.
Demonstration
use egui::{Color32, Painter, Shape, Ui, ViewportId};
fn main() -> eframe::Result {
let native_options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_position([0.0, 0.0])
.with_inner_size([500.0, 500.0]),
..Default::default()
};
return eframe::run_native(
"My egui App",
native_options,
Box::new(|_cc| Ok(Box::new(MyApp::default()))),
);
}
#[derive(Default)]
pub struct MyApp {
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
paint_animation(ui);
second_viewport(ui);
request_updates(ui);
});
}
}
pub fn second_viewport(ui: &mut egui::Ui) -> ViewportId {
let title = "second viewport";
let id: ViewportId = ViewportId::from_hash_of(title);
ui.ctx().show_viewport_deferred(
id.clone(),
egui::ViewportBuilder::default()
.with_title(title)
.with_position([510.0, 0.0])
.with_inner_size([500.0, 500.0]),
move |ctx, _class| {
egui::CentralPanel::default().show(ctx, |ui| {
paint_animation(ui);
request_updates(ui);
});
},
);
id
}
pub fn paint_animation(ui: &mut Ui) {
let painter = Painter::new(
ui.ctx().clone(),
ui.layer_id(),
ui.available_rect_before_wrap(),
);
let step = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.subsec_millis()
/ 5;
painter.add(Shape::circle_filled(
[100.0 + step as f32, 100.0 + step as f32].into(),
100.0,
Color32::RED,
));
// Make sure we allocate what we used (everything)
ui.expand_to_include_rect(painter.clip_rect());
}
fn request_updates(ui: &mut Ui) {
let mut ids: Vec<ViewportId> = Vec::new();
ui.ctx().input(|i| {
ids = i.raw.viewports.keys().cloned().collect();
});
for id in ids {
ui.ctx().request_repaint_of(id);
};
}
P.S. I'd be grateful if someone could suggest a workaround to have animations smooth, yet painting code in multiple threads, so I could continue my development for now.
Describe the bug When multiple viewports are open, animations using request_repaint() work only on the active viewport, and requests to update other viewports are ignored.
To Reproduce I have created a minimal demonstration, which is included below. Compile and run. See how animation works only on window that is clicked. Replace show_viewport_deferred() on line 41 to show_viewport_immediate() to see expected behaviour.
Expected behavior Animation to work identically in both windows.
Demonstration