fix: optimize performance by wrapping trace logs, adding captured drag event subscriptions, and adding regression tests for adjustment compositing.

This commit is contained in:
Your Name
2026-07-24 02:04:35 +03:00
parent f2cca7e6a1
commit fba10b753c
9 changed files with 364 additions and 50 deletions
+41 -4
View File
@@ -3550,6 +3550,7 @@ impl HcieIcedApp {
}
Message::CanvasCursorPos { x, y } => {
crate::canvas::perf::record_idle_pointer_message(false);
self.canvas_cursor_pos = Some((x, y));
}
@@ -4707,6 +4708,7 @@ impl HcieIcedApp {
self.layer_style_dragging = true;
}
Message::LayerStyleDialogDragMove(x, y) | Message::DockPointerMoved(x, y) => {
crate::canvas::perf::record_idle_pointer_message(true);
self.last_cursor_pos = Some((x, y));
let pointer = iced::Point::new(x, y);
if self.dock.drag.is_none() {
@@ -9677,13 +9679,19 @@ impl HcieIcedApp {
colors,
));
}
let _elapsed = view_start.elapsed();
let elapsed = view_start.elapsed();
if !self.tool_state.is_drawing {
crate::canvas::perf::record_idle_view(elapsed);
}
// Performance log measuring Elm view reconstruction time.
// useful to track widget layout allocation and view model reconstruction times.
// log::info!("[perf] view(): {:.1}ms", elapsed.as_secs_f64() * 1000.0);
stack.width(Length::Fill).height(Length::Fill).into()
} else {
let _elapsed = view_start.elapsed();
let elapsed = view_start.elapsed();
if !self.tool_state.is_drawing {
crate::canvas::perf::record_idle_view(elapsed);
}
// Performance log measuring Elm view reconstruction time.
// log::info!("[perf] view(): {:.1}ms", elapsed.as_secs_f64() * 1000.0);
content.into()
@@ -9933,7 +9941,9 @@ impl HcieIcedApp {
iced::mouse::Event::ButtonPressed(iced::mouse::Button::Left) => (status
== iced::event::Status::Ignored)
.then_some(Message::OverlayOutsideClick),
iced::mouse::Event::CursorMoved { position } => {
iced::mouse::Event::CursorMoved { position }
if status == iced::event::Status::Ignored =>
{
Some(Message::DockPointerMoved(position.x, position.y))
}
iced::mouse::Event::ButtonReleased(iced::mouse::Button::Left) => {
@@ -9982,6 +9992,27 @@ impl HcieIcedApp {
}
});
// Captured canvas events normally stay local to the retained overlay.
// During a real global drag, forward captured movement so dock/dialog
// interactions continue across the canvas without rebuilding the app
// for every idle canvas movement.
let captured_drag_pointer = if self.layer_style_dragging
|| self.dock.header_drag.is_some()
|| self.dock.drag.is_some()
|| self.dock.floating_drag.is_some()
{
iced::event::listen_with(|event, status, _id| match event {
iced::Event::Mouse(iced::mouse::Event::CursorMoved { position })
if status == iced::event::Status::Captured =>
{
Some(Message::DockPointerMoved(position.x, position.y))
}
_ => None,
})
} else {
iced::Subscription::none()
};
// The marching ants are rendered in the persistent GPU canvas shader.
// Use a real timer rather than an immediately-ready async loop: the old
// loop generated an unbounded stream of CompositeRefresh messages and
@@ -10010,7 +10041,13 @@ impl HcieIcedApp {
iced::Subscription::none()
};
iced::Subscription::batch(vec![keyboard, mouse, marching_ants, stroke_frames])
iced::Subscription::batch(vec![
keyboard,
mouse,
captured_drag_pointer,
marching_ants,
stroke_frames,
])
}
}