From 3480b54201a5f361cca0bcd0d45dd6546a7a7bc9 Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Wed, 23 Sep 2026 03:37:02 -0700 Subject: [PATCH] Box the optional exact State menu target to bound message size --- crates/oa-desktop/src/app/state_diagram.rs | 2 +- crates/oa-desktop/src/app/state_multiselect_tests.rs | 8 ++++---- crates/oa-desktop/src/model_menu.rs | 9 +++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/crates/oa-desktop/src/app/state_diagram.rs b/crates/oa-desktop/src/app/state_diagram.rs index eccbd6f2..6f56df5a 100644 --- a/crates/oa-desktop/src/app/state_diagram.rs +++ b/crates/oa-desktop/src/app/state_diagram.rs @@ -165,7 +165,7 @@ impl App { let mut request = crate::model_menu::Request::object(object, anchor); request.canvas = Some(context); request.placement = placement; - request.selection_target = selection_target; + request.selection_target = selection_target.map(Box::new); request.bend = bend; request.route_segment = route_segment; return self.handle(Message::Menu(crate::model_menu::Event::Open(request))); diff --git a/crates/oa-desktop/src/app/state_multiselect_tests.rs b/crates/oa-desktop/src/app/state_multiselect_tests.rs index 26673dfc..4fde933e 100644 --- a/crates/oa-desktop/src/app/state_multiselect_tests.rs +++ b/crates/oa-desktop/src/app/state_multiselect_tests.rs @@ -1016,7 +1016,7 @@ async fn state_actions_trigger_captures_exact_row_without_owner_placement_and_st }; assert_eq!(request.object, relation); assert_eq!(request.placement, None); - assert_eq!(request.selection_target, Some(row.clone())); + assert_eq!(request.selection_target.as_deref(), Some(&row)); assert_eq!(request.canvas, f.app.state_context()); let mut wrong = request.clone(); wrong.placement = Some(f.a); @@ -1028,7 +1028,7 @@ async fn state_actions_trigger_captures_exact_row_without_owner_placement_and_st .app .update(Message::Menu(MenuEvent::Open(request.clone()))); let opened = f.app.model_menu.as_ref().unwrap(); - assert_eq!(opened.request.selection_target, Some(row.clone())); + assert_eq!(opened.request.selection_target.as_deref(), Some(&row)); assert_eq!(opened.request.placement, None); assert_eq!( f.app.multiselect_snapshot().unwrap().targets(), @@ -1080,10 +1080,10 @@ async fn state_actions_trigger_captures_exact_row_without_owner_placement_and_st model_menu::Opened::new(&f.app, stale_row.clone(), 2).is_none(), "a fresh envelope cannot rebind the old row occurrence" ); - stale_row.selection_target = Some(Target::StateRow { + stale_row.selection_target = Some(Box::new(Target::StateRow { placement: f.b, relation, - }); + })); assert!( model_menu::Opened::new(&f.app, stale_row, 2).is_some(), "the replacement occurrence is independently visible" diff --git a/crates/oa-desktop/src/model_menu.rs b/crates/oa-desktop/src/model_menu.rs index e34b54a8..4ca4b6a0 100644 --- a/crates/oa-desktop/src/model_menu.rs +++ b/crates/oa-desktop/src/model_menu.rs @@ -12,7 +12,7 @@ pub struct Request { pub anchor: Point, pub object: Id, pub placement: Option, - pub selection_target: Option, + pub selection_target: Option>, pub bend: Option, pub route_point: Option, pub route_segment: Option<(usize, Position)>, @@ -98,7 +98,7 @@ impl Opened { fn target_matches(app: &App, request: &Request) -> bool { use crate::diagram_usage::Target; - let Some(target) = &request.selection_target else { + let Some(target) = request.selection_target.as_deref() else { return true; }; if request.canvas.is_none() || !app.multiselect_target_visible(target) { @@ -157,7 +157,7 @@ pub fn trigger(app: &App) -> iced::Element<'_, Message> { } else if app.page == Page::Behavior { request.canvas = app.state_context(); if let Some(target) = app.diagram_selection.as_ref().and_then(|s| s.primary()) { - request.selection_target = Some(target.clone()); + request.selection_target = Some(Box::new(target.clone())); request.placement = match target { crate::diagram_usage::Target::Placement(id) => { if let Some(node) = request @@ -244,7 +244,8 @@ pub fn popup(app: &App) -> Option> { .map(|d| projection::project_view_with_index(p, d, app.document.view_index())); let target = request .selection_target - .clone() + .as_deref() + .cloned() .or_else(|| request.placement.map(Target::Placement)) .or_else(|| { view.as_ref()?