From db76c5ca3bb9f5d3b32847bcd6d9435240e31c8c Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Mon, 5 Jan 2026 08:22:54 +0100 Subject: [PATCH] Fix new `move_to_top` flag breaking widget order (#7825) * closes https://github.com/emilk/egui/issues/7812 * related https://github.com/emilk/egui/pull/7805 That pr introduced a bug that caused a mismatch in the `by_layer` / `by_id` widget rects. This should fix it by updating the index of all following widgets. Not super pretty and efficient, but I'm not sure if there's a better way. Maybe we could also just leave a "tombstone" / duplicate there in the by_layer map so we don't need to update the indexes? --- crates/egui/src/widget_rect.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/egui/src/widget_rect.rs b/crates/egui/src/widget_rect.rs index e03423623..a84dde519 100644 --- a/crates/egui/src/widget_rect.rs +++ b/crates/egui/src/widget_rect.rs @@ -164,6 +164,8 @@ impl WidgetRects { let InteractOptions { move_to_top } = options; + let mut shift_layer_index_after = None; + let layer_widgets = by_layer.entry(layer_id).or_default(); match by_id.entry(widget_rect.id) { @@ -187,6 +189,7 @@ impl WidgetRects { if existing.layer_id == widget_rect.layer_id { if move_to_top { layer_widgets.remove(*idx_in_layer); + shift_layer_index_after = Some(*idx_in_layer); *idx_in_layer = layer_widgets.len(); layer_widgets.push(*existing); } else { @@ -200,6 +203,16 @@ impl WidgetRects { } } } + + if let Some(shift_start) = shift_layer_index_after { + #[expect(clippy::needless_range_loop)] + for i in shift_start..layer_widgets.len() { + let w = &layer_widgets[i]; + if let Some((idx_in_by_id, _)) = by_id.get_mut(&w.id) { + *idx_in_by_id = i; + } + } + } } pub fn set_info(&mut self, id: Id, info: WidgetInfo) {