diff --git a/crates/engine/src/commands/prop.rs b/crates/engine/src/commands/prop.rs index d92573b4..132e77e1 100644 --- a/crates/engine/src/commands/prop.rs +++ b/crates/engine/src/commands/prop.rs @@ -462,7 +462,12 @@ fn select_prop(s: &mut Session, p: &Value) -> Result { /// Deselect only the named property, preserving unrelated property, layer, key and /// mask-vertex selections. Selected keys also imply selectedProperties in the script API. fn deselect_prop(s: &mut Session, params: &Value) -> Result { - let (_, lid, uid) = prop_ref(s, params, "prop.deselect")?; + // Groups (masks, effects) are selected by uid too, so resolve the uid as prop.select does. + let (_, lid) = layer_p(s, params, "prop.deselect")?; + let uid = match params.get("prop").and_then(Value::as_u64) { + Some(u) => u, + None => prop_ref(s, params, "prop.deselect")?.2, + }; let mask = s.active_comp().and_then(|c| c.layer(lid)).and_then(|l| path_points(l, uid, l.layer_time(s.time()))).map(|(mask, _)| mask); s.state.selected_props.retain(|(layer, prop)| *layer != lid || *prop != uid); s.state.selected_keys.retain(|key| key.layer != lid || key.prop != uid); diff --git a/crates/script/src/tests.rs b/crates/script/src/tests.rs index 8e9a5f26..03c9e7a1 100644 --- a/crates/script/src/tests.rs +++ b/crates/script/src/tests.rs @@ -556,13 +556,7 @@ fn text_document_baseline_flags_reflect_pending_edits_and_applied_value() { [pendingSuper, appliedSuper, pendingSub, appliedSub, cleared, appliedClear, repeatClear]; "#, ); - assert_eq!( - o.result, - json!([ - [true, false], ["super", true, false], [false, true], [false, true], - [false, false], [false, false], [false, false] - ]) - ); + assert_eq!(o.result, json!([[true, false], ["super", true, false], [false, true], [false, true], [false, false], [false, false], [false, false]])); } #[test] @@ -587,10 +581,7 @@ fn setting_item_selected_false_preserves_other_project_items() { + "|" + JSON.stringify(states); "#, ); - assert_eq!( - o.result, - json!("Keep,Target|[[true,true],[false,true],[false,true],[true,true]]") - ); + assert_eq!(o.result, json!("Keep,Target|[[true,true],[false,true],[false,true],[true,true]]")); } #[test] @@ -640,3 +631,28 @@ fn property_selected_false_preserves_other_property_and_key_selections() { ); assert_eq!(out.result, json!([[[true, true], [false, true], [false, true], [true, true]], 2, 2])); } + +#[test] +fn group_selected_false_deselects_masks_and_effects() { + let mut s = session(); + let out = ok( + &mut s, + r#" + var c = app.project.items.addComp("Groups", 64, 64, 1, 1, 10); + c.openInViewer(); + var l = c.layers.addSolid([1, 0, 0], "Layer", 64, 64, 1); + var m = l.property("ADBE Mask Parade").addProperty("ADBE Mask Atom"); + var fx = l.property("ADBE Effect Parade").addProperty("Gaussian Blur"); + app.run("edit.deselectAll", {}); + m.selected = true; + fx.selected = true; + var states = [[m.selected, fx.selected]]; + m.selected = false; + states.push([m.selected, fx.selected]); + fx.selected = false; + states.push([m.selected, fx.selected]); + states; + "#, + ); + assert_eq!(out.result, json!([[true, true], [false, true], [false, false]])); +}