autocommit 2022-02-06 16:33:54 CET
This commit is contained in:
parent
c92346324b
commit
dc2cb71012
104 changed files with 2563 additions and 4617 deletions
|
|
@ -1,654 +0,0 @@
|
|||
pub mod cursor;
|
||||
mod types;
|
||||
pub mod wl_subsurface;
|
||||
pub mod xdg_surface;
|
||||
|
||||
use crate::backend::{KeyState, ScrollAxis, SeatId};
|
||||
use crate::client::{Client, DynEventFormatter, RequestParser};
|
||||
use crate::fixed::Fixed;
|
||||
use crate::ifs::wl_buffer::WlBuffer;
|
||||
use crate::ifs::wl_callback::WlCallback;
|
||||
use crate::ifs::wl_output::WlOutputId;
|
||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||
use crate::ifs::wl_surface::cursor::CursorSurface;
|
||||
use crate::ifs::wl_surface::wl_subsurface::WlSubsurface;
|
||||
use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceRole};
|
||||
use crate::object::Object;
|
||||
use crate::pixman::Region;
|
||||
use crate::rect::Rect;
|
||||
use crate::render::Renderer;
|
||||
use crate::tree::{Node, NodeId};
|
||||
use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||
use crate::utils::clonecell::CloneCell;
|
||||
use crate::utils::linkedlist::LinkedList;
|
||||
use crate::utils::smallmap::SmallMap;
|
||||
use crate::xkbcommon::ModifierState;
|
||||
use crate::NumCell;
|
||||
use ahash::AHashMap;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::rc::Rc;
|
||||
pub use types::*;
|
||||
|
||||
const DESTROY: u32 = 0;
|
||||
const ATTACH: u32 = 1;
|
||||
const DAMAGE: u32 = 2;
|
||||
const FRAME: u32 = 3;
|
||||
const SET_OPAQUE_REGION: u32 = 4;
|
||||
const SET_INPUT_REGION: u32 = 5;
|
||||
const COMMIT: u32 = 6;
|
||||
const SET_BUFFER_TRANSFORM: u32 = 7;
|
||||
const SET_BUFFER_SCALE: u32 = 8;
|
||||
const DAMAGE_BUFFER: u32 = 9;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const ENTER: u32 = 0;
|
||||
#[allow(dead_code)]
|
||||
const LEAVE: u32 = 1;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const INVALID_SCALE: u32 = 0;
|
||||
#[allow(dead_code)]
|
||||
const INVALID_TRANSFORM: u32 = 1;
|
||||
#[allow(dead_code)]
|
||||
const INVALID_SIZE: u32 = 2;
|
||||
|
||||
id!(WlSurfaceId);
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum SurfaceRole {
|
||||
None,
|
||||
Subsurface,
|
||||
XdgSurface,
|
||||
Cursor,
|
||||
}
|
||||
|
||||
impl SurfaceRole {
|
||||
fn name(self) -> &'static str {
|
||||
match self {
|
||||
SurfaceRole::None => "none",
|
||||
SurfaceRole::Subsurface => "subsurface",
|
||||
SurfaceRole::XdgSurface => "xdg_surface",
|
||||
SurfaceRole::Cursor => "cursor",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WlSurface {
|
||||
pub id: WlSurfaceId,
|
||||
pub node_id: SurfaceNodeId,
|
||||
pub client: Rc<Client>,
|
||||
role: Cell<SurfaceRole>,
|
||||
pending: PendingState,
|
||||
input_region: Cell<Option<Region>>,
|
||||
opaque_region: Cell<Option<Region>>,
|
||||
pub extents: Cell<Rect>,
|
||||
pub buffer_abs_pos: Cell<Rect>,
|
||||
pub need_extents_update: Cell<bool>,
|
||||
pub buffer: CloneCell<Option<Rc<WlBuffer>>>,
|
||||
pub buf_x: NumCell<i32>,
|
||||
pub buf_y: NumCell<i32>,
|
||||
pub children: RefCell<Option<Box<ParentData>>>,
|
||||
ext: CloneCell<Rc<dyn SurfaceExt>>,
|
||||
pub frame_requests: RefCell<Vec<Rc<WlCallback>>>,
|
||||
seat_state: NodeSeatState,
|
||||
xdg: CloneCell<Option<Rc<XdgSurface>>>,
|
||||
cursors: SmallMap<SeatId, Rc<CursorSurface>, 1>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
enum CommitContext {
|
||||
RootCommit,
|
||||
ChildCommit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
enum CommitAction {
|
||||
ContinueCommit,
|
||||
AbortCommit,
|
||||
}
|
||||
|
||||
trait SurfaceExt {
|
||||
fn pre_commit(self: Rc<Self>, ctx: CommitContext) -> Result<CommitAction, WlSurfaceError> {
|
||||
let _ = ctx;
|
||||
Ok(CommitAction::ContinueCommit)
|
||||
}
|
||||
|
||||
fn post_commit(&self) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
fn is_some(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn update_subsurface_parent_extents(&self) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
fn subsurface_parent(&self) -> Option<Rc<WlSurface>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn extents_changed(&self) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
fn into_subsurface(self: Rc<Self>) -> Option<Rc<WlSubsurface>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NoneSurfaceExt;
|
||||
|
||||
impl SurfaceExt for NoneSurfaceExt {
|
||||
fn is_some(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct PendingState {
|
||||
buffer: Cell<Option<Option<(i32, i32, Rc<WlBuffer>)>>>,
|
||||
opaque_region: Cell<Option<Option<Region>>>,
|
||||
input_region: Cell<Option<Option<Region>>>,
|
||||
frame_request: RefCell<Vec<Rc<WlCallback>>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ParentData {
|
||||
subsurfaces: AHashMap<WlSurfaceId, Rc<WlSubsurface>>,
|
||||
pub below: LinkedList<StackElement>,
|
||||
pub above: LinkedList<StackElement>,
|
||||
}
|
||||
|
||||
pub struct StackElement {
|
||||
pub pending: Cell<bool>,
|
||||
pub sub_surface: Rc<WlSubsurface>,
|
||||
}
|
||||
|
||||
impl WlSurface {
|
||||
pub fn new(id: WlSurfaceId, client: &Rc<Client>) -> Self {
|
||||
Self {
|
||||
id,
|
||||
node_id: client.state.node_ids.next(),
|
||||
client: client.clone(),
|
||||
role: Cell::new(SurfaceRole::None),
|
||||
pending: Default::default(),
|
||||
input_region: Cell::new(None),
|
||||
opaque_region: Cell::new(None),
|
||||
extents: Default::default(),
|
||||
buffer_abs_pos: Cell::new(Default::default()),
|
||||
need_extents_update: Cell::new(false),
|
||||
buffer: CloneCell::new(None),
|
||||
buf_x: Default::default(),
|
||||
buf_y: Default::default(),
|
||||
children: Default::default(),
|
||||
ext: CloneCell::new(client.state.none_surface_ext.clone()),
|
||||
frame_requests: RefCell::new(vec![]),
|
||||
seat_state: Default::default(),
|
||||
xdg: Default::default(),
|
||||
cursors: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_absolute_position(&self, x1: i32, y1: i32) {
|
||||
self.buffer_abs_pos
|
||||
.set(self.buffer_abs_pos.get().at_point(x1, y1));
|
||||
if let Some(children) = self.children.borrow_mut().deref_mut() {
|
||||
for ss in children.subsurfaces.values() {
|
||||
let pos = ss.position.get();
|
||||
ss.surface
|
||||
.set_absolute_position(x1 + pos.x1(), y1 + pos.y1());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_cursor(&self) -> bool {
|
||||
self.role.get() == SurfaceRole::Cursor
|
||||
}
|
||||
|
||||
pub fn get_cursor(
|
||||
self: &Rc<Self>,
|
||||
seat: &Rc<WlSeatGlobal>,
|
||||
) -> Result<Rc<CursorSurface>, WlSurfaceError> {
|
||||
if let Some(cursor) = self.cursors.get(&seat.id()) {
|
||||
return Ok(cursor);
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn belongs_to_toplevel(&self) -> bool {
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
return xdg.role() == XdgSurfaceRole::XdgToplevel;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn enter_event(self: &Rc<Self>, output: WlOutputId) -> DynEventFormatter {
|
||||
Box::new(Enter {
|
||||
obj: self.clone(),
|
||||
output,
|
||||
})
|
||||
}
|
||||
|
||||
fn set_xdg_surface(&self, xdg: Option<Rc<XdgSurface>>) {
|
||||
let ch = self.children.borrow();
|
||||
if let Some(ch) = &*ch {
|
||||
for ss in ch.subsurfaces.values() {
|
||||
ss.surface.set_xdg_surface(xdg.clone());
|
||||
}
|
||||
}
|
||||
if self.seat_state.is_active() {
|
||||
if let Some(xdg) = &xdg {
|
||||
xdg.surface_active_changed(true);
|
||||
}
|
||||
}
|
||||
self.xdg.set(xdg);
|
||||
}
|
||||
|
||||
fn set_role(&self, role: SurfaceRole) -> Result<(), WlSurfaceError> {
|
||||
use SurfaceRole::*;
|
||||
match (self.role.get(), role) {
|
||||
(None, _) => {}
|
||||
(old, new) if old == new => {}
|
||||
(old, new) => {
|
||||
return Err(WlSurfaceError::IncompatibleRole {
|
||||
id: self.id,
|
||||
old,
|
||||
new,
|
||||
})
|
||||
}
|
||||
}
|
||||
self.role.set(role);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unset_ext(&self) {
|
||||
self.ext.set(self.client.state.none_surface_ext.clone());
|
||||
}
|
||||
|
||||
fn calculate_extents(&self) {
|
||||
let old_extents = self.extents.get();
|
||||
let mut extents = Rect::new_empty(0, 0);
|
||||
if let Some(b) = self.buffer.get() {
|
||||
extents = b.rect;
|
||||
}
|
||||
let children = self.children.borrow();
|
||||
if let Some(children) = &*children {
|
||||
for ss in children.subsurfaces.values() {
|
||||
let ce = ss.surface.extents.get();
|
||||
if !ce.is_empty() {
|
||||
let cp = ss.position.get();
|
||||
let ce = ce.move_(cp.x1(), cp.y1());
|
||||
extents = if extents.is_empty() {
|
||||
ce
|
||||
} else {
|
||||
extents.union(ce)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
self.extents.set(extents);
|
||||
self.need_extents_update.set(false);
|
||||
if old_extents != extents {
|
||||
self.ext.get().extents_changed()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_root(self: &Rc<Self>) -> Rc<WlSurface> {
|
||||
let mut root = self.clone();
|
||||
loop {
|
||||
if let Some(parent) = root.ext.get().subsurface_parent() {
|
||||
root = parent;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
root
|
||||
}
|
||||
|
||||
fn parse<'a, T: RequestParser<'a>>(
|
||||
&self,
|
||||
parser: MsgParser<'_, 'a>,
|
||||
) -> Result<T, MsgParserError> {
|
||||
self.client.parse(self, parser)
|
||||
}
|
||||
|
||||
fn unset_cursors(&self) {
|
||||
while let Some((_, cursor)) = self.cursors.pop() {
|
||||
cursor.handle_surface_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||
let _req: Destroy = self.parse(parser)?;
|
||||
self.unset_cursors();
|
||||
self.destroy_node(true);
|
||||
if self.ext.get().is_some() {
|
||||
return Err(DestroyError::ReloObjectStillExists);
|
||||
}
|
||||
{
|
||||
let mut children = self.children.borrow_mut();
|
||||
if let Some(children) = &mut *children {
|
||||
for ss in children.subsurfaces.values() {
|
||||
ss.surface.unset_ext();
|
||||
}
|
||||
}
|
||||
*children = None;
|
||||
}
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn attach(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), AttachError> {
|
||||
let req: Attach = self.parse(parser)?;
|
||||
let buf = if req.buffer.is_some() {
|
||||
Some((req.x, req.y, self.client.lookup(req.buffer)?))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.pending.buffer.set(Some(buf));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn damage(&self, parser: MsgParser<'_, '_>) -> Result<(), DamageError> {
|
||||
let _req: Damage = self.parse(parser)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn frame(&self, parser: MsgParser<'_, '_>) -> Result<(), FrameError> {
|
||||
let req: Frame = self.parse(parser)?;
|
||||
let cb = Rc::new(WlCallback::new(req.callback));
|
||||
self.client.add_client_obj(&cb)?;
|
||||
self.pending.frame_request.borrow_mut().push(cb);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_opaque_region(&self, parser: MsgParser<'_, '_>) -> Result<(), SetOpaqueRegionError> {
|
||||
let region: SetOpaqueRegion = self.parse(parser)?;
|
||||
let region = if region.region.is_some() {
|
||||
Some(self.client.lookup(region.region)?.region())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.pending.opaque_region.set(Some(region));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_input_region(&self, parser: MsgParser<'_, '_>) -> Result<(), SetInputRegionError> {
|
||||
let req: SetInputRegion = self.parse(parser)?;
|
||||
let region = if req.region.is_some() {
|
||||
Some(self.client.lookup(req.region)?.region())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.pending.input_region.set(Some(region));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn do_commit(self: &Rc<Self>, ctx: CommitContext) -> Result<(), WlSurfaceError> {
|
||||
let ext = self.ext.get();
|
||||
if ext.clone().pre_commit(ctx)? == CommitAction::AbortCommit {
|
||||
return Ok(());
|
||||
}
|
||||
{
|
||||
let children = self.children.borrow();
|
||||
if let Some(children) = children.deref() {
|
||||
for child in children.subsurfaces.values() {
|
||||
child.surface.do_commit(CommitContext::ChildCommit)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(buffer_change) = self.pending.buffer.take() {
|
||||
let mut old_size = None;
|
||||
let mut new_size = None;
|
||||
if let Some(buffer) = self.buffer.take() {
|
||||
old_size = Some(buffer.rect);
|
||||
if !buffer.destroyed() {
|
||||
self.client.event(buffer.release());
|
||||
}
|
||||
}
|
||||
if let Some((dx, dy, buffer)) = buffer_change {
|
||||
let _ = buffer.update_texture();
|
||||
new_size = Some(buffer.rect);
|
||||
self.buffer_abs_pos.set(
|
||||
self.buffer_abs_pos
|
||||
.get()
|
||||
.with_size(buffer.rect.width(), buffer.rect.height())
|
||||
.unwrap(),
|
||||
);
|
||||
self.buffer.set(Some(buffer));
|
||||
self.buf_x.fetch_add(dx);
|
||||
self.buf_y.fetch_add(dy);
|
||||
if (dx, dy) != (0, 0) {
|
||||
self.need_extents_update.set(true);
|
||||
for (_, cursor) in &self.cursors {
|
||||
cursor.dec_hotspot(dx, dy);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.buf_x.set(0);
|
||||
self.buf_y.set(0);
|
||||
for (_, cursor) in &self.cursors {
|
||||
cursor.set_hotspot(0, 0);
|
||||
}
|
||||
}
|
||||
if old_size != new_size {
|
||||
self.need_extents_update.set(true);
|
||||
}
|
||||
for (_, cursor) in &self.cursors {
|
||||
cursor.handle_buffer_change();
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut pfr = self.pending.frame_request.borrow_mut();
|
||||
self.frame_requests.borrow_mut().extend(pfr.drain(..));
|
||||
}
|
||||
{
|
||||
if let Some(region) = self.pending.input_region.take() {
|
||||
self.input_region.set(region);
|
||||
}
|
||||
if let Some(region) = self.pending.opaque_region.take() {
|
||||
self.opaque_region.set(region);
|
||||
}
|
||||
}
|
||||
if self.need_extents_update.get() {
|
||||
self.calculate_extents();
|
||||
}
|
||||
ext.post_commit();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn commit(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), CommitError> {
|
||||
let _req: Commit = self.parse(parser)?;
|
||||
self.do_commit(CommitContext::RootCommit)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_buffer_transform(
|
||||
&self,
|
||||
parser: MsgParser<'_, '_>,
|
||||
) -> Result<(), SetBufferTransformError> {
|
||||
let _req: SetBufferTransform = self.parse(parser)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_buffer_scale(&self, parser: MsgParser<'_, '_>) -> Result<(), SetBufferScaleError> {
|
||||
let _req: SetBufferScale = self.parse(parser)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn damage_buffer(&self, parser: MsgParser<'_, '_>) -> Result<(), DamageBufferError> {
|
||||
let _req: DamageBuffer = self.parse(parser)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn find_surface_at(self: &Rc<Self>, x: i32, y: i32) -> Option<(Rc<Self>, i32, i32)> {
|
||||
let buffer = match self.buffer.get() {
|
||||
Some(b) => b,
|
||||
_ => return None,
|
||||
};
|
||||
let children = self.children.borrow();
|
||||
let children = match children.deref() {
|
||||
Some(c) => c,
|
||||
_ => {
|
||||
return if buffer.rect.contains(x, y) {
|
||||
Some((self.clone(), x, y))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
};
|
||||
let ss = |c: &LinkedList<StackElement>| {
|
||||
for child in c.rev_iter() {
|
||||
if child.pending.get() {
|
||||
continue;
|
||||
}
|
||||
let pos = child.sub_surface.position.get();
|
||||
if pos.contains(x, y) {
|
||||
let (x, y) = pos.translate(x, y);
|
||||
if let Some(res) = child.sub_surface.surface.find_surface_at(x, y) {
|
||||
return Some(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
};
|
||||
if let Some(res) = ss(&children.above) {
|
||||
return Some(res);
|
||||
}
|
||||
if buffer.rect.contains(x, y) {
|
||||
return Some((self.clone(), x, y));
|
||||
}
|
||||
if let Some(res) = ss(&children.below) {
|
||||
return Some(res);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
WlSurface, WlSurfaceError;
|
||||
|
||||
DESTROY => destroy,
|
||||
ATTACH => attach,
|
||||
DAMAGE => damage,
|
||||
FRAME => frame,
|
||||
SET_OPAQUE_REGION => set_opaque_region,
|
||||
SET_INPUT_REGION => set_input_region,
|
||||
COMMIT => commit,
|
||||
SET_BUFFER_TRANSFORM => set_buffer_transform,
|
||||
SET_BUFFER_SCALE => set_buffer_scale,
|
||||
DAMAGE_BUFFER => damage_buffer,
|
||||
}
|
||||
|
||||
impl Object for WlSurface {
|
||||
fn num_requests(&self) -> u32 {
|
||||
DAMAGE_BUFFER + 1
|
||||
}
|
||||
|
||||
fn break_loops(&self) {
|
||||
self.unset_cursors();
|
||||
self.destroy_node(true);
|
||||
*self.children.borrow_mut() = None;
|
||||
self.unset_ext();
|
||||
mem::take(self.frame_requests.borrow_mut().deref_mut());
|
||||
self.buffer.set(None);
|
||||
self.xdg.set(None);
|
||||
}
|
||||
}
|
||||
|
||||
dedicated_add_obj!(WlSurface, WlSurfaceId, surfaces);
|
||||
|
||||
tree_id!(SurfaceNodeId);
|
||||
impl Node for WlSurface {
|
||||
fn id(&self) -> NodeId {
|
||||
self.node_id.into()
|
||||
}
|
||||
|
||||
fn seat_state(&self) -> &NodeSeatState {
|
||||
&self.seat_state
|
||||
}
|
||||
|
||||
fn destroy_node(&self, _detach: bool) {
|
||||
let children = self.children.borrow();
|
||||
if let Some(ch) = children.deref() {
|
||||
for ss in ch.subsurfaces.values() {
|
||||
ss.surface.destroy_node(false);
|
||||
}
|
||||
}
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
let mut remove = vec![];
|
||||
for (seat, s) in &xdg.focus_surface {
|
||||
if s.id == self.id {
|
||||
remove.push(seat);
|
||||
}
|
||||
}
|
||||
for seat in remove {
|
||||
xdg.focus_surface.remove(&seat);
|
||||
}
|
||||
if self.seat_state.is_active() {
|
||||
xdg.surface_active_changed(false);
|
||||
}
|
||||
}
|
||||
self.seat_state.destroy_node(self);
|
||||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
self.buffer_abs_pos.get()
|
||||
}
|
||||
|
||||
fn active_changed(&self, active: bool) {
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
xdg.surface_active_changed(active);
|
||||
}
|
||||
}
|
||||
|
||||
fn key(&self, seat: &WlSeatGlobal, key: u32, state: u32, mods: Option<ModifierState>) {
|
||||
seat.key_surface(self, key, state, mods);
|
||||
}
|
||||
|
||||
fn button(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
|
||||
seat.button_surface(&self, button, state);
|
||||
}
|
||||
|
||||
fn scroll(&self, seat: &WlSeatGlobal, delta: i32, axis: ScrollAxis) {
|
||||
seat.scroll_surface(self, delta, axis);
|
||||
}
|
||||
|
||||
fn focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
xdg.focus_surface.insert(seat.id(), self);
|
||||
}
|
||||
}
|
||||
|
||||
fn unfocus(&self, seat: &WlSeatGlobal) {
|
||||
seat.unfocus_surface(self);
|
||||
}
|
||||
|
||||
fn leave(&self, seat: &WlSeatGlobal) {
|
||||
seat.leave_surface(self);
|
||||
}
|
||||
|
||||
fn enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
seat.enter_surface(&self, x, y)
|
||||
}
|
||||
|
||||
fn motion(&self, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
seat.motion_surface(self, x, y)
|
||||
}
|
||||
|
||||
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||
renderer.render_surface(self, x, y);
|
||||
}
|
||||
|
||||
fn client(&self) -> Option<Rc<Client>> {
|
||||
Some(self.client.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,353 +0,0 @@
|
|||
use crate::client::{ClientError, EventFormatter, RequestParser};
|
||||
use crate::ifs::wl_callback::WlCallbackId;
|
||||
use crate::ifs::wl_output::WlOutputId;
|
||||
use crate::ifs::wl_region::WlRegionId;
|
||||
use crate::ifs::wl_surface::xdg_surface::XdgSurfaceError;
|
||||
use crate::ifs::wl_surface::{SurfaceRole, WlSurface, WlSurfaceId, ENTER};
|
||||
use crate::object::Object;
|
||||
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum WlSurfaceError {
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error(transparent)]
|
||||
XdgSurfaceError(Box<XdgSurfaceError>),
|
||||
#[error("Could not process `destroy` request")]
|
||||
DestroyError(#[source] Box<DestroyError>),
|
||||
#[error("Could not process `attach` request")]
|
||||
AttachError(#[source] Box<AttachError>),
|
||||
#[error("Could not process `damage` request")]
|
||||
DamageError(#[source] Box<DamageError>),
|
||||
#[error("Could not process `frame` request")]
|
||||
FrameError(#[source] Box<FrameError>),
|
||||
#[error("Could not process `set_opaque_region` request")]
|
||||
SetOpaqueRegionError(#[source] Box<SetOpaqueRegionError>),
|
||||
#[error("Could not process `set_input_region` request")]
|
||||
SetInputRegionError(#[source] Box<SetInputRegionError>),
|
||||
#[error("Could not process `commit` request")]
|
||||
CommitError(#[source] Box<CommitError>),
|
||||
#[error("Could not process `set_buffer_transform` request")]
|
||||
SetBufferTransformError(#[source] Box<SetBufferTransformError>),
|
||||
#[error("Could not process `set_buffer_scale_error` request")]
|
||||
SetBufferScaleError(#[source] Box<SetBufferScaleError>),
|
||||
#[error("Could not process `damage_buffer` request")]
|
||||
DamageBufferError(#[source] Box<DamageBufferError>),
|
||||
#[error("Surface {} cannot be assigned the role {} because it already has the role {}", .id, .new.name(), .old.name())]
|
||||
IncompatibleRole {
|
||||
id: WlSurfaceId,
|
||||
old: SurfaceRole,
|
||||
new: SurfaceRole,
|
||||
},
|
||||
}
|
||||
efrom!(WlSurfaceError, ClientError);
|
||||
efrom!(WlSurfaceError, XdgSurfaceError);
|
||||
efrom!(WlSurfaceError, DestroyError);
|
||||
efrom!(WlSurfaceError, AttachError);
|
||||
efrom!(WlSurfaceError, DamageError);
|
||||
efrom!(WlSurfaceError, FrameError);
|
||||
efrom!(WlSurfaceError, SetOpaqueRegionError);
|
||||
efrom!(WlSurfaceError, SetInputRegionError);
|
||||
efrom!(WlSurfaceError, CommitError);
|
||||
efrom!(
|
||||
WlSurfaceError,
|
||||
SetBufferTransformError,
|
||||
SetBufferTransformError
|
||||
);
|
||||
efrom!(WlSurfaceError, SetBufferScaleError);
|
||||
efrom!(WlSurfaceError, DamageBufferError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DestroyError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("Cannot destroy a `wl_surface` before its role object")]
|
||||
ReloObjectStillExists,
|
||||
}
|
||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||
efrom!(DestroyError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AttachError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(AttachError, ParseFailed, MsgParserError);
|
||||
efrom!(AttachError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DamageError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(DamageError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FrameError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(FrameError, ParseFailed, MsgParserError);
|
||||
efrom!(FrameError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetOpaqueRegionError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetOpaqueRegionError, ParseFailed, MsgParserError);
|
||||
efrom!(SetOpaqueRegionError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetInputRegionError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetInputRegionError, ParseFailed, MsgParserError);
|
||||
efrom!(SetInputRegionError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CommitError {
|
||||
#[error(transparent)]
|
||||
WlSurfaceError(Box<WlSurfaceError>),
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(CommitError, WlSurfaceError);
|
||||
efrom!(CommitError, ParseFailed, MsgParserError);
|
||||
efrom!(CommitError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetBufferTransformError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(SetBufferTransformError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetBufferScaleError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(SetBufferScaleError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DamageBufferError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(DamageBufferError, ParseFailed, MsgParserError);
|
||||
|
||||
pub(super) struct Destroy;
|
||||
impl RequestParser<'_> for Destroy {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for Destroy {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "destroy()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Attach {
|
||||
pub buffer: crate::ifs::wl_buffer::WlBufferId,
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
}
|
||||
impl RequestParser<'_> for Attach {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
buffer: parser.object()?,
|
||||
x: parser.int()?,
|
||||
y: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for Attach {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"attach(buffer: {}, x: {}, y: {})",
|
||||
self.buffer, self.x, self.y
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Damage {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
impl RequestParser<'_> for Damage {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
x: parser.int()?,
|
||||
y: parser.int()?,
|
||||
width: parser.int()?,
|
||||
height: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for Damage {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"damage(x: {}, y: {}, width: {}, height: {})",
|
||||
self.x, self.y, self.width, self.height
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Frame {
|
||||
pub callback: WlCallbackId,
|
||||
}
|
||||
impl RequestParser<'_> for Frame {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
callback: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for Frame {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "frame(callback: {})", self.callback)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetOpaqueRegion {
|
||||
pub region: WlRegionId,
|
||||
}
|
||||
impl RequestParser<'_> for SetOpaqueRegion {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
region: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetOpaqueRegion {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_opaque_region(region: {})", self.region)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetInputRegion {
|
||||
pub region: WlRegionId,
|
||||
}
|
||||
impl RequestParser<'_> for SetInputRegion {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
region: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetInputRegion {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_input_region(region: {})", self.region)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Commit;
|
||||
impl RequestParser<'_> for Commit {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for Commit {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "commit()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetBufferTransform {
|
||||
pub transform: i32,
|
||||
}
|
||||
impl RequestParser<'_> for SetBufferTransform {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
transform: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetBufferTransform {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_buffer_transform(transform: {})", self.transform)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetBufferScale {
|
||||
pub scale: i32,
|
||||
}
|
||||
impl RequestParser<'_> for SetBufferScale {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
scale: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetBufferScale {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_buffer_scale(scale: {})", self.scale)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct DamageBuffer {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
impl RequestParser<'_> for DamageBuffer {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
x: parser.int()?,
|
||||
y: parser.int()?,
|
||||
width: parser.int()?,
|
||||
height: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for DamageBuffer {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"damage_buffer(x: {}, y: {}, width: {}, height: {})",
|
||||
self.x, self.y, self.width, self.height
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Enter {
|
||||
pub obj: Rc<WlSurface>,
|
||||
pub output: WlOutputId,
|
||||
}
|
||||
impl EventFormatter for Enter {
|
||||
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
||||
fmt.header(self.obj.id, ENTER).object(self.output);
|
||||
}
|
||||
fn obj(&self) -> &dyn Object {
|
||||
self.obj.deref()
|
||||
}
|
||||
}
|
||||
impl Debug for Enter {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "enter(output: {})", self.output)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
mod types;
|
||||
|
||||
use crate::ifs::wl_surface::{
|
||||
CommitAction, CommitContext, StackElement, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError,
|
||||
|
|
@ -12,22 +11,17 @@ use crate::NumCell;
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
pub use types::*;
|
||||
|
||||
const DESTROY: u32 = 0;
|
||||
const SET_POSITION: u32 = 1;
|
||||
const PLACE_ABOVE: u32 = 2;
|
||||
const PLACE_BELOW: u32 = 3;
|
||||
const SET_SYNC: u32 = 4;
|
||||
const SET_DESYNC: u32 = 5;
|
||||
use thiserror::Error;
|
||||
use crate::client::ClientError;
|
||||
use crate::wire::wl_subsurface::*;
|
||||
use crate::utils::buffd::MsgParserError;
|
||||
use crate::wire::WlSubsurfaceId;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const BAD_SURFACE: u32 = 0;
|
||||
|
||||
const MAX_SUBSURFACE_DEPTH: u32 = 100;
|
||||
|
||||
id!(WlSubsurfaceId);
|
||||
|
||||
pub struct WlSubsurface {
|
||||
id: WlSubsurfaceId,
|
||||
pub surface: Rc<WlSurface>,
|
||||
|
|
@ -295,3 +289,87 @@ impl SurfaceExt for WlSubsurface {
|
|||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum WlSubsurfaceError {
|
||||
#[error("Could not process `destroy` request")]
|
||||
DestroyError(#[from] DestroyError),
|
||||
#[error("Could not process `set_position` request")]
|
||||
SetPosition(#[from] SetPositionError),
|
||||
#[error("Could not process `place_above` request")]
|
||||
PlaceAbove(#[from] PlaceAboveError),
|
||||
#[error("Could not process `place_below` request")]
|
||||
PlaceBelow(#[from] PlaceBelowError),
|
||||
#[error("Could not process `set_sync` request")]
|
||||
SetSync(#[from] SetSyncError),
|
||||
#[error("Could not process `set_desync` request")]
|
||||
SetDesync(#[from] SetDesyncError),
|
||||
#[error("Surface {0} already has an attached `wl_subsurface`")]
|
||||
AlreadyAttached(WlSurfaceId),
|
||||
#[error("Surface {0} cannot be made its own parent")]
|
||||
OwnParent(WlSurfaceId),
|
||||
#[error("Surface {0} cannot be made a subsurface of {1} because it's an ancestor of {1}")]
|
||||
Ancestor(WlSurfaceId, WlSurfaceId),
|
||||
#[error("Subsurfaces cannot be nested deeper than 100 levels")]
|
||||
MaxDepthExceeded,
|
||||
#[error(transparent)]
|
||||
WlSurfaceError(Box<WlSurfaceError>),
|
||||
}
|
||||
efrom!(WlSubsurfaceError, WlSurfaceError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DestroyError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||
efrom!(DestroyError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetPositionError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(SetPositionError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlaceAboveError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
PlacementError(#[from] PlacementError),
|
||||
}
|
||||
efrom!(PlaceAboveError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlacementError {
|
||||
#[error("Cannot place {0} above/below itself")]
|
||||
AboveSelf(WlSurfaceId),
|
||||
#[error("{0} is not a sibling of {1}")]
|
||||
NotASibling(WlSurfaceId, WlSurfaceId),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlaceBelowError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
PlacementError(#[from] PlacementError),
|
||||
}
|
||||
efrom!(PlaceBelowError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetSyncError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(SetSyncError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetDesyncError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(SetDesyncError, ParseFailed, MsgParserError);
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
use crate::client::{ClientError, RequestParser};
|
||||
use crate::ifs::wl_surface::{WlSurfaceError, WlSurfaceId};
|
||||
use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum WlSubsurfaceError {
|
||||
#[error("Could not process `destroy` request")]
|
||||
DestroyError(#[from] DestroyError),
|
||||
#[error("Could not process `set_position` request")]
|
||||
SetPosition(#[from] SetPositionError),
|
||||
#[error("Could not process `place_above` request")]
|
||||
PlaceAbove(#[from] PlaceAboveError),
|
||||
#[error("Could not process `place_below` request")]
|
||||
PlaceBelow(#[from] PlaceBelowError),
|
||||
#[error("Could not process `set_sync` request")]
|
||||
SetSync(#[from] SetSyncError),
|
||||
#[error("Could not process `set_desync` request")]
|
||||
SetDesync(#[from] SetDesyncError),
|
||||
#[error("Surface {0} already has an attached `wl_subsurface`")]
|
||||
AlreadyAttached(WlSurfaceId),
|
||||
#[error("Surface {0} cannot be made its own parent")]
|
||||
OwnParent(WlSurfaceId),
|
||||
#[error("Surface {0} cannot be made a subsurface of {1} because it's an ancestor of {1}")]
|
||||
Ancestor(WlSurfaceId, WlSurfaceId),
|
||||
#[error("Subsurfaces cannot be nested deeper than 100 levels")]
|
||||
MaxDepthExceeded,
|
||||
#[error(transparent)]
|
||||
WlSurfaceError(Box<WlSurfaceError>),
|
||||
}
|
||||
efrom!(WlSubsurfaceError, WlSurfaceError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DestroyError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||
efrom!(DestroyError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetPositionError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(SetPositionError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlaceAboveError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
PlacementError(#[from] PlacementError),
|
||||
}
|
||||
efrom!(PlaceAboveError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlacementError {
|
||||
#[error("Cannot place {0} above/below itself")]
|
||||
AboveSelf(WlSurfaceId),
|
||||
#[error("{0} is not a sibling of {1}")]
|
||||
NotASibling(WlSurfaceId, WlSurfaceId),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlaceBelowError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
PlacementError(#[from] PlacementError),
|
||||
}
|
||||
efrom!(PlaceBelowError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetSyncError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(SetSyncError, ParseFailed, MsgParserError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetDesyncError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
}
|
||||
efrom!(SetDesyncError, ParseFailed, MsgParserError);
|
||||
|
||||
pub(super) struct Destroy;
|
||||
impl RequestParser<'_> for Destroy {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for Destroy {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "destroy()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetPosition {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
}
|
||||
impl RequestParser<'_> for SetPosition {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
x: parser.int()?,
|
||||
y: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetPosition {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_position(x: {}, y: {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct PlaceAbove {
|
||||
pub sibling: WlSurfaceId,
|
||||
}
|
||||
impl RequestParser<'_> for PlaceAbove {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
sibling: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for PlaceAbove {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "place_above(sibling: {})", self.sibling,)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct PlaceBelow {
|
||||
pub sibling: WlSurfaceId,
|
||||
}
|
||||
impl RequestParser<'_> for PlaceBelow {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
sibling: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for PlaceBelow {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "place_below(sibling: {})", self.sibling,)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetSync;
|
||||
impl RequestParser<'_> for SetSync {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for SetSync {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_sync()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetDesync;
|
||||
impl RequestParser<'_> for SetDesync {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for SetDesync {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_desync()")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,388 +0,0 @@
|
|||
mod types;
|
||||
pub mod xdg_popup;
|
||||
pub mod xdg_toplevel;
|
||||
|
||||
use crate::backend::SeatId;
|
||||
use crate::client::DynEventFormatter;
|
||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_popup::{XdgPopup, XdgPopupId};
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel;
|
||||
use crate::ifs::wl_surface::{
|
||||
CommitAction, CommitContext, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError,
|
||||
};
|
||||
use crate::ifs::xdg_wm_base::XdgWmBase;
|
||||
use crate::object::Object;
|
||||
use crate::rect::Rect;
|
||||
use crate::tree::{FindTreeResult, FoundNode, Node, WorkspaceNode};
|
||||
use crate::utils::buffd::MsgParser;
|
||||
use crate::utils::clonecell::CloneCell;
|
||||
use crate::utils::copyhashmap::CopyHashMap;
|
||||
use crate::utils::smallmap::SmallMap;
|
||||
use crate::NumCell;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
pub use types::*;
|
||||
|
||||
const DESTROY: u32 = 0;
|
||||
const GET_TOPLEVEL: u32 = 1;
|
||||
const GET_POPUP: u32 = 2;
|
||||
const SET_WINDOW_GEOMETRY: u32 = 3;
|
||||
const ACK_CONFIGURE: u32 = 4;
|
||||
|
||||
const CONFIGURE: u32 = 0;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const NOT_CONSTRUCTED: u32 = 1;
|
||||
const ALREADY_CONSTRUCTED: u32 = 2;
|
||||
#[allow(dead_code)]
|
||||
const UNCONFIGURED_BUFFER: u32 = 3;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum XdgSurfaceRole {
|
||||
None,
|
||||
XdgPopup,
|
||||
XdgToplevel,
|
||||
}
|
||||
|
||||
impl XdgSurfaceRole {
|
||||
fn name(self) -> &'static str {
|
||||
match self {
|
||||
XdgSurfaceRole::None => "none",
|
||||
XdgSurfaceRole::XdgPopup => "xdg_popup",
|
||||
XdgSurfaceRole::XdgToplevel => "xdg_toplevel",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
id!(XdgSurfaceId);
|
||||
|
||||
pub struct XdgSurface {
|
||||
id: XdgSurfaceId,
|
||||
base: Rc<XdgWmBase>,
|
||||
role: Cell<XdgSurfaceRole>,
|
||||
pub surface: Rc<WlSurface>,
|
||||
requested_serial: NumCell<u32>,
|
||||
acked_serial: Cell<Option<u32>>,
|
||||
geometry: Cell<Option<Rect>>,
|
||||
extents: Cell<Rect>,
|
||||
pub absolute_desired_extents: Cell<Rect>,
|
||||
ext: CloneCell<Option<Rc<dyn XdgSurfaceExt>>>,
|
||||
popups: CopyHashMap<XdgPopupId, Rc<XdgPopup>>,
|
||||
pending: PendingXdgSurfaceData,
|
||||
pub(super) focus_surface: SmallMap<SeatId, Rc<WlSurface>, 1>,
|
||||
seat_state: NodeSeatState,
|
||||
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct PendingXdgSurfaceData {
|
||||
geometry: Cell<Option<Rect>>,
|
||||
}
|
||||
|
||||
trait XdgSurfaceExt {
|
||||
fn initial_configure(self: Rc<Self>) -> Result<(), XdgSurfaceError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn post_commit(self: Rc<Self>) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
fn into_node(self: Rc<Self>) -> Option<Rc<dyn Node>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn extents_changed(&self) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
fn surface_active_changed(self: Rc<Self>, active: bool) {
|
||||
let _ = active;
|
||||
}
|
||||
}
|
||||
|
||||
impl XdgSurface {
|
||||
pub fn new(wm_base: &Rc<XdgWmBase>, id: XdgSurfaceId, surface: &Rc<WlSurface>) -> Self {
|
||||
Self {
|
||||
id,
|
||||
base: wm_base.clone(),
|
||||
role: Cell::new(XdgSurfaceRole::None),
|
||||
surface: surface.clone(),
|
||||
requested_serial: NumCell::new(0),
|
||||
acked_serial: Cell::new(None),
|
||||
geometry: Cell::new(None),
|
||||
extents: Cell::new(Default::default()),
|
||||
absolute_desired_extents: Cell::new(Default::default()),
|
||||
ext: Default::default(),
|
||||
popups: Default::default(),
|
||||
pending: Default::default(),
|
||||
focus_surface: Default::default(),
|
||||
seat_state: Default::default(),
|
||||
workspace: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_absolute_desired_extents(&self, ext: &Rect) {
|
||||
let prev = self.absolute_desired_extents.replace(*ext);
|
||||
if ext.x1() != prev.x1() || ext.y1() != prev.y1() {
|
||||
let (mut x1, mut y1) = (ext.x1(), ext.y1());
|
||||
if let Some(geo) = self.geometry.get() {
|
||||
x1 -= geo.x1();
|
||||
y1 -= geo.y1();
|
||||
}
|
||||
self.surface.set_absolute_position(x1, y1);
|
||||
self.update_popup_positions();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn surface_active_changed(&self, active: bool) {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.surface_active_changed(active);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn role(&self) -> XdgSurfaceRole {
|
||||
self.role.get()
|
||||
}
|
||||
|
||||
fn set_workspace(&self, ws: &Rc<WorkspaceNode>) {
|
||||
self.workspace.set(Some(ws.clone()));
|
||||
let pu = self.popups.lock();
|
||||
for pu in pu.values() {
|
||||
pu.xdg.set_workspace(ws);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_role(&self, role: XdgSurfaceRole) -> Result<(), XdgSurfaceError> {
|
||||
use XdgSurfaceRole::*;
|
||||
match (self.role.get(), role) {
|
||||
(None, _) => {}
|
||||
(old, new) if old == new => {}
|
||||
(old, new) => {
|
||||
return Err(XdgSurfaceError::IncompatibleRole {
|
||||
id: self.id,
|
||||
old,
|
||||
new,
|
||||
})
|
||||
}
|
||||
}
|
||||
self.role.set(role);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn focus_surface(&self, seat: &WlSeatGlobal) -> Rc<WlSurface> {
|
||||
self.focus_surface
|
||||
.get(&seat.id())
|
||||
.unwrap_or_else(|| self.surface.clone())
|
||||
}
|
||||
|
||||
fn destroy_node(&self) {
|
||||
self.workspace.set(None);
|
||||
self.surface.destroy_node(false);
|
||||
let popups = self.popups.lock();
|
||||
for popup in popups.values() {
|
||||
popup.destroy_node(true);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn geometry(&self) -> Option<Rect> {
|
||||
self.geometry.get()
|
||||
}
|
||||
|
||||
pub fn send_configure(self: &Rc<Self>) {
|
||||
let serial = self.requested_serial.fetch_add(1) + 1;
|
||||
self.surface.client.event(self.configure(serial));
|
||||
}
|
||||
|
||||
pub fn configure(self: &Rc<Self>, serial: u32) -> DynEventFormatter {
|
||||
Box::new(Configure {
|
||||
obj: self.clone(),
|
||||
serial,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn install(self: &Rc<Self>) -> Result<(), XdgSurfaceError> {
|
||||
self.surface.set_role(SurfaceRole::XdgSurface)?;
|
||||
if self.surface.ext.get().is_some() {
|
||||
return Err(XdgSurfaceError::AlreadyAttached(self.surface.id));
|
||||
}
|
||||
self.surface.ext.set(self.clone());
|
||||
self.surface.set_xdg_surface(Some(self.clone()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||
let _req: Destroy = self.surface.client.parse(self, parser)?;
|
||||
if self.ext.get().is_some() {
|
||||
return Err(DestroyError::RoleNotYetDestroyed(self.id));
|
||||
}
|
||||
{
|
||||
let children = self.popups.lock();
|
||||
if !children.is_empty() {
|
||||
return Err(DestroyError::PopupsNotYetDestroyed);
|
||||
}
|
||||
}
|
||||
self.surface.set_xdg_surface(None);
|
||||
self.surface.unset_ext();
|
||||
self.base.surfaces.remove(&self.id);
|
||||
self.surface.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_toplevel(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), GetToplevelError> {
|
||||
let req: GetToplevel = self.surface.client.parse(&**self, parser)?;
|
||||
self.set_role(XdgSurfaceRole::XdgToplevel)?;
|
||||
if self.ext.get().is_some() {
|
||||
self.surface.client.protocol_error(
|
||||
&**self,
|
||||
ALREADY_CONSTRUCTED,
|
||||
format!(
|
||||
"wl_surface {} already has an assigned xdg_toplevel",
|
||||
self.surface.id
|
||||
),
|
||||
);
|
||||
return Err(GetToplevelError::AlreadyConstructed);
|
||||
}
|
||||
let toplevel = Rc::new(XdgToplevel::new(req.id, self));
|
||||
self.surface.client.add_client_obj(&toplevel)?;
|
||||
self.ext.set(Some(toplevel));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_popup(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), GetPopupError> {
|
||||
let req: GetPopup = self.surface.client.parse(&**self, parser)?;
|
||||
self.set_role(XdgSurfaceRole::XdgPopup)?;
|
||||
let mut parent = None;
|
||||
if req.parent.is_some() {
|
||||
parent = Some(self.surface.client.lookup(req.parent)?);
|
||||
}
|
||||
let positioner = self.surface.client.lookup(req.positioner)?;
|
||||
if self.ext.get().is_some() {
|
||||
self.surface.client.protocol_error(
|
||||
&**self,
|
||||
ALREADY_CONSTRUCTED,
|
||||
format!(
|
||||
"wl_surface {} already has an assigned xdg_popup",
|
||||
self.surface.id
|
||||
),
|
||||
);
|
||||
return Err(GetPopupError::AlreadyConstructed);
|
||||
}
|
||||
let popup = Rc::new(XdgPopup::new(req.id, self, parent.as_ref(), &positioner)?);
|
||||
self.surface.client.add_client_obj(&popup)?;
|
||||
if let Some(parent) = &parent {
|
||||
parent.popups.set(req.id, popup.clone());
|
||||
}
|
||||
self.ext.set(Some(popup));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_window_geometry(&self, parser: MsgParser<'_, '_>) -> Result<(), SetWindowGeometryError> {
|
||||
let req: SetWindowGeometry = self.surface.client.parse(self, parser)?;
|
||||
if req.height <= 0 || req.width <= 0 {
|
||||
return Err(SetWindowGeometryError::NonPositiveWidthHeight);
|
||||
}
|
||||
let extents = Rect::new_sized(req.x, req.y, req.width, req.height).unwrap();
|
||||
self.pending.geometry.set(Some(extents));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ack_configure(&self, parser: MsgParser<'_, '_>) -> Result<(), AckConfigureError> {
|
||||
let req: AckConfigure = self.surface.client.parse(self, parser)?;
|
||||
if self.requested_serial.get() == req.serial {
|
||||
self.acked_serial.set(Some(req.serial));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_extents(&self) {
|
||||
let old_extents = self.extents.get();
|
||||
let mut new_extents = self.surface.extents.get();
|
||||
if let Some(geometry) = self.geometry.get() {
|
||||
new_extents = new_extents.intersect(geometry);
|
||||
}
|
||||
self.extents.set(new_extents);
|
||||
if old_extents != new_extents {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.extents_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_tree_at(&self, mut x: i32, mut y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||
if let Some(geo) = self.geometry.get() {
|
||||
let (xt, yt) = geo.translate_inv(x, y);
|
||||
x = xt;
|
||||
y = yt;
|
||||
}
|
||||
match self.surface.find_surface_at(x, y) {
|
||||
Some((node, x, y)) => {
|
||||
tree.push(FoundNode { node, x, y });
|
||||
FindTreeResult::AcceptsInput
|
||||
}
|
||||
_ => FindTreeResult::Other,
|
||||
}
|
||||
}
|
||||
|
||||
fn update_popup_positions(&self) {
|
||||
let popups = self.popups.lock();
|
||||
for popup in popups.values() {
|
||||
popup.update_absolute_position();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
XdgSurface, XdgSurfaceError;
|
||||
|
||||
DESTROY => destroy,
|
||||
GET_TOPLEVEL => get_toplevel,
|
||||
GET_POPUP => get_popup,
|
||||
SET_WINDOW_GEOMETRY => set_window_geometry,
|
||||
ACK_CONFIGURE => ack_configure,
|
||||
}
|
||||
|
||||
impl Object for XdgSurface {
|
||||
fn num_requests(&self) -> u32 {
|
||||
ACK_CONFIGURE + 1
|
||||
}
|
||||
|
||||
fn break_loops(&self) {
|
||||
self.focus_surface.take();
|
||||
}
|
||||
}
|
||||
|
||||
dedicated_add_obj!(XdgSurface, XdgSurfaceId, xdg_surfaces);
|
||||
|
||||
impl SurfaceExt for XdgSurface {
|
||||
fn pre_commit(self: Rc<Self>, _ctx: CommitContext) -> Result<CommitAction, WlSurfaceError> {
|
||||
{
|
||||
let ase = self.acked_serial.get();
|
||||
let rse = self.requested_serial.get();
|
||||
if ase != Some(rse) {
|
||||
if ase.is_none() {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.initial_configure()?;
|
||||
}
|
||||
self.surface.client.event(self.configure(rse));
|
||||
}
|
||||
// return CommitAction::AbortCommit;
|
||||
}
|
||||
}
|
||||
if let Some(geometry) = self.pending.geometry.take() {
|
||||
self.geometry.set(Some(geometry));
|
||||
self.update_extents();
|
||||
}
|
||||
Ok(CommitAction::ContinueCommit)
|
||||
}
|
||||
|
||||
fn post_commit(&self) {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.post_commit();
|
||||
}
|
||||
}
|
||||
|
||||
fn extents_changed(&self) {
|
||||
self.update_extents();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
use crate::client::{ClientError, EventFormatter, RequestParser};
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_popup::{XdgPopupError, XdgPopupId};
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevelId;
|
||||
use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceId, XdgSurfaceRole, CONFIGURE};
|
||||
use crate::ifs::wl_surface::{WlSurfaceError, WlSurfaceId};
|
||||
use crate::ifs::xdg_positioner::XdgPositionerId;
|
||||
use crate::object::Object;
|
||||
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum XdgSurfaceError {
|
||||
#[error("Could not process `destroy` request")]
|
||||
DestroyError(#[from] DestroyError),
|
||||
#[error("Could not process `get_toplevel` request")]
|
||||
GetToplevelError(#[from] GetToplevelError),
|
||||
#[error("Could not process `get_popup` request")]
|
||||
GetPopupError(#[from] GetPopupError),
|
||||
#[error("Could not process `set_window_geometry` request")]
|
||||
SetWindowGeometryError(#[from] SetWindowGeometryError),
|
||||
#[error("Could not process `ack_configure` request")]
|
||||
AckConfigureError(#[from] AckConfigureError),
|
||||
#[error("Surface {0} cannot be turned into a xdg_surface because it already has an attached xdg_surface")]
|
||||
AlreadyAttached(WlSurfaceId),
|
||||
#[error(transparent)]
|
||||
WlSurfaceError(Box<WlSurfaceError>),
|
||||
#[error(transparent)]
|
||||
XdgPopupError(#[from] XdgPopupError),
|
||||
#[error("Surface {} cannot be assigned the role {} because it already has the role {}", .id, .new.name(), .old.name())]
|
||||
IncompatibleRole {
|
||||
id: XdgSurfaceId,
|
||||
old: XdgSurfaceRole,
|
||||
new: XdgSurfaceRole,
|
||||
},
|
||||
}
|
||||
efrom!(XdgSurfaceError, WlSurfaceError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DestroyError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("Cannot destroy xdg_surface {0} because it's associated xdg_toplevel/popup is not yet destroyed")]
|
||||
RoleNotYetDestroyed(XdgSurfaceId),
|
||||
#[error("The surface still has popups attached")]
|
||||
PopupsNotYetDestroyed,
|
||||
}
|
||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||
efrom!(DestroyError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GetToplevelError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("The surface already has an assigned xdg_toplevel")]
|
||||
AlreadyConstructed,
|
||||
#[error(transparent)]
|
||||
WlSurfaceError(Box<WlSurfaceError>),
|
||||
#[error(transparent)]
|
||||
XdgSurfaceError(Box<XdgSurfaceError>),
|
||||
}
|
||||
efrom!(GetToplevelError, ParseFailed, MsgParserError);
|
||||
efrom!(GetToplevelError, ClientError);
|
||||
efrom!(GetToplevelError, WlSurfaceError);
|
||||
efrom!(GetToplevelError, XdgSurfaceError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GetPopupError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("The surface already has an assigned xdg_popup")]
|
||||
AlreadyConstructed,
|
||||
#[error(transparent)]
|
||||
WlSurfaceError(Box<WlSurfaceError>),
|
||||
#[error(transparent)]
|
||||
XdgPopupError(Box<XdgPopupError>),
|
||||
#[error(transparent)]
|
||||
XdgSurfaceError(Box<XdgSurfaceError>),
|
||||
}
|
||||
efrom!(GetPopupError, ParseFailed, MsgParserError);
|
||||
efrom!(GetPopupError, ClientError);
|
||||
efrom!(GetPopupError, XdgPopupError);
|
||||
efrom!(GetPopupError, WlSurfaceError);
|
||||
efrom!(GetPopupError, XdgSurfaceError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetWindowGeometryError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("Tried no set a non-positive width/height")]
|
||||
NonPositiveWidthHeight,
|
||||
}
|
||||
efrom!(SetWindowGeometryError, ParseFailed, MsgParserError);
|
||||
efrom!(SetWindowGeometryError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AckConfigureError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(AckConfigureError, ParseFailed, MsgParserError);
|
||||
efrom!(AckConfigureError, ClientError);
|
||||
|
||||
pub(super) struct Destroy;
|
||||
impl RequestParser<'_> for Destroy {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for Destroy {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "destroy()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct GetToplevel {
|
||||
pub id: XdgToplevelId,
|
||||
}
|
||||
impl RequestParser<'_> for GetToplevel {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
id: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for GetToplevel {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "get_toplevel(id: {})", self.id)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct GetPopup {
|
||||
pub id: XdgPopupId,
|
||||
pub parent: XdgSurfaceId,
|
||||
pub positioner: XdgPositionerId,
|
||||
}
|
||||
impl RequestParser<'_> for GetPopup {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
id: parser.object()?,
|
||||
parent: parser.object()?,
|
||||
positioner: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for GetPopup {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"get_popup(id: {}, parent: {}, positioner: {})",
|
||||
self.id, self.parent, self.positioner
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetWindowGeometry {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
impl RequestParser<'_> for SetWindowGeometry {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
x: parser.int()?,
|
||||
y: parser.int()?,
|
||||
width: parser.int()?,
|
||||
height: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetWindowGeometry {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"set_window_geometry(x: {}, y: {}, width: {}, height: {})",
|
||||
self.x, self.y, self.width, self.height
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct AckConfigure {
|
||||
pub serial: u32,
|
||||
}
|
||||
impl RequestParser<'_> for AckConfigure {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
serial: parser.uint()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for AckConfigure {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "ack_configure(serial: {})", self.serial)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Configure {
|
||||
pub obj: Rc<XdgSurface>,
|
||||
pub serial: u32,
|
||||
}
|
||||
impl EventFormatter for Configure {
|
||||
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
||||
fmt.header(self.obj.id, CONFIGURE).uint(self.serial);
|
||||
}
|
||||
|
||||
fn obj(&self) -> &dyn Object {
|
||||
&*self.obj
|
||||
}
|
||||
}
|
||||
impl Debug for Configure {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "configure(serial: {})", self.serial)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
mod types;
|
||||
|
||||
use crate::client::{Client, DynEventFormatter};
|
||||
use crate::client::{Client, ClientError, DynEventFormatter};
|
||||
use crate::cursor::KnownCursor;
|
||||
use crate::fixed::Fixed;
|
||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||
|
|
@ -15,21 +14,15 @@ use crate::utils::clonecell::CloneCell;
|
|||
use crate::utils::linkedlist::LinkedNode;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
pub use types::*;
|
||||
|
||||
const DESTROY: u32 = 0;
|
||||
const GRAB: u32 = 1;
|
||||
const REPOSITION: u32 = 2;
|
||||
|
||||
const CONFIGURE: u32 = 0;
|
||||
const POPUP_DONE: u32 = 1;
|
||||
const REPOSITIONED: u32 = 2;
|
||||
use thiserror::Error;
|
||||
use crate::wire::xdg_popup::*;
|
||||
use crate::utils::buffd::MsgParserError;
|
||||
use crate::wire::XdgPopupId;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const INVALID_GRAB: u32 = 1;
|
||||
|
||||
tree_id!(PopupId);
|
||||
id!(XdgPopupId);
|
||||
|
||||
pub struct XdgPopup {
|
||||
id: XdgPopupId,
|
||||
|
|
@ -67,7 +60,7 @@ impl XdgPopup {
|
|||
|
||||
fn configure(self: &Rc<Self>, x: i32, y: i32, width: i32, height: i32) -> DynEventFormatter {
|
||||
Box::new(Configure {
|
||||
obj: self.clone(),
|
||||
self_id: self.id,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
|
|
@ -77,13 +70,13 @@ impl XdgPopup {
|
|||
|
||||
fn repositioned(self: &Rc<Self>, token: u32) -> DynEventFormatter {
|
||||
Box::new(Repositioned {
|
||||
obj: self.clone(),
|
||||
self_id: self.id,
|
||||
token,
|
||||
})
|
||||
}
|
||||
|
||||
fn popup_done(self: &Rc<Self>) -> DynEventFormatter {
|
||||
Box::new(PopupDone { obj: self.clone() })
|
||||
Box::new(PopupDone { self_id: self.id })
|
||||
}
|
||||
|
||||
fn update_position(&self, parent: &XdgSurface) -> Result<(), XdgPopupError> {
|
||||
|
|
@ -355,3 +348,51 @@ impl XdgSurfaceExt for XdgPopup {
|
|||
self.xdg.surface.client.state.tree_changed();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum XdgPopupError {
|
||||
#[error("Could not process `destroy` request")]
|
||||
DestroyError(#[from] DestroyError),
|
||||
#[error("Could not process `grab` request")]
|
||||
GrabError(#[from] GrabError),
|
||||
#[error("Could not process `reposition` request")]
|
||||
RepositionError(#[from] RepositionError),
|
||||
#[error("The `xdg_positioner` is incomplete")]
|
||||
Incomplete,
|
||||
#[error("The anchor rectangle of the `xdg_positioner` extends outside the parent")]
|
||||
#[allow(dead_code)]
|
||||
AnchorRectOutside,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DestroyError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||
efrom!(DestroyError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GrabError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(GrabError, ParseFailed, MsgParserError);
|
||||
efrom!(GrabError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RepositionError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error(transparent)]
|
||||
XdgPopupError(Box<XdgPopupError>),
|
||||
}
|
||||
efrom!(RepositionError, ParseFailed, MsgParserError);
|
||||
efrom!(RepositionError, ClientError);
|
||||
efrom!(RepositionError, XdgPopupError);
|
||||
|
|
@ -1,178 +0,0 @@
|
|||
use crate::client::{ClientError, EventFormatter, RequestParser};
|
||||
use crate::ifs::wl_seat::WlSeatId;
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_popup::{
|
||||
XdgPopup, CONFIGURE, POPUP_DONE, REPOSITIONED,
|
||||
};
|
||||
use crate::ifs::xdg_positioner::XdgPositionerId;
|
||||
use crate::object::Object;
|
||||
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum XdgPopupError {
|
||||
#[error("Could not process `destroy` request")]
|
||||
DestroyError(#[from] DestroyError),
|
||||
#[error("Could not process `grab` request")]
|
||||
GrabError(#[from] GrabError),
|
||||
#[error("Could not process `reposition` request")]
|
||||
RepositionError(#[from] RepositionError),
|
||||
#[error("The `xdg_positioner` is incomplete")]
|
||||
Incomplete,
|
||||
#[error("The anchor rectangle of the `xdg_positioner` extends outside the parent")]
|
||||
#[allow(dead_code)]
|
||||
AnchorRectOutside,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DestroyError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||
efrom!(DestroyError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GrabError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(GrabError, ParseFailed, MsgParserError);
|
||||
efrom!(GrabError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RepositionError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error(transparent)]
|
||||
XdgPopupError(Box<XdgPopupError>),
|
||||
}
|
||||
efrom!(RepositionError, ParseFailed, MsgParserError);
|
||||
efrom!(RepositionError, ClientError);
|
||||
efrom!(RepositionError, XdgPopupError);
|
||||
|
||||
pub(super) struct Destroy;
|
||||
impl RequestParser<'_> for Destroy {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for Destroy {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "destroy()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Grab {
|
||||
pub seat: WlSeatId,
|
||||
pub serial: u32,
|
||||
}
|
||||
impl RequestParser<'_> for Grab {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
seat: parser.object()?,
|
||||
serial: parser.uint()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for Grab {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "grab(seat: {}, serial: {})", self.seat, self.serial)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Reposition {
|
||||
pub positioner: XdgPositionerId,
|
||||
pub token: u32,
|
||||
}
|
||||
impl RequestParser<'_> for Reposition {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
positioner: parser.object()?,
|
||||
token: parser.uint()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for Reposition {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"reposition(positioner: {}, token: {})",
|
||||
self.positioner, self.token,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Configure {
|
||||
pub obj: Rc<XdgPopup>,
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
impl EventFormatter for Configure {
|
||||
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
||||
fmt.header(self.obj.id, CONFIGURE)
|
||||
.int(self.x)
|
||||
.int(self.y)
|
||||
.int(self.width)
|
||||
.int(self.height);
|
||||
}
|
||||
|
||||
fn obj(&self) -> &dyn Object {
|
||||
&*self.obj
|
||||
}
|
||||
}
|
||||
impl Debug for Configure {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"configure(x: {}, y: {}, width: {}, height: {})",
|
||||
self.x, self.y, self.width, self.height
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct PopupDone {
|
||||
pub obj: Rc<XdgPopup>,
|
||||
}
|
||||
impl EventFormatter for PopupDone {
|
||||
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
||||
fmt.header(self.obj.id, POPUP_DONE);
|
||||
}
|
||||
|
||||
fn obj(&self) -> &dyn Object {
|
||||
&*self.obj
|
||||
}
|
||||
}
|
||||
impl Debug for PopupDone {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "popup_done()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Repositioned {
|
||||
pub obj: Rc<XdgPopup>,
|
||||
pub token: u32,
|
||||
}
|
||||
impl EventFormatter for Repositioned {
|
||||
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
||||
fmt.header(self.obj.id, REPOSITIONED).uint(self.token);
|
||||
}
|
||||
|
||||
fn obj(&self) -> &dyn Object {
|
||||
&*self.obj
|
||||
}
|
||||
}
|
||||
impl Debug for Repositioned {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "repositioned(token: {})", self.token)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
mod types;
|
||||
|
||||
use crate::backend::SeatId;
|
||||
use crate::bugs::Bugs;
|
||||
use crate::client::{Client, DynEventFormatter};
|
||||
use crate::client::{Client, ClientError, DynEventFormatter};
|
||||
use crate::cursor::KnownCursor;
|
||||
use crate::fixed::Fixed;
|
||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||
|
|
@ -18,30 +17,14 @@ use crate::utils::linkedlist::LinkedNode;
|
|||
use crate::utils::smallmap::SmallMap;
|
||||
use crate::{bugs, NumCell};
|
||||
use ahash::{AHashMap, AHashSet};
|
||||
use bstr::ByteSlice;
|
||||
use num_derive::FromPrimitive;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
pub use types::*;
|
||||
|
||||
const DESTROY: u32 = 0;
|
||||
const SET_PARENT: u32 = 1;
|
||||
const SET_TITLE: u32 = 2;
|
||||
const SET_APP_ID: u32 = 3;
|
||||
const SHOW_WINDOW_MENU: u32 = 4;
|
||||
const MOVE: u32 = 5;
|
||||
const RESIZE: u32 = 6;
|
||||
const SET_MAX_SIZE: u32 = 7;
|
||||
const SET_MIN_SIZE: u32 = 8;
|
||||
const SET_MAXIMIZED: u32 = 9;
|
||||
const UNSET_MAXIMIZED: u32 = 10;
|
||||
const SET_FULLSCREEN: u32 = 11;
|
||||
const UNSET_FULLSCREEN: u32 = 12;
|
||||
const SET_MINIMIZED: u32 = 13;
|
||||
|
||||
const CONFIGURE: u32 = 0;
|
||||
const CLOSE: u32 = 1;
|
||||
use thiserror::Error;
|
||||
use crate::wire::xdg_toplevel::*;
|
||||
use crate::utils::buffd::MsgParserError;
|
||||
use crate::wire::XdgToplevelId;
|
||||
|
||||
#[derive(Copy, Clone, Debug, FromPrimitive)]
|
||||
pub enum ResizeEdge {
|
||||
|
|
@ -73,8 +56,6 @@ const STATE_TILED_TOP: u32 = 7;
|
|||
#[allow(dead_code)]
|
||||
const STATE_TILED_BOTTOM: u32 = 8;
|
||||
|
||||
id!(XdgToplevelId);
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub enum Decoration {
|
||||
#[allow(dead_code)]
|
||||
|
|
@ -172,8 +153,8 @@ impl XdgToplevel {
|
|||
}
|
||||
|
||||
fn configure(self: &Rc<Self>, width: i32, height: i32) -> DynEventFormatter {
|
||||
Box::new(Configure {
|
||||
obj: self.clone(),
|
||||
Box::new(ConfigureOut {
|
||||
self_id: self.id,
|
||||
width,
|
||||
height,
|
||||
states: self.states.borrow().iter().copied().collect(),
|
||||
|
|
@ -207,15 +188,13 @@ impl XdgToplevel {
|
|||
}
|
||||
|
||||
fn set_title(&self, parser: MsgParser<'_, '_>) -> Result<(), SetTitleError> {
|
||||
let _req: SetTitle = self.xdg.surface.client.parse(self, parser)?;
|
||||
let _req: SetTitleIn = self.xdg.surface.client.parse(self, parser)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_app_id(&self, parser: MsgParser<'_, '_>) -> Result<(), SetAppIdError> {
|
||||
let req: SetAppId = self.xdg.surface.client.parse(self, parser)?;
|
||||
if let Ok(s) = req.app_id.to_str() {
|
||||
self.bugs.set(bugs::get(s));
|
||||
}
|
||||
let req: SetAppIdIn = self.xdg.surface.client.parse(self, parser)?;
|
||||
self.bugs.set(bugs::get(req.app_id));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -560,3 +539,179 @@ impl XdgSurfaceExt for XdgToplevel {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum XdgToplevelError {
|
||||
#[error("Could not process `destroy` request")]
|
||||
DestroyError(#[from] DestroyError),
|
||||
#[error("Could not process `set_parent` request")]
|
||||
SetParentError(#[from] SetParentError),
|
||||
#[error("Could not process `set_title` request")]
|
||||
SetTitleError(#[from] SetTitleError),
|
||||
#[error("Could not process `set_app_id` request")]
|
||||
SetAppIdError(#[from] SetAppIdError),
|
||||
#[error("Could not process `show_window_menu` request")]
|
||||
ShowWindowMenuError(#[from] ShowWindowMenuError),
|
||||
#[error("Could not process `move` request")]
|
||||
MoveError(#[from] MoveError),
|
||||
#[error("Could not process `resize` request")]
|
||||
ResizeError(#[from] ResizeError),
|
||||
#[error("Could not process `set_max_size` request")]
|
||||
SetMaxSizeError(#[from] SetMaxSizeError),
|
||||
#[error("Could not process `set_min_size` request")]
|
||||
SetMinSizeError(#[from] SetMinSizeError),
|
||||
#[error("Could not process `set_maximized` request")]
|
||||
SetMaximizedError(#[from] SetMaximizedError),
|
||||
#[error("Could not process `unset_maximized` request")]
|
||||
UnsetMaximizedError(#[from] UnsetMaximizedError),
|
||||
#[error("Could not process `set_fullscreen` request")]
|
||||
SetFullscreenError(#[from] SetFullscreenError),
|
||||
#[error("Could not process `unset_fullscreen` request")]
|
||||
UnsetFullscreenError(#[from] UnsetFullscreenError),
|
||||
#[error("Could not process `set_minimized` request")]
|
||||
SetMinimizedError(#[from] SetMinimizedError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DestroyError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||
efrom!(DestroyError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetParentError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetParentError, ParseFailed, MsgParserError);
|
||||
efrom!(SetParentError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetTitleError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetTitleError, ParseFailed, MsgParserError);
|
||||
efrom!(SetTitleError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetAppIdError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetAppIdError, ParseFailed, MsgParserError);
|
||||
efrom!(SetAppIdError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ShowWindowMenuError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(ShowWindowMenuError, ParseFailed, MsgParserError);
|
||||
efrom!(ShowWindowMenuError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum MoveError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(MoveError, ParseFailed, MsgParserError);
|
||||
efrom!(MoveError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ResizeError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(ResizeError, ParseFailed, MsgParserError);
|
||||
efrom!(ResizeError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetMaxSizeError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("width/height must be non-negative")]
|
||||
NonNegative,
|
||||
}
|
||||
efrom!(SetMaxSizeError, ParseFailed, MsgParserError);
|
||||
efrom!(SetMaxSizeError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetMinSizeError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("width/height must be non-negative")]
|
||||
NonNegative,
|
||||
}
|
||||
efrom!(SetMinSizeError, ParseFailed, MsgParserError);
|
||||
efrom!(SetMinSizeError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetMaximizedError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetMaximizedError, ParseFailed, MsgParserError);
|
||||
efrom!(SetMaximizedError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum UnsetMaximizedError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(UnsetMaximizedError, ParseFailed, MsgParserError);
|
||||
efrom!(UnsetMaximizedError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetFullscreenError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetFullscreenError, ParseFailed, MsgParserError);
|
||||
efrom!(SetFullscreenError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum UnsetFullscreenError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(UnsetFullscreenError, ParseFailed, MsgParserError);
|
||||
efrom!(UnsetFullscreenError, ClientError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetMinimizedError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetMinimizedError, ParseFailed, MsgParserError);
|
||||
efrom!(SetMinimizedError, ClientError, ClientError);
|
||||
|
|
@ -1,472 +0,0 @@
|
|||
use super::CONFIGURE;
|
||||
use crate::client::{ClientError, EventFormatter, RequestParser};
|
||||
use crate::ifs::wl_seat::WlSeatId;
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::{XdgToplevel, XdgToplevelId, CLOSE};
|
||||
use crate::object::Object;
|
||||
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
||||
use bstr::BStr;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum XdgToplevelError {
|
||||
#[error("Could not process `destroy` request")]
|
||||
DestroyError(#[from] DestroyError),
|
||||
#[error("Could not process `set_parent` request")]
|
||||
SetParentError(#[from] SetParentError),
|
||||
#[error("Could not process `set_title` request")]
|
||||
SetTitleError(#[from] SetTitleError),
|
||||
#[error("Could not process `set_app_id` request")]
|
||||
SetAppIdError(#[from] SetAppIdError),
|
||||
#[error("Could not process `show_window_menu` request")]
|
||||
ShowWindowMenuError(#[from] ShowWindowMenuError),
|
||||
#[error("Could not process `move` request")]
|
||||
MoveError(#[from] MoveError),
|
||||
#[error("Could not process `resize` request")]
|
||||
ResizeError(#[from] ResizeError),
|
||||
#[error("Could not process `set_max_size` request")]
|
||||
SetMaxSizeError(#[from] SetMaxSizeError),
|
||||
#[error("Could not process `set_min_size` request")]
|
||||
SetMinSizeError(#[from] SetMinSizeError),
|
||||
#[error("Could not process `set_maximized` request")]
|
||||
SetMaximizedError(#[from] SetMaximizedError),
|
||||
#[error("Could not process `unset_maximized` request")]
|
||||
UnsetMaximizedError(#[from] UnsetMaximizedError),
|
||||
#[error("Could not process `set_fullscreen` request")]
|
||||
SetFullscreenError(#[from] SetFullscreenError),
|
||||
#[error("Could not process `unset_fullscreen` request")]
|
||||
UnsetFullscreenError(#[from] UnsetFullscreenError),
|
||||
#[error("Could not process `set_minimized` request")]
|
||||
SetMinimizedError(#[from] SetMinimizedError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DestroyError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(DestroyError, ParseFailed, MsgParserError);
|
||||
efrom!(DestroyError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetParentError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetParentError, ParseFailed, MsgParserError);
|
||||
efrom!(SetParentError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetTitleError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetTitleError, ParseFailed, MsgParserError);
|
||||
efrom!(SetTitleError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetAppIdError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetAppIdError, ParseFailed, MsgParserError);
|
||||
efrom!(SetAppIdError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ShowWindowMenuError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(ShowWindowMenuError, ParseFailed, MsgParserError);
|
||||
efrom!(ShowWindowMenuError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum MoveError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(MoveError, ParseFailed, MsgParserError);
|
||||
efrom!(MoveError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ResizeError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(ResizeError, ParseFailed, MsgParserError);
|
||||
efrom!(ResizeError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetMaxSizeError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("width/height must be non-negative")]
|
||||
NonNegative,
|
||||
}
|
||||
efrom!(SetMaxSizeError, ParseFailed, MsgParserError);
|
||||
efrom!(SetMaxSizeError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetMinSizeError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("width/height must be non-negative")]
|
||||
NonNegative,
|
||||
}
|
||||
efrom!(SetMinSizeError, ParseFailed, MsgParserError);
|
||||
efrom!(SetMinSizeError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetMaximizedError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetMaximizedError, ParseFailed, MsgParserError);
|
||||
efrom!(SetMaximizedError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum UnsetMaximizedError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(UnsetMaximizedError, ParseFailed, MsgParserError);
|
||||
efrom!(UnsetMaximizedError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetFullscreenError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetFullscreenError, ParseFailed, MsgParserError);
|
||||
efrom!(SetFullscreenError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum UnsetFullscreenError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(UnsetFullscreenError, ParseFailed, MsgParserError);
|
||||
efrom!(UnsetFullscreenError, ClientError, ClientError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SetMinimizedError {
|
||||
#[error("Parsing failed")]
|
||||
ParseFailed(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(SetMinimizedError, ParseFailed, MsgParserError);
|
||||
efrom!(SetMinimizedError, ClientError, ClientError);
|
||||
|
||||
pub(super) struct Destroy;
|
||||
impl RequestParser<'_> for Destroy {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for Destroy {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "destroy()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetParent {
|
||||
pub parent: XdgToplevelId,
|
||||
}
|
||||
impl RequestParser<'_> for SetParent {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
parent: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetParent {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_parent(parent: {})", self.parent)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetTitle<'a> {
|
||||
pub title: &'a BStr,
|
||||
}
|
||||
impl<'a> RequestParser<'a> for SetTitle<'a> {
|
||||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
title: parser.bstr()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl<'a> Debug for SetTitle<'a> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_title(title: {:?})", self.title)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetAppId<'a> {
|
||||
pub app_id: &'a BStr,
|
||||
}
|
||||
impl<'a> RequestParser<'a> for SetAppId<'a> {
|
||||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
app_id: parser.bstr()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl<'a> Debug for SetAppId<'a> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_app_id(app_id: {:?})", self.app_id)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct ShowWindowMenu {
|
||||
pub seat: WlSeatId,
|
||||
pub serial: u32,
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
}
|
||||
impl RequestParser<'_> for ShowWindowMenu {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
seat: parser.object()?,
|
||||
serial: parser.uint()?,
|
||||
x: parser.int()?,
|
||||
y: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for ShowWindowMenu {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"show_window_menu(seat: {}, serial: {}, x: {}, y: {})",
|
||||
self.seat, self.serial, self.x, self.y
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Move {
|
||||
pub seat: WlSeatId,
|
||||
pub serial: u32,
|
||||
}
|
||||
impl RequestParser<'_> for Move {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
seat: parser.object()?,
|
||||
serial: parser.uint()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for Move {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "move(seat: {}, serial: {})", self.seat, self.serial)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Resize {
|
||||
pub seat: WlSeatId,
|
||||
pub serial: u32,
|
||||
pub edges: u32,
|
||||
}
|
||||
impl RequestParser<'_> for Resize {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
seat: parser.object()?,
|
||||
serial: parser.uint()?,
|
||||
edges: parser.uint()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for Resize {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"resize(seat: {}, serial: {}, edges: {})",
|
||||
self.seat, self.serial, self.edges
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetMaxSize {
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
impl RequestParser<'_> for SetMaxSize {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
width: parser.int()?,
|
||||
height: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetMaxSize {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"set_max_size(width: {}, height: {})",
|
||||
self.width, self.height
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetMinSize {
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
}
|
||||
impl RequestParser<'_> for SetMinSize {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
width: parser.int()?,
|
||||
height: parser.int()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetMinSize {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"set_min_size(width: {}, height: {})",
|
||||
self.width, self.height
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetMaximized;
|
||||
impl RequestParser<'_> for SetMaximized {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for SetMaximized {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_maximized()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct UnsetMaximized;
|
||||
impl RequestParser<'_> for UnsetMaximized {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for UnsetMaximized {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "unset_maximized()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetFullscreen {
|
||||
pub output: crate::ifs::wl_output::WlOutputId,
|
||||
}
|
||||
impl RequestParser<'_> for SetFullscreen {
|
||||
fn parse(parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self {
|
||||
output: parser.object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Debug for SetFullscreen {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_fullscreen(output: {})", self.output)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct UnsetFullscreen;
|
||||
impl RequestParser<'_> for UnsetFullscreen {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for UnsetFullscreen {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "unset_fullscreen()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct SetMinimized;
|
||||
impl RequestParser<'_> for SetMinimized {
|
||||
fn parse(_parser: &mut MsgParser<'_, '_>) -> Result<Self, MsgParserError> {
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
impl Debug for SetMinimized {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "set_minimized()")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Configure {
|
||||
pub obj: Rc<XdgToplevel>,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
pub states: Vec<u32>,
|
||||
}
|
||||
impl EventFormatter for Configure {
|
||||
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
||||
fmt.header(self.obj.id, CONFIGURE)
|
||||
.int(self.width)
|
||||
.int(self.height)
|
||||
.array(|fmt| {
|
||||
for &state in &self.states {
|
||||
fmt.uint(state);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn obj(&self) -> &dyn Object {
|
||||
&*self.obj
|
||||
}
|
||||
}
|
||||
impl Debug for Configure {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"configure(width: {}, height: {}, states: {:?})",
|
||||
self.width, self.height, self.states
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Close {
|
||||
pub obj: Rc<XdgToplevel>,
|
||||
}
|
||||
impl EventFormatter for Close {
|
||||
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
||||
fmt.header(self.obj.id, CLOSE);
|
||||
}
|
||||
|
||||
fn obj(&self) -> &dyn Object {
|
||||
&*self.obj
|
||||
}
|
||||
}
|
||||
impl Debug for Close {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "close()")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue