linux: query window geometry for determining the surface extents

This commit is contained in:
Dzmitry Malyshau 2024-02-07 00:33:40 -08:00
parent d3562d4c9c
commit e3ae7c4fe0
2 changed files with 29 additions and 26 deletions

View file

@ -299,6 +299,10 @@ impl BladeRenderer {
self.viewport_size = size; self.viewport_size = size;
} }
pub fn viewport_size(&self) -> gpu::Extent {
self.viewport_size
}
pub fn atlas(&self) -> &Arc<BladeAtlas> { pub fn atlas(&self) -> &Arc<BladeAtlas> {
&self.atlas &self.atlas
} }

View file

@ -31,26 +31,30 @@ struct Callbacks {
struct LinuxWindowInner { struct LinuxWindowInner {
bounds: Bounds<i32>, bounds: Bounds<i32>,
title_height: i32,
border_width: i32,
scale_factor: f32, scale_factor: f32,
renderer: BladeRenderer, renderer: BladeRenderer,
} }
impl LinuxWindowInner { impl LinuxWindowInner {
fn render_extent(&self) -> gpu::Extent { fn content_size(&self) -> Size<Pixels> {
gpu::Extent { let size = self.renderer.viewport_size();
width: (self.bounds.size.width - 2 * self.border_width) as u32, Size {
height: (self.bounds.size.height - 2 * self.border_width - self.title_height) as u32, width: size.width.into(),
depth: 1, height: size.height.into(),
} }
} }
fn content_size(&self) -> Size<Pixels> { }
let extent = self.render_extent();
Size { fn query_render_extent(xcb_connection: &xcb::Connection, x_window: x::Window) -> gpu::Extent {
width: extent.width.into(), let cookie = xcb_connection.send_request(&x::GetGeometry {
height: extent.height.into(), drawable: x::Drawable::Window(x_window),
} });
let reply = xcb_connection.wait_for_reply(cookie).unwrap();
println!("Got geometry {:?}", reply);
gpu::Extent {
width: reply.width() as u32,
height: reply.height() as u32,
depth: 1,
} }
} }
@ -143,7 +147,6 @@ impl LinuxWindowState {
}, },
WindowBounds::Fixed(bounds) => bounds.map(|p| p.0 as i32), WindowBounds::Fixed(bounds) => bounds.map(|p| p.0 as i32),
}; };
let border_width = 0i32;
xcb_connection.send_request(&x::CreateWindow { xcb_connection.send_request(&x::CreateWindow {
depth: x::COPY_FROM_PARENT as u8, depth: x::COPY_FROM_PARENT as u8,
@ -153,7 +156,7 @@ impl LinuxWindowState {
y: bounds.origin.y as i16, y: bounds.origin.y as i16,
width: bounds.size.width as u16, width: bounds.size.width as u16,
height: bounds.size.height as u16, height: bounds.size.height as u16,
border_width: border_width as u16, border_width: 0,
class: x::WindowClass::InputOutput, class: x::WindowClass::InputOutput,
visual: screen.root_visual(), visual: screen.root_visual(),
value_list: &xcb_values, value_list: &xcb_values,
@ -183,6 +186,10 @@ impl LinuxWindowState {
xcb_connection.send_request(&x::MapWindow { window: x_window }); xcb_connection.send_request(&x::MapWindow { window: x_window });
xcb_connection.flush().unwrap(); xcb_connection.flush().unwrap();
//Warning: it looks like this reported size is immediately invalidated
// on some platforms, followed by a "ConfigureNotify" event.
let gpu_extent = query_render_extent(&xcb_connection, x_window);
let raw = RawWindow { let raw = RawWindow {
connection: as_raw_xcb_connection::AsRawXcbConnection::as_raw_xcb_connection( connection: as_raw_xcb_connection::AsRawXcbConnection::as_raw_xcb_connection(
xcb_connection, xcb_connection,
@ -204,12 +211,6 @@ impl LinuxWindowState {
.unwrap(), .unwrap(),
); );
let gpu_extent = gpu::Extent {
width: bounds.size.width as u32,
height: bounds.size.height as u32,
depth: 1,
};
Self { Self {
xcb_connection: Arc::clone(xcb_connection), xcb_connection: Arc::clone(xcb_connection),
display: Rc::new(LinuxDisplay::new(xcb_connection, x_screen_index)), display: Rc::new(LinuxDisplay::new(xcb_connection, x_screen_index)),
@ -218,8 +219,6 @@ impl LinuxWindowState {
callbacks: Mutex::new(Callbacks::default()), callbacks: Mutex::new(Callbacks::default()),
inner: Mutex::new(LinuxWindowInner { inner: Mutex::new(LinuxWindowInner {
bounds, bounds,
title_height: 0, //TODO
border_width,
scale_factor: 1.0, scale_factor: 1.0,
renderer: BladeRenderer::new(gpu, gpu_extent), renderer: BladeRenderer::new(gpu, gpu_extent),
}), }),
@ -254,9 +253,9 @@ impl LinuxWindowState {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
let old_bounds = mem::replace(&mut inner.bounds, bounds); let old_bounds = mem::replace(&mut inner.bounds, bounds);
do_move = old_bounds.origin != bounds.origin; do_move = old_bounds.origin != bounds.origin;
if old_bounds.size != bounds.size { let gpu_size = query_render_extent(&self.xcb_connection, self.x_window);
let extent = inner.render_extent(); if inner.renderer.viewport_size() != gpu_size {
inner.renderer.resize(extent); inner.renderer.resize(gpu_size);
resize_args = Some((inner.content_size(), inner.scale_factor)); resize_args = Some((inner.content_size(), inner.scale_factor));
} }
} }