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)]
|
#[derive(Default, Debug, Clone, PartialEq)]
|
||||||
struct DecoParams {
|
struct DecoParams {
|
||||||
|
has_geometry: bool,
|
||||||
bounds: Bounds,
|
bounds: Bounds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,6 +157,23 @@ impl Deco {
|
||||||
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(
|
pub fn handle_window_geometry(
|
||||||
&self,
|
&self,
|
||||||
x: i32,
|
x: i32,
|
||||||
|
|
@ -167,7 +185,9 @@ impl Deco {
|
||||||
"decoration {:?} handling geometry {width}x{height} @ {x},{y}",
|
"decoration {:?} handling geometry {width}x{height} @ {x},{y}",
|
||||||
self.wl_surface
|
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,
|
x,
|
||||||
y,
|
y,
|
||||||
width,
|
width,
|
||||||
|
|
|
||||||
13
src/main.rs
13
src/main.rs
|
|
@ -5,7 +5,11 @@ use wl_proxy::{
|
||||||
baseline::Baseline,
|
baseline::Baseline,
|
||||||
object::{ConcreteObject, Object, ObjectCoreApi, ObjectRcUtils},
|
object::{ConcreteObject, Object, ObjectCoreApi, ObjectRcUtils},
|
||||||
protocols::{
|
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,
|
xdg_shell::xdg_wm_base::XdgWmBase,
|
||||||
},
|
},
|
||||||
simple::{SimpleCommandExt, SimpleProxy},
|
simple::{SimpleCommandExt, SimpleProxy},
|
||||||
|
|
@ -14,6 +18,7 @@ use wl_proxy::{
|
||||||
use crate::globals::Globals;
|
use crate::globals::Globals;
|
||||||
|
|
||||||
mod buffer;
|
mod buffer;
|
||||||
|
mod client_buffer;
|
||||||
mod deco;
|
mod deco;
|
||||||
mod globals;
|
mod globals;
|
||||||
mod seat;
|
mod seat;
|
||||||
|
|
@ -40,6 +45,12 @@ impl WlRegistryHandler for ClientWlRegistry {
|
||||||
.set_handler(xdg::ClientXdgWmBase {
|
.set_handler(xdg::ClientXdgWmBase {
|
||||||
globals: self.globals.clone(),
|
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);
|
slf.send_bind(name, id);
|
||||||
|
|
|
||||||
57
src/xdg.rs
57
src/xdg.rs
|
|
@ -4,7 +4,8 @@ use wl_proxy::{
|
||||||
object::ObjectUtils,
|
object::ObjectUtils,
|
||||||
protocols::{
|
protocols::{
|
||||||
wayland::{
|
wayland::{
|
||||||
wl_output::WlOutput,
|
wl_buffer::WlBuffer,
|
||||||
|
wl_output::{WlOutput, WlOutputTransform},
|
||||||
wl_surface::{WlSurface, WlSurfaceHandler},
|
wl_surface::{WlSurface, WlSurfaceHandler},
|
||||||
},
|
},
|
||||||
xdg_shell::{
|
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 struct ClientWlSurface {
|
||||||
pub xdg_surface: Rc<XdgSurface>,
|
pub xdg_surface: Rc<XdgSurface>,
|
||||||
|
pub transform: Option<WlOutputTransform>,
|
||||||
|
pub scale: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlSurfaceHandler for ClientWlSurface {
|
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>) {
|
fn handle_commit(&mut self, slf: &Rc<WlSurface>) {
|
||||||
log::debug!("commit {slf:?}");
|
log::debug!("commit {slf:?}");
|
||||||
let surf_handler = self.xdg_surface.get_handler_ref::<ClientXdgSurface>();
|
let surf_handler = self.xdg_surface.get_handler_ref::<ClientXdgSurface>();
|
||||||
|
|
@ -47,6 +98,8 @@ impl XdgWmBaseHandler for ClientXdgWmBase {
|
||||||
) {
|
) {
|
||||||
surface.set_handler(ClientWlSurface {
|
surface.set_handler(ClientWlSurface {
|
||||||
xdg_surface: id.clone(),
|
xdg_surface: id.clone(),
|
||||||
|
scale: None,
|
||||||
|
transform: None,
|
||||||
});
|
});
|
||||||
id.set_handler(ClientXdgSurface {
|
id.set_handler(ClientXdgSurface {
|
||||||
deco: None,
|
deco: None,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue