Use intrinsic (buffer) size when geometry is not set
The simplest clients like vkcube do not set geometry, and were left without decorations
This commit is contained in:
parent
186584398c
commit
36c87d4638
4 changed files with 196 additions and 4 deletions
108
src/client_buffer.rs
Normal file
108
src/client_buffer.rs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
use std::{os::unix::prelude::OwnedFd, rc::Rc};
|
||||
|
||||
use wl_proxy::protocols::{
|
||||
linux_dmabuf_v1::{
|
||||
zwp_linux_buffer_params_v1::{
|
||||
ZwpLinuxBufferParamsV1, ZwpLinuxBufferParamsV1Flags, ZwpLinuxBufferParamsV1Handler,
|
||||
},
|
||||
zwp_linux_dmabuf_v1::{ZwpLinuxDmabufV1, ZwpLinuxDmabufV1Handler},
|
||||
},
|
||||
wayland::{
|
||||
wl_buffer::{WlBuffer, WlBufferHandler},
|
||||
wl_shm::{WlShm, WlShmFormat, WlShmHandler},
|
||||
wl_shm_pool::{WlShmPool, WlShmPoolHandler},
|
||||
},
|
||||
};
|
||||
|
||||
pub struct ClientWlBuffer {
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
|
||||
impl WlBufferHandler for ClientWlBuffer {}
|
||||
|
||||
pub struct ClientWlShm;
|
||||
|
||||
impl WlShmHandler for ClientWlShm {
|
||||
fn handle_create_pool(
|
||||
&mut self,
|
||||
slf: &Rc<WlShm>,
|
||||
id: &Rc<WlShmPool>,
|
||||
fd: &Rc<OwnedFd>,
|
||||
size: i32,
|
||||
) {
|
||||
id.set_handler(ClientWlShmPool {});
|
||||
slf.send_create_pool(id, fd, size);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientWlShmPool {}
|
||||
|
||||
impl WlShmPoolHandler for ClientWlShmPool {
|
||||
fn handle_create_buffer(
|
||||
&mut self,
|
||||
slf: &Rc<WlShmPool>,
|
||||
id: &Rc<WlBuffer>,
|
||||
offset: i32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
stride: i32,
|
||||
format: WlShmFormat,
|
||||
) {
|
||||
id.set_handler(ClientWlBuffer { width, height });
|
||||
slf.send_create_buffer(id, offset, width, height, stride, format);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientZwpLinuxDmabufV1;
|
||||
|
||||
impl ZwpLinuxDmabufV1Handler for ClientZwpLinuxDmabufV1 {
|
||||
fn handle_create_params(
|
||||
&mut self,
|
||||
slf: &Rc<ZwpLinuxDmabufV1>,
|
||||
params_id: &Rc<ZwpLinuxBufferParamsV1>,
|
||||
) {
|
||||
params_id.set_handler(ClientZwpLinuxBufferParamsV1 { size: None });
|
||||
slf.send_create_params(params_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientZwpLinuxBufferParamsV1 {
|
||||
size: Option<(i32, i32)>,
|
||||
}
|
||||
|
||||
impl ZwpLinuxBufferParamsV1Handler for ClientZwpLinuxBufferParamsV1 {
|
||||
fn handle_create(
|
||||
&mut self,
|
||||
slf: &Rc<ZwpLinuxBufferParamsV1>,
|
||||
width: i32,
|
||||
height: i32,
|
||||
format: u32,
|
||||
flags: ZwpLinuxBufferParamsV1Flags,
|
||||
) {
|
||||
self.size = Some((width, height));
|
||||
slf.send_create(width, height, format, flags);
|
||||
}
|
||||
|
||||
fn handle_created(&mut self, slf: &Rc<ZwpLinuxBufferParamsV1>, buffer: &Rc<WlBuffer>) {
|
||||
if let Some((width, height)) = self.size {
|
||||
buffer.set_handler(ClientWlBuffer { width, height });
|
||||
} else {
|
||||
log::warn!("dma-buf created without size {slf:?} {buffer:?}");
|
||||
}
|
||||
slf.send_created(buffer);
|
||||
}
|
||||
|
||||
fn handle_create_immed(
|
||||
&mut self,
|
||||
slf: &Rc<ZwpLinuxBufferParamsV1>,
|
||||
buffer_id: &Rc<WlBuffer>,
|
||||
width: i32,
|
||||
height: i32,
|
||||
format: u32,
|
||||
flags: ZwpLinuxBufferParamsV1Flags,
|
||||
) {
|
||||
buffer_id.set_handler(ClientWlBuffer { width, height });
|
||||
slf.send_create_immed(buffer_id, width, height, format, flags);
|
||||
}
|
||||
}
|
||||
22
src/deco.rs
22
src/deco.rs
|
|
@ -21,6 +21,7 @@ use crate::{buffer::SimpleBufferPool, globals::Globals, util::Bounds};
|
|||
|
||||
#[derive(Default, Debug, Clone, PartialEq)]
|
||||
struct DecoParams {
|
||||
has_geometry: bool,
|
||||
bounds: Bounds,
|
||||
}
|
||||
|
||||
|
|
@ -156,6 +157,23 @@ impl Deco {
|
|||
deco
|
||||
}
|
||||
|
||||
pub fn handle_intrinsic_size(&self, width: i32, height: i32) {
|
||||
let mut params = self.next_params.borrow_mut();
|
||||
if params.has_geometry {
|
||||
return;
|
||||
}
|
||||
log::debug!(
|
||||
"decoration {:?} handling buffer size {width}x{height}",
|
||||
self.wl_surface
|
||||
);
|
||||
params.bounds = Bounds {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn handle_window_geometry(
|
||||
&self,
|
||||
x: i32,
|
||||
|
|
@ -167,7 +185,9 @@ impl Deco {
|
|||
"decoration {:?} handling geometry {width}x{height} @ {x},{y}",
|
||||
self.wl_surface
|
||||
);
|
||||
self.next_params.borrow_mut().bounds = Bounds {
|
||||
let mut params = self.next_params.borrow_mut();
|
||||
params.has_geometry = true;
|
||||
params.bounds = Bounds {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
|
|
|
|||
13
src/main.rs
13
src/main.rs
|
|
@ -5,7 +5,11 @@ use wl_proxy::{
|
|||
baseline::Baseline,
|
||||
object::{ConcreteObject, Object, ObjectCoreApi, ObjectRcUtils},
|
||||
protocols::{
|
||||
wayland::wl_registry::{WlRegistry, WlRegistryHandler},
|
||||
linux_dmabuf_v1::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
|
||||
wayland::{
|
||||
wl_registry::{WlRegistry, WlRegistryHandler},
|
||||
wl_shm::WlShm,
|
||||
},
|
||||
xdg_shell::xdg_wm_base::XdgWmBase,
|
||||
},
|
||||
simple::{SimpleCommandExt, SimpleProxy},
|
||||
|
|
@ -14,6 +18,7 @@ use wl_proxy::{
|
|||
use crate::globals::Globals;
|
||||
|
||||
mod buffer;
|
||||
mod client_buffer;
|
||||
mod deco;
|
||||
mod globals;
|
||||
mod seat;
|
||||
|
|
@ -40,6 +45,12 @@ impl WlRegistryHandler for ClientWlRegistry {
|
|||
.set_handler(xdg::ClientXdgWmBase {
|
||||
globals: self.globals.clone(),
|
||||
}),
|
||||
WlShm::INTERFACE => id
|
||||
.downcast::<WlShm>()
|
||||
.set_handler(client_buffer::ClientWlShm),
|
||||
ZwpLinuxDmabufV1::INTERFACE => id
|
||||
.downcast::<ZwpLinuxDmabufV1>()
|
||||
.set_handler(client_buffer::ClientZwpLinuxDmabufV1),
|
||||
_ => {}
|
||||
}
|
||||
slf.send_bind(name, id);
|
||||
|
|
|
|||
57
src/xdg.rs
57
src/xdg.rs
|
|
@ -4,7 +4,8 @@ use wl_proxy::{
|
|||
object::ObjectUtils,
|
||||
protocols::{
|
||||
wayland::{
|
||||
wl_output::WlOutput,
|
||||
wl_buffer::WlBuffer,
|
||||
wl_output::{WlOutput, WlOutputTransform},
|
||||
wl_surface::{WlSurface, WlSurfaceHandler},
|
||||
},
|
||||
xdg_shell::{
|
||||
|
|
@ -17,13 +18,63 @@ use wl_proxy::{
|
|||
},
|
||||
};
|
||||
|
||||
use crate::{deco::Deco, globals::Globals, util::Bounds};
|
||||
use crate::{client_buffer, deco::Deco, globals::Globals, util::Bounds};
|
||||
|
||||
pub struct ClientWlSurface {
|
||||
pub xdg_surface: Rc<XdgSurface>,
|
||||
pub transform: Option<WlOutputTransform>,
|
||||
pub scale: Option<i32>,
|
||||
}
|
||||
|
||||
impl WlSurfaceHandler for ClientWlSurface {
|
||||
fn handle_set_buffer_transform(&mut self, slf: &Rc<WlSurface>, transform: WlOutputTransform) {
|
||||
self.transform = Some(transform);
|
||||
slf.send_set_buffer_transform(transform);
|
||||
}
|
||||
|
||||
fn handle_set_buffer_scale(&mut self, slf: &Rc<WlSurface>, scale: i32) {
|
||||
self.scale = Some(scale);
|
||||
slf.send_set_buffer_scale(scale);
|
||||
}
|
||||
|
||||
fn handle_attach(
|
||||
&mut self,
|
||||
slf: &Rc<WlSurface>,
|
||||
buffer: Option<&Rc<WlBuffer>>,
|
||||
x: i32,
|
||||
y: i32,
|
||||
) {
|
||||
let surf_handler = self.xdg_surface.get_handler_ref::<ClientXdgSurface>();
|
||||
if let Some(buffer) = buffer {
|
||||
if let Ok(buf_handler) = buffer.try_get_handler_ref::<client_buffer::ClientWlBuffer>() {
|
||||
if let Some(deco) = surf_handler.deco.as_ref() {
|
||||
let mut width = buf_handler.width;
|
||||
let mut height = buf_handler.height;
|
||||
if let Some(scale) = self.scale {
|
||||
width /= scale;
|
||||
height /= scale;
|
||||
}
|
||||
if let Some(transform) = self.transform
|
||||
&& (transform == WlOutputTransform::_90
|
||||
|| transform == WlOutputTransform::_270
|
||||
|| transform == WlOutputTransform::FLIPPED_270
|
||||
|| transform == WlOutputTransform::FLIPPED_270)
|
||||
{
|
||||
std::mem::swap(&mut width, &mut height);
|
||||
}
|
||||
deco.handle_intrinsic_size(width, height);
|
||||
} else {
|
||||
log::debug!("surface {slf:?} buffer attach before deco");
|
||||
}
|
||||
} else {
|
||||
log::warn!("surface {slf:?} buffer with unknown size {buffer:?}");
|
||||
}
|
||||
} else {
|
||||
log::debug!("surface {slf:?} buffer cleared");
|
||||
}
|
||||
slf.send_attach(buffer, x, y);
|
||||
}
|
||||
|
||||
fn handle_commit(&mut self, slf: &Rc<WlSurface>) {
|
||||
log::debug!("commit {slf:?}");
|
||||
let surf_handler = self.xdg_surface.get_handler_ref::<ClientXdgSurface>();
|
||||
|
|
@ -47,6 +98,8 @@ impl XdgWmBaseHandler for ClientXdgWmBase {
|
|||
) {
|
||||
surface.set_handler(ClientWlSurface {
|
||||
xdg_surface: id.clone(),
|
||||
scale: None,
|
||||
transform: None,
|
||||
});
|
||||
id.set_handler(ClientXdgSurface {
|
||||
deco: None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue