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 @@ where
|
||||||
<R as Renderer>::TextureId: 'static,
|
<R as Renderer>::TextureId: 'static,
|
||||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||||
{
|
{
|
||||||
Workspace(RelocateRenderElement<WorkspaceRenderElement<R>>),
|
Workspace(RelocateRenderElement<CropRenderElement<WorkspaceRenderElement<R>>>),
|
||||||
Cursor(RelocateRenderElement<CursorRenderElement<R>>),
|
Cursor(RelocateRenderElement<CursorRenderElement<R>>),
|
||||||
Dnd(WaylandSurfaceRenderElement<R>),
|
Dnd(WaylandSurfaceRenderElement<R>),
|
||||||
MoveGrab(CosmicMappedRenderElement<R>),
|
MoveGrab(CosmicMappedRenderElement<R>),
|
||||||
|
|
@ -266,13 +266,13 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> From<WorkspaceRenderElement<R>> for CosmicElement<R>
|
impl<R> From<CropRenderElement<WorkspaceRenderElement<R>>> for CosmicElement<R>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: 'static,
|
<R as Renderer>::TextureId: 'static,
|
||||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||||
{
|
{
|
||||||
fn from(elem: WorkspaceRenderElement<R>) -> Self {
|
fn from(elem: CropRenderElement<WorkspaceRenderElement<R>>) -> Self {
|
||||||
Self::Workspace(RelocateRenderElement::from_element(
|
Self::Workspace(RelocateRenderElement::from_element(
|
||||||
elem,
|
elem,
|
||||||
(0, 0),
|
(0, 0),
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use std::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
ops::ControlFlow,
|
||||||
sync::{Arc, RwLock, Weak},
|
sync::{Arc, RwLock, Weak},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
@ -14,16 +15,13 @@ use crate::{
|
||||||
backend::{kms::render::gles::GbmGlowBackend, render::element::DamageElement},
|
backend::{kms::render::gles::GbmGlowBackend, render::element::DamageElement},
|
||||||
shell::{
|
shell::{
|
||||||
element::CosmicMappedKey,
|
element::CosmicMappedKey,
|
||||||
focus::target::WindowGroup,
|
focus::{render_input_order, target::WindowGroup, Stage},
|
||||||
grabs::{SeatMenuGrabState, SeatMoveGrabState},
|
grabs::{SeatMenuGrabState, SeatMoveGrabState},
|
||||||
layout::tiling::ANIMATION_DURATION,
|
layout::tiling::ANIMATION_DURATION,
|
||||||
CosmicMappedRenderElement, OverviewMode, SeatExt, SessionLock, Trigger, WorkspaceDelta,
|
CosmicMappedRenderElement, OverviewMode, SeatExt, Trigger, WorkspaceDelta,
|
||||||
WorkspaceRenderElement,
|
WorkspaceRenderElement,
|
||||||
},
|
},
|
||||||
utils::{
|
utils::{prelude::*, quirks::workspace_overview_is_open},
|
||||||
prelude::*,
|
|
||||||
quirks::{workspace_overview_is_open, WORKSPACE_OVERVIEW_NAMESPACE},
|
|
||||||
},
|
|
||||||
wayland::{
|
wayland::{
|
||||||
handlers::{
|
handlers::{
|
||||||
data_device::get_dnd_icon,
|
data_device::get_dnd_icon,
|
||||||
|
|
@ -34,9 +32,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use cosmic::Theme;
|
use cosmic::Theme;
|
||||||
use cosmic_comp_config::workspace::WorkspaceLayout;
|
|
||||||
use element::FromGlesError;
|
use element::FromGlesError;
|
||||||
use keyframe::{ease, functions::EaseInOutCubic};
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
allocator::dmabuf::Dmabuf,
|
allocator::dmabuf::Dmabuf,
|
||||||
|
|
@ -46,7 +42,7 @@ use smithay::{
|
||||||
damage::{Error as RenderError, OutputDamageTracker, RenderOutputResult},
|
damage::{Error as RenderError, OutputDamageTracker, RenderOutputResult},
|
||||||
element::{
|
element::{
|
||||||
surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement},
|
surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement},
|
||||||
utils::{Relocate, RelocateRenderElement},
|
utils::{CropRenderElement, Relocate, RelocateRenderElement},
|
||||||
AsRenderElements, Element, Id, Kind, RenderElement,
|
AsRenderElements, Element, Id, Kind, RenderElement,
|
||||||
},
|
},
|
||||||
gles::{
|
gles::{
|
||||||
|
|
@ -60,13 +56,12 @@ use smithay::{
|
||||||
TextureFilter,
|
TextureFilter,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
desktop::{layer_map_for_output, PopupManager},
|
|
||||||
input::Seat,
|
input::Seat,
|
||||||
output::{Output, OutputNoMode},
|
output::{Output, OutputNoMode},
|
||||||
utils::{IsAlive, Logical, Monotonic, Physical, Point, Rectangle, Scale, Time, Transform},
|
utils::{IsAlive, Logical, Monotonic, Point, Rectangle, Scale, Time, Transform},
|
||||||
wayland::{
|
wayland::{
|
||||||
dmabuf::get_dmabuf,
|
dmabuf::get_dmabuf,
|
||||||
shell::wlr_layer::Layer,
|
session_lock::LockSurface,
|
||||||
shm::{shm_format_to_fourcc, with_buffer_contents},
|
shm::{shm_format_to_fourcc, with_buffer_contents},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -504,60 +499,6 @@ pub enum ElementFilter {
|
||||||
LayerShellOnly,
|
LayerShellOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct SplitRenderElements<E> {
|
|
||||||
pub w_elements: Vec<E>,
|
|
||||||
pub p_elements: Vec<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E> Default for SplitRenderElements<E> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
w_elements: Vec::new(),
|
|
||||||
p_elements: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E> SplitRenderElements<E> {
|
|
||||||
pub fn extend(&mut self, other: Self) {
|
|
||||||
self.w_elements.extend(other.w_elements);
|
|
||||||
self.p_elements.extend(other.p_elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extend_map<E2, F: FnMut(E2) -> E>(&mut self, other: SplitRenderElements<E2>, mut f: F) {
|
|
||||||
self.w_elements
|
|
||||||
.extend(other.w_elements.into_iter().map(&mut f));
|
|
||||||
self.p_elements
|
|
||||||
.extend(other.p_elements.into_iter().map(&mut f));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn join(mut self) -> Vec<E> {
|
|
||||||
self.p_elements.extend(self.w_elements);
|
|
||||||
self.p_elements
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> SplitRenderElements<CosmicElement<R>>
|
|
||||||
where
|
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
|
||||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
|
||||||
{
|
|
||||||
fn extend_from_workspace_elements<E: Into<WorkspaceRenderElement<R>>>(
|
|
||||||
&mut self,
|
|
||||||
other: SplitRenderElements<E>,
|
|
||||||
offset: Point<i32, Physical>,
|
|
||||||
) {
|
|
||||||
self.extend_map(other, |element| {
|
|
||||||
CosmicElement::Workspace(RelocateRenderElement::from_element(
|
|
||||||
element.into(),
|
|
||||||
offset,
|
|
||||||
Relocate::Relative,
|
|
||||||
))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[profiling::function]
|
#[profiling::function]
|
||||||
pub fn workspace_elements<R>(
|
pub fn workspace_elements<R>(
|
||||||
_gpu: Option<&DrmNode>,
|
_gpu: Option<&DrmNode>,
|
||||||
|
|
@ -578,7 +519,7 @@ where
|
||||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||||
WorkspaceRenderElement<R>: RenderElement<R>,
|
WorkspaceRenderElement<R>: RenderElement<R>,
|
||||||
{
|
{
|
||||||
let mut elements = SplitRenderElements::default();
|
let mut elements = Vec::new();
|
||||||
|
|
||||||
let theme = shell.read().unwrap().theme().clone();
|
let theme = shell.read().unwrap().theme().clone();
|
||||||
let seats = shell
|
let seats = shell
|
||||||
|
|
@ -588,8 +529,9 @@ where
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
let scale = output.current_scale().fractional_scale();
|
||||||
|
|
||||||
elements.p_elements.extend(cursor_elements(
|
elements.extend(cursor_elements(
|
||||||
renderer,
|
renderer,
|
||||||
seats.iter(),
|
seats.iter(),
|
||||||
&theme,
|
&theme,
|
||||||
|
|
@ -602,7 +544,6 @@ where
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
{
|
{
|
||||||
let output_geo = output.geometry();
|
let output_geo = output.geometry();
|
||||||
let scale = output.current_scale().fractional_scale();
|
|
||||||
|
|
||||||
if let Some((state, timings)) = _fps {
|
if let Some((state, timings)) = _fps {
|
||||||
let debug_active = shell.read().unwrap().debug_active;
|
let debug_active = shell.read().unwrap().debug_active;
|
||||||
|
|
@ -621,23 +562,12 @@ where
|
||||||
)
|
)
|
||||||
.map_err(FromGlesError::from_gles_error)
|
.map_err(FromGlesError::from_gles_error)
|
||||||
.map_err(RenderError::Rendering)?;
|
.map_err(RenderError::Rendering)?;
|
||||||
elements.p_elements.push(fps_overlay.into());
|
elements.push(fps_overlay.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let shell = shell.read().unwrap();
|
let shell = shell.read().unwrap();
|
||||||
|
|
||||||
// If session locked, only show session lock surfaces
|
|
||||||
if let Some(session_lock) = &shell.session_lock {
|
|
||||||
elements.p_elements.extend(
|
|
||||||
session_lock_elements(renderer, output, session_lock)
|
|
||||||
.into_iter()
|
|
||||||
.map(|x| WorkspaceRenderElement::from(x).into()),
|
|
||||||
);
|
|
||||||
return Ok(elements.join());
|
|
||||||
}
|
|
||||||
|
|
||||||
let theme = theme.cosmic();
|
|
||||||
let overview = shell.overview_mode();
|
let overview = shell.overview_mode();
|
||||||
let (resize_mode, resize_indicator) = shell.resize_mode();
|
let (resize_mode, resize_indicator) = shell.resize_mode();
|
||||||
let resize_indicator = resize_indicator.map(|indicator| (resize_mode, indicator));
|
let resize_indicator = resize_indicator.map(|indicator| (resize_mode, indicator));
|
||||||
|
|
@ -666,310 +596,252 @@ where
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_some();
|
.is_some();
|
||||||
let focused_output = last_active_seat.focused_or_active_output();
|
let focused_output = last_active_seat.focused_or_active_output();
|
||||||
let output_size = output.geometry().size;
|
|
||||||
let output_scale = output.current_scale().fractional_scale();
|
|
||||||
|
|
||||||
let set = shell.workspaces.sets.get(output).ok_or(OutputNoMode)?;
|
let set = shell.workspaces.sets.get(output).ok_or(OutputNoMode)?;
|
||||||
let workspace = set
|
let workspace = set
|
||||||
.workspaces
|
.workspaces
|
||||||
.iter()
|
.iter()
|
||||||
.find(|w| w.handle == current.0)
|
.find(|w| w.handle == current.0)
|
||||||
.ok_or(OutputNoMode)?;
|
.ok_or(OutputNoMode)?;
|
||||||
let is_active_space = workspace.outputs().any(|o| o == &focused_output);
|
let is_active_space = workspace.output == focused_output;
|
||||||
|
|
||||||
let has_fullscreen = workspace
|
|
||||||
.fullscreen
|
|
||||||
.as_ref()
|
|
||||||
.filter(|f| !f.is_animating())
|
|
||||||
.is_some();
|
|
||||||
let overlay_elements = split_layer_elements(renderer, output, Layer::Overlay, element_filter);
|
|
||||||
|
|
||||||
// overlay is above everything
|
|
||||||
elements
|
|
||||||
.p_elements
|
|
||||||
.extend(overlay_elements.p_elements.into_iter().map(Into::into));
|
|
||||||
elements
|
|
||||||
.p_elements
|
|
||||||
.extend(overlay_elements.w_elements.into_iter().map(Into::into));
|
|
||||||
|
|
||||||
if !has_fullscreen {
|
|
||||||
elements.extend_from_workspace_elements(
|
|
||||||
split_layer_elements(renderer, output, Layer::Top, element_filter),
|
|
||||||
(0, 0).into(),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
let active_hint = if shell.active_hint {
|
let active_hint = if shell.active_hint {
|
||||||
theme.active_hint as u8
|
theme.cosmic().active_hint as u8
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
// overlay redirect windows
|
let output_size = output
|
||||||
// they need to be over sticky windows, because they could be popups of sticky windows,
|
.geometry()
|
||||||
// and we can't differenciate that.
|
.size
|
||||||
if element_filter != ElementFilter::LayerShellOnly {
|
.as_logical()
|
||||||
elements.p_elements.extend(
|
.to_physical_precise_round(scale);
|
||||||
shell
|
let crop_to_output = |element: WorkspaceRenderElement<R>| {
|
||||||
.override_redirect_windows
|
CropRenderElement::from_element(
|
||||||
.iter()
|
element.into(),
|
||||||
.filter(|or| {
|
scale,
|
||||||
(*or)
|
Rectangle::from_loc_and_size((0, 0), output_size),
|
||||||
.geometry()
|
)
|
||||||
.as_global()
|
|
||||||
.intersection(workspace.output.geometry())
|
|
||||||
.is_some()
|
|
||||||
})
|
|
||||||
.flat_map(|or| {
|
|
||||||
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
|
|
||||||
or,
|
|
||||||
renderer,
|
|
||||||
(or.geometry().loc - workspace.output.geometry().loc.as_logical())
|
|
||||||
.to_physical_precise_round(output_scale),
|
|
||||||
Scale::from(output_scale),
|
|
||||||
1.0,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.map(|p_element| p_element.into()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sticky windows
|
|
||||||
if !has_fullscreen && element_filter != ElementFilter::LayerShellOnly {
|
|
||||||
let alpha = match &overview.0 {
|
|
||||||
OverviewMode::Started(_, started) => {
|
|
||||||
(1.0 - (Instant::now().duration_since(*started).as_millis()
|
|
||||||
/ ANIMATION_DURATION.as_millis()) as f32)
|
|
||||||
.max(0.0)
|
|
||||||
* 0.4
|
|
||||||
+ 0.6
|
|
||||||
}
|
|
||||||
OverviewMode::Ended(_, ended) => {
|
|
||||||
((Instant::now().duration_since(*ended).as_millis()
|
|
||||||
/ ANIMATION_DURATION.as_millis()) as f32)
|
|
||||||
* 0.4
|
|
||||||
+ 0.6
|
|
||||||
}
|
|
||||||
OverviewMode::Active(_) => 0.6,
|
|
||||||
OverviewMode::None => 1.0,
|
|
||||||
};
|
|
||||||
|
|
||||||
let current_focus = (!move_active && is_active_space)
|
|
||||||
.then_some(last_active_seat)
|
|
||||||
.map(|seat| workspace.focus_stack.get(seat));
|
|
||||||
|
|
||||||
elements.extend_from_workspace_elements(
|
|
||||||
set.sticky_layer.render(
|
|
||||||
renderer,
|
|
||||||
current_focus.as_ref().and_then(|stack| stack.last()),
|
|
||||||
resize_indicator.clone(),
|
|
||||||
active_hint,
|
|
||||||
alpha,
|
|
||||||
theme,
|
|
||||||
),
|
|
||||||
(0, 0).into(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let offset = match previous.as_ref() {
|
|
||||||
Some((previous, previous_idx, start)) => {
|
|
||||||
let layout = shell.workspaces.layout;
|
|
||||||
|
|
||||||
let workspace = shell
|
|
||||||
.workspaces
|
|
||||||
.space_for_handle(&previous)
|
|
||||||
.ok_or(OutputNoMode)?;
|
|
||||||
let has_fullscreen = workspace.fullscreen.is_some();
|
|
||||||
let is_active_space = workspace.outputs().any(|o| o == &focused_output);
|
|
||||||
|
|
||||||
let percentage = match start {
|
|
||||||
WorkspaceDelta::Shortcut(st) => ease(
|
|
||||||
EaseInOutCubic,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
Instant::now().duration_since(*st).as_millis() as f32
|
|
||||||
/ ANIMATION_DURATION.as_millis() as f32,
|
|
||||||
),
|
|
||||||
WorkspaceDelta::Gesture(prog) => *prog as f32,
|
|
||||||
WorkspaceDelta::GestureEnd(st, spring) => {
|
|
||||||
(spring.value_at(Instant::now().duration_since(*st)) as f32).clamp(0.0, 1.0)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let offset = Point::<i32, Logical>::from(match (layout, *previous_idx < current.1) {
|
|
||||||
(WorkspaceLayout::Vertical, true) => {
|
|
||||||
(0, (-output_size.h as f32 * percentage).round() as i32)
|
|
||||||
}
|
|
||||||
(WorkspaceLayout::Vertical, false) => {
|
|
||||||
(0, (output_size.h as f32 * percentage).round() as i32)
|
|
||||||
}
|
|
||||||
(WorkspaceLayout::Horizontal, true) => {
|
|
||||||
((-output_size.w as f32 * percentage).round() as i32, 0)
|
|
||||||
}
|
|
||||||
(WorkspaceLayout::Horizontal, false) => {
|
|
||||||
((output_size.w as f32 * percentage).round() as i32, 0)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
elements.extend_from_workspace_elements(
|
|
||||||
workspace
|
|
||||||
.render::<R>(
|
|
||||||
renderer,
|
|
||||||
(!move_active && is_active_space).then_some(last_active_seat),
|
|
||||||
overview.clone(),
|
|
||||||
resize_indicator.clone(),
|
|
||||||
active_hint,
|
|
||||||
theme,
|
|
||||||
)
|
|
||||||
.map_err(|_| OutputNoMode)?,
|
|
||||||
offset.to_physical_precise_round(output_scale),
|
|
||||||
);
|
|
||||||
|
|
||||||
if !has_fullscreen {
|
|
||||||
elements.extend_from_workspace_elements(
|
|
||||||
background_layer_elements(renderer, output, element_filter),
|
|
||||||
offset.to_physical_precise_round(output_scale),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Point::<i32, Logical>::from(match (layout, *previous_idx < current.1) {
|
|
||||||
(WorkspaceLayout::Vertical, true) => (0, output_size.h + offset.y),
|
|
||||||
(WorkspaceLayout::Vertical, false) => (0, -(output_size.h - offset.y)),
|
|
||||||
(WorkspaceLayout::Horizontal, true) => (output_size.w + offset.x, 0),
|
|
||||||
(WorkspaceLayout::Horizontal, false) => (-(output_size.w - offset.x), 0),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
None => (0, 0).into(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if element_filter != ElementFilter::LayerShellOnly {
|
render_input_order(
|
||||||
elements.extend_from_workspace_elements(
|
&*shell,
|
||||||
workspace
|
output,
|
||||||
.render::<R>(
|
previous,
|
||||||
renderer,
|
current,
|
||||||
(!move_active && is_active_space).then_some(&last_active_seat),
|
element_filter,
|
||||||
overview,
|
|stage| {
|
||||||
resize_indicator,
|
match stage {
|
||||||
active_hint,
|
Stage::SessionLock(lock_surface) => {
|
||||||
theme,
|
elements.extend(
|
||||||
)
|
session_lock_elements(renderer, output, lock_surface)
|
||||||
.map_err(|_| OutputNoMode)?,
|
.into_iter()
|
||||||
offset.to_physical_precise_round(output_scale),
|
.map(Into::into)
|
||||||
);
|
.flat_map(crop_to_output)
|
||||||
}
|
.map(Into::into),
|
||||||
|
);
|
||||||
if !has_fullscreen {
|
}
|
||||||
elements.extend_from_workspace_elements(
|
Stage::LayerPopup {
|
||||||
background_layer_elements(renderer, output, element_filter),
|
popup, location, ..
|
||||||
offset.to_physical_precise_round(output_scale),
|
} => {
|
||||||
);
|
elements.extend(
|
||||||
}
|
render_elements_from_surface_tree::<_, WorkspaceRenderElement<_>>(
|
||||||
|
|
||||||
Ok(elements.join())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn split_layer_elements<R>(
|
|
||||||
renderer: &mut R,
|
|
||||||
output: &Output,
|
|
||||||
layer: Layer,
|
|
||||||
element_filter: ElementFilter,
|
|
||||||
) -> SplitRenderElements<WorkspaceRenderElement<R>>
|
|
||||||
where
|
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
|
||||||
<R as Renderer>::TextureId: Clone + 'static,
|
|
||||||
<R as Renderer>::Error: FromGlesError,
|
|
||||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
|
||||||
WorkspaceRenderElement<R>: RenderElement<R>,
|
|
||||||
{
|
|
||||||
let layer_map = layer_map_for_output(output);
|
|
||||||
let output_scale = output.current_scale().fractional_scale();
|
|
||||||
|
|
||||||
let mut elements = SplitRenderElements::default();
|
|
||||||
|
|
||||||
layer_map
|
|
||||||
.layers_on(layer)
|
|
||||||
.rev()
|
|
||||||
.filter(|s| {
|
|
||||||
!(element_filter == ElementFilter::ExcludeWorkspaceOverview
|
|
||||||
&& s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
|
|
||||||
})
|
|
||||||
.filter_map(|surface| {
|
|
||||||
layer_map
|
|
||||||
.layer_geometry(surface)
|
|
||||||
.map(|geo| (geo.loc, surface))
|
|
||||||
})
|
|
||||||
.for_each(|(location, surface)| {
|
|
||||||
let location = location.to_physical_precise_round(output_scale);
|
|
||||||
let surface = surface.wl_surface();
|
|
||||||
let scale = Scale::from(output_scale);
|
|
||||||
|
|
||||||
elements
|
|
||||||
.p_elements
|
|
||||||
.extend(PopupManager::popups_for_surface(surface).flat_map(
|
|
||||||
|(popup, popup_offset)| {
|
|
||||||
let offset = (popup_offset - popup.geometry().loc)
|
|
||||||
.to_f64()
|
|
||||||
.to_physical(scale)
|
|
||||||
.to_i32_round();
|
|
||||||
|
|
||||||
render_elements_from_surface_tree(
|
|
||||||
renderer,
|
renderer,
|
||||||
popup.wl_surface(),
|
popup.wl_surface(),
|
||||||
location + offset,
|
location
|
||||||
scale,
|
.to_local(output)
|
||||||
|
.as_logical()
|
||||||
|
.to_physical_precise_round(scale),
|
||||||
|
Scale::from(scale),
|
||||||
1.0,
|
1.0,
|
||||||
Kind::Unspecified,
|
Kind::Unspecified,
|
||||||
)
|
)
|
||||||
},
|
.into_iter()
|
||||||
));
|
.flat_map(crop_to_output)
|
||||||
|
.map(Into::into),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Stage::LayerSurface { layer, location } => {
|
||||||
|
elements.extend(
|
||||||
|
render_elements_from_surface_tree::<_, WorkspaceRenderElement<_>>(
|
||||||
|
renderer,
|
||||||
|
&layer.wl_surface(),
|
||||||
|
location
|
||||||
|
.to_local(output)
|
||||||
|
.as_logical()
|
||||||
|
.to_physical_precise_round(scale),
|
||||||
|
Scale::from(scale),
|
||||||
|
1.0,
|
||||||
|
Kind::Unspecified,
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(crop_to_output)
|
||||||
|
.map(Into::into),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Stage::OverrideRedirect { surface, location } => {
|
||||||
|
elements.extend(
|
||||||
|
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
|
||||||
|
surface,
|
||||||
|
renderer,
|
||||||
|
location
|
||||||
|
.to_local(output)
|
||||||
|
.as_logical()
|
||||||
|
.to_physical_precise_round(scale),
|
||||||
|
Scale::from(scale),
|
||||||
|
1.0,
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(crop_to_output)
|
||||||
|
.map(Into::into),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Stage::StickyPopups(layout) => {
|
||||||
|
let alpha = match &overview.0 {
|
||||||
|
OverviewMode::Started(_, started) => {
|
||||||
|
(1.0 - (Instant::now().duration_since(*started).as_millis()
|
||||||
|
/ ANIMATION_DURATION.as_millis())
|
||||||
|
as f32)
|
||||||
|
.max(0.0)
|
||||||
|
* 0.4
|
||||||
|
+ 0.6
|
||||||
|
}
|
||||||
|
OverviewMode::Ended(_, ended) => {
|
||||||
|
((Instant::now().duration_since(*ended).as_millis()
|
||||||
|
/ ANIMATION_DURATION.as_millis())
|
||||||
|
as f32)
|
||||||
|
* 0.4
|
||||||
|
+ 0.6
|
||||||
|
}
|
||||||
|
OverviewMode::Active(_) => 0.6,
|
||||||
|
OverviewMode::None => 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
elements
|
elements.extend(
|
||||||
.w_elements
|
layout
|
||||||
.extend(render_elements_from_surface_tree(
|
.render_popups(renderer, alpha)
|
||||||
renderer,
|
.into_iter()
|
||||||
surface,
|
.map(Into::into)
|
||||||
location,
|
.flat_map(crop_to_output)
|
||||||
scale,
|
.map(Into::into),
|
||||||
1.0,
|
);
|
||||||
Kind::Unspecified,
|
}
|
||||||
));
|
Stage::Sticky(layout) => {
|
||||||
});
|
let alpha = match &overview.0 {
|
||||||
|
OverviewMode::Started(_, started) => {
|
||||||
|
(1.0 - (Instant::now().duration_since(*started).as_millis()
|
||||||
|
/ ANIMATION_DURATION.as_millis())
|
||||||
|
as f32)
|
||||||
|
.max(0.0)
|
||||||
|
* 0.4
|
||||||
|
+ 0.6
|
||||||
|
}
|
||||||
|
OverviewMode::Ended(_, ended) => {
|
||||||
|
((Instant::now().duration_since(*ended).as_millis()
|
||||||
|
/ ANIMATION_DURATION.as_millis())
|
||||||
|
as f32)
|
||||||
|
* 0.4
|
||||||
|
+ 0.6
|
||||||
|
}
|
||||||
|
OverviewMode::Active(_) => 0.6,
|
||||||
|
OverviewMode::None => 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
elements
|
let current_focus = (!move_active && is_active_space)
|
||||||
}
|
.then_some(last_active_seat)
|
||||||
|
.map(|seat| workspace.focus_stack.get(seat));
|
||||||
|
|
||||||
// bottom and background layer surfaces
|
elements.extend(
|
||||||
pub fn background_layer_elements<R>(
|
layout
|
||||||
renderer: &mut R,
|
.render(
|
||||||
output: &Output,
|
renderer,
|
||||||
element_filter: ElementFilter,
|
current_focus.as_ref().and_then(|stack| stack.last()),
|
||||||
) -> SplitRenderElements<WorkspaceRenderElement<R>>
|
resize_indicator.clone(),
|
||||||
where
|
active_hint,
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
alpha,
|
||||||
<R as Renderer>::TextureId: Clone + 'static,
|
&theme.cosmic(),
|
||||||
<R as Renderer>::Error: FromGlesError,
|
)
|
||||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
.into_iter()
|
||||||
WorkspaceRenderElement<R>: RenderElement<R>,
|
.map(Into::into)
|
||||||
{
|
.flat_map(crop_to_output)
|
||||||
let mut elements = split_layer_elements(renderer, output, Layer::Bottom, element_filter);
|
.map(Into::into),
|
||||||
elements.extend(split_layer_elements(
|
)
|
||||||
renderer,
|
}
|
||||||
output,
|
Stage::WorkspacePopups { workspace, offset } => {
|
||||||
Layer::Background,
|
elements.extend(
|
||||||
element_filter,
|
match workspace.render_popups(
|
||||||
));
|
renderer,
|
||||||
elements
|
(!move_active && is_active_space).then_some(last_active_seat),
|
||||||
|
overview.clone(),
|
||||||
|
&theme.cosmic(),
|
||||||
|
) {
|
||||||
|
Ok(elements) => {
|
||||||
|
elements
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(crop_to_output)
|
||||||
|
.map(|element| {
|
||||||
|
CosmicElement::Workspace(
|
||||||
|
RelocateRenderElement::from_element(
|
||||||
|
element,
|
||||||
|
offset.to_physical_precise_round(scale),
|
||||||
|
Relocate::Relative,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
return ControlFlow::Break(Err(OutputNoMode));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Stage::Workspace { workspace, offset } => {
|
||||||
|
elements.extend(
|
||||||
|
match workspace.render(
|
||||||
|
renderer,
|
||||||
|
(!move_active && is_active_space).then_some(last_active_seat),
|
||||||
|
overview.clone(),
|
||||||
|
resize_indicator.clone(),
|
||||||
|
active_hint,
|
||||||
|
&theme.cosmic(),
|
||||||
|
) {
|
||||||
|
Ok(elements) => {
|
||||||
|
elements
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(crop_to_output)
|
||||||
|
.map(|element| {
|
||||||
|
CosmicElement::Workspace(
|
||||||
|
RelocateRenderElement::from_element(
|
||||||
|
element,
|
||||||
|
offset.to_physical_precise_round(scale),
|
||||||
|
Relocate::Relative,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
return ControlFlow::Break(Err(OutputNoMode));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn session_lock_elements<R>(
|
fn session_lock_elements<R>(
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
session_lock: &SessionLock,
|
lock_surface: Option<&LockSurface>,
|
||||||
) -> Vec<WaylandSurfaceRenderElement<R>>
|
) -> Vec<WaylandSurfaceRenderElement<R>>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll,
|
R: Renderer + ImportAll,
|
||||||
<R as Renderer>::TextureId: Clone + 'static,
|
<R as Renderer>::TextureId: Clone + 'static,
|
||||||
{
|
{
|
||||||
if let Some(surface) = session_lock.surfaces.get(output) {
|
if let Some(surface) = lock_surface {
|
||||||
let scale = Scale::from(output.current_scale().fractional_scale());
|
let scale = Scale::from(output.current_scale().fractional_scale());
|
||||||
render_elements_from_surface_tree(
|
render_elements_from_surface_tree(
|
||||||
renderer,
|
renderer,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{
|
backend::render::element::{AsGlowRenderer, FromGlesError},
|
||||||
element::{AsGlowRenderer, FromGlesError},
|
|
||||||
SplitRenderElements,
|
|
||||||
},
|
|
||||||
state::State,
|
state::State,
|
||||||
utils::{iced::IcedElementInternal, prelude::*},
|
utils::{iced::IcedElementInternal, prelude::*},
|
||||||
};
|
};
|
||||||
|
|
@ -657,13 +654,42 @@ impl CosmicMapped {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split_render_elements<R, C>(
|
pub fn popup_render_elements<R, C>(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
location: smithay::utils::Point<i32, smithay::utils::Physical>,
|
location: smithay::utils::Point<i32, smithay::utils::Physical>,
|
||||||
scale: smithay::utils::Scale<f64>,
|
scale: smithay::utils::Scale<f64>,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
) -> SplitRenderElements<C>
|
) -> Vec<C>
|
||||||
|
where
|
||||||
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||||
|
C: From<CosmicMappedRenderElement<R>>,
|
||||||
|
{
|
||||||
|
match &self.element {
|
||||||
|
CosmicMappedInternal::Stack(s) => s
|
||||||
|
.popup_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||||
|
renderer, location, scale, alpha,
|
||||||
|
),
|
||||||
|
CosmicMappedInternal::Window(w) => w
|
||||||
|
.popup_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||||
|
renderer, location, scale, alpha,
|
||||||
|
),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
.into_iter()
|
||||||
|
.map(C::from)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_elements<R, C>(
|
||||||
|
&self,
|
||||||
|
renderer: &mut R,
|
||||||
|
location: smithay::utils::Point<i32, smithay::utils::Physical>,
|
||||||
|
scale: smithay::utils::Scale<f64>,
|
||||||
|
alpha: f32,
|
||||||
|
) -> Vec<C>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
|
@ -671,7 +697,7 @@ impl CosmicMapped {
|
||||||
C: From<CosmicMappedRenderElement<R>>,
|
C: From<CosmicMappedRenderElement<R>>,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
let debug_elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() {
|
let mut elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() {
|
||||||
let window = self.active_window();
|
let window = self.active_window();
|
||||||
let window_geo = window.geometry();
|
let window_geo = window.geometry();
|
||||||
let (min_size, max_size, size) =
|
let (min_size, max_size, size) =
|
||||||
|
|
@ -840,30 +866,21 @@ impl CosmicMapped {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "debug"))]
|
#[cfg(not(feature = "debug"))]
|
||||||
let debug_elements = Vec::new();
|
let mut elements = Vec::new();
|
||||||
|
|
||||||
let mut elements = SplitRenderElements {
|
|
||||||
w_elements: debug_elements,
|
|
||||||
p_elements: Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
|
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
|
||||||
elements.extend_map(
|
elements.extend(match &self.element {
|
||||||
match &self.element {
|
CosmicMappedInternal::Stack(s) => s.render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||||
CosmicMappedInternal::Stack(s) => s
|
renderer, location, scale, alpha,
|
||||||
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
|
),
|
||||||
renderer, location, scale, alpha,
|
CosmicMappedInternal::Window(w) => w
|
||||||
),
|
.render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||||
CosmicMappedInternal::Window(w) => w
|
renderer, location, scale, alpha,
|
||||||
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
|
),
|
||||||
renderer, location, scale, alpha,
|
_ => unreachable!(),
|
||||||
),
|
});
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
C::from,
|
|
||||||
);
|
|
||||||
|
|
||||||
elements
|
elements.into_iter().map(C::from).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_theme(&self, theme: cosmic::Theme) {
|
pub(crate) fn update_theme(&self, theme: cosmic::Theme) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{surface::RESIZE_BORDER, window::Focus, CosmicSurface};
|
use super::{surface::RESIZE_BORDER, window::Focus, CosmicSurface};
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{cursor::CursorState, SplitRenderElements},
|
backend::render::cursor::CursorState,
|
||||||
shell::{
|
shell::{
|
||||||
focus::target::PointerFocusTarget,
|
focus::target::PointerFocusTarget,
|
||||||
grabs::{ReleaseMode, ResizeEdge},
|
grabs::{ReleaseMode, ResizeEdge},
|
||||||
|
|
@ -541,13 +541,40 @@ impl CosmicStack {
|
||||||
self.0.loop_handle()
|
self.0.loop_handle()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split_render_elements<R, C>(
|
pub fn popup_render_elements<R, C>(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
location: Point<i32, Physical>,
|
location: Point<i32, Physical>,
|
||||||
scale: Scale<f64>,
|
scale: Scale<f64>,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
) -> SplitRenderElements<C>
|
) -> Vec<C>
|
||||||
|
where
|
||||||
|
R: Renderer + ImportAll + ImportMem,
|
||||||
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
C: From<CosmicStackRenderElement<R>>,
|
||||||
|
{
|
||||||
|
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
|
||||||
|
self.0.with_program(|p| {
|
||||||
|
let windows = p.windows.lock().unwrap();
|
||||||
|
let active = p.active.load(Ordering::SeqCst);
|
||||||
|
|
||||||
|
windows[active]
|
||||||
|
.popup_render_elements::<R, CosmicStackRenderElement<R>>(
|
||||||
|
renderer, window_loc, scale, alpha,
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.map(C::from)
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_elements<R, C>(
|
||||||
|
&self,
|
||||||
|
renderer: &mut R,
|
||||||
|
location: Point<i32, Physical>,
|
||||||
|
scale: Scale<f64>,
|
||||||
|
alpha: f32,
|
||||||
|
) -> Vec<C>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem,
|
R: Renderer + ImportAll + ImportMem,
|
||||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
|
@ -564,28 +591,20 @@ impl CosmicStack {
|
||||||
let stack_loc = location + offset;
|
let stack_loc = location + offset;
|
||||||
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
|
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
|
||||||
|
|
||||||
let w_elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
|
let mut elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
|
||||||
&self.0, renderer, stack_loc, scale, alpha,
|
&self.0, renderer, stack_loc, scale, alpha,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut elements = SplitRenderElements {
|
elements.extend(self.0.with_program(|p| {
|
||||||
w_elements: w_elements.into_iter().map(C::from).collect(),
|
let windows = p.windows.lock().unwrap();
|
||||||
p_elements: Vec::new(),
|
let active = p.active.load(Ordering::SeqCst);
|
||||||
};
|
|
||||||
|
|
||||||
elements.extend_map(
|
windows[active].render_elements::<R, CosmicStackRenderElement<R>>(
|
||||||
self.0.with_program(|p| {
|
renderer, window_loc, scale, alpha,
|
||||||
let windows = p.windows.lock().unwrap();
|
)
|
||||||
let active = p.active.load(Ordering::SeqCst);
|
}));
|
||||||
|
|
||||||
windows[active].split_render_elements::<R, CosmicStackRenderElement<R>>(
|
elements.into_iter().map(C::from).collect()
|
||||||
renderer, window_loc, scale, alpha,
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
C::from,
|
|
||||||
);
|
|
||||||
|
|
||||||
elements
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {
|
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,9 @@ use smithay::{
|
||||||
},
|
},
|
||||||
wayland_server::protocol::wl_surface::WlSurface,
|
wayland_server::protocol::wl_surface::WlSurface,
|
||||||
},
|
},
|
||||||
utils::{user_data::UserDataMap, IsAlive, Logical, Rectangle, Serial, Size},
|
utils::{
|
||||||
|
user_data::UserDataMap, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size,
|
||||||
|
},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{with_states, SurfaceData},
|
compositor::{with_states, SurfaceData},
|
||||||
seat::WaylandFocus,
|
seat::WaylandFocus,
|
||||||
|
|
@ -45,7 +47,6 @@ use smithay::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::SplitRenderElements,
|
|
||||||
state::{State, SurfaceDmabufFeedback},
|
state::{State, SurfaceDmabufFeedback},
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::handlers::decoration::PreferredDecorationMode,
|
wayland::handlers::decoration::PreferredDecorationMode,
|
||||||
|
|
@ -590,13 +591,13 @@ impl CosmicSurface {
|
||||||
self.0.user_data()
|
self.0.user_data()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split_render_elements<R, C>(
|
pub fn popup_render_elements<R, C>(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
location: smithay::utils::Point<i32, smithay::utils::Physical>,
|
location: Point<i32, Physical>,
|
||||||
scale: smithay::utils::Scale<f64>,
|
scale: Scale<f64>,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
) -> SplitRenderElements<C>
|
) -> Vec<C>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll,
|
R: Renderer + ImportAll,
|
||||||
<R as Renderer>::TextureId: Clone + 'static,
|
<R as Renderer>::TextureId: Clone + 'static,
|
||||||
|
|
@ -605,9 +606,8 @@ impl CosmicSurface {
|
||||||
match self.0.underlying_surface() {
|
match self.0.underlying_surface() {
|
||||||
WindowSurface::Wayland(toplevel) => {
|
WindowSurface::Wayland(toplevel) => {
|
||||||
let surface = toplevel.wl_surface();
|
let surface = toplevel.wl_surface();
|
||||||
|
PopupManager::popups_for_surface(surface)
|
||||||
let p_elements = PopupManager::popups_for_surface(surface)
|
.flat_map(move |(popup, popup_offset)| {
|
||||||
.flat_map(|(popup, popup_offset)| {
|
|
||||||
let offset = (self.0.geometry().loc + popup_offset - popup.geometry().loc)
|
let offset = (self.0.geometry().loc + popup_offset - popup.geometry().loc)
|
||||||
.to_physical_precise_round(scale);
|
.to_physical_precise_round(scale);
|
||||||
|
|
||||||
|
|
@ -620,26 +620,40 @@ impl CosmicSurface {
|
||||||
element::Kind::Unspecified,
|
element::Kind::Unspecified,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect()
|
||||||
|
}
|
||||||
|
WindowSurface::X11(_) => Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let w_elements = render_elements_from_surface_tree(
|
pub fn render_elements<R, C>(
|
||||||
|
&self,
|
||||||
|
renderer: &mut R,
|
||||||
|
location: Point<i32, Physical>,
|
||||||
|
scale: Scale<f64>,
|
||||||
|
alpha: f32,
|
||||||
|
) -> Vec<C>
|
||||||
|
where
|
||||||
|
R: Renderer + ImportAll,
|
||||||
|
<R as Renderer>::TextureId: Clone + 'static,
|
||||||
|
C: From<WaylandSurfaceRenderElement<R>>,
|
||||||
|
{
|
||||||
|
match self.0.underlying_surface() {
|
||||||
|
WindowSurface::Wayland(toplevel) => {
|
||||||
|
let surface = toplevel.wl_surface();
|
||||||
|
|
||||||
|
render_elements_from_surface_tree(
|
||||||
renderer,
|
renderer,
|
||||||
surface,
|
surface,
|
||||||
location,
|
location,
|
||||||
scale,
|
scale,
|
||||||
alpha,
|
alpha,
|
||||||
element::Kind::Unspecified,
|
element::Kind::Unspecified,
|
||||||
);
|
)
|
||||||
|
}
|
||||||
SplitRenderElements {
|
WindowSurface::X11(surface) => {
|
||||||
w_elements,
|
surface.render_elements(renderer, location, scale, alpha)
|
||||||
p_elements,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
WindowSurface::X11(surface) => SplitRenderElements {
|
|
||||||
w_elements: surface.render_elements(renderer, location, scale, alpha),
|
|
||||||
p_elements: Vec::new(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -663,10 +677,7 @@ impl SpaceElement for CosmicSurface {
|
||||||
SpaceElement::bbox(&self.0)
|
SpaceElement::bbox(&self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_in_input_region(
|
fn is_in_input_region(&self, point: &Point<f64, smithay::utils::Logical>) -> bool {
|
||||||
&self,
|
|
||||||
point: &smithay::utils::Point<f64, smithay::utils::Logical>,
|
|
||||||
) -> bool {
|
|
||||||
SpaceElement::is_in_input_region(&self.0, point)
|
SpaceElement::is_in_input_region(&self.0, point)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -784,8 +795,8 @@ where
|
||||||
fn render_elements<C: From<Self::RenderElement>>(
|
fn render_elements<C: From<Self::RenderElement>>(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
location: smithay::utils::Point<i32, smithay::utils::Physical>,
|
location: Point<i32, Physical>,
|
||||||
scale: smithay::utils::Scale<f64>,
|
scale: Scale<f64>,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
) -> Vec<C> {
|
) -> Vec<C> {
|
||||||
self.0.render_elements(renderer, location, scale, alpha)
|
self.0.render_elements(renderer, location, scale, alpha)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{cursor::CursorState, SplitRenderElements},
|
backend::render::cursor::CursorState,
|
||||||
shell::{
|
shell::{
|
||||||
focus::target::PointerFocusTarget,
|
focus::target::PointerFocusTarget,
|
||||||
grabs::{ReleaseMode, ResizeEdge},
|
grabs::{ReleaseMode, ResizeEdge},
|
||||||
|
|
@ -41,7 +41,7 @@ use smithay::{
|
||||||
output::Output,
|
output::Output,
|
||||||
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||||
render_elements,
|
render_elements,
|
||||||
utils::{IsAlive, Logical, Point, Rectangle, Serial, Size},
|
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size},
|
||||||
wayland::seat::WaylandFocus,
|
wayland::seat::WaylandFocus,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
|
@ -308,13 +308,13 @@ impl CosmicWindow {
|
||||||
self.0.loop_handle()
|
self.0.loop_handle()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split_render_elements<R, C>(
|
pub fn popup_render_elements<R, C>(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
location: smithay::utils::Point<i32, smithay::utils::Physical>,
|
location: Point<i32, Physical>,
|
||||||
scale: smithay::utils::Scale<f64>,
|
scale: Scale<f64>,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
) -> SplitRenderElements<C>
|
) -> Vec<C>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem,
|
R: Renderer + ImportAll + ImportMem,
|
||||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
|
@ -328,17 +328,44 @@ impl CosmicWindow {
|
||||||
location
|
location
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut elements = SplitRenderElements::default();
|
self.0.with_program(|p| {
|
||||||
|
p.window
|
||||||
|
.popup_render_elements::<R, CosmicWindowRenderElement<R>>(
|
||||||
|
renderer, window_loc, scale, alpha,
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.map(C::from)
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
elements.extend_map(
|
pub fn render_elements<R, C>(
|
||||||
self.0.with_program(|p| {
|
&self,
|
||||||
p.window
|
renderer: &mut R,
|
||||||
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
|
location: Point<i32, Physical>,
|
||||||
renderer, window_loc, scale, alpha,
|
scale: Scale<f64>,
|
||||||
)
|
alpha: f32,
|
||||||
}),
|
) -> Vec<C>
|
||||||
C::from,
|
where
|
||||||
);
|
R: Renderer + ImportAll + ImportMem,
|
||||||
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
C: From<CosmicWindowRenderElement<R>>,
|
||||||
|
{
|
||||||
|
let has_ssd = self.0.with_program(|p| p.has_ssd(false));
|
||||||
|
|
||||||
|
let window_loc = if has_ssd {
|
||||||
|
location + Point::from((0, (SSD_HEIGHT as f64 * scale.y) as i32))
|
||||||
|
} else {
|
||||||
|
location
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut elements = Vec::new();
|
||||||
|
|
||||||
|
elements.extend(self.0.with_program(|p| {
|
||||||
|
p.window.render_elements::<R, CosmicWindowRenderElement<R>>(
|
||||||
|
renderer, window_loc, scale, alpha,
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
|
||||||
if has_ssd {
|
if has_ssd {
|
||||||
let ssd_loc = location
|
let ssd_loc = location
|
||||||
|
|
@ -346,16 +373,12 @@ impl CosmicWindow {
|
||||||
.0
|
.0
|
||||||
.with_program(|p| p.window.geometry().loc)
|
.with_program(|p| p.window.geometry().loc)
|
||||||
.to_physical_precise_round(scale);
|
.to_physical_precise_round(scale);
|
||||||
elements.w_elements.extend(
|
elements.extend(AsRenderElements::<R>::render_elements::<
|
||||||
AsRenderElements::<R>::render_elements::<CosmicWindowRenderElement<R>>(
|
CosmicWindowRenderElement<R>,
|
||||||
&self.0, renderer, ssd_loc, scale, alpha,
|
>(&self.0, renderer, ssd_loc, scale, alpha))
|
||||||
)
|
|
||||||
.into_iter()
|
|
||||||
.map(C::from),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elements
|
elements.into_iter().map(C::from).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {
|
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{
|
backend::render::{
|
||||||
cursor::CursorState, element::AsGlowRenderer, BackdropShader, IndicatorShader, Key,
|
cursor::CursorState, element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, Usage,
|
||||||
SplitRenderElements, Usage,
|
|
||||||
},
|
},
|
||||||
shell::{
|
shell::{
|
||||||
element::{
|
element::{
|
||||||
|
|
@ -181,12 +180,18 @@ impl MoveGrabState {
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let SplitRenderElements {
|
let w_elements = self
|
||||||
w_elements,
|
|
||||||
p_elements,
|
|
||||||
} = self
|
|
||||||
.window
|
.window
|
||||||
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
|
.render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||||
|
renderer,
|
||||||
|
(render_location - self.window.geometry().loc)
|
||||||
|
.to_physical_precise_round(output_scale),
|
||||||
|
output_scale,
|
||||||
|
alpha,
|
||||||
|
);
|
||||||
|
let p_elements = self
|
||||||
|
.window
|
||||||
|
.popup_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||||
renderer,
|
renderer,
|
||||||
(render_location - self.window.geometry().loc)
|
(render_location - self.window.geometry().loc)
|
||||||
.to_physical_precise_round(output_scale),
|
.to_physical_precise_round(output_scale),
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ use smithay::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, SplitRenderElements, Usage},
|
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, Usage},
|
||||||
shell::{
|
shell::{
|
||||||
element::{
|
element::{
|
||||||
resize_indicator::ResizeIndicator,
|
resize_indicator::ResizeIndicator,
|
||||||
|
|
@ -1260,6 +1260,52 @@ impl FloatingLayout {
|
||||||
}
|
}
|
||||||
self.refresh(); //fixup any out of bounds elements
|
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]
|
#[profiling::function]
|
||||||
pub fn render<R>(
|
pub fn render<R>(
|
||||||
|
|
@ -1270,7 +1316,7 @@ impl FloatingLayout {
|
||||||
indicator_thickness: u8,
|
indicator_thickness: u8,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
theme: &cosmic::theme::CosmicTheme,
|
theme: &cosmic::theme::CosmicTheme,
|
||||||
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
|
) -> Vec<CosmicMappedRenderElement<R>>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
|
@ -1285,7 +1331,7 @@ impl FloatingLayout {
|
||||||
};
|
};
|
||||||
let output_scale = output.current_scale().fractional_scale();
|
let output_scale = output.current_scale().fractional_scale();
|
||||||
|
|
||||||
let mut elements = SplitRenderElements::default();
|
let mut elements = Vec::default();
|
||||||
|
|
||||||
for elem in self
|
for elem in self
|
||||||
.animations
|
.animations
|
||||||
|
|
@ -1301,10 +1347,7 @@ impl FloatingLayout {
|
||||||
.unwrap_or_else(|| (self.space.element_geometry(elem).unwrap().as_local(), alpha));
|
.unwrap_or_else(|| (self.space.element_geometry(elem).unwrap().as_local(), alpha));
|
||||||
|
|
||||||
let render_location = geometry.loc - elem.geometry().loc.as_local();
|
let render_location = geometry.loc - elem.geometry().loc.as_local();
|
||||||
let SplitRenderElements {
|
let mut window_elements = elem.render_elements(
|
||||||
mut w_elements,
|
|
||||||
p_elements,
|
|
||||||
} = elem.split_render_elements(
|
|
||||||
renderer,
|
renderer,
|
||||||
render_location
|
render_location
|
||||||
.as_logical()
|
.as_logical()
|
||||||
|
|
@ -1331,7 +1374,7 @@ impl FloatingLayout {
|
||||||
y: geometry.size.h as f64 / buffer_size.h as f64,
|
y: geometry.size.h as f64 / buffer_size.h as f64,
|
||||||
};
|
};
|
||||||
|
|
||||||
w_elements = w_elements
|
window_elements = window_elements
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|element| match element {
|
.map(|element| match element {
|
||||||
CosmicMappedRenderElement::Stack(elem) => {
|
CosmicMappedRenderElement::Stack(elem) => {
|
||||||
|
|
@ -1387,7 +1430,7 @@ impl FloatingLayout {
|
||||||
|
|
||||||
resize.resize(resize_geometry.size.as_logical());
|
resize.resize(resize_geometry.size.as_logical());
|
||||||
resize.output_enter(output, Rectangle::default() /* unused */);
|
resize.output_enter(output, Rectangle::default() /* unused */);
|
||||||
elements.w_elements.extend(
|
window_elements.extend(
|
||||||
resize
|
resize
|
||||||
.render_elements::<CosmicWindowRenderElement<R>>(
|
.render_elements::<CosmicWindowRenderElement<R>>(
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -1419,12 +1462,11 @@ impl FloatingLayout {
|
||||||
active_window_hint.blue,
|
active_window_hint.blue,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
elements.w_elements.push(element.into());
|
window_elements.push(element.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.w_elements.extend(w_elements);
|
elements.extend(window_elements);
|
||||||
elements.p_elements.extend(p_elements);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elements
|
elements
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{
|
backend::render::{
|
||||||
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, SplitRenderElements, Usage,
|
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, Usage, ACTIVE_GROUP_COLOR,
|
||||||
ACTIVE_GROUP_COLOR, GROUP_COLOR,
|
GROUP_COLOR,
|
||||||
},
|
},
|
||||||
shell::{
|
shell::{
|
||||||
element::{
|
element::{
|
||||||
|
|
@ -60,7 +60,7 @@ use smithay::{
|
||||||
input::Seat,
|
input::Seat,
|
||||||
output::Output,
|
output::Output,
|
||||||
reexports::wayland_server::Client,
|
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},
|
wayland::{compositor::add_blocker, seat::WaylandFocus},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
|
@ -3863,7 +3863,7 @@ impl TilingLayout {
|
||||||
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
||||||
indicator_thickness: u8,
|
indicator_thickness: u8,
|
||||||
theme: &cosmic::theme::CosmicTheme,
|
theme: &cosmic::theme::CosmicTheme,
|
||||||
) -> Result<SplitRenderElements<CosmicMappedRenderElement<R>>, OutputNotMapped>
|
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
|
@ -3896,7 +3896,7 @@ impl TilingLayout {
|
||||||
};
|
};
|
||||||
let draw_groups = overview.0.alpha();
|
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_overview = !matches!(overview.0, OverviewMode::None);
|
||||||
let is_mouse_tiling = (matches!(overview.0.trigger(), Some(Trigger::Pointer(_))))
|
let is_mouse_tiling = (matches!(overview.0.trigger(), Some(Trigger::Pointer(_))))
|
||||||
|
|
@ -3931,7 +3931,7 @@ impl TilingLayout {
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
// all old windows we want to fade out
|
// all old windows we want to fade out
|
||||||
elements.extend(render_old_tree(
|
elements.extend(render_old_tree_windows(
|
||||||
reference_tree,
|
reference_tree,
|
||||||
target_tree,
|
target_tree,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -3969,7 +3969,7 @@ impl TilingLayout {
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
// all alive windows
|
// all alive windows
|
||||||
elements.extend(render_new_tree(
|
elements.extend(render_new_tree_windows(
|
||||||
target_tree,
|
target_tree,
|
||||||
reference_tree,
|
reference_tree,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -4001,12 +4001,139 @@ impl TilingLayout {
|
||||||
|
|
||||||
// tiling hints
|
// tiling hints
|
||||||
if let Some(group_elements) = group_elements {
|
if let Some(group_elements) = group_elements {
|
||||||
elements.w_elements.extend(group_elements);
|
elements.extend(group_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(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) {
|
fn gaps(&self) -> (i32, i32) {
|
||||||
let g = self.theme.cosmic().gaps;
|
let g = self.theme.cosmic().gaps;
|
||||||
(g.0 as i32, g.1 as i32)
|
(g.0 as i32, g.1 as i32)
|
||||||
|
|
@ -4690,7 +4817,48 @@ where
|
||||||
(geometries, elements)
|
(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>,
|
reference_tree: &Tree<Data>,
|
||||||
target_tree: &Tree<Data>,
|
target_tree: &Tree<Data>,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
|
|
@ -4700,7 +4868,7 @@ fn render_old_tree<R>(
|
||||||
indicator_thickness: u8,
|
indicator_thickness: u8,
|
||||||
is_swap_mode: bool,
|
is_swap_mode: bool,
|
||||||
theme: &cosmic::theme::CosmicTheme,
|
theme: &cosmic::theme::CosmicTheme,
|
||||||
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
|
) -> Vec<CosmicMappedRenderElement<R>>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
|
@ -4709,8 +4877,80 @@ where
|
||||||
CosmicStackRenderElement<R>: RenderElement<R>,
|
CosmicStackRenderElement<R>: RenderElement<R>,
|
||||||
{
|
{
|
||||||
let window_hint = crate::theme::active_window_hint(theme);
|
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() {
|
if let Some(root) = reference_tree.root_node_id() {
|
||||||
let geometries = geometries.unwrap_or_default();
|
let geometries = geometries.unwrap_or_default();
|
||||||
reference_tree
|
reference_tree
|
||||||
|
|
@ -4779,71 +5019,71 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
|
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
|
processor(mapped, elem_geometry, geo, alpha, minimize_geo.is_some())
|
||||||
.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);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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>,
|
target_tree: &Tree<Data>,
|
||||||
reference_tree: Option<&Tree<Data>>,
|
reference_tree: Option<&Tree<Data>>,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
|
|
@ -4862,7 +5102,7 @@ fn render_new_tree<R>(
|
||||||
swapping_stack_surface_id: &Id,
|
swapping_stack_surface_id: &Id,
|
||||||
placeholder_id: &Id,
|
placeholder_id: &Id,
|
||||||
theme: &cosmic::theme::CosmicTheme,
|
theme: &cosmic::theme::CosmicTheme,
|
||||||
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
|
) -> Vec<CosmicMappedRenderElement<R>>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
|
@ -4905,7 +5145,6 @@ where
|
||||||
|
|
||||||
let mut animating_window_elements = Vec::new();
|
let mut animating_window_elements = Vec::new();
|
||||||
let mut window_elements = Vec::new();
|
let mut window_elements = Vec::new();
|
||||||
let mut popup_elements = Vec::new();
|
|
||||||
|
|
||||||
let mut group_backdrop = None;
|
let mut group_backdrop = None;
|
||||||
let mut indicators = Vec::new();
|
let mut indicators = Vec::new();
|
||||||
|
|
@ -4916,10 +5155,11 @@ where
|
||||||
let output_scale = output.current_scale().fractional_scale();
|
let output_scale = output.current_scale().fractional_scale();
|
||||||
|
|
||||||
let (swap_indicator, swap_tree) = overview.1.unzip();
|
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_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 window_hint = crate::theme::active_window_hint(theme);
|
||||||
let group_color = GROUP_COLOR;
|
let group_color = GROUP_COLOR;
|
||||||
|
|
||||||
// render placeholder, if we are swapping to an empty workspace
|
// render placeholder, if we are swapping to an empty workspace
|
||||||
if target_tree.root_node_id().is_none() && swap_desc.is_some() {
|
if target_tree.root_node_id().is_none() && swap_desc.is_some() {
|
||||||
window_elements.push(
|
window_elements.push(
|
||||||
|
|
@ -4968,165 +5208,48 @@ where
|
||||||
(swap_geo.loc.as_logical() - window_geo.loc).to_physical_precise_round(output_scale);
|
(swap_geo.loc.as_logical() - window_geo.loc).to_physical_precise_round(output_scale);
|
||||||
|
|
||||||
swap_elements.extend(
|
swap_elements.extend(
|
||||||
window
|
AsRenderElements::render_elements::<CosmicWindowRenderElement<R>>(
|
||||||
.render_elements::<CosmicWindowRenderElement<R>>(
|
&window,
|
||||||
renderer,
|
renderer,
|
||||||
render_loc,
|
render_loc,
|
||||||
output_scale.into(),
|
output_scale.into(),
|
||||||
1.0,
|
1.0,
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|window| {
|
.map(|window| {
|
||||||
CosmicMappedRenderElement::GrabbedWindow(RescaleRenderElement::from_element(
|
CosmicMappedRenderElement::GrabbedWindow(RescaleRenderElement::from_element(
|
||||||
window,
|
window,
|
||||||
swap_geo
|
swap_geo
|
||||||
.loc
|
.loc
|
||||||
.as_logical()
|
.as_logical()
|
||||||
.to_physical_precise_round(output_scale),
|
.to_physical_precise_round(output_scale),
|
||||||
ease(
|
ease(
|
||||||
Linear,
|
Linear,
|
||||||
1.0,
|
1.0,
|
||||||
swap_factor(window_geo.size),
|
swap_factor(window_geo.size),
|
||||||
transition.unwrap_or(1.0),
|
transition.unwrap_or(1.0),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// render actual tree nodes
|
// render actual tree nodes
|
||||||
let old_geometries = old_geometries.unwrap_or_default();
|
render_new_tree(
|
||||||
let geometries = geometries.unwrap_or_default();
|
target_tree,
|
||||||
target_tree
|
reference_tree,
|
||||||
.root_node_id()
|
geometries,
|
||||||
.into_iter()
|
old_geometries,
|
||||||
.flat_map(|root| target_tree.traverse_pre_order_ids(root).unwrap())
|
percentage,
|
||||||
.map(|id| (target_tree, id))
|
swap_tree,
|
||||||
.chain(
|
swap_desc.as_ref(),
|
||||||
swap_tree
|
|node_id, data, geo, original_geo, alpha, animating| {
|
||||||
.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)
|
|
||||||
};
|
|
||||||
|
|
||||||
if swap_desc.as_ref().map(|desc| &desc.node) == Some(&node_id)
|
if swap_desc.as_ref().map(|desc| &desc.node) == Some(&node_id)
|
||||||
|| focused.as_ref() == Some(&node_id)
|
|| focused.as_ref() == Some(&node_id)
|
||||||
{
|
{
|
||||||
if indicator_thickness > 0 || data.is_group() {
|
if indicator_thickness > 0 || data.is_group() {
|
||||||
let mut geo = geo.clone();
|
let mut geo = geo.clone();
|
||||||
|
|
||||||
if data.is_group() {
|
if data.is_group() {
|
||||||
let outer_gap: i32 = (if is_overview { GAP_KEYBOARD } else { 4 } as f32
|
let outer_gap: i32 = (if is_overview { GAP_KEYBOARD } else { 4 } as f32
|
||||||
* percentage)
|
* percentage)
|
||||||
|
|
@ -5251,10 +5374,8 @@ where
|
||||||
|
|
||||||
if let Data::Mapped { mapped, .. } = data {
|
if let Data::Mapped { mapped, .. } = data {
|
||||||
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
|
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
|
||||||
let SplitRenderElements {
|
|
||||||
mut w_elements,
|
let mut elements = mapped.render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||||
p_elements,
|
|
||||||
} = mapped.split_render_elements::<R, CosmicMappedRenderElement<R>>(
|
|
||||||
renderer,
|
renderer,
|
||||||
//original_location,
|
//original_location,
|
||||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||||
|
|
@ -5262,6 +5383,7 @@ where
|
||||||
Scale::from(output_scale),
|
Scale::from(output_scale),
|
||||||
alpha,
|
alpha,
|
||||||
);
|
);
|
||||||
|
|
||||||
if swap_desc
|
if swap_desc
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.filter(|swap_desc| swap_desc.node == node_id)
|
.filter(|swap_desc| swap_desc.node == node_id)
|
||||||
|
|
@ -5284,7 +5406,7 @@ where
|
||||||
{
|
{
|
||||||
let mut geo = mapped.active_window_geometry().as_local();
|
let mut geo = mapped.active_window_geometry().as_local();
|
||||||
geo.loc += original_geo.loc;
|
geo.loc += original_geo.loc;
|
||||||
w_elements.insert(
|
elements.insert(
|
||||||
0,
|
0,
|
||||||
CosmicMappedRenderElement::Overlay(BackdropShader::element(
|
CosmicMappedRenderElement::Overlay(BackdropShader::element(
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -5305,7 +5427,7 @@ where
|
||||||
(ConstrainScaleBehavior::CutOff, ConstrainAlign::TOP_LEFT)
|
(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(
|
CosmicMappedRenderElement::Stack(elem) => constrain_render_elements(
|
||||||
std::iter::once(elem),
|
std::iter::once(elem),
|
||||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||||
|
|
@ -5344,6 +5466,7 @@ where
|
||||||
.map(CosmicMappedRenderElement::TiledOverlay),
|
.map(CosmicMappedRenderElement::TiledOverlay),
|
||||||
x => Some(x),
|
x => Some(x),
|
||||||
});
|
});
|
||||||
|
|
||||||
if swap_desc
|
if swap_desc
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|swap_desc| {
|
.map(|swap_desc| {
|
||||||
|
|
@ -5356,21 +5479,19 @@ where
|
||||||
})
|
})
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
swap_elements.extend(w_elements);
|
swap_elements.extend(elements);
|
||||||
} else {
|
} else {
|
||||||
if animating {
|
if animating {
|
||||||
animating_window_elements.extend(w_elements);
|
animating_window_elements.extend(elements);
|
||||||
} else {
|
} else {
|
||||||
window_elements.extend(w_elements);
|
window_elements.extend(elements);
|
||||||
}
|
|
||||||
if !mapped.is_maximized(false) {
|
|
||||||
popup_elements.extend(p_elements);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
window_elements = resize_elements
|
resize_elements
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.chain(swap_elements)
|
.chain(swap_elements)
|
||||||
|
|
@ -5378,12 +5499,147 @@ where
|
||||||
.chain(window_elements)
|
.chain(window_elements)
|
||||||
.chain(animating_window_elements)
|
.chain(animating_window_elements)
|
||||||
.chain(group_backdrop.into_iter().map(Into::into))
|
.chain(group_backdrop.into_iter().map(Into::into))
|
||||||
.collect();
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
SplitRenderElements {
|
fn render_new_tree(
|
||||||
w_elements: window_elements,
|
target_tree: &Tree<Data>,
|
||||||
p_elements: popup_elements,
|
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>(
|
fn scale_to_center<C>(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{
|
backend::render::{
|
||||||
element::{AsGlowRenderer, FromGlesError},
|
element::{AsGlowRenderer, FromGlesError},
|
||||||
BackdropShader, SplitRenderElements,
|
BackdropShader,
|
||||||
},
|
},
|
||||||
shell::{
|
shell::{
|
||||||
layout::{floating::FloatingLayout, tiling::TilingLayout},
|
layout::{floating::FloatingLayout, tiling::TilingLayout},
|
||||||
|
|
@ -921,10 +921,6 @@ impl Workspace {
|
||||||
.chain(self.tiling_layer.mapped().map(|(w, _)| w))
|
.chain(self.tiling_layer.mapped().map(|(w, _)| w))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outputs(&self) -> impl Iterator<Item = &Output> {
|
|
||||||
self.floating_layer.space.outputs()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.floating_layer.mapped().next().is_none()
|
self.floating_layer.mapped().next().is_none()
|
||||||
&& self.tiling_layer.mapped().next().is_none()
|
&& self.tiling_layer.mapped().next().is_none()
|
||||||
|
|
@ -1012,7 +1008,7 @@ impl Workspace {
|
||||||
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
||||||
indicator_thickness: u8,
|
indicator_thickness: u8,
|
||||||
theme: &CosmicTheme,
|
theme: &CosmicTheme,
|
||||||
) -> Result<SplitRenderElements<WorkspaceRenderElement<R>>, OutputNotMapped>
|
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: Send + Clone + 'static,
|
<R as Renderer>::TextureId: Send + Clone + 'static,
|
||||||
|
|
@ -1021,7 +1017,7 @@ impl Workspace {
|
||||||
CosmicStackRenderElement<R>: RenderElement<R>,
|
CosmicStackRenderElement<R>: RenderElement<R>,
|
||||||
WorkspaceRenderElement<R>: RenderElement<R>,
|
WorkspaceRenderElement<R>: RenderElement<R>,
|
||||||
{
|
{
|
||||||
let mut elements = SplitRenderElements::default();
|
let mut elements = Vec::default();
|
||||||
|
|
||||||
let output_scale = self.output.current_scale().fractional_scale();
|
let output_scale = self.output.current_scale().fractional_scale();
|
||||||
let zone = {
|
let zone = {
|
||||||
|
|
@ -1104,26 +1100,19 @@ impl Workspace {
|
||||||
y: target_geo.size.h as f64 / bbox.size.h as f64,
|
y: target_geo.size.h as f64 / bbox.size.h as f64,
|
||||||
};
|
};
|
||||||
|
|
||||||
let SplitRenderElements {
|
elements.extend(
|
||||||
w_elements,
|
fullscreen
|
||||||
p_elements,
|
.surface
|
||||||
} = fullscreen
|
.render_elements::<R, CosmicWindowRenderElement<R>>(
|
||||||
.surface
|
renderer,
|
||||||
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
|
render_loc,
|
||||||
renderer,
|
output_scale.into(),
|
||||||
render_loc,
|
alpha,
|
||||||
output_scale.into(),
|
)
|
||||||
alpha,
|
|
||||||
);
|
|
||||||
elements.w_elements.extend(
|
|
||||||
w_elements
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|elem| RescaleRenderElement::from_element(elem, render_loc, scale))
|
.map(|elem| RescaleRenderElement::from_element(elem, render_loc, scale))
|
||||||
.map(Into::into),
|
.map(Into::into),
|
||||||
);
|
);
|
||||||
elements
|
|
||||||
.p_elements
|
|
||||||
.extend(p_elements.into_iter().map(Into::into))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self
|
if self
|
||||||
|
|
@ -1155,16 +1144,18 @@ impl Workspace {
|
||||||
OverviewMode::None => 1.0,
|
OverviewMode::None => 1.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
elements.extend_map(
|
elements.extend(
|
||||||
self.floating_layer.render::<R>(
|
self.floating_layer
|
||||||
renderer,
|
.render::<R>(
|
||||||
focused.as_ref(),
|
renderer,
|
||||||
resize_indicator.clone(),
|
focused.as_ref(),
|
||||||
indicator_thickness,
|
resize_indicator.clone(),
|
||||||
alpha,
|
indicator_thickness,
|
||||||
theme,
|
alpha,
|
||||||
),
|
theme,
|
||||||
WorkspaceRenderElement::from,
|
)
|
||||||
|
.into_iter()
|
||||||
|
.map(WorkspaceRenderElement::from),
|
||||||
);
|
);
|
||||||
|
|
||||||
let alpha = match &overview.0 {
|
let alpha = match &overview.0 {
|
||||||
|
|
@ -1181,21 +1172,23 @@ impl Workspace {
|
||||||
};
|
};
|
||||||
|
|
||||||
//tiling surfaces
|
//tiling surfaces
|
||||||
elements.extend_map(
|
elements.extend(
|
||||||
self.tiling_layer.render::<R>(
|
self.tiling_layer
|
||||||
renderer,
|
.render::<R>(
|
||||||
draw_focus_indicator,
|
renderer,
|
||||||
zone,
|
draw_focus_indicator,
|
||||||
overview,
|
zone,
|
||||||
resize_indicator,
|
overview,
|
||||||
indicator_thickness,
|
resize_indicator,
|
||||||
theme,
|
indicator_thickness,
|
||||||
)?,
|
theme,
|
||||||
WorkspaceRenderElement::from,
|
)?
|
||||||
|
.into_iter()
|
||||||
|
.map(WorkspaceRenderElement::from),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(alpha) = alpha {
|
if let Some(alpha) = alpha {
|
||||||
elements.w_elements.push(
|
elements.push(
|
||||||
Into::<CosmicMappedRenderElement<R>>::into(BackdropShader::element(
|
Into::<CosmicMappedRenderElement<R>>::into(BackdropShader::element(
|
||||||
renderer,
|
renderer,
|
||||||
self.backdrop_id.clone(),
|
self.backdrop_id.clone(),
|
||||||
|
|
@ -1214,6 +1207,159 @@ impl Workspace {
|
||||||
|
|
||||||
Ok(elements)
|
Ok(elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[profiling::function]
|
||||||
|
pub fn render_popups<'a, R>(
|
||||||
|
&self,
|
||||||
|
renderer: &mut R,
|
||||||
|
draw_focus_indicator: Option<&Seat<State>>,
|
||||||
|
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
|
||||||
|
theme: &CosmicTheme,
|
||||||
|
) -> Result<Vec<WorkspaceRenderElement<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>,
|
||||||
|
WorkspaceRenderElement<R>: RenderElement<R>,
|
||||||
|
{
|
||||||
|
let mut elements = Vec::default();
|
||||||
|
|
||||||
|
let output_scale = self.output.current_scale().fractional_scale();
|
||||||
|
let zone = {
|
||||||
|
let layer_map = layer_map_for_output(&self.output);
|
||||||
|
layer_map.non_exclusive_zone().as_local()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(fullscreen) = self.fullscreen.as_ref() {
|
||||||
|
// fullscreen window
|
||||||
|
let bbox = fullscreen.surface.bbox().as_local();
|
||||||
|
let element_geo = Rectangle::from_loc_and_size(
|
||||||
|
self.element_for_surface(&fullscreen.surface)
|
||||||
|
.and_then(|elem| {
|
||||||
|
self.floating_layer
|
||||||
|
.element_geometry(elem)
|
||||||
|
.or_else(|| self.tiling_layer.element_geometry(elem))
|
||||||
|
.map(|mut geo| {
|
||||||
|
geo.loc -= elem.geometry().loc.as_local();
|
||||||
|
geo
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or(bbox)
|
||||||
|
.loc,
|
||||||
|
fullscreen.original_geometry.size.as_local(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut full_geo =
|
||||||
|
Rectangle::from_loc_and_size((0, 0), self.output.geometry().size.as_local());
|
||||||
|
if fullscreen.start_at.is_none() {
|
||||||
|
if bbox != full_geo {
|
||||||
|
if bbox.size.w < full_geo.size.w {
|
||||||
|
full_geo.loc.x += (full_geo.size.w - bbox.size.w) / 2;
|
||||||
|
full_geo.size.w = bbox.size.w;
|
||||||
|
}
|
||||||
|
if bbox.size.h < full_geo.size.h {
|
||||||
|
full_geo.loc.y += (full_geo.size.h - bbox.size.h) / 2;
|
||||||
|
full_geo.size.h = bbox.size.h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (target_geo, alpha) = match (fullscreen.start_at, fullscreen.ended_at) {
|
||||||
|
(Some(started), _) => {
|
||||||
|
let duration = Instant::now().duration_since(started).as_secs_f64()
|
||||||
|
/ FULLSCREEN_ANIMATION_DURATION.as_secs_f64();
|
||||||
|
(
|
||||||
|
ease(
|
||||||
|
EaseInOutCubic,
|
||||||
|
EaseRectangle(element_geo),
|
||||||
|
EaseRectangle(full_geo),
|
||||||
|
duration,
|
||||||
|
)
|
||||||
|
.0,
|
||||||
|
ease(EaseInOutCubic, 0.0, 1.0, duration),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
(_, Some(ended)) => {
|
||||||
|
let duration = Instant::now().duration_since(ended).as_secs_f64()
|
||||||
|
/ FULLSCREEN_ANIMATION_DURATION.as_secs_f64();
|
||||||
|
(
|
||||||
|
ease(
|
||||||
|
EaseInOutCubic,
|
||||||
|
EaseRectangle(full_geo),
|
||||||
|
EaseRectangle(element_geo),
|
||||||
|
duration,
|
||||||
|
)
|
||||||
|
.0,
|
||||||
|
ease(EaseInOutCubic, 1.0, 0.0, duration),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
(None, None) => (full_geo, 1.0),
|
||||||
|
};
|
||||||
|
|
||||||
|
let render_loc = target_geo
|
||||||
|
.loc
|
||||||
|
.as_logical()
|
||||||
|
.to_physical_precise_round(output_scale);
|
||||||
|
|
||||||
|
elements.extend(
|
||||||
|
fullscreen
|
||||||
|
.surface
|
||||||
|
.popup_render_elements::<R, CosmicWindowRenderElement<R>>(
|
||||||
|
renderer,
|
||||||
|
render_loc,
|
||||||
|
output_scale.into(),
|
||||||
|
alpha,
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self
|
||||||
|
.fullscreen
|
||||||
|
.as_ref()
|
||||||
|
.map(|f| f.start_at.is_some() || f.ended_at.is_some())
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
|
// floating surfaces
|
||||||
|
let alpha = match &overview.0 {
|
||||||
|
OverviewMode::Started(_, started) => {
|
||||||
|
(1.0 - (Instant::now().duration_since(*started).as_millis()
|
||||||
|
/ ANIMATION_DURATION.as_millis()) as f32)
|
||||||
|
.max(0.0)
|
||||||
|
* 0.4
|
||||||
|
+ 0.6
|
||||||
|
}
|
||||||
|
OverviewMode::Ended(_, ended) => {
|
||||||
|
((Instant::now().duration_since(*ended).as_millis()
|
||||||
|
/ ANIMATION_DURATION.as_millis()) as f32)
|
||||||
|
* 0.4
|
||||||
|
+ 0.6
|
||||||
|
}
|
||||||
|
OverviewMode::Active(_) => 0.6,
|
||||||
|
OverviewMode::None => 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.extend(
|
||||||
|
self.floating_layer
|
||||||
|
.render_popups::<R>(renderer, alpha)
|
||||||
|
.into_iter()
|
||||||
|
.map(WorkspaceRenderElement::from),
|
||||||
|
);
|
||||||
|
|
||||||
|
//tiling surfaces
|
||||||
|
elements.extend(
|
||||||
|
self.tiling_layer
|
||||||
|
.render_popups::<R>(renderer, draw_focus_indicator, zone, overview, theme)?
|
||||||
|
.into_iter()
|
||||||
|
.map(WorkspaceRenderElement::from),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(elements)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FocusStacks {
|
impl FocusStacks {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue