autocommit 2022-02-01 23:33:59 CET
This commit is contained in:
parent
41c5f8cf89
commit
2dbe3ba732
21 changed files with 814 additions and 86 deletions
|
|
@ -1,8 +1,10 @@
|
|||
use crate::ifs::wl_seat::WlSeatGlobal;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::rect::Rect;
|
||||
use crate::render::Renderer;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use crate::cursor::Cursor;
|
||||
|
||||
pub struct CursorSurface {
|
||||
seat: Rc<WlSeatGlobal>,
|
||||
|
|
@ -38,15 +40,6 @@ impl CursorSurface {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn set_position(&self, x: i32, y: i32) {
|
||||
self.pos.set((x, y));
|
||||
self.update_extents();
|
||||
}
|
||||
|
||||
pub fn handle_unset(&self) {
|
||||
self.surface.cursors.remove(&self.seat.id());
|
||||
}
|
||||
|
||||
pub fn handle_surface_destroy(&self) {
|
||||
self.seat.set_cursor(None);
|
||||
}
|
||||
|
|
@ -71,12 +64,23 @@ impl CursorSurface {
|
|||
self.hotspot.set((hot_x - hotspot_dx, hot_y - hotspot_dy));
|
||||
self.update_extents();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn surface(&self) -> &Rc<WlSurface> {
|
||||
&self.surface
|
||||
impl Cursor for CursorSurface {
|
||||
fn set_position(&self, x: i32, y: i32) {
|
||||
self.pos.set((x, y));
|
||||
self.update_extents();
|
||||
}
|
||||
|
||||
pub fn extents(&self) -> Rect {
|
||||
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
renderer.render_surface(&self.surface, x, y);
|
||||
}
|
||||
|
||||
fn extents(&self) -> Rect {
|
||||
self.extents.get()
|
||||
}
|
||||
|
||||
fn handle_unset(&self) {
|
||||
self.surface.cursors.remove(&self.seat.id());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ impl WlSurface {
|
|||
}
|
||||
self.set_role(SurfaceRole::Cursor)?;
|
||||
let cursor = Rc::new(CursorSurface::new(seat, self));
|
||||
cursor.handle_buffer_change();
|
||||
self.cursors.insert(seat.id(), cursor.clone());
|
||||
Ok(cursor)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use crate::client::{ClientId, DynEventFormatter};
|
|||
use crate::fixed::Fixed;
|
||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||
use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceError, XdgSurfaceExt};
|
||||
use crate::ifs::xdg_positioner::{XdgPositioned, XdgPositioner};
|
||||
use crate::ifs::xdg_positioner::{XdgPositioned, XdgPositioner, CA};
|
||||
use crate::object::{Interface, Object, ObjectId};
|
||||
use crate::rect::Rect;
|
||||
use crate::render::Renderer;
|
||||
|
|
@ -15,6 +15,7 @@ use crate::utils::linkedlist::LinkedNode;
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
pub use types::*;
|
||||
use crate::cursor::KnownCursor;
|
||||
|
||||
const DESTROY: u32 = 0;
|
||||
const GRAB: u32 = 1;
|
||||
|
|
@ -85,13 +86,94 @@ impl XdgPopup {
|
|||
Box::new(PopupDone { obj: self.clone() })
|
||||
}
|
||||
|
||||
fn update_relative_position(&self, parent: &XdgSurface) -> Result<(), XdgPopupError> {
|
||||
let parent = parent.extents.get();
|
||||
let positioner = self.pos.borrow();
|
||||
if !parent.contains_rect(&positioner.ar) {
|
||||
// return Err(XdgPopupError::AnchorRectOutside);
|
||||
fn update_position(&self, parent: &XdgSurface) -> Result<(), XdgPopupError> {
|
||||
// let parent = parent.extents.get();
|
||||
let positioner = self.pos.borrow_mut();
|
||||
// if !parent.contains_rect(&positioner.ar) {
|
||||
// return Err(XdgPopupError::AnchorRectOutside);
|
||||
// }
|
||||
let parent_abs = parent.absolute_desired_extents.get();
|
||||
let mut rel_pos = positioner.get_position(false, false);
|
||||
let mut abs_pos = rel_pos.move_(parent_abs.x1(), parent_abs.y1());
|
||||
if let Some(ws) = parent.workspace.get() {
|
||||
let output_pos = ws.output.get().position.get();
|
||||
let mut overflow = output_pos.get_overflow(&abs_pos);
|
||||
if !overflow.is_contained() {
|
||||
let mut flip_x = positioner.ca.contains(CA::FLIP_X) && overflow.x_overflow();
|
||||
let mut flip_y = positioner.ca.contains(CA::FLIP_Y) && overflow.y_overflow();
|
||||
if flip_x || flip_y {
|
||||
let mut adj_rel = positioner.get_position(flip_x, flip_y);
|
||||
let mut adj_abs = adj_rel.move_(parent_abs.x1(), parent_abs.y1());
|
||||
let mut adj_overflow = output_pos.get_overflow(&adj_abs);
|
||||
let mut recalculate = false;
|
||||
if flip_x && adj_overflow.x_overflow() {
|
||||
flip_x = false;
|
||||
recalculate = true;
|
||||
}
|
||||
if flip_y && adj_overflow.y_overflow() {
|
||||
flip_y = false;
|
||||
recalculate = true;
|
||||
}
|
||||
if flip_x || flip_y {
|
||||
if recalculate {
|
||||
adj_rel = positioner.get_position(flip_x, flip_y);
|
||||
adj_abs = adj_rel.move_(parent_abs.x1(), parent_abs.y1());
|
||||
adj_overflow = output_pos.get_overflow(&adj_abs);
|
||||
}
|
||||
rel_pos = adj_rel;
|
||||
abs_pos = adj_abs;
|
||||
overflow = adj_overflow;
|
||||
}
|
||||
}
|
||||
let (mut dx, mut dy) = (0, 0);
|
||||
if positioner.ca.contains(CA::SLIDE_X) && overflow.x_overflow() {
|
||||
dx = if overflow.left > 0 || overflow.left + overflow.right > 0 {
|
||||
parent_abs.x1() - abs_pos.x1()
|
||||
} else {
|
||||
parent_abs.x2() - abs_pos.x2()
|
||||
};
|
||||
}
|
||||
if positioner.ca.contains(CA::SLIDE_Y) && overflow.y_overflow() {
|
||||
dy = if overflow.top > 0 || overflow.top + overflow.bottom > 0 {
|
||||
parent_abs.y1() - abs_pos.y1()
|
||||
} else {
|
||||
parent_abs.y2() - abs_pos.y2()
|
||||
};
|
||||
}
|
||||
if dx != 0 || dy != 0 {
|
||||
rel_pos = rel_pos.move_(dx, dy);
|
||||
abs_pos = rel_pos.move_(parent_abs.x1(), parent_abs.y1());
|
||||
overflow = output_pos.get_overflow(&abs_pos);
|
||||
}
|
||||
let (mut dx1, mut dx2, mut dy1, mut dy2) = (0, 0, 0, 0);
|
||||
if positioner.ca.contains(CA::RESIZE_X) {
|
||||
dx1 = overflow.left.max(0);
|
||||
dx2 = -overflow.right.max(0);
|
||||
}
|
||||
if positioner.ca.contains(CA::RESIZE_Y) {
|
||||
dy1 = overflow.top.max(0);
|
||||
dy2 = -overflow.bottom.max(0);
|
||||
}
|
||||
if dx1 > 0 || dx2 < 0 || dy1 > 0 || dy2 < 0 {
|
||||
abs_pos = Rect::new(
|
||||
abs_pos.x1() + dx1,
|
||||
abs_pos.y1() + dy1,
|
||||
abs_pos.x2() + dx2,
|
||||
abs_pos.y2() + dy2,
|
||||
)
|
||||
.unwrap();
|
||||
rel_pos = Rect::new_sized(
|
||||
abs_pos.x1() - parent_abs.x1(),
|
||||
abs_pos.y1() - parent_abs.y1(),
|
||||
abs_pos.width(),
|
||||
abs_pos.height(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
self.relative_position.set(positioner.get_position());
|
||||
self.relative_position.set(rel_pos);
|
||||
self.xdg.absolute_desired_extents.set(abs_pos);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +216,7 @@ impl XdgPopup {
|
|||
.get_xdg_positioner(req.positioner)?
|
||||
.value();
|
||||
if let Some(parent) = self.parent.get() {
|
||||
self.update_relative_position(&parent)?;
|
||||
self.update_position(&parent)?;
|
||||
let rel = self.relative_position.get();
|
||||
self.xdg.surface.client.event(self.repositioned(req.token));
|
||||
self.xdg.surface.client.event(self.configure(
|
||||
|
|
@ -144,24 +226,6 @@ impl XdgPopup {
|
|||
rel.height(),
|
||||
));
|
||||
self.xdg.send_configure();
|
||||
let parent = parent.absolute_desired_extents.get();
|
||||
self.xdg
|
||||
.absolute_desired_extents
|
||||
.set(rel.move_(parent.x1(), parent.y1()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_request_(
|
||||
self: &Rc<Self>,
|
||||
request: u32,
|
||||
parser: MsgParser<'_, '_>,
|
||||
) -> Result<(), XdgPopupError> {
|
||||
match request {
|
||||
DESTROY => self.destroy(parser)?,
|
||||
GRAB => self.grab(parser)?,
|
||||
REPOSITION => self.reposition(parser)?,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -171,7 +235,13 @@ impl XdgPopup {
|
|||
}
|
||||
}
|
||||
|
||||
handle_request!(XdgPopup);
|
||||
handle_request! {
|
||||
XdgPopup, XdgPopupError;
|
||||
|
||||
DESTROY => destroy,
|
||||
GRAB => grab,
|
||||
REPOSITION => reposition,
|
||||
}
|
||||
|
||||
impl Object for XdgPopup {
|
||||
fn id(&self) -> ObjectId {
|
||||
|
|
@ -183,7 +253,11 @@ impl Object for XdgPopup {
|
|||
}
|
||||
|
||||
fn num_requests(&self) -> u32 {
|
||||
REPOSITION + 1
|
||||
let last_req = match self.xdg.base.version {
|
||||
0..=2 => GRAB,
|
||||
_ => REPOSITION,
|
||||
};
|
||||
last_req + 1
|
||||
}
|
||||
|
||||
fn break_loops(&self) {
|
||||
|
|
@ -228,6 +302,10 @@ impl Node for XdgPopup {
|
|||
seat.enter_popup(&self);
|
||||
}
|
||||
|
||||
fn pointer_target(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
seat.set_known_cursor(KnownCursor::Default);
|
||||
}
|
||||
|
||||
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
renderer.render_xdg_surface(&self.xdg, x, y)
|
||||
}
|
||||
|
|
@ -244,7 +322,7 @@ impl Node for XdgPopup {
|
|||
impl XdgSurfaceExt for XdgPopup {
|
||||
fn initial_configure(self: Rc<Self>) -> Result<(), XdgSurfaceError> {
|
||||
if let Some(parent) = self.parent.get() {
|
||||
self.update_relative_position(&parent)?;
|
||||
self.update_position(&parent)?;
|
||||
let rel = self.relative_position.get();
|
||||
self.xdg.surface.client.event(self.configure(
|
||||
rel.x1(),
|
||||
|
|
@ -252,10 +330,6 @@ impl XdgSurfaceExt for XdgPopup {
|
|||
rel.width(),
|
||||
rel.height(),
|
||||
));
|
||||
let parent = parent.absolute_desired_extents.get();
|
||||
self.xdg
|
||||
.absolute_desired_extents
|
||||
.set(rel.move_(parent.x1(), parent.y1()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use std::cell::{Cell, RefCell};
|
|||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
pub use types::*;
|
||||
use crate::cursor::KnownCursor;
|
||||
|
||||
const DESTROY: u32 = 0;
|
||||
const SET_PARENT: u32 = 1;
|
||||
|
|
@ -395,6 +396,10 @@ impl Node for XdgToplevel {
|
|||
seat.enter_toplevel(&self);
|
||||
}
|
||||
|
||||
fn pointer_target(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
seat.set_known_cursor(KnownCursor::Default);
|
||||
}
|
||||
|
||||
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
renderer.render_xdg_surface(&self.xdg, x, y)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue