Batch layout animation candidates
This commit is contained in:
parent
41d2fef177
commit
b50e8d5683
3 changed files with 55 additions and 5 deletions
|
|
@ -364,6 +364,7 @@ fn start_compositor2(
|
||||||
layout_animations_requested: Default::default(),
|
layout_animations_requested: Default::default(),
|
||||||
layout_animations_active: Default::default(),
|
layout_animations_active: Default::default(),
|
||||||
layout_animation_curve_override: Default::default(),
|
layout_animation_curve_override: Default::default(),
|
||||||
|
layout_animation_batch: Default::default(),
|
||||||
suppress_animations_for_next_layout: Default::default(),
|
suppress_animations_for_next_layout: Default::default(),
|
||||||
toplevels: Default::default(),
|
toplevels: Default::default(),
|
||||||
const_40hz_latch: Default::default(),
|
const_40hz_latch: Default::default(),
|
||||||
|
|
|
||||||
53
src/state.rs
53
src/state.rs
|
|
@ -157,6 +157,14 @@ use {
|
||||||
uapi::{OwnedFd, c},
|
uapi::{OwnedFd, c},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub(crate) struct LayoutAnimationCandidate {
|
||||||
|
node_id: NodeId,
|
||||||
|
old: Rect,
|
||||||
|
new: Rect,
|
||||||
|
retained: Option<Rc<RetainedToplevel>>,
|
||||||
|
curve: AnimationCurve,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub pid: c::pid_t,
|
pub pid: c::pid_t,
|
||||||
pub kb_ctx: KbvmContext,
|
pub kb_ctx: KbvmContext,
|
||||||
|
|
@ -271,6 +279,7 @@ pub struct State {
|
||||||
pub layout_animations_requested: Cell<bool>,
|
pub layout_animations_requested: Cell<bool>,
|
||||||
pub layout_animations_active: Cell<bool>,
|
pub layout_animations_active: Cell<bool>,
|
||||||
pub layout_animation_curve_override: Cell<Option<AnimationCurve>>,
|
pub layout_animation_curve_override: Cell<Option<AnimationCurve>>,
|
||||||
|
pub(crate) layout_animation_batch: RefCell<Option<Vec<LayoutAnimationCandidate>>>,
|
||||||
pub suppress_animations_for_next_layout: Cell<bool>,
|
pub suppress_animations_for_next_layout: Cell<bool>,
|
||||||
pub toplevels: CopyHashMap<ToplevelIdentifier, Weak<dyn ToplevelNode>>,
|
pub toplevels: CopyHashMap<ToplevelIdentifier, Weak<dyn ToplevelNode>>,
|
||||||
pub const_40hz_latch: EventSource<dyn LatchListener>,
|
pub const_40hz_latch: EventSource<dyn LatchListener>,
|
||||||
|
|
@ -1526,25 +1535,59 @@ impl State {
|
||||||
if old_output != new_output || old_scale != new_scale {
|
if old_output != new_output || old_scale != new_scale {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let now = self.now_nsec();
|
let candidate = LayoutAnimationCandidate {
|
||||||
let started = self.animations.set_target(
|
|
||||||
node_id,
|
node_id,
|
||||||
old,
|
old,
|
||||||
new,
|
new,
|
||||||
retained,
|
retained,
|
||||||
now,
|
|
||||||
self.animations.duration_ms.get(),
|
|
||||||
curve,
|
curve,
|
||||||
|
};
|
||||||
|
if let Some(batch) = self.layout_animation_batch.borrow_mut().as_mut() {
|
||||||
|
batch.push(candidate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.start_layout_animation_candidate(candidate, self.now_nsec());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_layout_animation_candidate(
|
||||||
|
self: &Rc<Self>,
|
||||||
|
candidate: LayoutAnimationCandidate,
|
||||||
|
now_nsec: u64,
|
||||||
|
) {
|
||||||
|
let started = self.animations.set_target(
|
||||||
|
candidate.node_id,
|
||||||
|
candidate.old,
|
||||||
|
candidate.new,
|
||||||
|
candidate.retained,
|
||||||
|
now_nsec,
|
||||||
|
self.animations.duration_ms.get(),
|
||||||
|
candidate.curve,
|
||||||
);
|
);
|
||||||
if started {
|
if started {
|
||||||
self.damage(expand_damage_rect(
|
self.damage(expand_damage_rect(
|
||||||
old.union(new),
|
candidate.old.union(candidate.new),
|
||||||
self.theme.sizes.border_width.get().max(0),
|
self.theme.sizes.border_width.get().max(0),
|
||||||
));
|
));
|
||||||
self.ensure_animation_tick();
|
self.ensure_animation_tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn begin_layout_animation_batch(&self) {
|
||||||
|
self.layout_animation_batch
|
||||||
|
.borrow_mut()
|
||||||
|
.get_or_insert_with(Vec::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish_layout_animation_batch(self: &Rc<Self>) {
|
||||||
|
let Some(candidates) = self.layout_animation_batch.borrow_mut().take() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let now = self.now_nsec();
|
||||||
|
for candidate in candidates {
|
||||||
|
self.start_layout_animation_candidate(candidate, now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn queue_spawn_in_animation(
|
pub fn queue_spawn_in_animation(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
|
|
|
||||||
|
|
@ -1771,7 +1771,13 @@ pub async fn container_layout(state: Rc<State>) {
|
||||||
let animate = container.animate_next_layout.replace(false)
|
let animate = container.animate_next_layout.replace(false)
|
||||||
&& !state.suppress_animations_for_next_layout.get();
|
&& !state.suppress_animations_for_next_layout.get();
|
||||||
let prev_active = state.layout_animations_active.replace(animate);
|
let prev_active = state.layout_animations_active.replace(animate);
|
||||||
|
if animate {
|
||||||
|
state.begin_layout_animation_batch();
|
||||||
|
}
|
||||||
container.perform_layout();
|
container.perform_layout();
|
||||||
|
if animate {
|
||||||
|
state.finish_layout_animation_batch();
|
||||||
|
}
|
||||||
state.layout_animations_active.set(prev_active);
|
state.layout_animations_active.set(prev_active);
|
||||||
}
|
}
|
||||||
state.suppress_animations_for_next_layout.set(false);
|
state.suppress_animations_for_next_layout.set(false);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue