Scripting: Property.selected=false deselects mask and effect groups too (#566 follow-up)

prop.deselect resolved its uid through prop_ref, which only finds leaf
properties, so mask.selected=false threw. Resolve it as prop.select does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
This commit is contained in:
Claude committed 2026-10-10 12:49:52 +00:00
1 parent 45897f0aaf
commit 20ac6189bc
2 files changed
+33 -12

No files matched your search

+6 -1
View File
@@ -462,7 +462,12 @@ fn select_prop(s: &mut Session, p: &Value) -> Result<Value> {
/// 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<Value> {
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);
+27 -11
View File
@@ -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]]));
}