render: Use render_input_order
This commit is contained in:
parent
140d870e7b
commit
51c8588f89
10 changed files with 1154 additions and 763 deletions
|
|
@ -24,7 +24,7 @@ use smithay::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, SplitRenderElements, Usage},
|
||||
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, Usage},
|
||||
shell::{
|
||||
element::{
|
||||
resize_indicator::ResizeIndicator,
|
||||
|
|
@ -1260,6 +1260,52 @@ impl FloatingLayout {
|
|||
}
|
||||
self.refresh(); //fixup any out of bounds elements
|
||||
}
|
||||
#[profiling::function]
|
||||
pub fn render_popups<R>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
alpha: f32,
|
||||
) -> Vec<CosmicMappedRenderElement<R>>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
CosmicWindowRenderElement<R>: RenderElement<R>,
|
||||
CosmicStackRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
let output = self.space.outputs().next().unwrap();
|
||||
let output_scale = output.current_scale().fractional_scale();
|
||||
|
||||
let mut elements = Vec::default();
|
||||
|
||||
for elem in self
|
||||
.animations
|
||||
.iter()
|
||||
.filter(|(_, anim)| matches!(anim, Animation::Minimize { .. }))
|
||||
.map(|(elem, _)| elem)
|
||||
.chain(self.space.elements().rev())
|
||||
{
|
||||
let (geometry, alpha) = self
|
||||
.animations
|
||||
.get(elem)
|
||||
.map(|anim| (*anim.previous_geometry(), alpha * anim.alpha()))
|
||||
.unwrap_or_else(|| (self.space.element_geometry(elem).unwrap().as_local(), alpha));
|
||||
|
||||
let render_location = geometry.loc - elem.geometry().loc.as_local();
|
||||
elements.extend(
|
||||
elem.popup_render_elements(
|
||||
renderer,
|
||||
render_location
|
||||
.as_logical()
|
||||
.to_physical_precise_round(output_scale),
|
||||
output_scale.into(),
|
||||
alpha,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
elements
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
pub fn render<R>(
|
||||
|
|
@ -1270,7 +1316,7 @@ impl FloatingLayout {
|
|||
indicator_thickness: u8,
|
||||
alpha: f32,
|
||||
theme: &cosmic::theme::CosmicTheme,
|
||||
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
|
||||
) -> Vec<CosmicMappedRenderElement<R>>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||
|
|
@ -1285,7 +1331,7 @@ impl FloatingLayout {
|
|||
};
|
||||
let output_scale = output.current_scale().fractional_scale();
|
||||
|
||||
let mut elements = SplitRenderElements::default();
|
||||
let mut elements = Vec::default();
|
||||
|
||||
for elem in self
|
||||
.animations
|
||||
|
|
@ -1301,10 +1347,7 @@ impl FloatingLayout {
|
|||
.unwrap_or_else(|| (self.space.element_geometry(elem).unwrap().as_local(), alpha));
|
||||
|
||||
let render_location = geometry.loc - elem.geometry().loc.as_local();
|
||||
let SplitRenderElements {
|
||||
mut w_elements,
|
||||
p_elements,
|
||||
} = elem.split_render_elements(
|
||||
let mut window_elements = elem.render_elements(
|
||||
renderer,
|
||||
render_location
|
||||
.as_logical()
|
||||
|
|
@ -1331,7 +1374,7 @@ impl FloatingLayout {
|
|||
y: geometry.size.h as f64 / buffer_size.h as f64,
|
||||
};
|
||||
|
||||
w_elements = w_elements
|
||||
window_elements = window_elements
|
||||
.into_iter()
|
||||
.map(|element| match element {
|
||||
CosmicMappedRenderElement::Stack(elem) => {
|
||||
|
|
@ -1387,7 +1430,7 @@ impl FloatingLayout {
|
|||
|
||||
resize.resize(resize_geometry.size.as_logical());
|
||||
resize.output_enter(output, Rectangle::default() /* unused */);
|
||||
elements.w_elements.extend(
|
||||
window_elements.extend(
|
||||
resize
|
||||
.render_elements::<CosmicWindowRenderElement<R>>(
|
||||
renderer,
|
||||
|
|
@ -1419,12 +1462,11 @@ impl FloatingLayout {
|
|||
active_window_hint.blue,
|
||||
],
|
||||
);
|
||||
elements.w_elements.push(element.into());
|
||||
window_elements.push(element.into());
|
||||
}
|
||||
}
|
||||
|
||||
elements.w_elements.extend(w_elements);
|
||||
elements.p_elements.extend(p_elements);
|
||||
elements.extend(window_elements);
|
||||
}
|
||||
|
||||
elements
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
use crate::{
|
||||
backend::render::{
|
||||
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, SplitRenderElements, Usage,
|
||||
ACTIVE_GROUP_COLOR, GROUP_COLOR,
|
||||
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, Usage, ACTIVE_GROUP_COLOR,
|
||||
GROUP_COLOR,
|
||||
},
|
||||
shell::{
|
||||
element::{
|
||||
|
|
@ -60,7 +60,7 @@ use smithay::{
|
|||
input::Seat,
|
||||
output::Output,
|
||||
reexports::wayland_server::Client,
|
||||
utils::{IsAlive, Logical, Point, Rectangle, Scale, Size},
|
||||
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Size},
|
||||
wayland::{compositor::add_blocker, seat::WaylandFocus},
|
||||
};
|
||||
use std::{
|
||||
|
|
@ -3863,7 +3863,7 @@ impl TilingLayout {
|
|||
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
||||
indicator_thickness: u8,
|
||||
theme: &cosmic::theme::CosmicTheme,
|
||||
) -> Result<SplitRenderElements<CosmicMappedRenderElement<R>>, OutputNotMapped>
|
||||
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||
|
|
@ -3896,7 +3896,7 @@ impl TilingLayout {
|
|||
};
|
||||
let draw_groups = overview.0.alpha();
|
||||
|
||||
let mut elements = SplitRenderElements::default();
|
||||
let mut elements = Vec::default();
|
||||
|
||||
let is_overview = !matches!(overview.0, OverviewMode::None);
|
||||
let is_mouse_tiling = (matches!(overview.0.trigger(), Some(Trigger::Pointer(_))))
|
||||
|
|
@ -3931,7 +3931,7 @@ impl TilingLayout {
|
|||
.unzip();
|
||||
|
||||
// all old windows we want to fade out
|
||||
elements.extend(render_old_tree(
|
||||
elements.extend(render_old_tree_windows(
|
||||
reference_tree,
|
||||
target_tree,
|
||||
renderer,
|
||||
|
|
@ -3969,7 +3969,7 @@ impl TilingLayout {
|
|||
.unzip();
|
||||
|
||||
// all alive windows
|
||||
elements.extend(render_new_tree(
|
||||
elements.extend(render_new_tree_windows(
|
||||
target_tree,
|
||||
reference_tree,
|
||||
renderer,
|
||||
|
|
@ -4001,12 +4001,139 @@ impl TilingLayout {
|
|||
|
||||
// tiling hints
|
||||
if let Some(group_elements) = group_elements {
|
||||
elements.w_elements.extend(group_elements);
|
||||
elements.extend(group_elements);
|
||||
}
|
||||
|
||||
Ok(elements)
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
pub fn render_popups<R>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
seat: Option<&Seat<State>>,
|
||||
non_exclusive_zone: Rectangle<i32, Local>,
|
||||
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
|
||||
theme: &cosmic::theme::CosmicTheme,
|
||||
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
CosmicWindowRenderElement<R>: RenderElement<R>,
|
||||
CosmicStackRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
let output_scale = self.output.current_scale().fractional_scale();
|
||||
|
||||
let (target_tree, duration, _) = if self.queue.animation_start.is_some() {
|
||||
self.queue
|
||||
.trees
|
||||
.get(1)
|
||||
.expect("Animation ongoing, should have two trees")
|
||||
} else {
|
||||
self.queue.trees.front().unwrap()
|
||||
};
|
||||
let reference_tree = self
|
||||
.queue
|
||||
.animation_start
|
||||
.is_some()
|
||||
.then(|| &self.queue.trees.front().unwrap().0);
|
||||
|
||||
let percentage = if let Some(animation_start) = self.queue.animation_start {
|
||||
let percentage = Instant::now().duration_since(animation_start).as_millis() as f32
|
||||
/ duration.as_millis() as f32;
|
||||
ease(EaseInOutCubic, 0.0, 1.0, percentage)
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
let draw_groups = overview.0.alpha();
|
||||
|
||||
let mut elements = Vec::default();
|
||||
|
||||
let is_mouse_tiling = (matches!(overview.0.trigger(), Some(Trigger::Pointer(_))))
|
||||
.then(|| self.last_overview_hover.as_ref().map(|x| &x.1));
|
||||
let swap_desc = if let Some(Trigger::KeyboardSwap(_, desc)) = overview.0.trigger() {
|
||||
Some(desc.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// all gone windows and fade them out
|
||||
let old_geometries = if let Some(reference_tree) = reference_tree.as_ref() {
|
||||
let (geometries, _) = if let Some(transition) = draw_groups {
|
||||
Some(geometries_for_groupview(
|
||||
reference_tree,
|
||||
&mut *renderer,
|
||||
non_exclusive_zone,
|
||||
seat, // TODO: Would be better to be an old focus,
|
||||
// but for that we have to associate focus with a tree (and animate focus changes properly)
|
||||
1.0 - transition,
|
||||
transition,
|
||||
output_scale,
|
||||
&self.placeholder_id,
|
||||
is_mouse_tiling,
|
||||
swap_desc.clone(),
|
||||
overview.1.as_ref().and_then(|(_, tree)| tree.clone()),
|
||||
theme,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.unzip();
|
||||
|
||||
// all old windows we want to fade out
|
||||
elements.extend(render_old_tree_popups(
|
||||
reference_tree,
|
||||
target_tree,
|
||||
renderer,
|
||||
geometries.clone(),
|
||||
output_scale,
|
||||
percentage,
|
||||
swap_desc.is_some(),
|
||||
));
|
||||
|
||||
geometries
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let (geometries, _) = if let Some(transition) = draw_groups {
|
||||
Some(geometries_for_groupview(
|
||||
target_tree,
|
||||
&mut *renderer,
|
||||
non_exclusive_zone,
|
||||
seat,
|
||||
transition,
|
||||
transition,
|
||||
output_scale,
|
||||
&self.placeholder_id,
|
||||
is_mouse_tiling,
|
||||
swap_desc.clone(),
|
||||
overview.1.as_ref().and_then(|(_, tree)| tree.clone()),
|
||||
theme,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.unzip();
|
||||
|
||||
// all alive windows
|
||||
elements.extend(render_new_tree_popups(
|
||||
target_tree,
|
||||
reference_tree,
|
||||
renderer,
|
||||
geometries,
|
||||
old_geometries,
|
||||
seat,
|
||||
&self.output,
|
||||
percentage,
|
||||
overview,
|
||||
swap_desc.clone(),
|
||||
));
|
||||
|
||||
Ok(elements)
|
||||
}
|
||||
|
||||
fn gaps(&self) -> (i32, i32) {
|
||||
let g = self.theme.cosmic().gaps;
|
||||
(g.0 as i32, g.1 as i32)
|
||||
|
|
@ -4690,7 +4817,48 @@ where
|
|||
(geometries, elements)
|
||||
}
|
||||
|
||||
fn render_old_tree<R>(
|
||||
fn render_old_tree_popups<R>(
|
||||
reference_tree: &Tree<Data>,
|
||||
target_tree: &Tree<Data>,
|
||||
renderer: &mut R,
|
||||
geometries: Option<HashMap<NodeId, Rectangle<i32, Local>>>,
|
||||
output_scale: f64,
|
||||
percentage: f32,
|
||||
is_swap_mode: bool,
|
||||
) -> Vec<CosmicMappedRenderElement<R>>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
CosmicWindowRenderElement<R>: RenderElement<R>,
|
||||
CosmicStackRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
let mut elements = Vec::default();
|
||||
|
||||
render_old_tree(
|
||||
reference_tree,
|
||||
target_tree,
|
||||
geometries,
|
||||
output_scale,
|
||||
percentage,
|
||||
is_swap_mode,
|
||||
|mapped, elem_geometry, geo, alpha, _| {
|
||||
elements.extend(
|
||||
mapped.popup_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer,
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
Scale::from(output_scale),
|
||||
alpha,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
elements
|
||||
}
|
||||
|
||||
fn render_old_tree_windows<R>(
|
||||
reference_tree: &Tree<Data>,
|
||||
target_tree: &Tree<Data>,
|
||||
renderer: &mut R,
|
||||
|
|
@ -4700,7 +4868,7 @@ fn render_old_tree<R>(
|
|||
indicator_thickness: u8,
|
||||
is_swap_mode: bool,
|
||||
theme: &cosmic::theme::CosmicTheme,
|
||||
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
|
||||
) -> Vec<CosmicMappedRenderElement<R>>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||
|
|
@ -4709,8 +4877,80 @@ where
|
|||
CosmicStackRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
let window_hint = crate::theme::active_window_hint(theme);
|
||||
let mut elements = SplitRenderElements::default();
|
||||
let mut elements = Vec::default();
|
||||
|
||||
render_old_tree(
|
||||
reference_tree,
|
||||
target_tree,
|
||||
geometries,
|
||||
output_scale,
|
||||
percentage,
|
||||
is_swap_mode,
|
||||
|mapped, elem_geometry, geo, alpha, is_minimizing| {
|
||||
let window_elements = mapped.render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer,
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale) - elem_geometry.loc,
|
||||
Scale::from(output_scale),
|
||||
alpha,
|
||||
);
|
||||
|
||||
elements.extend(window_elements.into_iter().flat_map(|element| {
|
||||
match element {
|
||||
CosmicMappedRenderElement::Stack(elem) => constrain_render_elements(
|
||||
std::iter::once(elem),
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
geo.as_logical().to_physical_precise_round(output_scale),
|
||||
elem_geometry,
|
||||
ConstrainScaleBehavior::Stretch,
|
||||
ConstrainAlign::CENTER,
|
||||
output_scale,
|
||||
)
|
||||
.next()
|
||||
.map(CosmicMappedRenderElement::TiledStack),
|
||||
CosmicMappedRenderElement::Window(elem) => constrain_render_elements(
|
||||
std::iter::once(elem),
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
geo.as_logical().to_physical_precise_round(output_scale),
|
||||
elem_geometry,
|
||||
ConstrainScaleBehavior::Stretch,
|
||||
ConstrainAlign::CENTER,
|
||||
output_scale,
|
||||
)
|
||||
.next()
|
||||
.map(CosmicMappedRenderElement::TiledWindow),
|
||||
x => Some(x),
|
||||
}
|
||||
}));
|
||||
if is_minimizing && indicator_thickness > 0 {
|
||||
elements.push(CosmicMappedRenderElement::FocusIndicator(
|
||||
IndicatorShader::focus_element(
|
||||
renderer,
|
||||
Key::Window(Usage::FocusIndicator, mapped.clone().key()),
|
||||
geo,
|
||||
indicator_thickness,
|
||||
output_scale,
|
||||
alpha,
|
||||
[window_hint.red, window_hint.green, window_hint.blue],
|
||||
),
|
||||
));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
elements
|
||||
}
|
||||
|
||||
fn render_old_tree(
|
||||
reference_tree: &Tree<Data>,
|
||||
target_tree: &Tree<Data>,
|
||||
geometries: Option<HashMap<NodeId, Rectangle<i32, Local>>>,
|
||||
output_scale: f64,
|
||||
percentage: f32,
|
||||
is_swap_mode: bool,
|
||||
mut processor: impl FnMut(&CosmicMapped, Rectangle<i32, Physical>, Rectangle<i32, Local>, f32, bool),
|
||||
) {
|
||||
if let Some(root) = reference_tree.root_node_id() {
|
||||
let geometries = geometries.unwrap_or_default();
|
||||
reference_tree
|
||||
|
|
@ -4779,71 +5019,71 @@ where
|
|||
};
|
||||
|
||||
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
|
||||
let SplitRenderElements {
|
||||
w_elements,
|
||||
p_elements,
|
||||
} = mapped.split_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer,
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
Scale::from(output_scale),
|
||||
alpha,
|
||||
);
|
||||
|
||||
elements
|
||||
.w_elements
|
||||
.extend(w_elements.into_iter().flat_map(|element| {
|
||||
match element {
|
||||
CosmicMappedRenderElement::Stack(elem) => constrain_render_elements(
|
||||
std::iter::once(elem),
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
geo.as_logical().to_physical_precise_round(output_scale),
|
||||
elem_geometry,
|
||||
ConstrainScaleBehavior::Stretch,
|
||||
ConstrainAlign::CENTER,
|
||||
output_scale,
|
||||
)
|
||||
.next()
|
||||
.map(CosmicMappedRenderElement::TiledStack),
|
||||
CosmicMappedRenderElement::Window(elem) => constrain_render_elements(
|
||||
std::iter::once(elem),
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
geo.as_logical().to_physical_precise_round(output_scale),
|
||||
elem_geometry,
|
||||
ConstrainScaleBehavior::Stretch,
|
||||
ConstrainAlign::CENTER,
|
||||
output_scale,
|
||||
)
|
||||
.next()
|
||||
.map(CosmicMappedRenderElement::TiledWindow),
|
||||
x => Some(x),
|
||||
}
|
||||
}));
|
||||
if minimize_geo.is_some() && indicator_thickness > 0 {
|
||||
elements
|
||||
.w_elements
|
||||
.push(CosmicMappedRenderElement::FocusIndicator(
|
||||
IndicatorShader::focus_element(
|
||||
renderer,
|
||||
Key::Window(Usage::FocusIndicator, mapped.clone().key()),
|
||||
geo,
|
||||
indicator_thickness,
|
||||
output_scale,
|
||||
alpha,
|
||||
[window_hint.red, window_hint.green, window_hint.blue],
|
||||
),
|
||||
));
|
||||
}
|
||||
elements.p_elements.extend(p_elements);
|
||||
processor(mapped, elem_geometry, geo, alpha, minimize_geo.is_some())
|
||||
});
|
||||
}
|
||||
|
||||
elements
|
||||
}
|
||||
|
||||
fn render_new_tree<R>(
|
||||
fn render_new_tree_popups<R>(
|
||||
target_tree: &Tree<Data>,
|
||||
reference_tree: Option<&Tree<Data>>,
|
||||
renderer: &mut R,
|
||||
geometries: Option<HashMap<NodeId, Rectangle<i32, Local>>>,
|
||||
old_geometries: Option<HashMap<NodeId, Rectangle<i32, Local>>>,
|
||||
seat: Option<&Seat<State>>,
|
||||
output: &Output,
|
||||
percentage: f32,
|
||||
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
|
||||
swap_desc: Option<NodeDesc>,
|
||||
) -> Vec<CosmicMappedRenderElement<R>>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
CosmicWindowRenderElement<R>: RenderElement<R>,
|
||||
CosmicStackRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
let mut popup_elements = Vec::new();
|
||||
let output_scale = output.current_scale().fractional_scale();
|
||||
|
||||
let is_active_output = seat
|
||||
.map(|seat| &seat.active_output() == output)
|
||||
.unwrap_or(false);
|
||||
|
||||
let (_, swap_tree) = overview.1.unzip();
|
||||
let swap_desc = swap_desc.filter(|_| is_active_output);
|
||||
let swap_tree = swap_tree.flatten().filter(|_| is_active_output);
|
||||
|
||||
render_new_tree(
|
||||
target_tree,
|
||||
reference_tree,
|
||||
geometries,
|
||||
old_geometries,
|
||||
percentage,
|
||||
swap_tree,
|
||||
swap_desc.as_ref(),
|
||||
|_node_id, data, geo, _original_geo, alpha, _| {
|
||||
if let Data::Mapped { mapped, .. } = data {
|
||||
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
|
||||
|
||||
popup_elements.extend(
|
||||
mapped.popup_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer,
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
Scale::from(output_scale),
|
||||
alpha,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
popup_elements
|
||||
}
|
||||
|
||||
fn render_new_tree_windows<R>(
|
||||
target_tree: &Tree<Data>,
|
||||
reference_tree: Option<&Tree<Data>>,
|
||||
renderer: &mut R,
|
||||
|
|
@ -4862,7 +5102,7 @@ fn render_new_tree<R>(
|
|||
swapping_stack_surface_id: &Id,
|
||||
placeholder_id: &Id,
|
||||
theme: &cosmic::theme::CosmicTheme,
|
||||
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
|
||||
) -> Vec<CosmicMappedRenderElement<R>>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||
|
|
@ -4905,7 +5145,6 @@ where
|
|||
|
||||
let mut animating_window_elements = Vec::new();
|
||||
let mut window_elements = Vec::new();
|
||||
let mut popup_elements = Vec::new();
|
||||
|
||||
let mut group_backdrop = None;
|
||||
let mut indicators = Vec::new();
|
||||
|
|
@ -4916,10 +5155,11 @@ where
|
|||
let output_scale = output.current_scale().fractional_scale();
|
||||
|
||||
let (swap_indicator, swap_tree) = overview.1.unzip();
|
||||
let swap_tree = swap_tree.flatten().filter(|_| is_active_output);
|
||||
let swap_desc = swap_desc.filter(|_| is_active_output);
|
||||
let swap_tree = swap_tree.flatten().filter(|_| is_active_output);
|
||||
let window_hint = crate::theme::active_window_hint(theme);
|
||||
let group_color = GROUP_COLOR;
|
||||
|
||||
// render placeholder, if we are swapping to an empty workspace
|
||||
if target_tree.root_node_id().is_none() && swap_desc.is_some() {
|
||||
window_elements.push(
|
||||
|
|
@ -4968,165 +5208,48 @@ where
|
|||
(swap_geo.loc.as_logical() - window_geo.loc).to_physical_precise_round(output_scale);
|
||||
|
||||
swap_elements.extend(
|
||||
window
|
||||
.render_elements::<CosmicWindowRenderElement<R>>(
|
||||
renderer,
|
||||
render_loc,
|
||||
output_scale.into(),
|
||||
1.0,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|window| {
|
||||
CosmicMappedRenderElement::GrabbedWindow(RescaleRenderElement::from_element(
|
||||
window,
|
||||
swap_geo
|
||||
.loc
|
||||
.as_logical()
|
||||
.to_physical_precise_round(output_scale),
|
||||
ease(
|
||||
Linear,
|
||||
1.0,
|
||||
swap_factor(window_geo.size),
|
||||
transition.unwrap_or(1.0),
|
||||
),
|
||||
))
|
||||
}),
|
||||
AsRenderElements::render_elements::<CosmicWindowRenderElement<R>>(
|
||||
&window,
|
||||
renderer,
|
||||
render_loc,
|
||||
output_scale.into(),
|
||||
1.0,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|window| {
|
||||
CosmicMappedRenderElement::GrabbedWindow(RescaleRenderElement::from_element(
|
||||
window,
|
||||
swap_geo
|
||||
.loc
|
||||
.as_logical()
|
||||
.to_physical_precise_round(output_scale),
|
||||
ease(
|
||||
Linear,
|
||||
1.0,
|
||||
swap_factor(window_geo.size),
|
||||
transition.unwrap_or(1.0),
|
||||
),
|
||||
))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// render actual tree nodes
|
||||
let old_geometries = old_geometries.unwrap_or_default();
|
||||
let geometries = geometries.unwrap_or_default();
|
||||
target_tree
|
||||
.root_node_id()
|
||||
.into_iter()
|
||||
.flat_map(|root| target_tree.traverse_pre_order_ids(root).unwrap())
|
||||
.map(|id| (target_tree, id))
|
||||
.chain(
|
||||
swap_tree
|
||||
.into_iter()
|
||||
.flat_map(|tree| {
|
||||
let sub_root = &swap_desc.as_ref().unwrap().node;
|
||||
if swap_desc.as_ref().unwrap().stack_window.is_none() {
|
||||
Some(
|
||||
tree.traverse_pre_order_ids(sub_root)
|
||||
.unwrap()
|
||||
.map(move |id| (tree, id)),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten(),
|
||||
)
|
||||
.for_each(|(target_tree, node_id)| {
|
||||
let data = target_tree.get(&node_id).unwrap().data();
|
||||
let (original_geo, scaled_geo) = (data.geometry(), geometries.get(&node_id));
|
||||
|
||||
let (old_original_geo, old_scaled_geo) =
|
||||
if let Some(reference_tree) = reference_tree.as_ref() {
|
||||
if let Some(root) = reference_tree.root_node_id() {
|
||||
reference_tree
|
||||
.traverse_pre_order_ids(root)
|
||||
.unwrap()
|
||||
.find(|id| &node_id == id)
|
||||
.map(|node_id| {
|
||||
(
|
||||
reference_tree.get(&node_id).unwrap().data().geometry(),
|
||||
old_geometries.get(&node_id),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.unzip();
|
||||
let mut old_geo = old_original_geo.map(|original_geo| {
|
||||
let (scale, offset) = old_scaled_geo
|
||||
.unwrap()
|
||||
.map(|adapted_geo| scale_to_center(original_geo, adapted_geo))
|
||||
.unwrap_or_else(|| (1.0.into(), (0, 0).into()));
|
||||
(
|
||||
old_scaled_geo
|
||||
.unwrap()
|
||||
.map(|adapted_geo| {
|
||||
Rectangle::from_loc_and_size(
|
||||
adapted_geo.loc + offset,
|
||||
(
|
||||
(original_geo.size.w as f64 * scale).round() as i32,
|
||||
(original_geo.size.h as f64 * scale).round() as i32,
|
||||
),
|
||||
)
|
||||
})
|
||||
.unwrap_or(*original_geo),
|
||||
1.0,
|
||||
)
|
||||
});
|
||||
|
||||
let was_minimized = if let Data::Mapped {
|
||||
minimize_rect: Some(minimize_rect),
|
||||
..
|
||||
} = &data
|
||||
{
|
||||
old_geo = Some((*minimize_rect, (percentage * 2.0).min(1.0)));
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let (scale, offset) = scaled_geo
|
||||
.map(|adapted_geo| scale_to_center(original_geo, adapted_geo))
|
||||
.unwrap_or_else(|| (1.0.into(), (0, 0).into()));
|
||||
let new_geo = scaled_geo
|
||||
.map(|adapted_geo| {
|
||||
Rectangle::from_loc_and_size(
|
||||
adapted_geo.loc + offset,
|
||||
(
|
||||
(original_geo.size.w as f64 * scale).round() as i32,
|
||||
(original_geo.size.h as f64 * scale).round() as i32,
|
||||
),
|
||||
)
|
||||
})
|
||||
.unwrap_or(*original_geo);
|
||||
|
||||
let (geo, alpha, animating) = if let Some((old_geo, alpha)) = old_geo.filter(|_| {
|
||||
swap_desc
|
||||
.as_ref()
|
||||
.map(|desc| desc.node != node_id && desc.stack_window.is_none())
|
||||
.unwrap_or(true)
|
||||
}) {
|
||||
(
|
||||
if was_minimized {
|
||||
ease(
|
||||
EaseInOutCubic,
|
||||
EaseRectangle(old_geo),
|
||||
EaseRectangle(new_geo),
|
||||
percentage,
|
||||
)
|
||||
.unwrap()
|
||||
} else {
|
||||
ease(
|
||||
Linear,
|
||||
EaseRectangle(old_geo),
|
||||
EaseRectangle(new_geo),
|
||||
percentage,
|
||||
)
|
||||
.unwrap()
|
||||
},
|
||||
alpha,
|
||||
old_geo != new_geo,
|
||||
)
|
||||
} else {
|
||||
(new_geo, percentage, false)
|
||||
};
|
||||
|
||||
render_new_tree(
|
||||
target_tree,
|
||||
reference_tree,
|
||||
geometries,
|
||||
old_geometries,
|
||||
percentage,
|
||||
swap_tree,
|
||||
swap_desc.as_ref(),
|
||||
|node_id, data, geo, original_geo, alpha, animating| {
|
||||
if swap_desc.as_ref().map(|desc| &desc.node) == Some(&node_id)
|
||||
|| focused.as_ref() == Some(&node_id)
|
||||
{
|
||||
if indicator_thickness > 0 || data.is_group() {
|
||||
let mut geo = geo.clone();
|
||||
|
||||
if data.is_group() {
|
||||
let outer_gap: i32 = (if is_overview { GAP_KEYBOARD } else { 4 } as f32
|
||||
* percentage)
|
||||
|
|
@ -5251,10 +5374,8 @@ where
|
|||
|
||||
if let Data::Mapped { mapped, .. } = data {
|
||||
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
|
||||
let SplitRenderElements {
|
||||
mut w_elements,
|
||||
p_elements,
|
||||
} = mapped.split_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
|
||||
let mut elements = mapped.render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer,
|
||||
//original_location,
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
|
|
@ -5262,6 +5383,7 @@ where
|
|||
Scale::from(output_scale),
|
||||
alpha,
|
||||
);
|
||||
|
||||
if swap_desc
|
||||
.as_ref()
|
||||
.filter(|swap_desc| swap_desc.node == node_id)
|
||||
|
|
@ -5284,7 +5406,7 @@ where
|
|||
{
|
||||
let mut geo = mapped.active_window_geometry().as_local();
|
||||
geo.loc += original_geo.loc;
|
||||
w_elements.insert(
|
||||
elements.insert(
|
||||
0,
|
||||
CosmicMappedRenderElement::Overlay(BackdropShader::element(
|
||||
renderer,
|
||||
|
|
@ -5305,7 +5427,7 @@ where
|
|||
(ConstrainScaleBehavior::CutOff, ConstrainAlign::TOP_LEFT)
|
||||
};
|
||||
|
||||
let w_elements = w_elements.into_iter().flat_map(|element| match element {
|
||||
let elements = elements.into_iter().flat_map(|element| match element {
|
||||
CosmicMappedRenderElement::Stack(elem) => constrain_render_elements(
|
||||
std::iter::once(elem),
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
|
|
@ -5344,6 +5466,7 @@ where
|
|||
.map(CosmicMappedRenderElement::TiledOverlay),
|
||||
x => Some(x),
|
||||
});
|
||||
|
||||
if swap_desc
|
||||
.as_ref()
|
||||
.map(|swap_desc| {
|
||||
|
|
@ -5356,21 +5479,19 @@ where
|
|||
})
|
||||
.unwrap_or(false)
|
||||
{
|
||||
swap_elements.extend(w_elements);
|
||||
swap_elements.extend(elements);
|
||||
} else {
|
||||
if animating {
|
||||
animating_window_elements.extend(w_elements);
|
||||
animating_window_elements.extend(elements);
|
||||
} else {
|
||||
window_elements.extend(w_elements);
|
||||
}
|
||||
if !mapped.is_maximized(false) {
|
||||
popup_elements.extend(p_elements);
|
||||
window_elements.extend(elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
window_elements = resize_elements
|
||||
resize_elements
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.chain(swap_elements)
|
||||
|
|
@ -5378,12 +5499,147 @@ where
|
|||
.chain(window_elements)
|
||||
.chain(animating_window_elements)
|
||||
.chain(group_backdrop.into_iter().map(Into::into))
|
||||
.collect();
|
||||
.collect()
|
||||
}
|
||||
|
||||
SplitRenderElements {
|
||||
w_elements: window_elements,
|
||||
p_elements: popup_elements,
|
||||
}
|
||||
fn render_new_tree(
|
||||
target_tree: &Tree<Data>,
|
||||
reference_tree: Option<&Tree<Data>>,
|
||||
geometries: Option<HashMap<NodeId, Rectangle<i32, Local>>>,
|
||||
old_geometries: Option<HashMap<NodeId, Rectangle<i32, Local>>>,
|
||||
percentage: f32,
|
||||
swap_tree: Option<&Tree<Data>>,
|
||||
swap_desc: Option<&NodeDesc>,
|
||||
mut processor: impl FnMut(NodeId, &Data, Rectangle<i32, Local>, &Rectangle<i32, Local>, f32, bool),
|
||||
) {
|
||||
let old_geometries = old_geometries.unwrap_or_default();
|
||||
let geometries = geometries.unwrap_or_default();
|
||||
target_tree
|
||||
.root_node_id()
|
||||
.into_iter()
|
||||
.flat_map(|root| target_tree.traverse_pre_order_ids(root).unwrap())
|
||||
.map(|id| (target_tree, id))
|
||||
.chain(
|
||||
swap_tree
|
||||
.into_iter()
|
||||
.flat_map(|tree| {
|
||||
let sub_root = &swap_desc.unwrap().node;
|
||||
if swap_desc.unwrap().stack_window.is_none() {
|
||||
Some(
|
||||
tree.traverse_pre_order_ids(sub_root)
|
||||
.unwrap()
|
||||
.map(move |id| (tree, id)),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten(),
|
||||
)
|
||||
.for_each(|(target_tree, node_id)| {
|
||||
let data = target_tree.get(&node_id).unwrap().data();
|
||||
let (original_geo, scaled_geo) = (data.geometry(), geometries.get(&node_id));
|
||||
|
||||
let (old_original_geo, old_scaled_geo) =
|
||||
if let Some(reference_tree) = reference_tree.as_ref() {
|
||||
if let Some(root) = reference_tree.root_node_id() {
|
||||
reference_tree
|
||||
.traverse_pre_order_ids(root)
|
||||
.unwrap()
|
||||
.find(|id| &node_id == id)
|
||||
.map(|node_id| {
|
||||
(
|
||||
reference_tree.get(&node_id).unwrap().data().geometry(),
|
||||
old_geometries.get(&node_id),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.unzip();
|
||||
let mut old_geo = old_original_geo.map(|original_geo| {
|
||||
let (scale, offset) = old_scaled_geo
|
||||
.unwrap()
|
||||
.map(|adapted_geo| scale_to_center(original_geo, adapted_geo))
|
||||
.unwrap_or_else(|| (1.0.into(), (0, 0).into()));
|
||||
(
|
||||
old_scaled_geo
|
||||
.unwrap()
|
||||
.map(|adapted_geo| {
|
||||
Rectangle::from_loc_and_size(
|
||||
adapted_geo.loc + offset,
|
||||
(
|
||||
(original_geo.size.w as f64 * scale).round() as i32,
|
||||
(original_geo.size.h as f64 * scale).round() as i32,
|
||||
),
|
||||
)
|
||||
})
|
||||
.unwrap_or(*original_geo),
|
||||
1.0,
|
||||
)
|
||||
});
|
||||
|
||||
let was_minimized = if let Data::Mapped {
|
||||
minimize_rect: Some(minimize_rect),
|
||||
..
|
||||
} = &data
|
||||
{
|
||||
old_geo = Some((*minimize_rect, (percentage * 2.0).min(1.0)));
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let (scale, offset) = scaled_geo
|
||||
.map(|adapted_geo| scale_to_center(original_geo, adapted_geo))
|
||||
.unwrap_or_else(|| (1.0.into(), (0, 0).into()));
|
||||
let new_geo = scaled_geo
|
||||
.map(|adapted_geo| {
|
||||
Rectangle::from_loc_and_size(
|
||||
adapted_geo.loc + offset,
|
||||
(
|
||||
(original_geo.size.w as f64 * scale).round() as i32,
|
||||
(original_geo.size.h as f64 * scale).round() as i32,
|
||||
),
|
||||
)
|
||||
})
|
||||
.unwrap_or(*original_geo);
|
||||
|
||||
let (geo, alpha, animating) = if let Some((old_geo, alpha)) = old_geo.filter(|_| {
|
||||
swap_desc
|
||||
.map(|desc| desc.node != node_id && desc.stack_window.is_none())
|
||||
.unwrap_or(true)
|
||||
}) {
|
||||
(
|
||||
if was_minimized {
|
||||
ease(
|
||||
EaseInOutCubic,
|
||||
EaseRectangle(old_geo),
|
||||
EaseRectangle(new_geo),
|
||||
percentage,
|
||||
)
|
||||
.unwrap()
|
||||
} else {
|
||||
ease(
|
||||
Linear,
|
||||
EaseRectangle(old_geo),
|
||||
EaseRectangle(new_geo),
|
||||
percentage,
|
||||
)
|
||||
.unwrap()
|
||||
},
|
||||
alpha,
|
||||
old_geo != new_geo,
|
||||
)
|
||||
} else {
|
||||
(new_geo, percentage, false)
|
||||
};
|
||||
|
||||
processor(node_id, data, geo, original_geo, alpha, animating)
|
||||
});
|
||||
}
|
||||
|
||||
fn scale_to_center<C>(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue