shell: Fix render order regarding popups
This commit is contained in:
parent
a308997fd4
commit
c7d4fa5d53
9 changed files with 676 additions and 544 deletions
|
|
@ -14,7 +14,7 @@ use smithay::{
|
|||
renderer::{
|
||||
element::{
|
||||
utils::{CropRenderElement, RelocateRenderElement, RescaleRenderElement},
|
||||
AsRenderElements, Element, RenderElement, UnderlyingStorage,
|
||||
Element, RenderElement, UnderlyingStorage,
|
||||
},
|
||||
gles::element::PixelShaderElement,
|
||||
glow::GlowRenderer,
|
||||
|
|
@ -550,6 +550,206 @@ impl CosmicMapped {
|
|||
debug.take();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split_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>, Vec<C>)
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: 'static,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
C: From<CosmicMappedRenderElement<R>>,
|
||||
{
|
||||
#[cfg(feature = "debug")]
|
||||
let mut debug_elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() {
|
||||
let window = self.active_window();
|
||||
let window_geo = window.geometry();
|
||||
let (min_size, max_size, size) =
|
||||
(window.min_size(), window.max_size(), window.geometry().size);
|
||||
|
||||
let area = Rectangle::<i32, Logical>::from_loc_and_size(
|
||||
location.to_f64().to_logical(scale).to_i32_round(),
|
||||
self.bbox().size,
|
||||
);
|
||||
|
||||
let glow_renderer = renderer.glow_renderer_mut();
|
||||
match debug.render(
|
||||
|ctx| {
|
||||
egui::Area::new("window")
|
||||
.anchor(
|
||||
egui::Align2::RIGHT_TOP,
|
||||
[
|
||||
-window_geo.loc.x as f32 - 10.0,
|
||||
window_geo.loc.y as f32 - 10.0,
|
||||
],
|
||||
)
|
||||
.show(ctx, |ui| {
|
||||
egui::Frame::none()
|
||||
.fill(egui::Color32::BLACK)
|
||||
.rounding(5.0)
|
||||
.inner_margin(10.0)
|
||||
.show(ui, |ui| {
|
||||
ui.heading(window.title());
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("App ID: ");
|
||||
ui.label(window.app_id());
|
||||
});
|
||||
ui.label(match window {
|
||||
CosmicSurface::Wayland(_) => "Protocol: Wayland",
|
||||
CosmicSurface::X11(_) => "Protocol: X11",
|
||||
_ => unreachable!(),
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("States: ");
|
||||
if window.is_maximized() {
|
||||
ui.label("🗖");
|
||||
}
|
||||
if window.is_fullscreen() {
|
||||
ui.label("⬜");
|
||||
}
|
||||
if window.is_activated() {
|
||||
ui.label("🖱");
|
||||
}
|
||||
if window.is_resizing().is_some() {
|
||||
ui.label("↔");
|
||||
}
|
||||
});
|
||||
|
||||
let plot = Plot::new("Sizes")
|
||||
.legend(Legend::default().position(Corner::RightBottom))
|
||||
.data_aspect(1.0)
|
||||
.view_aspect(1.0)
|
||||
.show_x(false)
|
||||
.show_y(false)
|
||||
.width(200.0)
|
||||
.height(200.0);
|
||||
plot.show(ui, |plot_ui| {
|
||||
let center = if let Some(max_size) = max_size {
|
||||
((max_size.w + 20) / 2, (max_size.h + 20) / 2)
|
||||
} else {
|
||||
(100, 100)
|
||||
};
|
||||
|
||||
if let Some(max_size) = max_size {
|
||||
let max_size_rect =
|
||||
Polygon::new(PlotPoints::new(vec![
|
||||
[10.0, 10.0],
|
||||
[max_size.w as f64 + 10.0, 10.0],
|
||||
[
|
||||
max_size.w as f64 + 10.0,
|
||||
max_size.h as f64 + 10.0,
|
||||
],
|
||||
[10.0, max_size.h as f64 + 10.0],
|
||||
[10.0, 10.0],
|
||||
]));
|
||||
plot_ui.polygon(
|
||||
max_size_rect
|
||||
.name(format!("{}x{}", max_size.w, max_size.h)),
|
||||
);
|
||||
}
|
||||
|
||||
let size_rect = Polygon::new(PlotPoints::new(vec![
|
||||
[
|
||||
(center.0 - size.w / 2) as f64,
|
||||
(center.1 - size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 + size.w / 2) as f64,
|
||||
(center.1 - size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 + size.w / 2) as f64,
|
||||
(center.1 + size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 - size.w / 2) as f64,
|
||||
(center.1 + size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 - size.w / 2) as f64,
|
||||
(center.1 - size.h / 2) as f64,
|
||||
],
|
||||
]));
|
||||
plot_ui.polygon(
|
||||
size_rect.name(format!("{}x{}", size.w, size.h)),
|
||||
);
|
||||
|
||||
if let Some(min_size) = min_size {
|
||||
let min_size_rect =
|
||||
Polygon::new(PlotPoints::new(vec![
|
||||
[
|
||||
(center.0 - min_size.w / 2) as f64,
|
||||
(center.1 - min_size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 + min_size.w / 2) as f64,
|
||||
(center.1 - min_size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 + min_size.w / 2) as f64,
|
||||
(center.1 + min_size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 - min_size.w / 2) as f64,
|
||||
(center.1 + min_size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 - min_size.w / 2) as f64,
|
||||
(center.1 - min_size.h / 2) as f64,
|
||||
],
|
||||
]));
|
||||
plot_ui.polygon(
|
||||
min_size_rect
|
||||
.name(format!("{}x{}", min_size.w, min_size.h)),
|
||||
);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
},
|
||||
glow_renderer,
|
||||
area,
|
||||
scale.x,
|
||||
0.8,
|
||||
) {
|
||||
Ok(element) => vec![element.into()],
|
||||
Err(err) => {
|
||||
debug!(?err, "Error rendering debug overlay.");
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
#[cfg(not(feature = "debug"))]
|
||||
let debug_elements = Vec::new();
|
||||
|
||||
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
|
||||
let (window_elements, popup_elements) = match &self.element {
|
||||
CosmicMappedInternal::Stack(s) => s
|
||||
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer, location, scale, alpha,
|
||||
),
|
||||
CosmicMappedInternal::Window(w) => w
|
||||
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer, location, scale, alpha,
|
||||
),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
(
|
||||
debug_elements
|
||||
.into_iter()
|
||||
.map(C::from)
|
||||
.chain(window_elements.into_iter().map(C::from))
|
||||
.collect(),
|
||||
popup_elements.into_iter().map(C::from).collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl IsAlive for CosmicMapped {
|
||||
|
|
@ -1026,200 +1226,3 @@ where
|
|||
CosmicMappedRenderElement::Egui(elem)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> AsRenderElements<R> for CosmicMapped
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
<R as Renderer>::TextureId: 'static,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
type RenderElement = CosmicMappedRenderElement<R>;
|
||||
fn render_elements<C: From<Self::RenderElement>>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
location: Point<i32, Physical>,
|
||||
scale: Scale<f64>,
|
||||
alpha: f32,
|
||||
) -> Vec<C> {
|
||||
#[cfg(feature = "debug")]
|
||||
let mut elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() {
|
||||
let window = self.active_window();
|
||||
let window_geo = window.geometry();
|
||||
let (min_size, max_size, size) =
|
||||
(window.min_size(), window.max_size(), window.geometry().size);
|
||||
|
||||
let area = Rectangle::<i32, Logical>::from_loc_and_size(
|
||||
location.to_f64().to_logical(scale).to_i32_round(),
|
||||
self.bbox().size,
|
||||
);
|
||||
|
||||
let glow_renderer = renderer.glow_renderer_mut();
|
||||
match debug.render(
|
||||
|ctx| {
|
||||
egui::Area::new("window")
|
||||
.anchor(
|
||||
egui::Align2::RIGHT_TOP,
|
||||
[
|
||||
-window_geo.loc.x as f32 - 10.0,
|
||||
window_geo.loc.y as f32 - 10.0,
|
||||
],
|
||||
)
|
||||
.show(ctx, |ui| {
|
||||
egui::Frame::none()
|
||||
.fill(egui::Color32::BLACK)
|
||||
.rounding(5.0)
|
||||
.inner_margin(10.0)
|
||||
.show(ui, |ui| {
|
||||
ui.heading(window.title());
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("App ID: ");
|
||||
ui.label(window.app_id());
|
||||
});
|
||||
ui.label(match window {
|
||||
CosmicSurface::Wayland(_) => "Protocol: Wayland",
|
||||
CosmicSurface::X11(_) => "Protocol: X11",
|
||||
_ => unreachable!(),
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("States: ");
|
||||
if window.is_maximized() {
|
||||
ui.label("🗖");
|
||||
}
|
||||
if window.is_fullscreen() {
|
||||
ui.label("⬜");
|
||||
}
|
||||
if window.is_activated() {
|
||||
ui.label("🖱");
|
||||
}
|
||||
if window.is_resizing().is_some() {
|
||||
ui.label("↔");
|
||||
}
|
||||
});
|
||||
|
||||
let plot = Plot::new("Sizes")
|
||||
.legend(Legend::default().position(Corner::RightBottom))
|
||||
.data_aspect(1.0)
|
||||
.view_aspect(1.0)
|
||||
.show_x(false)
|
||||
.show_y(false)
|
||||
.width(200.0)
|
||||
.height(200.0);
|
||||
plot.show(ui, |plot_ui| {
|
||||
let center = if let Some(max_size) = max_size {
|
||||
((max_size.w + 20) / 2, (max_size.h + 20) / 2)
|
||||
} else {
|
||||
(100, 100)
|
||||
};
|
||||
|
||||
if let Some(max_size) = max_size {
|
||||
let max_size_rect =
|
||||
Polygon::new(PlotPoints::new(vec![
|
||||
[10.0, 10.0],
|
||||
[max_size.w as f64 + 10.0, 10.0],
|
||||
[
|
||||
max_size.w as f64 + 10.0,
|
||||
max_size.h as f64 + 10.0,
|
||||
],
|
||||
[10.0, max_size.h as f64 + 10.0],
|
||||
[10.0, 10.0],
|
||||
]));
|
||||
plot_ui.polygon(
|
||||
max_size_rect
|
||||
.name(format!("{}x{}", max_size.w, max_size.h)),
|
||||
);
|
||||
}
|
||||
|
||||
let size_rect = Polygon::new(PlotPoints::new(vec![
|
||||
[
|
||||
(center.0 - size.w / 2) as f64,
|
||||
(center.1 - size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 + size.w / 2) as f64,
|
||||
(center.1 - size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 + size.w / 2) as f64,
|
||||
(center.1 + size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 - size.w / 2) as f64,
|
||||
(center.1 + size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 - size.w / 2) as f64,
|
||||
(center.1 - size.h / 2) as f64,
|
||||
],
|
||||
]));
|
||||
plot_ui.polygon(
|
||||
size_rect.name(format!("{}x{}", size.w, size.h)),
|
||||
);
|
||||
|
||||
if let Some(min_size) = min_size {
|
||||
let min_size_rect =
|
||||
Polygon::new(PlotPoints::new(vec![
|
||||
[
|
||||
(center.0 - min_size.w / 2) as f64,
|
||||
(center.1 - min_size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 + min_size.w / 2) as f64,
|
||||
(center.1 - min_size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 + min_size.w / 2) as f64,
|
||||
(center.1 + min_size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 - min_size.w / 2) as f64,
|
||||
(center.1 + min_size.h / 2) as f64,
|
||||
],
|
||||
[
|
||||
(center.0 - min_size.w / 2) as f64,
|
||||
(center.1 - min_size.h / 2) as f64,
|
||||
],
|
||||
]));
|
||||
plot_ui.polygon(
|
||||
min_size_rect
|
||||
.name(format!("{}x{}", min_size.w, min_size.h)),
|
||||
);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
},
|
||||
glow_renderer,
|
||||
area,
|
||||
scale.x,
|
||||
0.8,
|
||||
) {
|
||||
Ok(element) => vec![element.into()],
|
||||
Err(err) => {
|
||||
debug!(?err, "Error rendering debug overlay.");
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
#[cfg(not(feature = "debug"))]
|
||||
let mut elements = Vec::new();
|
||||
|
||||
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
|
||||
match &self.element {
|
||||
CosmicMappedInternal::Stack(s) => {
|
||||
elements.extend(AsRenderElements::<R>::render_elements::<
|
||||
CosmicMappedRenderElement<R>,
|
||||
>(s, renderer, location, scale, alpha))
|
||||
}
|
||||
CosmicMappedInternal::Window(w) => {
|
||||
elements.extend(AsRenderElements::<R>::render_elements::<
|
||||
CosmicMappedRenderElement<R>,
|
||||
>(w, renderer, location, scale, alpha))
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
elements.into_iter().map(C::from).collect()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ use smithay::{
|
|||
},
|
||||
output::Output,
|
||||
render_elements,
|
||||
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size},
|
||||
utils::{IsAlive, Logical, Point, Rectangle, Serial, Size},
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
use std::{
|
||||
|
|
@ -462,6 +462,50 @@ impl CosmicStack {
|
|||
pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> {
|
||||
self.0.loop_handle()
|
||||
}
|
||||
|
||||
pub fn split_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>, Vec<C>)
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
<R as Renderer>::TextureId: 'static,
|
||||
C: From<CosmicStackRenderElement<R>>,
|
||||
{
|
||||
let stack_loc = location
|
||||
+ self
|
||||
.0
|
||||
.with_program(|p| {
|
||||
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]
|
||||
.geometry()
|
||||
.loc
|
||||
})
|
||||
.to_physical_precise_round(scale);
|
||||
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
|
||||
|
||||
let elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
|
||||
&self.0, renderer, stack_loc, scale, alpha,
|
||||
);
|
||||
|
||||
let (window_elements, popup_elements) = self.0.with_program(|p| {
|
||||
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]
|
||||
.split_render_elements::<R, CosmicStackRenderElement<R>>(
|
||||
renderer, window_loc, scale, alpha,
|
||||
)
|
||||
});
|
||||
|
||||
(
|
||||
elements
|
||||
.into_iter()
|
||||
.map(C::from)
|
||||
.chain(window_elements.into_iter().map(C::from))
|
||||
.collect(),
|
||||
popup_elements.into_iter().map(C::from).collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
@ -1061,45 +1105,3 @@ render_elements! {
|
|||
Header = MemoryRenderBufferRenderElement<R>,
|
||||
Window = WaylandSurfaceRenderElement<R>,
|
||||
}
|
||||
|
||||
impl<R> AsRenderElements<R> for CosmicStack
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
<R as Renderer>::TextureId: 'static,
|
||||
{
|
||||
type RenderElement = CosmicStackRenderElement<R>;
|
||||
fn render_elements<C: From<Self::RenderElement>>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
location: Point<i32, Physical>,
|
||||
scale: Scale<f64>,
|
||||
alpha: f32,
|
||||
) -> Vec<C> {
|
||||
let stack_loc = location
|
||||
+ self
|
||||
.0
|
||||
.with_program(|p| {
|
||||
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]
|
||||
.geometry()
|
||||
.loc
|
||||
})
|
||||
.to_physical_precise_round(scale);
|
||||
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
|
||||
|
||||
let mut elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
|
||||
&self.0, renderer, stack_loc, scale, alpha,
|
||||
);
|
||||
|
||||
elements.extend(self.0.with_program(|p| {
|
||||
AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
|
||||
&p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)],
|
||||
renderer,
|
||||
window_loc,
|
||||
scale,
|
||||
alpha,
|
||||
)
|
||||
}));
|
||||
|
||||
elements.into_iter().map(C::from).collect()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ use std::time::Duration;
|
|||
use smithay::{
|
||||
backend::renderer::{
|
||||
element::{
|
||||
surface::WaylandSurfaceRenderElement, utils::select_dmabuf_feedback, AsRenderElements,
|
||||
RenderElementStates,
|
||||
surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement},
|
||||
utils::select_dmabuf_feedback,
|
||||
AsRenderElements, RenderElementStates,
|
||||
},
|
||||
ImportAll, Renderer,
|
||||
},
|
||||
|
|
@ -14,7 +15,7 @@ use smithay::{
|
|||
take_presentation_feedback_surface_tree, with_surfaces_surface_tree,
|
||||
OutputPresentationFeedback,
|
||||
},
|
||||
Window,
|
||||
PopupManager, Window,
|
||||
},
|
||||
input::{keyboard::KeyboardTarget, pointer::PointerTarget},
|
||||
output::Output,
|
||||
|
|
@ -591,6 +592,50 @@ impl CosmicSurface {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split_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>, Vec<C>)
|
||||
where
|
||||
R: Renderer + ImportAll,
|
||||
<R as Renderer>::TextureId: 'static,
|
||||
C: From<WaylandSurfaceRenderElement<R>>,
|
||||
{
|
||||
match self {
|
||||
CosmicSurface::Wayland(window) => {
|
||||
let surface = window.toplevel().wl_surface();
|
||||
|
||||
let popup_render_elements = PopupManager::popups_for_surface(surface)
|
||||
.flat_map(|(popup, popup_offset)| {
|
||||
let offset = (window.geometry().loc + popup_offset - popup.geometry().loc)
|
||||
.to_physical_precise_round(scale);
|
||||
|
||||
render_elements_from_surface_tree(
|
||||
renderer,
|
||||
popup.wl_surface(),
|
||||
location + offset,
|
||||
scale,
|
||||
alpha,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let window_render_elements =
|
||||
render_elements_from_surface_tree(renderer, surface, location, scale, alpha);
|
||||
|
||||
(window_render_elements, popup_render_elements)
|
||||
}
|
||||
CosmicSurface::X11(surface) => (
|
||||
surface.render_elements(renderer, location, scale, alpha),
|
||||
Vec::new(),
|
||||
),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyboardTarget<crate::state::State> for CosmicSurface {
|
||||
|
|
@ -761,6 +806,15 @@ impl WaylandFocus for CosmicSurface {
|
|||
}
|
||||
}
|
||||
|
||||
impl X11Relatable for CosmicSurface {
|
||||
fn is_window(&self, window: &X11Surface) -> bool {
|
||||
match self {
|
||||
CosmicSurface::X11(surface) => surface == window,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> AsRenderElements<R> for CosmicSurface
|
||||
where
|
||||
R: Renderer + ImportAll,
|
||||
|
|
@ -786,12 +840,3 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl X11Relatable for CosmicSurface {
|
||||
fn is_window(&self, window: &X11Surface) -> bool {
|
||||
match self {
|
||||
CosmicSurface::X11(surface) => surface == window,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@ use smithay::{
|
|||
},
|
||||
output::Output,
|
||||
render_elements,
|
||||
utils::{
|
||||
Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size,
|
||||
},
|
||||
utils::{Buffer as BufferCoords, IsAlive, Logical, Point, Rectangle, Serial, Size},
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
use std::{
|
||||
|
|
@ -164,6 +162,50 @@ impl CosmicWindow {
|
|||
pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> {
|
||||
self.0.loop_handle()
|
||||
}
|
||||
|
||||
pub fn split_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>, Vec<C>)
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
<R as Renderer>::TextureId: '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 window_elements, popup_elements) = self.0.with_program(|p| {
|
||||
p.window
|
||||
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
|
||||
renderer, window_loc, scale, alpha,
|
||||
)
|
||||
});
|
||||
|
||||
if has_ssd {
|
||||
let ssd_loc = location
|
||||
+ self
|
||||
.0
|
||||
.with_program(|p| p.window.geometry().loc)
|
||||
.to_physical_precise_round(scale);
|
||||
window_elements.extend(AsRenderElements::<R>::render_elements::<
|
||||
CosmicWindowRenderElement<R>,
|
||||
>(&self.0, renderer, ssd_loc, scale, alpha))
|
||||
}
|
||||
|
||||
(
|
||||
window_elements.into_iter().map(C::from).collect(),
|
||||
popup_elements.into_iter().map(C::from).collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
@ -555,44 +597,3 @@ render_elements! {
|
|||
Header = MemoryRenderBufferRenderElement<R>,
|
||||
Window = WaylandSurfaceRenderElement<R>,
|
||||
}
|
||||
|
||||
impl<R> AsRenderElements<R> for CosmicWindow
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
<R as Renderer>::TextureId: 'static,
|
||||
{
|
||||
type RenderElement = CosmicWindowRenderElement<R>;
|
||||
fn render_elements<C: From<Self::RenderElement>>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
location: Point<i32, Physical>,
|
||||
scale: Scale<f64>,
|
||||
alpha: f32,
|
||||
) -> Vec<C> {
|
||||
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 = self.0.with_program(|p| {
|
||||
AsRenderElements::<R>::render_elements::<CosmicWindowRenderElement<R>>(
|
||||
&p.window, renderer, window_loc, scale, alpha,
|
||||
)
|
||||
});
|
||||
if has_ssd {
|
||||
let ssd_loc = location
|
||||
+ self
|
||||
.0
|
||||
.with_program(|p| p.window.geometry().loc)
|
||||
.to_physical_precise_round(scale);
|
||||
elements.extend(AsRenderElements::<R>::render_elements::<
|
||||
CosmicWindowRenderElement<R>,
|
||||
>(&self.0, renderer, ssd_loc, scale, alpha))
|
||||
}
|
||||
|
||||
elements.into_iter().map(C::from).collect()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue