Fallback layout animations by motion group
This commit is contained in:
parent
a516b2e721
commit
4ee2c324e1
3 changed files with 115 additions and 27 deletions
64
src/state.rs
64
src/state.rs
|
|
@ -5,7 +5,9 @@ use {
|
|||
animation::{
|
||||
AnimationCurve, AnimationState, AnimationTick, RetainedExitLayer, RetainedToplevel,
|
||||
expand_damage_rect,
|
||||
multiphase::{MultiphaseRequest, MultiphaseWindow, plan_no_overlap},
|
||||
multiphase::{
|
||||
MultiphaseRequest, MultiphaseWindow, partition_motion_groups, plan_no_overlap,
|
||||
},
|
||||
spawn_in_start_rect,
|
||||
},
|
||||
async_engine::{AsyncEngine, SpawnedFuture},
|
||||
|
|
@ -1586,51 +1588,59 @@ impl State {
|
|||
return;
|
||||
};
|
||||
let now = self.now_nsec();
|
||||
if self.start_multiphase_layout_animation(&candidates, now) {
|
||||
return;
|
||||
}
|
||||
for candidate in candidates {
|
||||
self.start_layout_animation_candidate(candidate, now);
|
||||
}
|
||||
}
|
||||
|
||||
fn start_multiphase_layout_animation(
|
||||
self: &Rc<Self>,
|
||||
candidates: &[LayoutAnimationCandidate],
|
||||
now_nsec: u64,
|
||||
) -> bool {
|
||||
if candidates.len() < 2 {
|
||||
return false;
|
||||
}
|
||||
let windows: Vec<_> = candidates
|
||||
.iter()
|
||||
.map(|candidate| MultiphaseWindow {
|
||||
node_id: candidate.node_id,
|
||||
from: self
|
||||
.animations
|
||||
.visual_rect(candidate.node_id, candidate.old, now_nsec),
|
||||
.visual_rect(candidate.node_id, candidate.old, now),
|
||||
to: candidate.new,
|
||||
})
|
||||
.collect();
|
||||
let Some(first) = windows.first() else {
|
||||
for group in partition_motion_groups(&windows) {
|
||||
if self.start_multiphase_layout_animation(&candidates, &windows, &group, now) {
|
||||
continue;
|
||||
}
|
||||
for idx in group {
|
||||
self.start_layout_animation_candidate(candidates[idx].clone(), now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn start_multiphase_layout_animation(
|
||||
self: &Rc<Self>,
|
||||
candidates: &[LayoutAnimationCandidate],
|
||||
windows: &[MultiphaseWindow],
|
||||
group: &[usize],
|
||||
now_nsec: u64,
|
||||
) -> bool {
|
||||
if group.len() < 2 {
|
||||
return false;
|
||||
}
|
||||
let request_windows: Vec<_> = group.iter().map(|&idx| windows[idx]).collect();
|
||||
let Some(first) = request_windows.first() else {
|
||||
return false;
|
||||
};
|
||||
let mut bounds = first.from.union(first.to);
|
||||
for window in &windows[1..] {
|
||||
for window in &request_windows[1..] {
|
||||
bounds = bounds.union(window.from).union(window.to);
|
||||
}
|
||||
let Ok(plan) = plan_no_overlap(&MultiphaseRequest { bounds, windows }) else {
|
||||
let Ok(plan) = plan_no_overlap(&MultiphaseRequest {
|
||||
bounds,
|
||||
windows: request_windows,
|
||||
}) else {
|
||||
return false;
|
||||
};
|
||||
if plan.phases.is_empty() {
|
||||
return false;
|
||||
}
|
||||
let mut entries = vec![];
|
||||
for candidate in candidates {
|
||||
let mut current =
|
||||
self.animations
|
||||
.visual_rect(candidate.node_id, candidate.old, now_nsec);
|
||||
let mut damage = current.union(candidate.new);
|
||||
for &idx in group {
|
||||
let candidate = &candidates[idx];
|
||||
let window = windows[idx];
|
||||
let mut current = window.from;
|
||||
let mut damage = current.union(window.to);
|
||||
let mut phases = vec![];
|
||||
for phase in &plan.phases {
|
||||
match phase
|
||||
|
|
@ -1646,7 +1656,7 @@ impl State {
|
|||
None => phases.push((current, current)),
|
||||
}
|
||||
}
|
||||
if current != candidate.new {
|
||||
if current != window.to {
|
||||
return false;
|
||||
}
|
||||
let retained = self
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue