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