Add xdg positioner fixup
This commit is contained in:
parent
20e16ca508
commit
8dce5e323a
2 changed files with 114 additions and 15 deletions
14
src/deco.rs
14
src/deco.rs
|
|
@ -178,10 +178,20 @@ impl Deco {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn transform_size(&self, width: i32, height: i32) -> (i32, i32) {
|
||||
(
|
||||
width + self.border_size * 2,
|
||||
height + self.top_size + self.border_size,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn transform_anchor(&self, x: i32, y: i32) -> (i32, i32) {
|
||||
(x + self.border_size, y + self.top_size)
|
||||
}
|
||||
|
||||
fn draw(&self) -> eyre::Result<Rc<WlBuffer>> {
|
||||
let bounds = self.bounds.borrow();
|
||||
let width = bounds.width + 2 * self.border_size;
|
||||
let height = bounds.height + self.top_size + self.border_size;
|
||||
let (width, height) = self.transform_size(bounds.width, bounds.height);
|
||||
log::info!("{:?} -> {}x{}", bounds, width, height);
|
||||
|
||||
let mut pool = self.pool.borrow_mut();
|
||||
|
|
|
|||
115
src/xdg.rs
115
src/xdg.rs
|
|
@ -1,17 +1,20 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use wl_proxy::protocols::{
|
||||
wayland::{wl_output::WlOutput, wl_surface::WlSurface},
|
||||
xdg_shell::{
|
||||
xdg_popup::XdgPopup,
|
||||
xdg_positioner::XdgPositioner,
|
||||
xdg_surface::{XdgSurface, XdgSurfaceHandler},
|
||||
xdg_toplevel::{XdgToplevel, XdgToplevelHandler, XdgToplevelState},
|
||||
xdg_wm_base::{XdgWmBase, XdgWmBaseHandler},
|
||||
use wl_proxy::{
|
||||
object::ObjectUtils,
|
||||
protocols::{
|
||||
wayland::{wl_output::WlOutput, wl_surface::WlSurface},
|
||||
xdg_shell::{
|
||||
xdg_popup::XdgPopup,
|
||||
xdg_positioner::{XdgPositioner, XdgPositionerHandler},
|
||||
xdg_surface::{XdgSurface, XdgSurfaceHandler},
|
||||
xdg_toplevel::{XdgToplevel, XdgToplevelHandler, XdgToplevelState},
|
||||
xdg_wm_base::{XdgWmBase, XdgWmBaseHandler},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{deco::Deco, globals::Globals};
|
||||
use crate::{deco::Deco, globals::Globals, util::Bounds};
|
||||
|
||||
pub struct ClientXdgWmBase {
|
||||
pub globals: Rc<Globals>,
|
||||
|
|
@ -31,6 +34,11 @@ impl XdgWmBaseHandler for ClientXdgWmBase {
|
|||
});
|
||||
slf.send_get_xdg_surface(id, surface);
|
||||
}
|
||||
|
||||
fn handle_create_positioner(&mut self, slf: &Rc<XdgWmBase>, id: &Rc<XdgPositioner>) {
|
||||
id.set_handler(ClientXdgPositioner::new());
|
||||
slf.send_create_positioner(id);
|
||||
}
|
||||
}
|
||||
|
||||
struct ClientXdgSurface {
|
||||
|
|
@ -54,10 +62,18 @@ impl XdgSurfaceHandler for ClientXdgSurface {
|
|||
parent: Option<&Rc<XdgSurface>>,
|
||||
positioner: &Rc<XdgPositioner>,
|
||||
) {
|
||||
// if let Some(parent) = parent {
|
||||
// let handler = parent.get_handler_ref::<ClientXdgSurface>();
|
||||
// self.deco.subsurface.send_place_below(&handler.wl_surface);
|
||||
// } welp sad
|
||||
if let Some(parent) = parent {
|
||||
let parent_handler = parent.get_handler_ref::<ClientXdgSurface>();
|
||||
// self.deco.subsurface.send_place_below(&handler.wl_surface); .. welp
|
||||
if let Some(ref deco) = parent_handler.deco {
|
||||
let mut pos_handler = positioner.get_handler_mut::<ClientXdgPositioner>();
|
||||
pos_handler.parent_assigned(positioner, deco);
|
||||
} else {
|
||||
log::warn!("no parent toplevel decoration for popup");
|
||||
}
|
||||
} else {
|
||||
log::warn!("no parent for popup");
|
||||
}
|
||||
slf.send_get_popup(id, parent, positioner);
|
||||
}
|
||||
|
||||
|
|
@ -133,3 +149,76 @@ impl XdgToplevelHandler for ClientXdgToplevel {
|
|||
slf.send_configure_bounds(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
enum PositionerOp {
|
||||
SetAnchorRect(Bounds),
|
||||
SetParentSize(i32, i32),
|
||||
}
|
||||
|
||||
struct ClientXdgPositioner {
|
||||
parent_deco: Option<Rc<Deco>>,
|
||||
op_queue: Vec<PositionerOp>,
|
||||
}
|
||||
|
||||
impl ClientXdgPositioner {
|
||||
fn new() -> ClientXdgPositioner {
|
||||
ClientXdgPositioner {
|
||||
parent_deco: None,
|
||||
op_queue: Vec::with_capacity(4),
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_assigned(&mut self, slf: &Rc<XdgPositioner>, deco: &Rc<Deco>) {
|
||||
self.parent_deco = Some(deco.clone());
|
||||
while let Some(op) = self.op_queue.drain(..).next() {
|
||||
match op {
|
||||
PositionerOp::SetAnchorRect(bounds) => {
|
||||
let (x, y) = deco.transform_anchor(bounds.x, bounds.y);
|
||||
slf.send_set_anchor_rect(x, y, bounds.width, bounds.height);
|
||||
}
|
||||
PositionerOp::SetParentSize(mut width, mut height) => {
|
||||
(width, height) = deco.transform_size(width, height);
|
||||
slf.send_set_parent_size(width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl XdgPositionerHandler for ClientXdgPositioner {
|
||||
fn handle_set_anchor_rect(
|
||||
&mut self,
|
||||
slf: &Rc<XdgPositioner>,
|
||||
mut x: i32,
|
||||
mut y: i32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) {
|
||||
if let Some(ref deco) = self.parent_deco {
|
||||
(x, y) = deco.transform_anchor(x, y);
|
||||
slf.send_set_anchor_rect(x, y, width, height);
|
||||
} else {
|
||||
self.op_queue.push(PositionerOp::SetAnchorRect(Bounds {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_set_parent_size(
|
||||
&mut self,
|
||||
slf: &Rc<XdgPositioner>,
|
||||
mut parent_width: i32,
|
||||
mut parent_height: i32,
|
||||
) {
|
||||
if let Some(ref deco) = self.parent_deco {
|
||||
(parent_width, parent_height) = deco.transform_size(parent_width, parent_height);
|
||||
slf.send_set_parent_size(parent_width, parent_height);
|
||||
} else {
|
||||
self.op_queue
|
||||
.push(PositionerOp::SetParentSize(parent_width, parent_height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue