1
0
Fork 0
forked from wry/wry

autocommit 2022-02-01 23:33:59 CET

This commit is contained in:
Julian Orth 2022-02-01 23:33:59 +01:00
parent 41c5f8cf89
commit 2dbe3ba732
21 changed files with 814 additions and 86 deletions

View file

@ -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());
}
}

View file

@ -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)
}

View file

@ -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(())
}

View file

@ -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)
}