Draw decorations on commit, skip drawing if params unchanged
This commit is contained in:
parent
35d4419c04
commit
186584398c
4 changed files with 63 additions and 21 deletions
56
src/deco.rs
56
src/deco.rs
|
|
@ -8,7 +8,6 @@ use wl_proxy::{
|
|||
WpCursorShapeDeviceV1, WpCursorShapeDeviceV1Shape,
|
||||
},
|
||||
wayland::{
|
||||
wl_buffer::WlBuffer,
|
||||
wl_pointer::WlPointerButtonState,
|
||||
wl_seat::WlSeat,
|
||||
wl_subsurface::WlSubsurface,
|
||||
|
|
@ -20,8 +19,14 @@ use wl_proxy::{
|
|||
|
||||
use crate::{buffer::SimpleBufferPool, globals::Globals, util::Bounds};
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq)]
|
||||
struct DecoParams {
|
||||
bounds: Bounds,
|
||||
}
|
||||
|
||||
pub struct Deco {
|
||||
bounds: RefCell<Bounds>,
|
||||
last_params: RefCell<DecoParams>,
|
||||
next_params: RefCell<DecoParams>,
|
||||
top_size: i32,
|
||||
border_size: i32,
|
||||
|
||||
|
|
@ -34,10 +39,11 @@ pub struct Deco {
|
|||
|
||||
impl Deco {
|
||||
fn resize_anchor(&self, x: i32, y: i32) -> XdgToplevelResizeEdge {
|
||||
let bounds = &self.last_params.borrow().bounds;
|
||||
let n = y < self.border_size;
|
||||
let e = x >= self.bounds.borrow().width + self.border_size;
|
||||
let e = x >= bounds.width + self.border_size;
|
||||
let w = x < self.border_size;
|
||||
let s = y >= self.bounds.borrow().height + self.border_size;
|
||||
let s = y >= bounds.height + self.border_size;
|
||||
if n && e {
|
||||
XdgToplevelResizeEdge::TOP_RIGHT
|
||||
} else if n && w {
|
||||
|
|
@ -126,6 +132,7 @@ impl Deco {
|
|||
globals: &Rc<Globals>,
|
||||
) -> Rc<Deco> {
|
||||
let wl_surface = globals.wl_compositor.new_send_create_surface();
|
||||
log::debug!("creating deco for surface {host_surface:?} -> {wl_surface:?}");
|
||||
wl_surface.set_forward_to_client(false);
|
||||
let subsurface = globals
|
||||
.wl_subcompositor
|
||||
|
|
@ -135,12 +142,8 @@ impl Deco {
|
|||
let pool = SimpleBufferPool::new(globals, 1, 1).unwrap();
|
||||
let args = crate::ARGS.get().unwrap();
|
||||
let deco = Rc::new(Deco {
|
||||
bounds: RefCell::new(Bounds {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 10,
|
||||
height: 10,
|
||||
}),
|
||||
last_params: RefCell::new(Default::default()),
|
||||
next_params: RefCell::new(Default::default()),
|
||||
top_size: args.thickness as i32, // TODO: title
|
||||
border_size: args.thickness as i32,
|
||||
wl_surface: wl_surface.clone(),
|
||||
|
|
@ -159,17 +162,24 @@ impl Deco {
|
|||
y: i32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) -> eyre::Result<(i32, i32, i32, i32)> {
|
||||
self.bounds.replace(Bounds {
|
||||
) -> (i32, i32, i32, i32) {
|
||||
log::debug!(
|
||||
"decoration {:?} handling geometry {width}x{height} @ {x},{y}",
|
||||
self.wl_surface
|
||||
);
|
||||
self.next_params.borrow_mut().bounds = Bounds {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
});
|
||||
self.draw()?;
|
||||
};
|
||||
let width = width + self.border_size * 2;
|
||||
let height = height + self.top_size + self.border_size;
|
||||
Ok((x - self.border_size, y - self.top_size, width, height))
|
||||
(x - self.border_size, y - self.top_size, width, height)
|
||||
}
|
||||
|
||||
pub fn handle_commit(&self) -> eyre::Result<()> {
|
||||
self.draw()
|
||||
}
|
||||
|
||||
pub fn transform_configure(&self, width: i32, height: i32) -> (i32, i32) {
|
||||
|
|
@ -190,8 +200,18 @@ impl Deco {
|
|||
(x + self.border_size, y + self.top_size)
|
||||
}
|
||||
|
||||
fn draw(&self) -> eyre::Result<Rc<WlBuffer>> {
|
||||
let bounds = self.bounds.borrow();
|
||||
fn draw(&self) -> eyre::Result<()> {
|
||||
let params = self.next_params.borrow();
|
||||
if *params == *self.last_params.borrow() {
|
||||
log::debug!("decoration {:?} unchanged", self.wl_surface);
|
||||
return Ok(());
|
||||
}
|
||||
log::debug!(
|
||||
"decoration {:?} changed to {params:?}, drawing",
|
||||
self.wl_surface
|
||||
);
|
||||
self.last_params.replace(params.clone());
|
||||
let bounds = ¶ms.bounds;
|
||||
let (width, height) = self.transform_size(bounds.width, bounds.height);
|
||||
|
||||
let mut pool = self.pool.borrow_mut();
|
||||
|
|
@ -224,6 +244,6 @@ impl Deco {
|
|||
.send_set_position(bounds.x - self.border_size, bounds.y - self.top_size);
|
||||
self.wl_surface.send_commit();
|
||||
// let _ = self.globals.wl_display.new_send_sync();
|
||||
Ok(buf)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ impl WlPointerHandler for ProxyWlPointer {
|
|||
let Some((surface_x, surface_y)) = self.last_xy else {
|
||||
return;
|
||||
};
|
||||
log::debug!("pointer button at {surface_x},{surface_y} on {surface:?}");
|
||||
if let Ok(deco) = surface.try_get_handler_mut::<DecoSurface>() {
|
||||
deco.pointer_button(&self.seat, serial, surface_x, surface_y, button, state);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[derive(Default, Debug, Clone)]
|
||||
#[derive(Default, Debug, Clone, PartialEq)]
|
||||
pub struct Bounds {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
|
|
|
|||
25
src/xdg.rs
25
src/xdg.rs
|
|
@ -3,7 +3,10 @@ use std::rc::Rc;
|
|||
use wl_proxy::{
|
||||
object::ObjectUtils,
|
||||
protocols::{
|
||||
wayland::{wl_output::WlOutput, wl_surface::WlSurface},
|
||||
wayland::{
|
||||
wl_output::WlOutput,
|
||||
wl_surface::{WlSurface, WlSurfaceHandler},
|
||||
},
|
||||
xdg_shell::{
|
||||
xdg_popup::XdgPopup,
|
||||
xdg_positioner::{XdgPositioner, XdgPositionerHandler},
|
||||
|
|
@ -16,6 +19,21 @@ use wl_proxy::{
|
|||
|
||||
use crate::{deco::Deco, globals::Globals, util::Bounds};
|
||||
|
||||
pub struct ClientWlSurface {
|
||||
pub xdg_surface: Rc<XdgSurface>,
|
||||
}
|
||||
|
||||
impl WlSurfaceHandler for ClientWlSurface {
|
||||
fn handle_commit(&mut self, slf: &Rc<WlSurface>) {
|
||||
log::debug!("commit {slf:?}");
|
||||
let surf_handler = self.xdg_surface.get_handler_ref::<ClientXdgSurface>();
|
||||
if let Some(deco) = surf_handler.deco.as_ref() {
|
||||
deco.handle_commit().unwrap();
|
||||
}
|
||||
slf.send_commit();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientXdgWmBase {
|
||||
pub globals: Rc<Globals>,
|
||||
}
|
||||
|
|
@ -27,6 +45,9 @@ impl XdgWmBaseHandler for ClientXdgWmBase {
|
|||
id: &Rc<XdgSurface>,
|
||||
surface: &Rc<WlSurface>,
|
||||
) {
|
||||
surface.set_handler(ClientWlSurface {
|
||||
xdg_surface: id.clone(),
|
||||
});
|
||||
id.set_handler(ClientXdgSurface {
|
||||
deco: None,
|
||||
globals: self.globals.clone(),
|
||||
|
|
@ -86,7 +107,7 @@ impl XdgSurfaceHandler for ClientXdgSurface {
|
|||
mut height: i32,
|
||||
) {
|
||||
if let Some(deco) = self.deco.as_ref() {
|
||||
(x, y, width, height) = deco.handle_window_geometry(x, y, width, height).unwrap();
|
||||
(x, y, width, height) = deco.handle_window_geometry(x, y, width, height);
|
||||
}
|
||||
slf.send_set_window_geometry(x, y, width, height);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue