element: Refactor element acquisition to be push based
This commit is contained in:
parent
178c6593dc
commit
e4c0716951
18 changed files with 1096 additions and 1137 deletions
|
|
@ -17,7 +17,11 @@ use crate::{
|
|||
render::{
|
||||
element::DamageElement,
|
||||
shadow::{SHADOW_SHADER, ShadowShader},
|
||||
wayland::clipped_surface::{CLIPPING_SHADER, ClippingShader},
|
||||
wayland::{
|
||||
SurfaceRenderElement,
|
||||
clipped_surface::{CLIPPING_SHADER, ClippingShader},
|
||||
push_render_elements_from_surface_tree,
|
||||
},
|
||||
},
|
||||
},
|
||||
config::ScreenFilter,
|
||||
|
|
@ -47,11 +51,10 @@ use smithay::{
|
|||
allocator::Fourcc,
|
||||
drm::{DrmDeviceFd, DrmNode},
|
||||
renderer::{
|
||||
Color32F, ImportAll, Offscreen, Renderer, Texture, TextureFilter,
|
||||
Color32F, Offscreen, Texture, TextureFilter,
|
||||
damage::{Error as RenderError, OutputDamageTracker, RenderOutputResult},
|
||||
element::{
|
||||
Element, Id, Kind, RenderElement, WeakId,
|
||||
surface::{WaylandSurfaceRenderElement, render_elements_from_surface_tree},
|
||||
texture::{TextureRenderBuffer, TextureRenderElement},
|
||||
utils::{
|
||||
ConstrainAlign, ConstrainScaleBehavior, CropRenderElement, Relocate,
|
||||
|
|
@ -68,6 +71,7 @@ use smithay::{
|
|||
sync::SyncPoint,
|
||||
},
|
||||
},
|
||||
desktop::utils::bbox_from_surface_tree,
|
||||
input::Seat,
|
||||
output::{Output, OutputModeSource, OutputNoMode},
|
||||
utils::{
|
||||
|
|
@ -475,8 +479,8 @@ pub fn cursor_elements<'a, 'frame, R>(
|
|||
mode: CursorMode,
|
||||
exclude_dnd_icon: bool,
|
||||
scanout_node: Option<DrmNode>,
|
||||
) -> Vec<CosmicElement<R>>
|
||||
where
|
||||
push: &mut dyn FnMut(CosmicElement<R>),
|
||||
) where
|
||||
R: AsGlowRenderer,
|
||||
R::TextureId: Send + Clone + 'static,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
|
|
@ -490,7 +494,6 @@ where
|
|||
)
|
||||
})
|
||||
.unwrap_or_else(|| ((0., 0.).into(), 1.));
|
||||
let mut elements = Vec::new();
|
||||
|
||||
for seat in seats {
|
||||
let pointer = match seat.get_pointer() {
|
||||
|
|
@ -500,19 +503,16 @@ where
|
|||
let location = pointer.current_location() - output.current_location().to_f64();
|
||||
|
||||
if mode != CursorMode::None {
|
||||
elements.extend(
|
||||
cursor::draw_cursor(
|
||||
renderer,
|
||||
seat,
|
||||
location,
|
||||
scale.into(),
|
||||
zoom_scale,
|
||||
now,
|
||||
mode != CursorMode::NotDefault,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|(elem, hotspot)| {
|
||||
CosmicElement::Cursor(RescaleRenderElement::from_element(
|
||||
cursor::draw_cursor(
|
||||
renderer,
|
||||
seat,
|
||||
location,
|
||||
scale.into(),
|
||||
zoom_scale,
|
||||
now,
|
||||
mode != CursorMode::NotDefault,
|
||||
&mut |elem, hotspot| {
|
||||
push(CosmicElement::Cursor(RescaleRenderElement::from_element(
|
||||
RelocateRenderElement::from_element(
|
||||
elem,
|
||||
Point::from((-hotspot.x, -hotspot.y)),
|
||||
|
|
@ -523,70 +523,54 @@ where
|
|||
.to_physical(output.current_scale().fractional_scale())
|
||||
.to_i32_round(),
|
||||
zoom_scale,
|
||||
))
|
||||
}),
|
||||
)))
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if !exclude_dnd_icon && let Some(dnd_icon) = get_dnd_icon(seat) {
|
||||
elements.extend(
|
||||
cursor::draw_dnd_icon(
|
||||
renderer,
|
||||
&dnd_icon.surface,
|
||||
(location + dnd_icon.offset.to_f64()).to_i32_round(),
|
||||
scale,
|
||||
)
|
||||
.into_iter()
|
||||
.map(CosmicElement::Dnd),
|
||||
cursor::draw_dnd_icon(
|
||||
renderer,
|
||||
&dnd_icon.surface,
|
||||
(location + dnd_icon.offset.to_f64()).to_i32_round(),
|
||||
scale,
|
||||
&mut |elem| push(CosmicElement::Dnd(elem)),
|
||||
);
|
||||
}
|
||||
|
||||
let theme = theme.cosmic();
|
||||
if let Some(grab_elements) = seat
|
||||
if let Some(grab_state) = seat
|
||||
.user_data()
|
||||
.get::<SeatMoveGrabState>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.map(|state| {
|
||||
state.render::<CosmicMappedRenderElement<R>, R>(
|
||||
renderer,
|
||||
output,
|
||||
theme,
|
||||
scanout_node,
|
||||
)
|
||||
})
|
||||
{
|
||||
elements.extend(grab_elements.into_iter().map(|elem| {
|
||||
CosmicElement::MoveGrab(RescaleRenderElement::from_element(
|
||||
grab_state.render(renderer, output, theme, scanout_node, &mut |elem| {
|
||||
push(CosmicElement::MoveGrab(RescaleRenderElement::from_element(
|
||||
elem,
|
||||
focal_point
|
||||
.as_logical()
|
||||
.to_physical(output.current_scale().fractional_scale())
|
||||
.to_i32_round(),
|
||||
zoom_scale,
|
||||
))
|
||||
}));
|
||||
)));
|
||||
})
|
||||
}
|
||||
|
||||
if let Some((grab_elements, should_scale)) = seat
|
||||
if let Some(grab_state) = seat
|
||||
.user_data()
|
||||
.get::<SeatMenuGrabState>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.map(|state| {
|
||||
(
|
||||
state.render::<CosmicMappedRenderElement<R>, R>(renderer, output),
|
||||
!state.is_in_screen_space(),
|
||||
)
|
||||
})
|
||||
{
|
||||
elements.extend(grab_elements.into_iter().map(|elem| {
|
||||
CosmicElement::MoveGrab(RescaleRenderElement::from_element(
|
||||
elem,
|
||||
let should_scale = !grab_state.is_in_screen_space();
|
||||
grab_state.render(renderer, output, &mut |elem| {
|
||||
push(CosmicElement::MoveGrab(RescaleRenderElement::from_element(
|
||||
elem.into(),
|
||||
if should_scale {
|
||||
focal_point
|
||||
.as_logical()
|
||||
|
|
@ -596,12 +580,10 @@ where
|
|||
Point::from((0, 0))
|
||||
},
|
||||
if should_scale { zoom_scale } else { 1.0 },
|
||||
))
|
||||
}));
|
||||
)));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
elements
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "debug"))]
|
||||
|
|
@ -729,7 +711,7 @@ where
|
|||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
WorkspaceRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
let mut elements = Vec::new();
|
||||
let mut elements = Vec::<CosmicElement<R>>::new();
|
||||
|
||||
let shell_ref = shell.read();
|
||||
let seats = shell_ref.seats.iter().cloned().collect::<Vec<_>>();
|
||||
|
|
@ -742,7 +724,7 @@ where
|
|||
// that is prone to deadlock with the main-thread on some grabs.
|
||||
std::mem::drop(shell_ref);
|
||||
|
||||
elements.extend(cursor_elements(
|
||||
cursor_elements(
|
||||
renderer,
|
||||
seats.iter(),
|
||||
zoom_level,
|
||||
|
|
@ -752,7 +734,8 @@ where
|
|||
cursor_mode,
|
||||
element_filter == ElementFilter::ExcludeWorkspaceOverview,
|
||||
scanout_node,
|
||||
));
|
||||
&mut |elem| elements.push(elem),
|
||||
);
|
||||
|
||||
let shell = shell.read();
|
||||
let overview = shell.overview_mode();
|
||||
|
|
@ -828,72 +811,81 @@ where
|
|||
render_input_order::<()>(&shell, output, previous, current, element_filter, |stage| {
|
||||
match stage {
|
||||
Stage::ZoomUI => {
|
||||
elements.extend(ZoomState::render(renderer, output));
|
||||
ZoomState::render(renderer, output, &mut |elem| {
|
||||
elements.push(CosmicElement::Zoom(elem))
|
||||
});
|
||||
}
|
||||
Stage::SessionLock(lock_surface) => {
|
||||
elements.extend(
|
||||
session_lock_elements(renderer, output, lock_surface)
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.flat_map(crop_to_output)
|
||||
.map(Into::into),
|
||||
);
|
||||
session_lock_elements(renderer, output, lock_surface, &mut |elem| {
|
||||
elements.extend(crop_to_output(elem.into()).map(Into::into))
|
||||
})
|
||||
}
|
||||
Stage::LayerPopup {
|
||||
popup, location, ..
|
||||
} => {
|
||||
elements.extend(
|
||||
render_elements_from_surface_tree::<_, WorkspaceRenderElement<_>>(
|
||||
renderer,
|
||||
popup.wl_surface(),
|
||||
location
|
||||
.to_local(output)
|
||||
.as_logical()
|
||||
.to_physical_precise_round(scale),
|
||||
Scale::from(scale),
|
||||
1.0,
|
||||
FRAME_TIME_FILTER,
|
||||
)
|
||||
.into_iter()
|
||||
.flat_map(crop_to_output)
|
||||
.map(Into::into),
|
||||
);
|
||||
let mut geometry = popup.geometry().as_global();
|
||||
geometry.loc += location;
|
||||
|
||||
push_render_elements_from_surface_tree(
|
||||
renderer,
|
||||
popup.wl_surface(),
|
||||
location
|
||||
.to_local(output)
|
||||
.as_logical()
|
||||
.to_physical_precise_round(scale),
|
||||
geometry.to_local(output).as_logical().to_f64(),
|
||||
Scale::from(scale),
|
||||
1.0,
|
||||
false,
|
||||
[0; 4],
|
||||
FRAME_TIME_FILTER,
|
||||
&mut |elem| elements.extend(crop_to_output(elem.into()).map(Into::into)),
|
||||
None,
|
||||
)
|
||||
}
|
||||
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,
|
||||
FRAME_TIME_FILTER,
|
||||
)
|
||||
.into_iter()
|
||||
.flat_map(crop_to_output)
|
||||
.map(Into::into),
|
||||
let mut geometry = layer.geometry().as_global();
|
||||
geometry.loc += location;
|
||||
|
||||
push_render_elements_from_surface_tree(
|
||||
renderer,
|
||||
layer.wl_surface(),
|
||||
location
|
||||
.to_local(output)
|
||||
.as_logical()
|
||||
.to_physical_precise_round(scale),
|
||||
geometry.to_local(output).as_logical().to_f64(),
|
||||
Scale::from(scale),
|
||||
1.0,
|
||||
false,
|
||||
[0; 4],
|
||||
FRAME_TIME_FILTER,
|
||||
&mut |elem| elements.extend(crop_to_output(elem.into()).map(Into::into)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
Stage::OverrideRedirect { surface, location } => {
|
||||
elements.extend(surface.wl_surface().into_iter().flat_map(|surface| {
|
||||
render_elements_from_surface_tree::<_, WorkspaceRenderElement<_>>(
|
||||
if let Some(wl_surface) = surface.wl_surface() {
|
||||
let mut geometry = surface.geometry().as_global();
|
||||
geometry.loc += location;
|
||||
|
||||
push_render_elements_from_surface_tree(
|
||||
renderer,
|
||||
&surface,
|
||||
&wl_surface,
|
||||
location
|
||||
.to_local(output)
|
||||
.as_logical()
|
||||
.to_physical_precise_round(scale),
|
||||
geometry.to_local(output).as_logical().to_f64(),
|
||||
Scale::from(scale),
|
||||
1.0,
|
||||
false,
|
||||
[0; 4],
|
||||
FRAME_TIME_FILTER,
|
||||
)
|
||||
.into_iter()
|
||||
.flat_map(crop_to_output)
|
||||
.map(Into::into)
|
||||
}));
|
||||
&mut |elem| elements.extend(crop_to_output(elem.into()).map(Into::into)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
Stage::StickyPopups(layout) => {
|
||||
let alpha = match &overview.0 {
|
||||
|
|
@ -914,14 +906,11 @@ where
|
|||
OverviewMode::None => 1.0,
|
||||
};
|
||||
|
||||
elements.extend(
|
||||
layout
|
||||
.render_popups(renderer, alpha, scanout_node)
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.flat_map(crop_to_output)
|
||||
.map(Into::into),
|
||||
);
|
||||
layout.render_popups(renderer, alpha, scanout_node, &mut |elem| {
|
||||
if let Some(elem) = crop_to_output(elem.into()) {
|
||||
elements.push(elem.into())
|
||||
}
|
||||
});
|
||||
}
|
||||
Stage::Sticky(layout) => {
|
||||
let alpha = match &overview.0 {
|
||||
|
|
@ -946,82 +935,66 @@ where
|
|||
.then_some(last_active_seat)
|
||||
.map(|seat| workspace.focus_stack.get(seat));
|
||||
|
||||
elements.extend(
|
||||
layout
|
||||
.render(
|
||||
renderer,
|
||||
current_focus.as_ref().and_then(|stack| {
|
||||
stack.last().and_then(|t| match t {
|
||||
FocusTarget::Window(w) => Some(w),
|
||||
_ => None,
|
||||
})
|
||||
}),
|
||||
resize_indicator.clone(),
|
||||
active_hint,
|
||||
alpha,
|
||||
theme.cosmic(),
|
||||
scanout_node,
|
||||
)
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.flat_map(crop_to_output)
|
||||
.map(Into::into),
|
||||
)
|
||||
layout.render(
|
||||
renderer,
|
||||
current_focus.as_ref().and_then(|stack| {
|
||||
stack.last().and_then(|t| match t {
|
||||
FocusTarget::Window(w) => Some(w),
|
||||
_ => None,
|
||||
})
|
||||
}),
|
||||
resize_indicator.clone(),
|
||||
active_hint,
|
||||
alpha,
|
||||
theme.cosmic(),
|
||||
scanout_node,
|
||||
&mut |elem| {
|
||||
if let Some(elem) = crop_to_output(elem.into()) {
|
||||
elements.push(elem.into())
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
Stage::WorkspacePopups { workspace, offset } => {
|
||||
elements.extend(
|
||||
match workspace.render_popups(
|
||||
renderer,
|
||||
last_active_seat,
|
||||
!move_active && is_active_space,
|
||||
overview.clone(),
|
||||
theme.cosmic(),
|
||||
scanout_node,
|
||||
) {
|
||||
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));
|
||||
workspace.render_popups(
|
||||
renderer,
|
||||
last_active_seat,
|
||||
!move_active && is_active_space,
|
||||
overview.clone(),
|
||||
theme.cosmic(),
|
||||
scanout_node,
|
||||
&mut |elem| {
|
||||
if let Some(elem) = crop_to_output(elem) {
|
||||
elements.push(CosmicElement::Workspace(
|
||||
RelocateRenderElement::from_element(
|
||||
elem,
|
||||
offset.to_physical_precise_round(scale),
|
||||
Relocate::Relative,
|
||||
),
|
||||
));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
Stage::Workspace { workspace, offset } => {
|
||||
elements.extend(
|
||||
match workspace.render(
|
||||
renderer,
|
||||
last_active_seat,
|
||||
!move_active && is_active_space,
|
||||
overview.clone(),
|
||||
resize_indicator.clone(),
|
||||
active_hint,
|
||||
theme.cosmic(),
|
||||
scanout_node,
|
||||
) {
|
||||
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));
|
||||
workspace.render(
|
||||
renderer,
|
||||
last_active_seat,
|
||||
!move_active && is_active_space,
|
||||
overview.clone(),
|
||||
resize_indicator.clone(),
|
||||
active_hint,
|
||||
theme.cosmic(),
|
||||
scanout_node,
|
||||
&mut |elem| {
|
||||
if let Some(elem) = crop_to_output(elem) {
|
||||
elements.push(CosmicElement::Workspace(
|
||||
RelocateRenderElement::from_element(
|
||||
elem,
|
||||
offset.to_physical_precise_round(scale),
|
||||
Relocate::Relative,
|
||||
),
|
||||
));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -1038,23 +1011,26 @@ fn session_lock_elements<R>(
|
|||
renderer: &mut R,
|
||||
output: &Output,
|
||||
lock_surface: Option<&LockSurface>,
|
||||
) -> Vec<WaylandSurfaceRenderElement<R>>
|
||||
where
|
||||
R: Renderer + ImportAll,
|
||||
push: &mut dyn FnMut(SurfaceRenderElement<R>),
|
||||
) where
|
||||
R: AsGlowRenderer,
|
||||
R::TextureId: Clone + 'static,
|
||||
{
|
||||
if let Some(surface) = lock_surface {
|
||||
let scale = Scale::from(output.current_scale().fractional_scale());
|
||||
render_elements_from_surface_tree(
|
||||
push_render_elements_from_surface_tree(
|
||||
renderer,
|
||||
surface.wl_surface(),
|
||||
(0, 0),
|
||||
bbox_from_surface_tree(surface.wl_surface(), (0, 0)).to_f64(),
|
||||
scale,
|
||||
1.0,
|
||||
false,
|
||||
[0; 4],
|
||||
FRAME_TIME_FILTER,
|
||||
push,
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue