Review fixes for the landed batch

- Cryptomatte (#1183): planes shorter than the image read as empty instead of panicking.
- layer.addMarker (#1180): a comp marker no longer replaces one at the same time.
- Desktop (#1005): ignore macOS's -psn_ argument instead of refusing to launch.
- Doc comments put back on their own items (#1153, #1037).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon ThomasandClaude Opus 5.5 committed 2026-10-13 04:47:52 -04:00
1 parent 900b921dbf
commit 3ac283eee4
4 files changed
+12 -7

No files matched your search

+7 -1
View File
@@ -93,6 +93,9 @@ fn parse_args(args: impl IntoIterator<Item = String>, env_port: Result<String, s
"--version" => return Ok(None),
_ => match a.strip_prefix("--control=") {
Some(v) => out.control_port = Some(control_port("--control", Some(v))?),
// macOS LaunchServices may pass a process serial number (`-psn_0_1234`), notably on
// the first launch of a downloaded app; it is not an option of ours.
None if a.starts_with("-psn_") => {}
None if a.starts_with('-') && a != "-" => return Err(format!("unknown option `{a}`")),
None => out.files.push(a),
},
@@ -494,7 +497,7 @@ mod tests {
assert!(super::wayland_drop_notice(Some(OsStr::new("wayland-0")), Some(OsStr::new("x11"))).is_none());
}
/// The window's device never asks for more than the adapter offers (#198).
/// The window's wgpu instance skips indirect-call validation (Intel Metal, #1153).
#[test]
fn the_window_instance_skips_indirect_call_validation() {
if std::env::var_os("WGPU_VALIDATION_INDIRECT_CALL").is_some() {
@@ -507,6 +510,7 @@ mod tests {
assert!(!setup.instance_descriptor.flags.contains(eframe::wgpu::InstanceFlags::VALIDATION_INDIRECT_CALL));
}
/// The window's device never asks for more than the adapter offers (#198).
#[test]
fn device_limits_fit_the_adapter() {
use eframe::wgpu::Limits;
@@ -569,6 +573,8 @@ mod tests {
}
// Parsed left to right: an error before `--version` wins.
assert_eq!(fails(&["--nope", "--version"]), "unknown option `--nope`");
// Finder's process serial number is ignored, not imported or refused.
assert_eq!(parse(&["-psn_0_12345"]).map(|a| a.files), Some(vec![]));
let a = parse(&["clip.mov", "-", "--", "--demo", "-name.png"]).unwrap_or_default();
assert_eq!(a.files, ["clip.mov", "-", "--demo", "-name.png"]);
assert!(!a.demo);
+2 -2
View File
@@ -386,7 +386,7 @@ type RankPlanes<'a> = [(&'a [f32], &'a [f32])];
/// ranks (the Cryptomatte spec's matte), clamped to 0..1.
#[inline]
fn crypto_matte(planes: &RankPlanes, sel: &[u32], i: usize) -> f32 {
planes.iter().map(|(id, c)| (id[i], c[i])).filter(|(id, c)| *c > 0.0 && sel.contains(&id.to_bits())).map(|(_, c)| c).sum::<f32>().clamp(0.0, 1.0)
planes.iter().filter_map(|(id, c)| Some((*id.get(i)?, *c.get(i)?))).filter(|(id, c)| *c > 0.0 && sel.contains(&id.to_bits())).map(|(_, c)| c).sum::<f32>().clamp(0.0, 1.0)
}
/// The coverage-weighted ID colours at aux pixel `i` (the spec's preview).
@@ -394,7 +394,7 @@ fn crypto_matte(planes: &RankPlanes, sel: &[u32], i: usize) -> f32 {
fn crypto_colors(planes: &RankPlanes, i: usize) -> [f32; 3] {
let mut c = [0.0f32; 3];
for (id, cov) in planes {
let (id, cov) = (id[i], cov[i]);
let (Some(&id), Some(&cov)) = (id.get(i), cov.get(i)) else { continue };
let k = id_color(id);
for j in 0..3 {
c[j] += k[j] * cov;
-1
View File
@@ -557,7 +557,6 @@ fn add_marker(s: &mut Session, p: &Value) -> Result<Value> {
if ids.is_empty() {
s.edit("Add Marker", None, |proj, _| {
let c = proj.comp_mut(cid).ok_or(EngineError::NoComp)?;
c.markers.retain(|m| m.time != t);
c.markers.push(Marker { time: t, comment, ..Default::default() });
c.markers.sort_by_key(|m| m.time);
Ok(())
+3 -3
View File
@@ -94,9 +94,6 @@ fn label_index(l: Label) -> usize {
Label::ALL.iter().position(|x| *x == l).unwrap_or(0)
}
/// A comp's selected properties as `[layer, uid]`: the selected ones, then those with selected
/// keyframes (selecting a keyframe selects its property in After Effects, so scripts find
/// selected keys through `selectedProperties`).
/// Layer ids selected in `comp`, including a comp that is not the active one (#1001).
fn selected_layer_ids(s: &Session, comp: effectcraft_project::ItemId) -> Vec<u64> {
let layers = if s.active_comp_id() == Some(comp) {
@@ -118,6 +115,9 @@ fn layer_selected(s: &Session, comp: effectcraft_project::ItemId, layer: effectc
s.state.comp_selections.get(&comp).is_some_and(|sel| sel.layers.contains(&layer))
}
/// A comp's selected properties as `[layer, uid]`: the selected ones, then those with selected
/// keyframes (selecting a keyframe selects its property in After Effects, so scripts find
/// selected keys through `selectedProperties`).
fn selected_props(s: &Session, c: &effectcraft_project::Comp) -> Vec<J> {
let mut v: Vec<(u64, u64)> = vec![];
let keyed = s.state.selected_keys.iter().map(|k| (k.layer, k.prop));