Add resize/move via pointer
This commit is contained in:
parent
673af15cfd
commit
20e16ca508
5 changed files with 315 additions and 17 deletions
122
src/deco.rs
122
src/deco.rs
|
|
@ -1,8 +1,21 @@
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use wl_proxy::{
|
use wl_proxy::{
|
||||||
|
fixed::Fixed,
|
||||||
object::ObjectCoreApi,
|
object::ObjectCoreApi,
|
||||||
protocols::wayland::{wl_buffer::WlBuffer, wl_subsurface::WlSubsurface, wl_surface::WlSurface},
|
protocols::{
|
||||||
|
cursor_shape_v1::wp_cursor_shape_device_v1::{
|
||||||
|
WpCursorShapeDeviceV1, WpCursorShapeDeviceV1Shape,
|
||||||
|
},
|
||||||
|
wayland::{
|
||||||
|
wl_buffer::WlBuffer,
|
||||||
|
wl_pointer::WlPointerButtonState,
|
||||||
|
wl_seat::WlSeat,
|
||||||
|
wl_subsurface::WlSubsurface,
|
||||||
|
wl_surface::{WlSurface, WlSurfaceHandler},
|
||||||
|
},
|
||||||
|
xdg_shell::xdg_toplevel::{XdgToplevel, XdgToplevelResizeEdge},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{buffer::SimpleBufferPool, globals::Globals, util::Bounds};
|
use crate::{buffer::SimpleBufferPool, globals::Globals, util::Bounds};
|
||||||
|
|
@ -14,12 +27,104 @@ pub struct Deco {
|
||||||
|
|
||||||
wl_surface: Rc<WlSurface>,
|
wl_surface: Rc<WlSurface>,
|
||||||
subsurface: Rc<WlSubsurface>,
|
subsurface: Rc<WlSubsurface>,
|
||||||
|
toplevel: Rc<XdgToplevel>,
|
||||||
pool: RefCell<SimpleBufferPool>,
|
pool: RefCell<SimpleBufferPool>,
|
||||||
globals: Rc<Globals>,
|
globals: Rc<Globals>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deco {
|
impl Deco {
|
||||||
pub fn new(host_surface: &Rc<WlSurface>, globals: &Rc<Globals>) -> Deco {
|
fn resize_anchor(&self, x: i32, y: i32) -> XdgToplevelResizeEdge {
|
||||||
|
let n = y < self.border_size;
|
||||||
|
let e = x >= self.bounds.borrow().width + self.border_size;
|
||||||
|
let w = x < self.border_size;
|
||||||
|
let s = y >= self.bounds.borrow().height + self.border_size;
|
||||||
|
if n && e {
|
||||||
|
XdgToplevelResizeEdge::TOP_RIGHT
|
||||||
|
} else if n && w {
|
||||||
|
XdgToplevelResizeEdge::TOP_LEFT
|
||||||
|
} else if s && e {
|
||||||
|
XdgToplevelResizeEdge::BOTTOM_RIGHT
|
||||||
|
} else if s && w {
|
||||||
|
XdgToplevelResizeEdge::BOTTOM_LEFT
|
||||||
|
} else if n {
|
||||||
|
XdgToplevelResizeEdge::TOP
|
||||||
|
} else if e {
|
||||||
|
XdgToplevelResizeEdge::RIGHT
|
||||||
|
} else if w {
|
||||||
|
XdgToplevelResizeEdge::LEFT
|
||||||
|
} else if s {
|
||||||
|
XdgToplevelResizeEdge::BOTTOM
|
||||||
|
} else {
|
||||||
|
XdgToplevelResizeEdge::NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resize_cursor(anchor: XdgToplevelResizeEdge) -> WpCursorShapeDeviceV1Shape {
|
||||||
|
match anchor {
|
||||||
|
XdgToplevelResizeEdge::TOP_LEFT => WpCursorShapeDeviceV1Shape::NW_RESIZE,
|
||||||
|
XdgToplevelResizeEdge::TOP_RIGHT => WpCursorShapeDeviceV1Shape::NE_RESIZE,
|
||||||
|
XdgToplevelResizeEdge::BOTTOM_LEFT => WpCursorShapeDeviceV1Shape::SW_RESIZE,
|
||||||
|
XdgToplevelResizeEdge::BOTTOM_RIGHT => WpCursorShapeDeviceV1Shape::SE_RESIZE,
|
||||||
|
XdgToplevelResizeEdge::TOP => WpCursorShapeDeviceV1Shape::N_RESIZE,
|
||||||
|
XdgToplevelResizeEdge::LEFT => WpCursorShapeDeviceV1Shape::W_RESIZE,
|
||||||
|
XdgToplevelResizeEdge::RIGHT => WpCursorShapeDeviceV1Shape::E_RESIZE,
|
||||||
|
XdgToplevelResizeEdge::BOTTOM => WpCursorShapeDeviceV1Shape::S_RESIZE,
|
||||||
|
_ => WpCursorShapeDeviceV1Shape::DEFAULT,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DecoSurface(Rc<Deco>);
|
||||||
|
|
||||||
|
impl WlSurfaceHandler for DecoSurface {}
|
||||||
|
|
||||||
|
impl DecoSurface {
|
||||||
|
pub fn pointer_motion(
|
||||||
|
&self,
|
||||||
|
serial: u32,
|
||||||
|
surface_x: Fixed,
|
||||||
|
surface_y: Fixed,
|
||||||
|
cursor_shape: Option<&Rc<WpCursorShapeDeviceV1>>,
|
||||||
|
) {
|
||||||
|
let x = surface_x.to_i32_round_towards_nearest();
|
||||||
|
let y = surface_y.to_i32_round_towards_nearest();
|
||||||
|
cursor_shape
|
||||||
|
.unwrap()
|
||||||
|
.send_set_shape(serial, resize_cursor(self.0.resize_anchor(x, y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pointer_button(
|
||||||
|
&self,
|
||||||
|
seat: &Rc<WlSeat>,
|
||||||
|
serial: u32,
|
||||||
|
surface_x: Fixed,
|
||||||
|
surface_y: Fixed,
|
||||||
|
button: u32,
|
||||||
|
state: WlPointerButtonState,
|
||||||
|
) {
|
||||||
|
let x = surface_x.to_i32_round_towards_nearest();
|
||||||
|
let y = surface_y.to_i32_round_towards_nearest();
|
||||||
|
let anchor = self.0.resize_anchor(x, y);
|
||||||
|
const BTN_LEFT: u32 = 0x110;
|
||||||
|
if button != BTN_LEFT {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if state == WlPointerButtonState::PRESSED {
|
||||||
|
if anchor == XdgToplevelResizeEdge::NONE {
|
||||||
|
self.0.toplevel.send_move(seat, serial);
|
||||||
|
} else {
|
||||||
|
self.0.toplevel.send_resize(seat, serial, anchor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deco {
|
||||||
|
pub fn new(
|
||||||
|
host_surface: &Rc<WlSurface>,
|
||||||
|
toplevel: &Rc<XdgToplevel>,
|
||||||
|
globals: &Rc<Globals>,
|
||||||
|
) -> Rc<Deco> {
|
||||||
let wl_surface = globals.wl_compositor.new_send_create_surface();
|
let wl_surface = globals.wl_compositor.new_send_create_surface();
|
||||||
wl_surface.set_forward_to_client(false);
|
wl_surface.set_forward_to_client(false);
|
||||||
let subsurface = globals
|
let subsurface = globals
|
||||||
|
|
@ -28,7 +133,7 @@ impl Deco {
|
||||||
subsurface.set_forward_to_client(false);
|
subsurface.set_forward_to_client(false);
|
||||||
subsurface.send_place_below(&host_surface);
|
subsurface.send_place_below(&host_surface);
|
||||||
let pool = SimpleBufferPool::new(globals, 1, 1).unwrap();
|
let pool = SimpleBufferPool::new(globals, 1, 1).unwrap();
|
||||||
Deco {
|
let deco = Rc::new(Deco {
|
||||||
bounds: RefCell::new(Bounds {
|
bounds: RefCell::new(Bounds {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
|
|
@ -37,11 +142,14 @@ impl Deco {
|
||||||
}),
|
}),
|
||||||
top_size: 24,
|
top_size: 24,
|
||||||
border_size: 8,
|
border_size: 8,
|
||||||
wl_surface,
|
wl_surface: wl_surface.clone(),
|
||||||
subsurface,
|
subsurface,
|
||||||
|
toplevel: toplevel.clone(),
|
||||||
pool: RefCell::new(pool),
|
pool: RefCell::new(pool),
|
||||||
globals: globals.clone(),
|
globals: globals.clone(),
|
||||||
}
|
});
|
||||||
|
wl_surface.set_handler(DecoSurface(deco.clone()));
|
||||||
|
deco
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_window_geometry(
|
pub fn handle_window_geometry(
|
||||||
|
|
@ -88,6 +196,10 @@ impl Deco {
|
||||||
self.wl_surface.send_damage_buffer(0, 0, width, height);
|
self.wl_surface.send_damage_buffer(0, 0, width, height);
|
||||||
let input_region = self.globals.wl_compositor.new_send_create_region();
|
let input_region = self.globals.wl_compositor.new_send_create_region();
|
||||||
input_region.set_forward_to_client(false);
|
input_region.set_forward_to_client(false);
|
||||||
|
input_region.send_add(0, 0, width, self.top_size);
|
||||||
|
input_region.send_add(0, 0, self.border_size, height);
|
||||||
|
input_region.send_add(width - self.border_size, 0, self.border_size, height);
|
||||||
|
input_region.send_add(0, height - self.border_size, width, self.border_size);
|
||||||
self.wl_surface.send_set_input_region(Some(&input_region));
|
self.wl_surface.send_set_input_region(Some(&input_region));
|
||||||
self.subsurface
|
self.subsurface
|
||||||
.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);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{mem, rc::Rc};
|
use std::{collections::HashMap, mem, rc::Rc};
|
||||||
|
|
||||||
use wl_proxy::{
|
use wl_proxy::{
|
||||||
object::{ConcreteObject, Object, ObjectCoreApi, ObjectUtils},
|
object::{ConcreteObject, Object, ObjectCoreApi, ObjectUtils},
|
||||||
|
|
@ -15,12 +15,16 @@ pub use wl_proxy::protocols::{
|
||||||
wl_display::WlDisplay,
|
wl_display::WlDisplay,
|
||||||
wl_display::WlDisplayHandler,
|
wl_display::WlDisplayHandler,
|
||||||
wl_registry::{WlRegistry, WlRegistryHandler},
|
wl_registry::{WlRegistry, WlRegistryHandler},
|
||||||
|
wl_seat::WlSeat,
|
||||||
wl_shm::WlShm,
|
wl_shm::WlShm,
|
||||||
wl_subcompositor::WlSubcompositor,
|
wl_subcompositor::WlSubcompositor,
|
||||||
},
|
},
|
||||||
xdg_shell::xdg_wm_base::XdgWmBase,
|
xdg_shell::xdg_wm_base::XdgWmBase,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::seat::ProxyWlSeat;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct Globals {
|
pub struct Globals {
|
||||||
pub wl_display: Rc<WlDisplay>,
|
pub wl_display: Rc<WlDisplay>,
|
||||||
pub wl_compositor: Rc<WlCompositor>,
|
pub wl_compositor: Rc<WlCompositor>,
|
||||||
|
|
@ -69,9 +73,24 @@ impl WlRegistryHandler for ProxyWlRegistry {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
XdgWmBase::INTERFACE => bind!(xdg_wm_base, XdgWmBase, 7),
|
XdgWmBase::INTERFACE => bind!(xdg_wm_base, XdgWmBase, 7),
|
||||||
|
WlSeat::INTERFACE => display.handle_new_seat(slf, name, version),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_global_remove(&mut self, _slf: &Rc<WlRegistry>, name: u32) {
|
||||||
|
let display = &mut *self.wl_display.get_handler_mut::<ClientWlDisplay>();
|
||||||
|
if display.globals.is_none() {
|
||||||
|
display.initial_seats.remove(&name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(seat) = display.seats.remove(&name) {
|
||||||
|
// let proxy_wl_seat = &mut *seat.get_handler_mut::<ProxyWlSeat>();
|
||||||
|
// proxy_wl_seat.handle_capabilities(WlSeatCapability::empty());
|
||||||
|
seat.unset_handler();
|
||||||
|
seat.send_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler used for the initial, proxy-created wl_callback.
|
/// Handler used for the initial, proxy-created wl_callback.
|
||||||
|
|
@ -115,6 +134,9 @@ impl WlCallbackHandler for ProxyFirstSyncHandler {
|
||||||
wl_registry.set_handler(crate::ClientWlRegistry::new(&globals));
|
wl_registry.set_handler(crate::ClientWlRegistry::new(&globals));
|
||||||
}
|
}
|
||||||
display.globals = Some(globals);
|
display.globals = Some(globals);
|
||||||
|
for (name, version) in mem::take(&mut display.initial_seats) {
|
||||||
|
display.handle_new_seat(&self.wl_registry, name, version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,6 +150,11 @@ pub struct ClientWlDisplay {
|
||||||
|
|
||||||
/// The globals object created after our initial roundtrip.
|
/// The globals object created after our initial roundtrip.
|
||||||
globals: Option<Rc<Globals>>,
|
globals: Option<Rc<Globals>>,
|
||||||
|
/// The seats advertised by the server.
|
||||||
|
seats: HashMap<u32, Rc<WlSeat>>,
|
||||||
|
/// The seats advertised by the server that we haven't yet created a wl_seat object
|
||||||
|
/// for because the initial roundtrip has not yet completed.
|
||||||
|
initial_seats: HashMap<u32, u32>,
|
||||||
|
|
||||||
wl_compositor: Option<Rc<WlCompositor>>,
|
wl_compositor: Option<Rc<WlCompositor>>,
|
||||||
wl_shm: Option<Rc<WlShm>>,
|
wl_shm: Option<Rc<WlShm>>,
|
||||||
|
|
@ -139,6 +166,22 @@ pub struct ClientWlDisplay {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientWlDisplay {
|
impl ClientWlDisplay {
|
||||||
|
fn handle_new_seat(&mut self, registry: &Rc<WlRegistry>, name: u32, version: u32) {
|
||||||
|
let Some(globals) = &self.globals else {
|
||||||
|
self.initial_seats.insert(name, version);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let proxy = registry.state().create_object::<WlSeat>(version.min(10));
|
||||||
|
proxy.set_forward_to_client(false);
|
||||||
|
registry.send_bind(name, proxy.clone());
|
||||||
|
proxy.set_handler(ProxyWlSeat {
|
||||||
|
wl_seat: proxy.clone(),
|
||||||
|
globals: globals.clone(),
|
||||||
|
wl_pointer: None,
|
||||||
|
});
|
||||||
|
self.seats.insert(name, proxy);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ use crate::globals::Globals;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod deco;
|
mod deco;
|
||||||
mod globals;
|
mod globals;
|
||||||
|
mod seat;
|
||||||
mod util;
|
mod util;
|
||||||
mod xdg;
|
mod xdg;
|
||||||
|
|
||||||
|
|
|
||||||
137
src/seat.rs
Normal file
137
src/seat.rs
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use wl_proxy::{
|
||||||
|
fixed::Fixed,
|
||||||
|
object::{Object, ObjectCoreApi, ObjectUtils},
|
||||||
|
protocols::{
|
||||||
|
cursor_shape_v1::wp_cursor_shape_device_v1::WpCursorShapeDeviceV1,
|
||||||
|
wayland::{
|
||||||
|
wl_pointer::{WlPointer, WlPointerButtonState, WlPointerHandler},
|
||||||
|
wl_seat::{WlSeat, WlSeatCapability, WlSeatHandler},
|
||||||
|
wl_surface::WlSurface,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{deco::DecoSurface, globals::Globals};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ProxyWlSeat {
|
||||||
|
pub globals: Rc<Globals>,
|
||||||
|
pub wl_seat: Rc<WlSeat>,
|
||||||
|
pub wl_pointer: Option<Rc<WlPointer>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyWlSeat {
|
||||||
|
fn handle_capabilities(&mut self, capabilities: WlSeatCapability) {
|
||||||
|
if capabilities.contains(WlSeatCapability::POINTER) {
|
||||||
|
if self.wl_pointer.is_none() {
|
||||||
|
let wl_pointer = self.wl_seat.new_send_get_pointer();
|
||||||
|
wl_pointer.set_forward_to_client(false);
|
||||||
|
let wp_cursor_shape_device_v1 = self
|
||||||
|
.globals
|
||||||
|
.wp_cursor_shape_manager_v1
|
||||||
|
.as_ref()
|
||||||
|
.map(|m| m.new_send_get_pointer(&wl_pointer));
|
||||||
|
wl_pointer.set_handler(ProxyWlPointer {
|
||||||
|
serial: None,
|
||||||
|
seat: self.wl_seat.clone(),
|
||||||
|
wp_cursor_shape_device_v1,
|
||||||
|
surface: Default::default(),
|
||||||
|
last_xy: None,
|
||||||
|
});
|
||||||
|
self.wl_pointer = Some(wl_pointer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let Some(wl_pointer) = self.wl_pointer.take() {
|
||||||
|
let h = &mut *wl_pointer.get_handler_mut::<ProxyWlPointer>();
|
||||||
|
if let Some(dev) = &h.wp_cursor_shape_device_v1 {
|
||||||
|
dev.send_destroy();
|
||||||
|
}
|
||||||
|
wl_pointer.unset_handler();
|
||||||
|
wl_pointer.send_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WlSeatHandler for ProxyWlSeat {
|
||||||
|
fn handle_capabilities(&mut self, _slf: &Rc<WlSeat>, capabilities: WlSeatCapability) {
|
||||||
|
self.handle_capabilities(capabilities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ProxyWlPointer {
|
||||||
|
serial: Option<u32>,
|
||||||
|
seat: Rc<WlSeat>,
|
||||||
|
wp_cursor_shape_device_v1: Option<Rc<WpCursorShapeDeviceV1>>,
|
||||||
|
surface: Option<Rc<WlSurface>>,
|
||||||
|
last_xy: Option<(Fixed, Fixed)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WlPointerHandler for ProxyWlPointer {
|
||||||
|
fn handle_enter(
|
||||||
|
&mut self,
|
||||||
|
_slf: &Rc<WlPointer>,
|
||||||
|
serial: u32,
|
||||||
|
surface: &Rc<WlSurface>,
|
||||||
|
surface_x: Fixed,
|
||||||
|
surface_y: Fixed,
|
||||||
|
) {
|
||||||
|
self.surface = Some(surface.clone());
|
||||||
|
self.serial = Some(serial);
|
||||||
|
self.last_xy = Some((surface_x, surface_y));
|
||||||
|
if let Ok(deco) = surface.try_get_handler_mut::<DecoSurface>() {
|
||||||
|
deco.pointer_motion(
|
||||||
|
serial,
|
||||||
|
surface_x,
|
||||||
|
surface_y,
|
||||||
|
self.wp_cursor_shape_device_v1.as_ref(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_leave(&mut self, _slf: &Rc<WlPointer>, _serial: u32, _surface: &Rc<WlSurface>) {
|
||||||
|
self.surface = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_motion(
|
||||||
|
&mut self,
|
||||||
|
_slf: &Rc<WlPointer>,
|
||||||
|
_time: u32,
|
||||||
|
surface_x: Fixed,
|
||||||
|
surface_y: Fixed,
|
||||||
|
) {
|
||||||
|
let Some(ref surface) = self.surface else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
self.last_xy = Some((surface_x, surface_y));
|
||||||
|
if let Ok(deco) = surface.try_get_handler_mut::<DecoSurface>() {
|
||||||
|
deco.pointer_motion(
|
||||||
|
self.serial.unwrap(),
|
||||||
|
surface_x,
|
||||||
|
surface_y,
|
||||||
|
self.wp_cursor_shape_device_v1.as_ref(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_button(
|
||||||
|
&mut self,
|
||||||
|
_slf: &Rc<WlPointer>,
|
||||||
|
serial: u32,
|
||||||
|
_time: u32,
|
||||||
|
button: u32,
|
||||||
|
state: WlPointerButtonState,
|
||||||
|
) {
|
||||||
|
let Some(ref surface) = self.surface else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some((surface_x, surface_y)) = self.last_xy else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if let Ok(deco) = surface.try_get_handler_mut::<DecoSurface>() {
|
||||||
|
deco.pointer_button(&self.seat, serial, surface_x, surface_y, button, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/xdg.rs
27
src/xdg.rs
|
|
@ -25,19 +25,25 @@ impl XdgWmBaseHandler for ClientXdgWmBase {
|
||||||
surface: &Rc<WlSurface>,
|
surface: &Rc<WlSurface>,
|
||||||
) {
|
) {
|
||||||
id.set_handler(ClientXdgSurface {
|
id.set_handler(ClientXdgSurface {
|
||||||
deco: Rc::new(Deco::new(surface, &self.globals)),
|
deco: None,
|
||||||
|
globals: self.globals.clone(),
|
||||||
|
surface: surface.clone(),
|
||||||
});
|
});
|
||||||
slf.send_get_xdg_surface(id, surface);
|
slf.send_get_xdg_surface(id, surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClientXdgSurface {
|
struct ClientXdgSurface {
|
||||||
deco: Rc<Deco>,
|
globals: Rc<Globals>,
|
||||||
|
surface: Rc<WlSurface>,
|
||||||
|
deco: Option<Rc<Deco>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XdgSurfaceHandler for ClientXdgSurface {
|
impl XdgSurfaceHandler for ClientXdgSurface {
|
||||||
fn handle_get_toplevel(&mut self, slf: &Rc<XdgSurface>, id: &Rc<XdgToplevel>) {
|
fn handle_get_toplevel(&mut self, slf: &Rc<XdgSurface>, id: &Rc<XdgToplevel>) {
|
||||||
id.set_handler(ClientXdgToplevel::new(&self.deco));
|
let deco = Deco::new(&self.surface, id, &self.globals);
|
||||||
|
id.set_handler(ClientXdgToplevel::new(&deco));
|
||||||
|
self.deco = Some(deco);
|
||||||
slf.send_get_toplevel(id);
|
slf.send_get_toplevel(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,15 +64,14 @@ impl XdgSurfaceHandler for ClientXdgSurface {
|
||||||
fn handle_set_window_geometry(
|
fn handle_set_window_geometry(
|
||||||
&mut self,
|
&mut self,
|
||||||
slf: &Rc<XdgSurface>,
|
slf: &Rc<XdgSurface>,
|
||||||
x: i32,
|
mut x: i32,
|
||||||
y: i32,
|
mut y: i32,
|
||||||
width: i32,
|
mut width: i32,
|
||||||
height: i32,
|
mut height: i32,
|
||||||
) {
|
) {
|
||||||
let (x, y, width, height) = self
|
if let Some(deco) = self.deco.as_ref() {
|
||||||
.deco
|
(x, y, width, height) = deco.handle_window_geometry(x, y, width, height).unwrap();
|
||||||
.handle_window_geometry(x, y, width, height)
|
}
|
||||||
.unwrap();
|
|
||||||
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