poc window decorations

This commit is contained in:
galister
2026-01-03 20:57:14 +09:00
parent 57c450cb45
commit b6c16dff18
12 changed files with 178 additions and 36 deletions

View File

@@ -10,8 +10,8 @@ use crate::{
globals::Globals, globals::Globals,
layout::Widget, layout::Widget,
renderer_vk::text::{ renderer_vk::text::{
TextShadow,
custom_glyph::{CustomGlyph, CustomGlyphData}, custom_glyph::{CustomGlyph, CustomGlyphData},
TextShadow,
}, },
stack::{self, ScissorBoundary, ScissorStack, TransformStack}, stack::{self, ScissorBoundary, ScissorStack, TransformStack},
widget::{self, ScrollbarInfo, WidgetState}, widget::{self, ScrollbarInfo, WidgetState},
@@ -147,6 +147,11 @@ impl Color {
let a = (self.a.clamp(0.0, 1.0) * 255.0).round() as u8; let a = (self.a.clamp(0.0, 1.0) * 255.0).round() as u8;
format!("#{r:02X}{g:02X}{b:02X}{a:02X}") format!("#{r:02X}{g:02X}{b:02X}{a:02X}")
} }
#[must_use]
pub fn as_arr(&self) -> [f32; 4] {
[self.r, self.b, self.g, self.a]
}
} }
impl Default for Color { impl Default for Color {

View File

@@ -13,12 +13,12 @@ use vulkano::{
view::ImageView, view::ImageView,
}, },
pipeline::{ pipeline::{
Pipeline, PipelineBindPoint,
graphics::{self, vertex_input::Vertex, viewport::Viewport}, graphics::{self, vertex_input::Vertex, viewport::Viewport},
Pipeline, PipelineBindPoint,
}, },
}; };
use super::{WGfx, pipeline::WGfxPipeline}; use super::{pipeline::WGfxPipeline, WGfx};
pub struct WGfxPass<V> { pub struct WGfxPass<V> {
pub command_buffer: Arc<SecondaryAutoCommandBuffer>, pub command_buffer: Arc<SecondaryAutoCommandBuffer>,
@@ -34,6 +34,7 @@ where
pub(super) fn new( pub(super) fn new(
pipeline: &Arc<WGfxPipeline<V>>, pipeline: &Arc<WGfxPipeline<V>>,
dimensions: [f32; 2], dimensions: [f32; 2],
offset: [f32; 2],
vertex_buffer: Subbuffer<[V]>, vertex_buffer: Subbuffer<[V]>,
vertices: Range<u32>, vertices: Range<u32>,
instances: Range<u32>, instances: Range<u32>,
@@ -41,7 +42,7 @@ where
vk_scissor: &graphics::viewport::Scissor, vk_scissor: &graphics::viewport::Scissor,
) -> anyhow::Result<Self> { ) -> anyhow::Result<Self> {
let viewport = Viewport { let viewport = Viewport {
offset: [0.0, 0.0], offset,
extent: dimensions, extent: dimensions,
depth_range: 0.0..=1.0, depth_range: 0.0..=1.0,
}; };

View File

@@ -1,14 +1,14 @@
use std::{marker::PhantomData, ops::Range, sync::Arc}; use std::{marker::PhantomData, ops::Range, sync::Arc};
use smallvec::{SmallVec, smallvec}; use smallvec::{smallvec, SmallVec};
use vulkano::{ use vulkano::{
buffer::{ buffer::{
BufferContents, BufferUsage, Subbuffer,
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo}, allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
BufferContents, BufferUsage, Subbuffer,
}, },
descriptor_set::{ descriptor_set::{
DescriptorSet, WriteDescriptorSet,
layout::{DescriptorBindingFlags, DescriptorSetLayoutCreateFlags}, layout::{DescriptorBindingFlags, DescriptorSetLayoutCreateFlags},
DescriptorSet, WriteDescriptorSet,
}, },
format::Format, format::Format,
image::{ image::{
@@ -17,9 +17,8 @@ use vulkano::{
}, },
memory::allocator::MemoryTypeFilter, memory::allocator::MemoryTypeFilter,
pipeline::{ pipeline::{
DynamicState, GraphicsPipeline, Pipeline, PipelineLayout,
graphics::{ graphics::{
self, GraphicsPipelineCreateInfo, self,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState}, color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology}, input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState, multisample::MultisampleState,
@@ -27,13 +26,15 @@ use vulkano::{
subpass::PipelineRenderingCreateInfo, subpass::PipelineRenderingCreateInfo,
vertex_input::{Vertex, VertexDefinition, VertexInputState}, vertex_input::{Vertex, VertexDefinition, VertexInputState},
viewport::ViewportState, viewport::ViewportState,
GraphicsPipelineCreateInfo,
}, },
layout::PipelineDescriptorSetLayoutCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo,
DynamicState, GraphicsPipeline, Pipeline, PipelineLayout,
}, },
shader::{EntryPoint, ShaderModule}, shader::{EntryPoint, ShaderModule},
}; };
use super::{WGfx, pass::WGfxPass}; use super::{pass::WGfxPass, WGfx};
pub struct WGfxPipeline<V> { pub struct WGfxPipeline<V> {
pub graphics: Arc<WGfx>, pub graphics: Arc<WGfx>,
@@ -266,6 +267,7 @@ where
pub fn create_pass( pub fn create_pass(
self: &Arc<Self>, self: &Arc<Self>,
dimensions: [f32; 2], dimensions: [f32; 2],
offset: [f32; 2],
vertex_buffer: Subbuffer<[V]>, vertex_buffer: Subbuffer<[V]>,
vertices: Range<u32>, vertices: Range<u32>,
instances: Range<u32>, instances: Range<u32>,
@@ -275,6 +277,7 @@ where
WGfxPass::new( WGfxPass::new(
&self.clone(), &self.clone(),
dimensions, dimensions,
offset,
vertex_buffer, vertex_buffer,
vertices, vertices,
instances, instances,

View File

@@ -200,6 +200,7 @@ impl ImageRenderer {
let pass = self.pipeline.inner.create_pass( let pass = self.pipeline.inner.create_pass(
[res[0] as _, res[1] as _], [res[0] as _, res[1] as _],
[0.0, 0.0],
vert_buffer.clone(), vert_buffer.clone(),
0..4, 0..4,
0..1, 0..1,

View File

@@ -10,10 +10,10 @@ use vulkano::{
use crate::{ use crate::{
drawing::{Boundary, Rectangle}, drawing::{Boundary, Rectangle},
gfx::{ gfx::{
BLEND_ALPHA, WGfx,
cmd::GfxCommandBuffer, cmd::GfxCommandBuffer,
pass::WGfxPass, pass::WGfxPass,
pipeline::{WGfxPipeline, WPipelineCreateInfo}, pipeline::{WGfxPipeline, WPipelineCreateInfo},
WGfx, BLEND_ALPHA,
}, },
renderer_vk::model_buffer::ModelBuffer, renderer_vk::model_buffer::ModelBuffer,
}; };
@@ -151,6 +151,7 @@ impl RectRenderer {
let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline); let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline);
let pass = self.pipeline.color_rect.create_pass( let pass = self.pipeline.color_rect.create_pass(
[res[0] as _, res[1] as _], [res[0] as _, res[1] as _],
[0.0, 0.0],
self.vert_buffer.clone(), self.vert_buffer.clone(),
0..4, 0..4,
0..self.rect_vertices.len() as _, 0..self.rect_vertices.len() as _,

View File

@@ -4,9 +4,9 @@ use crate::{
}; };
use super::{ use super::{
ContentType, FontSystem, GlyphDetails, GpuCacheStatus, SwashCache, TextArea,
custom_glyph::{CustomGlyphCacheKey, RasterizeCustomGlyphRequest, RasterizedCustomGlyph}, custom_glyph::{CustomGlyphCacheKey, RasterizeCustomGlyphRequest, RasterizedCustomGlyph},
text_atlas::{GlyphVertex, TextAtlas, TextPipeline}, text_atlas::{GlyphVertex, TextAtlas, TextPipeline},
ContentType, FontSystem, GlyphDetails, GpuCacheStatus, SwashCache, TextArea,
}; };
use cosmic_text::{Color, SubpixelBin, SwashContent}; use cosmic_text::{Color, SubpixelBin, SwashContent};
use etagere::size2; use etagere::size2;
@@ -272,6 +272,7 @@ impl TextRenderer {
let pass = self.pipeline.inner.create_pass( let pass = self.pipeline.inner.create_pass(
[res[0] as _, res[1] as _], [res[0] as _, res[1] as _],
[0.0, 0.0],
self.vertex_buffer.clone(), self.vertex_buffer.clone(),
0..4, 0..4,
0..self.glyph_vertices.len() as u32, 0..self.glyph_vertices.len() as u32,

View File

@@ -0,0 +1,23 @@
<layout>
<elements>
<rectangle
width="100%" height="100%"
margin="4" box_sizing="border_box"
border_color="~color_faded" border="2"
round="50%" color="~color_faded"
justify_content="space_between">
<label id="label_title" color="~color_text" size="18" text="Test" weight="bold" />
<Button macro="button_style" tooltip="WATCH.EDIT_MODE" _press="" border_color="~color_faded_translucent" color="~color_faded_50" color2="~color_faded_10">
<sprite width="24" height="24" src="watch/edit.svg" />
</Button>
<Button macro="button_style" tooltip="DECOR.CLOSE_WINDOW" _long_release="" border_color="~color_danger_translucent" color="~color_danger_50" color2="~color_danger_10">
<sprite width="24" height="24" src="edit/close.svg" />
</Button>
</rectangle>
</elements>
</layout>

View File

@@ -75,6 +75,7 @@ impl LinePool {
let pass = self.pipeline.create_pass( let pass = self.pipeline.create_pass(
[1.0, 1.0], [1.0, 1.0],
[0.0, 0.0],
app.gfx_extras.quad_verts.clone(), app.gfx_extras.quad_verts.clone(),
0..4, 0..4,
0..1, 0..1,

View File

@@ -110,6 +110,7 @@ impl Skybox {
let set1 = pipeline.uniform_buffer_upload(1, vec![1f32])?; let set1 = pipeline.uniform_buffer_upload(1, vec![1f32])?;
let pass = pipeline.create_pass( let pass = pipeline.create_pass(
tgt.extent_f32(), tgt.extent_f32(),
[0.0, 0.0],
app.gfx_extras.quad_verts.clone(), app.gfx_extras.quad_verts.clone(),
0..4, 0..4,
0..1, 0..1,
@@ -161,6 +162,7 @@ impl Skybox {
.unwrap(); .unwrap();
let pass = pipeline.create_pass( let pass = pipeline.create_pass(
tgt.extent_f32(), tgt.extent_f32(),
[0.0, 0.0],
app.gfx_extras.quad_verts.clone(), app.gfx_extras.quad_verts.clone(),
0..4, 0..4,
0..1, 0..1,

View File

@@ -192,12 +192,20 @@ impl OverlayBackend for ScreenBackend {
.meta .meta
.is_some_and(|old| old.extent[..2] != meta.extent[..2]) .is_some_and(|old| old.extent[..2] != meta.extent[..2])
{ {
pipeline.set_extent(app, [meta.extent[0] as _, meta.extent[1] as _])?; pipeline.set_extent(
app,
[meta.extent[0] as _, meta.extent[1] as _],
[0., 0.],
)?;
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr())); self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
} }
} else { } else {
let pipeline = let pipeline = ScreenPipeline::new(
ScreenPipeline::new(&meta, app, self.stereo.unwrap_or(StereoMode::None))?; &meta,
app,
self.stereo.unwrap_or(StereoMode::None),
[0., 0.],
)?;
meta.extent[2] = pipeline.get_depth(); meta.extent[2] = pipeline.get_depth();
self.pipeline = Some(pipeline); self.pipeline = Some(pipeline);
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr())); self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));

View File

@@ -46,11 +46,17 @@ pub struct ScreenPipeline {
pipeline: Arc<WGfxPipeline<Vert2Uv>>, pipeline: Arc<WGfxPipeline<Vert2Uv>>,
buf_alpha: Subbuffer<[f32]>, buf_alpha: Subbuffer<[f32]>,
extentf: [f32; 2], extentf: [f32; 2],
offsetf: [f32; 2],
stereo: StereoMode, stereo: StereoMode,
} }
impl ScreenPipeline { impl ScreenPipeline {
pub fn new(meta: &FrameMeta, app: &mut AppState, stereo: StereoMode) -> anyhow::Result<Self> { pub fn new(
meta: &FrameMeta,
app: &mut AppState,
stereo: StereoMode,
offsetf: [f32; 2],
) -> anyhow::Result<Self> {
let extentf = [meta.extent[0] as f32, meta.extent[1] as f32]; let extentf = [meta.extent[0] as f32, meta.extent[1] as f32];
let pipeline = app.gfx.create_pipeline( let pipeline = app.gfx.create_pipeline(
@@ -70,11 +76,19 @@ impl ScreenPipeline {
app, app,
pipeline.clone(), pipeline.clone(),
extentf, extentf,
offsetf,
buf_alpha.clone() buf_alpha.clone()
)?], )?],
mouse: Self::create_mouse_pass(app, pipeline.clone(), extentf, buf_alpha.clone())?, mouse: Self::create_mouse_pass(
app,
pipeline.clone(),
extentf,
offsetf,
buf_alpha.clone(),
)?,
pipeline, pipeline,
extentf, extentf,
offsetf,
buf_alpha, buf_alpha,
stereo, stereo,
}; };
@@ -94,6 +108,7 @@ impl ScreenPipeline {
app, app,
self.pipeline.clone(), self.pipeline.clone(),
self.extentf, self.extentf,
self.offsetf,
self.buf_alpha.clone(), self.buf_alpha.clone(),
)?); )?);
} }
@@ -113,15 +128,34 @@ impl ScreenPipeline {
self.pass.len() as _ self.pass.len() as _
} }
pub fn set_extent(&mut self, app: &mut AppState, extentf: [f32; 2]) -> anyhow::Result<()> { pub fn set_extent(
&mut self,
app: &mut AppState,
extentf: [f32; 2],
offsetf: [f32; 2],
) -> anyhow::Result<()> {
self.extentf = extentf;
self.offsetf = offsetf;
for (eye, pass) in self.pass.iter_mut().enumerate() { for (eye, pass) in self.pass.iter_mut().enumerate() {
*pass = Self::create_pass(app, self.pipeline.clone(), extentf, self.buf_alpha.clone())?; *pass = Self::create_pass(
app,
self.pipeline.clone(),
extentf,
offsetf,
self.buf_alpha.clone(),
)?;
let verts = stereo_mode_to_verts(self.stereo, eye); let verts = stereo_mode_to_verts(self.stereo, eye);
pass.buf_vert.write()?.copy_from_slice(&verts); pass.buf_vert.write()?.copy_from_slice(&verts);
} }
self.mouse = self.mouse = Self::create_mouse_pass(
Self::create_mouse_pass(app, self.pipeline.clone(), extentf, self.buf_alpha.clone())?; app,
self.pipeline.clone(),
extentf,
offsetf,
self.buf_alpha.clone(),
)?;
Ok(()) Ok(())
} }
@@ -129,6 +163,7 @@ impl ScreenPipeline {
app: &mut AppState, app: &mut AppState,
pipeline: Arc<WGfxPipeline<Vert2Uv>>, pipeline: Arc<WGfxPipeline<Vert2Uv>>,
extentf: [f32; 2], extentf: [f32; 2],
offsetf: [f32; 2],
buf_alpha: Subbuffer<[f32]>, buf_alpha: Subbuffer<[f32]>,
) -> anyhow::Result<BufPass> { ) -> anyhow::Result<BufPass> {
let set0 = pipeline.uniform_sampler( let set0 = pipeline.uniform_sampler(
@@ -143,6 +178,7 @@ impl ScreenPipeline {
let pass = pipeline.create_pass( let pass = pipeline.create_pass(
extentf, extentf,
offsetf,
buf_vert.clone(), buf_vert.clone(),
0..4, 0..4,
0..1, 0..1,
@@ -157,6 +193,7 @@ impl ScreenPipeline {
app: &mut AppState, app: &mut AppState,
pipeline: Arc<WGfxPipeline<Vert2Uv>>, pipeline: Arc<WGfxPipeline<Vert2Uv>>,
extentf: [f32; 2], extentf: [f32; 2],
offsetf: [f32; 2],
buf_alpha: Subbuffer<[f32]>, buf_alpha: Subbuffer<[f32]>,
) -> anyhow::Result<BufPass> { ) -> anyhow::Result<BufPass> {
#[rustfmt::skip] #[rustfmt::skip]
@@ -184,6 +221,7 @@ impl ScreenPipeline {
let set1 = pipeline.buffer(1, buf_alpha)?; let set1 = pipeline.buffer(1, buf_alpha)?;
let pass = pipeline.create_pass( let pass = pipeline.create_pass(
extentf, extentf,
offsetf,
buf_vert.clone(), buf_vert.clone(),
0..4, 0..4,
0..1, 0..1,

View File

@@ -7,7 +7,15 @@ use std::sync::Arc;
use vulkano::{ use vulkano::{
buffer::BufferUsage, image::view::ImageView, pipeline::graphics::color_blend::AttachmentBlend, buffer::BufferUsage, image::view::ImageView, pipeline::graphics::color_blend::AttachmentBlend,
}; };
use wgui::gfx::pipeline::{WGfxPipeline, WPipelineCreateInfo}; use wgui::{
gfx::{
cmd::WGfxClearMode,
pipeline::{WGfxPipeline, WPipelineCreateInfo},
},
i18n::Translation,
parser::Fetchable,
widget::label::WidgetLabel,
};
use wlx_capture::frame::MouseMeta; use wlx_capture::frame::MouseMeta;
use wlx_common::{ use wlx_common::{
overlays::{BackendAttrib, BackendAttribValue, StereoMode}, overlays::{BackendAttrib, BackendAttribValue, StereoMode},
@@ -21,6 +29,7 @@ use crate::{
wayvr::{self, SurfaceBufWithImage}, wayvr::{self, SurfaceBufWithImage},
}, },
graphics::{ExtentExt, Vert2Uv, upload_quad_vertices}, graphics::{ExtentExt, Vert2Uv, upload_quad_vertices},
gui::panel::{GuiPanel, NewGuiPanelParams},
overlays::screen::capture::ScreenPipeline, overlays::screen::capture::ScreenPipeline,
state::{self, AppState}, state::{self, AppState},
subsystem::{hid::WheelDelta, input::KeyboardFocus}, subsystem::{hid::WheelDelta, input::KeyboardFocus},
@@ -33,9 +42,12 @@ use crate::{
}, },
}; };
const BORDER_SIZE: u32 = 5;
const BAR_SIZE: u32 = 24;
pub fn create_wl_window_overlay( pub fn create_wl_window_overlay(
name: Arc<str>, name: Arc<str>,
app: &AppState, app: &mut AppState,
window: wayvr::window::WindowHandle, window: wayvr::window::WindowHandle,
) -> anyhow::Result<OverlayWindowConfig> { ) -> anyhow::Result<OverlayWindowConfig> {
Ok(OverlayWindowConfig { Ok(OverlayWindowConfig {
@@ -71,12 +83,14 @@ pub struct WvrWindowBackend {
mouse: Option<MouseMeta>, mouse: Option<MouseMeta>,
stereo: Option<StereoMode>, stereo: Option<StereoMode>,
cur_image: Option<Arc<ImageView>>, cur_image: Option<Arc<ImageView>>,
panel: GuiPanel<()>,
mouse_transform: Affine2,
} }
impl WvrWindowBackend { impl WvrWindowBackend {
fn new( fn new(
name: Arc<str>, name: Arc<str>,
app: &AppState, app: &mut AppState,
window: wayvr::window::WindowHandle, window: wayvr::window::WindowHandle,
) -> anyhow::Result<Self> { ) -> anyhow::Result<Self> {
let popups_pipeline = app.gfx.create_pipeline( let popups_pipeline = app.gfx.create_pipeline(
@@ -85,6 +99,28 @@ impl WvrWindowBackend {
WPipelineCreateInfo::new(app.gfx.surface_format).use_blend(AttachmentBlend::default()), WPipelineCreateInfo::new(app.gfx.surface_format).use_blend(AttachmentBlend::default()),
)?; )?;
let mut panel = GuiPanel::new_from_template(
app,
"gui/decor.xml",
(),
NewGuiPanelParams {
resize_to_parent: true,
..Default::default()
},
)?;
{
let mut title = panel
.parser_state
.fetch_widget_as::<WidgetLabel>(&panel.layout.state, "label_title")?;
title.set_text_simple(
&mut app.wgui_globals.get(),
Translation::from_raw_text(&*name),
);
}
panel.update_layout()?;
Ok(Self { Ok(Self {
name, name,
pipeline: None, pipeline: None,
@@ -101,25 +137,29 @@ impl WvrWindowBackend {
None None
}, },
cur_image: None, cur_image: None,
panel,
mouse_transform: Affine2::ZERO,
}) })
} }
} }
impl OverlayBackend for WvrWindowBackend { impl OverlayBackend for WvrWindowBackend {
fn init(&mut self, _app: &mut state::AppState) -> anyhow::Result<()> { fn init(&mut self, app: &mut state::AppState) -> anyhow::Result<()> {
Ok(()) self.panel.init(app)
} }
fn pause(&mut self, _app: &mut state::AppState) -> anyhow::Result<()> { fn pause(&mut self, app: &mut state::AppState) -> anyhow::Result<()> {
Ok(()) self.panel.pause(app)
} }
fn resume(&mut self, _app: &mut state::AppState) -> anyhow::Result<()> { fn resume(&mut self, app: &mut state::AppState) -> anyhow::Result<()> {
self.just_resumed = true; self.just_resumed = true;
Ok(()) self.panel.resume(app)
} }
fn should_render(&mut self, app: &mut AppState) -> anyhow::Result<ShouldRender> { fn should_render(&mut self, app: &mut AppState) -> anyhow::Result<ShouldRender> {
let should_render_panel = self.panel.should_render(app)?;
let Some(toplevel) = app let Some(toplevel) = app
.wvr_server .wvr_server
.as_ref() .as_ref()
@@ -162,22 +202,37 @@ impl OverlayBackend for WvrWindowBackend {
let mut meta = FrameMeta { let mut meta = FrameMeta {
extent: surf.image.image().extent(), extent: surf.image.image().extent(),
format: surf.image.format(), format: surf.image.format(),
clear: WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.0]),
..Default::default() ..Default::default()
}; };
if let Some(pipeline) = self.pipeline.as_mut() { if let Some(pipeline) = self.pipeline.as_mut() {
let inner_extent = meta.extent;
meta.extent[0] += BORDER_SIZE * 2;
meta.extent[1] += BORDER_SIZE * 2 + BAR_SIZE;
meta.extent[2] = pipeline.get_depth(); meta.extent[2] = pipeline.get_depth();
if self if self
.meta .meta
.is_some_and(|old| old.extent[..2] != meta.extent[..2]) .is_some_and(|old| old.extent[..2] != meta.extent[..2])
{ {
pipeline.set_extent(app, [meta.extent[0] as _, meta.extent[1] as _])?; pipeline.set_extent(
app,
[inner_extent[0] as _, inner_extent[1] as _],
[BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _],
)?;
self.interaction_transform = self.interaction_transform =
Some(ui_transform(meta.extent.extent_u32arr())); Some(ui_transform(meta.extent.extent_u32arr()));
} }
} else { } else {
let pipeline = let pipeline = ScreenPipeline::new(
ScreenPipeline::new(&meta, app, self.stereo.unwrap_or(StereoMode::None))?; &meta,
app,
self.stereo.unwrap_or(StereoMode::None),
[BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _],
)?;
meta.extent[0] += BORDER_SIZE * 2;
meta.extent[1] += BORDER_SIZE * 2 + BAR_SIZE;
meta.extent[2] = pipeline.get_depth(); meta.extent[2] = pipeline.get_depth();
self.pipeline = Some(pipeline); self.pipeline = Some(pipeline);
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr())); self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
@@ -215,7 +270,7 @@ impl OverlayBackend for WvrWindowBackend {
} else if dirty { } else if dirty {
Ok(ShouldRender::Should) Ok(ShouldRender::Should)
} else { } else {
Ok(ShouldRender::Can) Ok(should_render_panel)
} }
} else { } else {
log::trace!("{}: no buffer for wl_surface", self.name); log::trace!("{}: no buffer for wl_surface", self.name);
@@ -229,6 +284,8 @@ impl OverlayBackend for WvrWindowBackend {
app: &mut state::AppState, app: &mut state::AppState,
rdr: &mut RenderResources, rdr: &mut RenderResources,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
self.panel.render(app, rdr)?;
let image = self.cur_image.as_ref().unwrap().clone(); let image = self.cur_image.as_ref().unwrap().clone();
self.pipeline self.pipeline
@@ -264,6 +321,7 @@ impl OverlayBackend for WvrWindowBackend {
let pass = self.popups_pipeline.create_pass( let pass = self.popups_pipeline.create_pass(
extentf, extentf,
[BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _],
buf_vert, buf_vert,
0..4, 0..4,
0..1, 0..1,
@@ -308,8 +366,8 @@ impl OverlayBackend for WvrWindowBackend {
} }
} }
fn on_left(&mut self, _app: &mut state::AppState, _pointer: usize) { fn on_left(&mut self, app: &mut state::AppState, pointer: usize) {
// Ignore event self.panel.on_left(app, pointer);
} }
fn on_pointer(&mut self, app: &mut state::AppState, hit: &input::PointerHit, pressed: bool) { fn on_pointer(&mut self, app: &mut state::AppState, hit: &input::PointerHit, pressed: bool) {