162 lines
4.3 KiB
Rust
162 lines
4.3 KiB
Rust
use smithay::{
|
|
backend::renderer::{
|
|
damage::OutputDamageTracker,
|
|
element::{
|
|
memory::MemoryRenderBufferRenderElement, solid::SolidColorRenderElement,
|
|
surface::WaylandSurfaceRenderElement, AsRenderElements, Id, Kind,
|
|
},
|
|
gles::{GlesRenderer, GlesTarget},
|
|
utils::CommitCounter,
|
|
Color32F, ImportAll, ImportDmaWl, ImportMem, ImportMemWl, Renderer, RendererSuper,
|
|
},
|
|
desktop::{space::SpaceElement, Window},
|
|
output::Output,
|
|
render_elements,
|
|
utils::{IsAlive, Physical, Point, Scale},
|
|
};
|
|
use wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode;
|
|
|
|
use crate::State;
|
|
|
|
render_elements! {
|
|
pub OutputElement<R> where R: ImportMem + ImportDmaWl + ImportMemWl;
|
|
Window=WaylandSurfaceRenderElement<R>,
|
|
Background=SolidColorRenderElement,
|
|
}
|
|
|
|
#[derive(PartialEq, Eq, Clone)]
|
|
pub struct DecoratedWindow {
|
|
pub window: Window,
|
|
}
|
|
|
|
impl DecoratedWindow {
|
|
pub fn new(window: Window) -> Self {
|
|
Self { window }
|
|
}
|
|
|
|
fn decorated(&self) -> bool {
|
|
let mut b = false;
|
|
if let Some(toplevel) = self.window.toplevel() {
|
|
toplevel.with_pending_state(|f| {
|
|
if let Some(decor) = f.decoration_mode {
|
|
b = decor == Mode::ServerSide;
|
|
}
|
|
});
|
|
}
|
|
b
|
|
}
|
|
}
|
|
|
|
impl SpaceElement for DecoratedWindow {
|
|
fn bbox(&self) -> smithay::utils::Rectangle<i32, smithay::utils::Logical> {
|
|
let mut bbox = self.window.bbox();
|
|
|
|
if self.decorated() {
|
|
bbox.loc.x -= 5;
|
|
bbox.loc.y -= 22;
|
|
}
|
|
|
|
bbox
|
|
}
|
|
|
|
fn is_in_input_region(
|
|
&self,
|
|
point: &smithay::utils::Point<f64, smithay::utils::Logical>,
|
|
) -> bool {
|
|
self.window.is_in_input_region(point)
|
|
}
|
|
|
|
fn set_activate(&self, activated: bool) {
|
|
self.window.set_activate(activated)
|
|
}
|
|
|
|
fn output_enter(
|
|
&self,
|
|
output: &Output,
|
|
overlap: smithay::utils::Rectangle<i32, smithay::utils::Logical>,
|
|
) {
|
|
self.window.output_enter(output, overlap)
|
|
}
|
|
|
|
fn output_leave(&self, output: &Output) {
|
|
self.window.output_leave(output)
|
|
}
|
|
}
|
|
|
|
impl IsAlive for DecoratedWindow {
|
|
fn alive(&self) -> bool {
|
|
self.window.alive()
|
|
}
|
|
}
|
|
|
|
impl<R> AsRenderElements<R> for DecoratedWindow
|
|
where
|
|
R: Renderer + ImportDmaWl + ImportMemWl + ImportMem + ImportAll,
|
|
<R as RendererSuper>::TextureId: Clone + Send + 'static,
|
|
{
|
|
type RenderElement = OutputElement<R>; // one enum, both variants
|
|
|
|
fn render_elements<C: From<Self::RenderElement>>(
|
|
&self,
|
|
renderer: &mut R,
|
|
location: Point<i32, Physical>,
|
|
scale: Scale<f64>,
|
|
alpha: f32,
|
|
) -> Vec<C> {
|
|
let mut elements: Vec<C> = Vec::new();
|
|
|
|
/* Start with actual window elements */
|
|
elements.extend(
|
|
self.window
|
|
.render_elements::<OutputElement<R>>(renderer, location, scale, alpha)
|
|
.into_iter()
|
|
.map(C::from),
|
|
);
|
|
|
|
/* If the window is decorated, push a solid color */
|
|
let decorated = self.decorated();
|
|
if decorated {
|
|
let mut bg_rect = self.window.geometry().to_physical_precise_round(scale);
|
|
|
|
bg_rect.size.w += 10;
|
|
bg_rect.size.h += 27;
|
|
|
|
let background = SolidColorRenderElement::new(
|
|
Id::new(),
|
|
bg_rect,
|
|
CommitCounter::default(),
|
|
Color32F::new(1.0, 0.75, 0.26, 1.0),
|
|
Kind::Unspecified,
|
|
);
|
|
|
|
elements.push(C::from(OutputElement::Background(background)));
|
|
}
|
|
|
|
elements
|
|
}
|
|
}
|
|
|
|
impl State {
|
|
pub fn render(
|
|
&self,
|
|
output: &Output,
|
|
renderer: &mut GlesRenderer,
|
|
framebuffer: &mut GlesTarget,
|
|
damage_tracker: &mut OutputDamageTracker,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
// let elem = DecorationElement::
|
|
|
|
smithay::desktop::space::render_output::<_, OutputElement<GlesRenderer>, _, _>(
|
|
output,
|
|
renderer,
|
|
framebuffer,
|
|
1.0,
|
|
0,
|
|
[&self.space],
|
|
&[],
|
|
damage_tracker,
|
|
[0.07, 0.16, 0.286, 1.0],
|
|
)?;
|
|
Ok(())
|
|
}
|
|
}
|