autocommit 2022-02-21 23:21:13 CET
This commit is contained in:
parent
1cbc7a6445
commit
145d1c15b7
31 changed files with 1455 additions and 252 deletions
|
|
@ -663,11 +663,8 @@ fn write_message<W: Write>(f: &mut W, obj: &BStr, message: &Message) -> Result<(
|
||||||
writeln!(f, " fn id(&self) -> ObjectId {{")?;
|
writeln!(f, " fn id(&self) -> ObjectId {{")?;
|
||||||
writeln!(f, " self.self_id.into()")?;
|
writeln!(f, " self.self_id.into()")?;
|
||||||
writeln!(f, " }}")?;
|
writeln!(f, " }}")?;
|
||||||
writeln!(
|
writeln!(f, " fn interface(&self) -> Interface {{")?;
|
||||||
f,
|
writeln!(f, " {}", obj)?;
|
||||||
" fn interface(&self) -> crate::object::Interface {{"
|
|
||||||
)?;
|
|
||||||
writeln!(f, " crate::object::Interface::{}", obj)?;
|
|
||||||
writeln!(f, " }}")?;
|
writeln!(f, " }}")?;
|
||||||
writeln!(f, " }}")?;
|
writeln!(f, " }}")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -681,6 +678,12 @@ fn write_file<W: Write>(f: &mut W, file: &DirEntry) -> Result<()> {
|
||||||
let camel_obj_name = to_camel(obj_name);
|
let camel_obj_name = to_camel(obj_name);
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
writeln!(f, "id!({}Id);", camel_obj_name)?;
|
writeln!(f, "id!({}Id);", camel_obj_name)?;
|
||||||
|
writeln!(f)?;
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"pub const {}: Interface = Interface(\"{}\");",
|
||||||
|
camel_obj_name, obj_name
|
||||||
|
)?;
|
||||||
let contents = std::fs::read(file.path())?;
|
let contents = std::fs::read(file.path())?;
|
||||||
let messages = parse_messages(&contents)?;
|
let messages = parse_messages(&contents)?;
|
||||||
if messages.is_empty() {
|
if messages.is_empty() {
|
||||||
|
|
@ -703,7 +706,7 @@ pub fn main() -> Result<()> {
|
||||||
writeln!(f, "use bstr::BStr;")?;
|
writeln!(f, "use bstr::BStr;")?;
|
||||||
writeln!(f, "use crate::fixed::Fixed;")?;
|
writeln!(f, "use crate::fixed::Fixed;")?;
|
||||||
writeln!(f, "use crate::client::{{EventFormatter, RequestParser}};")?;
|
writeln!(f, "use crate::client::{{EventFormatter, RequestParser}};")?;
|
||||||
writeln!(f, "use crate::object::ObjectId;")?;
|
writeln!(f, "use crate::object::{{ObjectId, Interface}};")?;
|
||||||
writeln!(
|
writeln!(
|
||||||
f,
|
f,
|
||||||
"use crate::utils::buffd::{{MsgFormatter, MsgParser, MsgParserError}};"
|
"use crate::utils::buffd::{{MsgFormatter, MsgParser, MsgParserError}};"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use crate::ifs::ipc::wl_data_source::WlDataSource;
|
||||||
use crate::ifs::ipc::zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1;
|
use crate::ifs::ipc::zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1;
|
||||||
use crate::ifs::wl_buffer::WlBuffer;
|
use crate::ifs::wl_buffer::WlBuffer;
|
||||||
use crate::ifs::wl_display::WlDisplay;
|
use crate::ifs::wl_display::WlDisplay;
|
||||||
|
use crate::ifs::wl_output::WlOutput;
|
||||||
use crate::ifs::wl_region::WlRegion;
|
use crate::ifs::wl_region::WlRegion;
|
||||||
use crate::ifs::wl_registry::WlRegistry;
|
use crate::ifs::wl_registry::WlRegistry;
|
||||||
use crate::ifs::wl_seat::WlSeat;
|
use crate::ifs::wl_seat::WlSeat;
|
||||||
|
|
@ -16,8 +17,8 @@ use crate::tree::Node;
|
||||||
use crate::utils::clonecell::CloneCell;
|
use crate::utils::clonecell::CloneCell;
|
||||||
use crate::utils::copyhashmap::CopyHashMap;
|
use crate::utils::copyhashmap::CopyHashMap;
|
||||||
use crate::wire::{
|
use crate::wire::{
|
||||||
WlBufferId, WlDataSourceId, WlRegionId, WlRegistryId, WlSeatId, WlSurfaceId, XdgPositionerId,
|
WlBufferId, WlDataSourceId, WlOutputId, WlRegionId, WlRegistryId, WlSeatId, WlSurfaceId,
|
||||||
XdgSurfaceId, XdgToplevelId, XdgWmBaseId, ZwpPrimarySelectionSourceV1Id,
|
XdgPositionerId, XdgSurfaceId, XdgToplevelId, XdgWmBaseId, ZwpPrimarySelectionSourceV1Id,
|
||||||
};
|
};
|
||||||
use ahash::AHashMap;
|
use ahash::AHashMap;
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
|
|
@ -29,6 +30,7 @@ pub struct Objects {
|
||||||
pub display: CloneCell<Option<Rc<WlDisplay>>>,
|
pub display: CloneCell<Option<Rc<WlDisplay>>>,
|
||||||
registry: CopyHashMap<ObjectId, Rc<dyn Object>>,
|
registry: CopyHashMap<ObjectId, Rc<dyn Object>>,
|
||||||
registries: CopyHashMap<WlRegistryId, Rc<WlRegistry>>,
|
registries: CopyHashMap<WlRegistryId, Rc<WlRegistry>>,
|
||||||
|
pub outputs: CopyHashMap<WlOutputId, Rc<WlOutput>>,
|
||||||
pub surfaces: CopyHashMap<WlSurfaceId, Rc<WlSurface>>,
|
pub surfaces: CopyHashMap<WlSurfaceId, Rc<WlSurface>>,
|
||||||
pub xdg_surfaces: CopyHashMap<XdgSurfaceId, Rc<XdgSurface>>,
|
pub xdg_surfaces: CopyHashMap<XdgSurfaceId, Rc<XdgSurface>>,
|
||||||
pub xdg_toplevel: CopyHashMap<XdgToplevelId, Rc<XdgToplevel>>,
|
pub xdg_toplevel: CopyHashMap<XdgToplevelId, Rc<XdgToplevel>>,
|
||||||
|
|
@ -52,6 +54,7 @@ impl Objects {
|
||||||
display: CloneCell::new(None),
|
display: CloneCell::new(None),
|
||||||
registry: Default::default(),
|
registry: Default::default(),
|
||||||
registries: Default::default(),
|
registries: Default::default(),
|
||||||
|
outputs: Default::default(),
|
||||||
surfaces: Default::default(),
|
surfaces: Default::default(),
|
||||||
xdg_surfaces: Default::default(),
|
xdg_surfaces: Default::default(),
|
||||||
xdg_toplevel: Default::default(),
|
xdg_toplevel: Default::default(),
|
||||||
|
|
@ -83,6 +86,7 @@ impl Objects {
|
||||||
}
|
}
|
||||||
self.display.set(None);
|
self.display.set(None);
|
||||||
self.registries.clear();
|
self.registries.clear();
|
||||||
|
self.outputs.clear();
|
||||||
self.surfaces.clear();
|
self.surfaces.clear();
|
||||||
self.xdg_surfaces.clear();
|
self.xdg_surfaces.clear();
|
||||||
self.wl_data_source.clear();
|
self.wl_data_source.clear();
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use crate::ifs::wl_drm::WlDrmGlobal;
|
||||||
use crate::ifs::wl_output::WlOutputGlobal;
|
use crate::ifs::wl_output::WlOutputGlobal;
|
||||||
use crate::ifs::wl_registry::WlRegistry;
|
use crate::ifs::wl_registry::WlRegistry;
|
||||||
use crate::ifs::wl_seat::WlSeatGlobal;
|
use crate::ifs::wl_seat::WlSeatGlobal;
|
||||||
|
use crate::ifs::zwlr_layer_shell_v1::ZwlrLayerShellV1Global;
|
||||||
use crate::object::{Interface, ObjectId};
|
use crate::object::{Interface, ObjectId};
|
||||||
use crate::utils::copyhashmap::CopyHashMap;
|
use crate::utils::copyhashmap::CopyHashMap;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -18,6 +19,7 @@ use std::error::Error;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use crate::ifs::zxdg_output_manager_v1::ZxdgOutputManagerV1Global;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum GlobalsError {
|
pub enum GlobalsError {
|
||||||
|
|
@ -103,6 +105,8 @@ impl Globals {
|
||||||
add_singleton!(ZxdgDecorationManagerV1Global);
|
add_singleton!(ZxdgDecorationManagerV1Global);
|
||||||
add_singleton!(OrgKdeKwinServerDecorationManagerGlobal);
|
add_singleton!(OrgKdeKwinServerDecorationManagerGlobal);
|
||||||
add_singleton!(ZwpPrimarySelectionDeviceManagerV1Global);
|
add_singleton!(ZwpPrimarySelectionDeviceManagerV1Global);
|
||||||
|
add_singleton!(ZwlrLayerShellV1Global);
|
||||||
|
add_singleton!(ZxdgOutputManagerV1Global);
|
||||||
slf
|
slf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,10 @@ pub mod wl_subcompositor;
|
||||||
pub mod wl_surface;
|
pub mod wl_surface;
|
||||||
pub mod xdg_positioner;
|
pub mod xdg_positioner;
|
||||||
pub mod xdg_wm_base;
|
pub mod xdg_wm_base;
|
||||||
|
pub mod zwlr_layer_shell_v1;
|
||||||
pub mod zwp_linux_buffer_params_v1;
|
pub mod zwp_linux_buffer_params_v1;
|
||||||
pub mod zwp_linux_dmabuf_v1;
|
pub mod zwp_linux_dmabuf_v1;
|
||||||
pub mod zxdg_decoration_manager_v1;
|
pub mod zxdg_decoration_manager_v1;
|
||||||
pub mod zxdg_toplevel_decoration_v1;
|
pub mod zxdg_toplevel_decoration_v1;
|
||||||
|
pub mod zxdg_output_manager_v1;
|
||||||
|
pub mod zxdg_output_v1;
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,17 @@ use crate::object::Object;
|
||||||
use crate::utils::buffd::MsgParser;
|
use crate::utils::buffd::MsgParser;
|
||||||
use crate::utils::buffd::MsgParserError;
|
use crate::utils::buffd::MsgParserError;
|
||||||
use crate::wire::wl_output::*;
|
use crate::wire::wl_output::*;
|
||||||
use crate::wire::WlOutputId;
|
use crate::wire::{WlOutputId, ZxdgOutputV1Id};
|
||||||
use ahash::AHashMap;
|
use ahash::AHashMap;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use crate::CloneCell;
|
||||||
|
use crate::ifs::zxdg_output_v1::ZxdgOutputV1;
|
||||||
|
use crate::rect::Rect;
|
||||||
|
use crate::tree::OutputNode;
|
||||||
|
use crate::utils::copyhashmap::CopyHashMap;
|
||||||
|
|
||||||
const SP_UNKNOWN: i32 = 0;
|
const SP_UNKNOWN: i32 = 0;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|
@ -48,10 +53,8 @@ const MODE_PREFERRED: u32 = 2;
|
||||||
pub struct WlOutputGlobal {
|
pub struct WlOutputGlobal {
|
||||||
name: GlobalName,
|
name: GlobalName,
|
||||||
output: Rc<dyn Output>,
|
output: Rc<dyn Output>,
|
||||||
pub x: Cell<i32>,
|
pos: Cell<Rect>,
|
||||||
pub y: Cell<i32>,
|
pub node: CloneCell<Option<Rc<OutputNode>>>,
|
||||||
width: Cell<i32>,
|
|
||||||
height: Cell<i32>,
|
|
||||||
pub bindings: RefCell<AHashMap<ClientId, AHashMap<WlOutputId, Rc<WlOutput>>>>,
|
pub bindings: RefCell<AHashMap<ClientId, AHashMap<WlOutputId, Rc<WlOutput>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,23 +63,27 @@ impl WlOutputGlobal {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
output: output.clone(),
|
output: output.clone(),
|
||||||
x: Cell::new(0),
|
pos: Cell::new(Rect::new_sized(0, 0, output.width(), output.height()).unwrap()),
|
||||||
y: Cell::new(0),
|
node: Default::default(),
|
||||||
width: Cell::new(output.width()),
|
|
||||||
height: Cell::new(output.height()),
|
|
||||||
bindings: Default::default(),
|
bindings: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn position(&self) -> Rect {
|
||||||
|
self.pos.get()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_properties(&self) {
|
pub fn update_properties(&self) {
|
||||||
let width = self.output.width();
|
let width = self.output.width();
|
||||||
let height = self.output.height();
|
let height = self.output.height();
|
||||||
|
|
||||||
let mut changed = false;
|
let pos = self.pos.get();
|
||||||
changed |= self.width.replace(width) != width;
|
let old_width = pos.width();
|
||||||
changed |= self.height.replace(height) != height;
|
let old_height = pos.height();
|
||||||
|
let changed = old_width != width || old_height != height;
|
||||||
|
|
||||||
if changed {
|
if changed {
|
||||||
|
self.pos.set(Rect::new_sized(pos.x1(), pos.y1(), width, height).unwrap());
|
||||||
let bindings = self.bindings.borrow_mut();
|
let bindings = self.bindings.borrow_mut();
|
||||||
for binding in bindings.values() {
|
for binding in bindings.values() {
|
||||||
for binding in binding.values() {
|
for binding in binding.values() {
|
||||||
|
|
@ -85,6 +92,10 @@ impl WlOutputGlobal {
|
||||||
binding.send_scale();
|
binding.send_scale();
|
||||||
binding.send_done();
|
binding.send_done();
|
||||||
binding.client.flush();
|
binding.client.flush();
|
||||||
|
let xdg = binding.xdg_outputs.lock();
|
||||||
|
for xdg in xdg.values() {
|
||||||
|
xdg.send_updates();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +110,7 @@ impl WlOutputGlobal {
|
||||||
let obj = Rc::new(WlOutput {
|
let obj = Rc::new(WlOutput {
|
||||||
global: self.clone(),
|
global: self.clone(),
|
||||||
id,
|
id,
|
||||||
|
xdg_outputs: Default::default(),
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
version,
|
version,
|
||||||
tracker: Default::default(),
|
tracker: Default::default(),
|
||||||
|
|
@ -141,10 +153,11 @@ impl Global for WlOutputGlobal {
|
||||||
dedicated_add_global!(WlOutputGlobal, outputs);
|
dedicated_add_global!(WlOutputGlobal, outputs);
|
||||||
|
|
||||||
pub struct WlOutput {
|
pub struct WlOutput {
|
||||||
global: Rc<WlOutputGlobal>,
|
pub global: Rc<WlOutputGlobal>,
|
||||||
pub id: WlOutputId,
|
pub id: WlOutputId,
|
||||||
|
pub xdg_outputs: CopyHashMap<ZxdgOutputV1Id, Rc<ZxdgOutputV1>>,
|
||||||
client: Rc<Client>,
|
client: Rc<Client>,
|
||||||
version: u32,
|
pub version: u32,
|
||||||
tracker: Tracker<Self>,
|
tracker: Tracker<Self>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,12 +166,13 @@ pub const SEND_SCALE_SINCE: u32 = 2;
|
||||||
|
|
||||||
impl WlOutput {
|
impl WlOutput {
|
||||||
fn send_geometry(&self) {
|
fn send_geometry(&self) {
|
||||||
|
let pos = self.global.pos.get();
|
||||||
let event = Geometry {
|
let event = Geometry {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
x: 0,
|
x: pos.x1(),
|
||||||
y: 0,
|
y: pos.y1(),
|
||||||
physical_width: self.global.width.get() as _,
|
physical_width: pos.width(),
|
||||||
physical_height: self.global.height.get() as _,
|
physical_height: pos.height(),
|
||||||
subpixel: SP_UNKNOWN,
|
subpixel: SP_UNKNOWN,
|
||||||
make: "i4",
|
make: "i4",
|
||||||
model: "i4",
|
model: "i4",
|
||||||
|
|
@ -168,11 +182,12 @@ impl WlOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_mode(&self) {
|
fn send_mode(&self) {
|
||||||
|
let pos = self.global.pos.get();
|
||||||
let event = Mode {
|
let event = Mode {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
flags: MODE_CURRENT,
|
flags: MODE_CURRENT,
|
||||||
width: self.global.width.get() as _,
|
width: pos.width(),
|
||||||
height: self.global.height.get() as _,
|
height: pos.height(),
|
||||||
refresh: 60_000_000,
|
refresh: 60_000_000,
|
||||||
};
|
};
|
||||||
self.client.event(event);
|
self.client.event(event);
|
||||||
|
|
@ -186,7 +201,7 @@ impl WlOutput {
|
||||||
self.client.event(event);
|
self.client.event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_done(&self) {
|
pub fn send_done(&self) {
|
||||||
let event = Done { self_id: self.id };
|
let event = Done { self_id: self.id };
|
||||||
self.client.event(event);
|
self.client.event(event);
|
||||||
}
|
}
|
||||||
|
|
@ -202,6 +217,7 @@ impl WlOutput {
|
||||||
|
|
||||||
fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), ReleaseError> {
|
fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), ReleaseError> {
|
||||||
let _req: Release = self.client.parse(self, parser)?;
|
let _req: Release = self.client.parse(self, parser)?;
|
||||||
|
self.xdg_outputs.clear();
|
||||||
self.remove_binding();
|
self.remove_binding();
|
||||||
self.client.remove_obj(self)?;
|
self.client.remove_obj(self)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -224,11 +240,12 @@ impl Object for WlOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn break_loops(&self) {
|
fn break_loops(&self) {
|
||||||
|
self.xdg_outputs.clear();
|
||||||
self.remove_binding();
|
self.remove_binding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
simple_add_obj!(WlOutput);
|
dedicated_add_obj!(WlOutput, WlOutputId, outputs);
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum WlOutputError {
|
pub enum WlOutputError {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ mod pointer_owner;
|
||||||
pub mod wl_keyboard;
|
pub mod wl_keyboard;
|
||||||
pub mod wl_pointer;
|
pub mod wl_pointer;
|
||||||
pub mod wl_touch;
|
pub mod wl_touch;
|
||||||
|
mod kb_owner;
|
||||||
|
|
||||||
use crate::async_engine::SpawnedFuture;
|
use crate::async_engine::SpawnedFuture;
|
||||||
use crate::client::{Client, ClientError, ClientId};
|
use crate::client::{Client, ClientError, ClientId};
|
||||||
|
|
@ -43,10 +44,12 @@ use i4config::Direction;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::DerefMut;
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uapi::{c, Errno, OwnedFd};
|
use uapi::{c, Errno, OwnedFd};
|
||||||
|
use crate::ifs::wl_output::{WlOutputGlobal};
|
||||||
|
use crate::ifs::wl_seat::kb_owner::KbOwnerHolder;
|
||||||
|
|
||||||
const POINTER: u32 = 1;
|
const POINTER: u32 = 1;
|
||||||
const KEYBOARD: u32 = 2;
|
const KEYBOARD: u32 = 2;
|
||||||
|
|
@ -112,6 +115,7 @@ pub struct WlSeatGlobal {
|
||||||
selection: CloneCell<Option<Rc<WlDataSource>>>,
|
selection: CloneCell<Option<Rc<WlDataSource>>>,
|
||||||
primary_selection: CloneCell<Option<Rc<ZwpPrimarySelectionSourceV1>>>,
|
primary_selection: CloneCell<Option<Rc<ZwpPrimarySelectionSourceV1>>>,
|
||||||
pointer_owner: PointerOwnerHolder,
|
pointer_owner: PointerOwnerHolder,
|
||||||
|
kb_owner: KbOwnerHolder,
|
||||||
dropped_dnd: RefCell<Option<DroppedDnd>>,
|
dropped_dnd: RefCell<Option<DroppedDnd>>,
|
||||||
shortcuts: CopyHashMap<(u32, u32), Modifiers>,
|
shortcuts: CopyHashMap<(u32, u32), Modifiers>,
|
||||||
queue_link: Cell<Option<LinkedNode<Rc<Self>>>>,
|
queue_link: Cell<Option<LinkedNode<Rc<Self>>>>,
|
||||||
|
|
@ -146,6 +150,7 @@ impl WlSeatGlobal {
|
||||||
selection: Default::default(),
|
selection: Default::default(),
|
||||||
primary_selection: Default::default(),
|
primary_selection: Default::default(),
|
||||||
pointer_owner: Default::default(),
|
pointer_owner: Default::default(),
|
||||||
|
kb_owner: Default::default(),
|
||||||
dropped_dnd: RefCell::new(None),
|
dropped_dnd: RefCell::new(None),
|
||||||
shortcuts: Default::default(),
|
shortcuts: Default::default(),
|
||||||
queue_link: Cell::new(None),
|
queue_link: Cell::new(None),
|
||||||
|
|
@ -162,6 +167,17 @@ impl WlSeatGlobal {
|
||||||
slf
|
slf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_output(&self) -> Option<Rc<WlOutputGlobal>> {
|
||||||
|
let ps = self.pointer_stack.borrow_mut();
|
||||||
|
for node in ps.deref() {
|
||||||
|
if node.is_output() {
|
||||||
|
let on = node.clone().into_output().unwrap();
|
||||||
|
return Some(on.global.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mark_last_active(self: &Rc<Self>) {
|
pub fn mark_last_active(self: &Rc<Self>) {
|
||||||
self.queue_link
|
self.queue_link
|
||||||
.set(Some(self.state.seat_queue.add_last(self.clone())));
|
.set(Some(self.state.seat_queue.add_last(self.clone())));
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,22 @@ impl NodeSeatState {
|
||||||
self.kb_foci.len() > 0
|
self.kb_foci.len() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn release_kb_grab(&self) {
|
||||||
|
for (_, seat) in &self.kb_foci {
|
||||||
|
seat.ungrab_kb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release_kb_focus(&self) {
|
||||||
|
while let Some((_, seat)) = self.kb_foci.pop() {
|
||||||
|
seat.ungrab_kb();
|
||||||
|
seat.keyboard_node.set(seat.state.root.clone());
|
||||||
|
if let Some(tl) = seat.toplevel_focus_history.last() {
|
||||||
|
seat.focus_xdg_surface(&tl.xdg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn destroy_node(&self, node: &dyn Node) {
|
pub fn destroy_node(&self, node: &dyn Node) {
|
||||||
while let Some((_, seat)) = self.grabs.pop() {
|
while let Some((_, seat)) = self.grabs.pop() {
|
||||||
seat.pointer_owner.revert_to_default(&seat);
|
seat.pointer_owner.revert_to_default(&seat);
|
||||||
|
|
@ -94,12 +110,7 @@ impl NodeSeatState {
|
||||||
}
|
}
|
||||||
seat.state.tree_changed();
|
seat.state.tree_changed();
|
||||||
}
|
}
|
||||||
while let Some((_, seat)) = self.kb_foci.pop() {
|
self.release_kb_focus();
|
||||||
seat.keyboard_node.set(seat.state.root.clone());
|
|
||||||
if let Some(tl) = seat.toplevel_focus_history.last() {
|
|
||||||
seat.focus_xdg_surface(&tl.xdg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,8 +135,9 @@ impl WlSeatGlobal {
|
||||||
Some(o) => o,
|
Some(o) => o,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
x += Fixed::from_int(output.x.get());
|
let pos = output.position();
|
||||||
y += Fixed::from_int(output.y.get());
|
x += Fixed::from_int(pos.x1());
|
||||||
|
y += Fixed::from_int(pos.y1());
|
||||||
self.set_new_position(x, y);
|
self.set_new_position(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,21 +228,16 @@ impl WlSeatGlobal {
|
||||||
self.focus_node(xdg.focus_surface(self));
|
self.focus_node(xdg.focus_surface(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focus_node(self: &Rc<Self>, node: Rc<dyn Node>) {
|
fn ungrab_kb(self: &Rc<Self>) {
|
||||||
let old = self.keyboard_node.get();
|
self.kb_owner.ungrab(self);
|
||||||
if old.id() == node.id() {
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
old.unfocus(self);
|
|
||||||
if old.seat_state().unfocus(self) {
|
|
||||||
old.active_changed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if node.seat_state().focus(self) {
|
pub fn grab(self: &Rc<Self>, node: Rc<dyn Node>) {
|
||||||
node.active_changed(true);
|
self.kb_owner.grab(self, node);
|
||||||
}
|
}
|
||||||
node.clone().focus(self);
|
|
||||||
self.keyboard_node.set(node.clone());
|
pub fn focus_node(self: &Rc<Self>, node: Rc<dyn Node>) {
|
||||||
|
self.kb_owner.set_kb_node(self, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offer_selection<T: ipc::Vtable>(
|
fn offer_selection<T: ipc::Vtable>(
|
||||||
|
|
@ -380,7 +387,7 @@ impl WlSeatGlobal {
|
||||||
let serial = self.serial.fetch_add(1);
|
let serial = self.serial.fetch_add(1);
|
||||||
self.surface_pointer_event(0, surface, |p| p.send_button(serial, 0, button, state));
|
self.surface_pointer_event(0, surface, |p| p.send_button(serial, 0, button, state));
|
||||||
self.surface_pointer_frame(surface);
|
self.surface_pointer_frame(surface);
|
||||||
if pressed && surface.belongs_to_toplevel() {
|
if pressed && surface.accepts_kb_focus() {
|
||||||
self.focus_node(surface.clone());
|
self.focus_node(surface.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
85
src/ifs/wl_seat/kb_owner.rs
Normal file
85
src/ifs/wl_seat/kb_owner.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::CloneCell;
|
||||||
|
use crate::ifs::wl_seat::WlSeatGlobal;
|
||||||
|
use crate::tree::Node;
|
||||||
|
|
||||||
|
pub struct KbOwnerHolder {
|
||||||
|
default: Rc<DefaultKbOwner>,
|
||||||
|
owner: CloneCell<Rc<dyn KbOwner>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for KbOwnerHolder {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
default: Rc::new(DefaultKbOwner),
|
||||||
|
owner: CloneCell::new(Rc::new(DefaultKbOwner)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KbOwnerHolder {
|
||||||
|
pub fn grab(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) -> bool {
|
||||||
|
self.owner.get().grab(seat, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ungrab(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
self.owner.get().ungrab(seat)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) {
|
||||||
|
self.owner.get().set_kb_node(seat, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DefaultKbOwner;
|
||||||
|
|
||||||
|
struct GrabKbOwner;
|
||||||
|
|
||||||
|
trait KbOwner {
|
||||||
|
fn grab(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) -> bool;
|
||||||
|
fn ungrab(&self, seat: &Rc<WlSeatGlobal>);
|
||||||
|
fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KbOwner for DefaultKbOwner {
|
||||||
|
fn grab(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) -> bool {
|
||||||
|
self.set_kb_node(seat, node);
|
||||||
|
seat.kb_owner.owner.set(Rc::new(GrabKbOwner));
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ungrab(&self, _seat: &Rc<WlSeatGlobal>) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) {
|
||||||
|
let old = seat.keyboard_node.get();
|
||||||
|
if old.id() == node.id() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
old.unfocus(seat);
|
||||||
|
if old.seat_state().unfocus(seat) {
|
||||||
|
old.active_changed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if node.seat_state().focus(seat) {
|
||||||
|
node.active_changed(true);
|
||||||
|
}
|
||||||
|
node.clone().focus(seat);
|
||||||
|
seat.keyboard_node.set(node.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KbOwner for GrabKbOwner {
|
||||||
|
fn grab(&self, _seat: &Rc<WlSeatGlobal>, _node: Rc<dyn Node>) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ungrab(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
seat.kb_owner.owner.set(seat.kb_owner.default.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_kb_node(&self, _seat: &Rc<WlSeatGlobal>, _node: Rc<dyn Node>) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -147,9 +147,11 @@ impl PointerOwner for DefaultPointerOwner {
|
||||||
}
|
}
|
||||||
if (stack.len(), found_tree.len()) == (divergence, divergence) {
|
if (stack.len(), found_tree.len()) == (divergence, divergence) {
|
||||||
if let Some(node) = found_tree.last() {
|
if let Some(node) = found_tree.last() {
|
||||||
node.node
|
node.node.clone().pointer_motion(
|
||||||
.clone()
|
seat,
|
||||||
.pointer_motion(seat, x.apply_fract(node.x), y.apply_fract(node.y));
|
x.apply_fract(node.x),
|
||||||
|
y.apply_fract(node.y),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Some(last) = stack.last() {
|
if let Some(last) = stack.last() {
|
||||||
|
|
@ -161,16 +163,20 @@ impl PointerOwner for DefaultPointerOwner {
|
||||||
}
|
}
|
||||||
if found_tree.len() == divergence {
|
if found_tree.len() == divergence {
|
||||||
if let Some(node) = found_tree.last() {
|
if let Some(node) = found_tree.last() {
|
||||||
node.node
|
node.node.clone().pointer_motion(
|
||||||
.clone()
|
seat,
|
||||||
.pointer_motion(seat, x.apply_fract(node.x), y.apply_fract(node.y));
|
x.apply_fract(node.x),
|
||||||
|
y.apply_fract(node.y),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for new in found_tree.drain(divergence..) {
|
for new in found_tree.drain(divergence..) {
|
||||||
new.node.seat_state().enter(seat);
|
new.node.seat_state().enter(seat);
|
||||||
new.node
|
new.node.clone().pointer_enter(
|
||||||
.clone()
|
seat,
|
||||||
.pointer_enter(seat, x.apply_fract(new.x), y.apply_fract(new.y));
|
x.apply_fract(new.x),
|
||||||
|
y.apply_fract(new.y),
|
||||||
|
);
|
||||||
stack.push(new.node);
|
stack.push(new.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
pub mod wl_subsurface;
|
pub mod wl_subsurface;
|
||||||
pub mod xdg_surface;
|
pub mod xdg_surface;
|
||||||
|
pub mod zwlr_layer_surface_v1;
|
||||||
|
|
||||||
use crate::backend::{KeyState, ScrollAxis};
|
use crate::backend::{KeyState, ScrollAxis};
|
||||||
use crate::client::{Client, ClientError, RequestParser};
|
use crate::client::{Client, ClientError, RequestParser};
|
||||||
|
|
@ -34,6 +35,7 @@ use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1Error;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const INVALID_SCALE: u32 = 0;
|
const INVALID_SCALE: u32 = 0;
|
||||||
|
|
@ -49,6 +51,7 @@ pub enum SurfaceRole {
|
||||||
XdgSurface,
|
XdgSurface,
|
||||||
Cursor,
|
Cursor,
|
||||||
DndIcon,
|
DndIcon,
|
||||||
|
ZwlrLayerSurface,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SurfaceRole {
|
impl SurfaceRole {
|
||||||
|
|
@ -59,6 +62,7 @@ impl SurfaceRole {
|
||||||
SurfaceRole::XdgSurface => "xdg_surface",
|
SurfaceRole::XdgSurface => "xdg_surface",
|
||||||
SurfaceRole::Cursor => "cursor",
|
SurfaceRole::Cursor => "cursor",
|
||||||
SurfaceRole::DndIcon => "dnd_icon",
|
SurfaceRole::DndIcon => "dnd_icon",
|
||||||
|
SurfaceRole::ZwlrLayerSurface => "zwlr_layer_surface",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +115,7 @@ trait SurfaceExt {
|
||||||
Ok(CommitAction::ContinueCommit)
|
Ok(CommitAction::ContinueCommit)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_commit(&self) {
|
fn post_commit(self: Rc<Self>) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,6 +138,10 @@ trait SurfaceExt {
|
||||||
fn into_subsurface(self: Rc<Self>) -> Option<Rc<WlSubsurface>> {
|
fn into_subsurface(self: Rc<Self>) -> Option<Rc<WlSubsurface>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn accepts_kb_focus(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NoneSurfaceExt;
|
pub struct NoneSurfaceExt;
|
||||||
|
|
@ -222,11 +230,11 @@ impl WlSurface {
|
||||||
Ok(cursor)
|
Ok(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn belongs_to_toplevel(&self) -> bool {
|
pub fn accepts_kb_focus(&self) -> bool {
|
||||||
if let Some(xdg) = self.xdg.get() {
|
if let Some(xdg) = self.xdg.get() {
|
||||||
return xdg.role() == XdgSurfaceRole::XdgToplevel;
|
return xdg.role() == XdgSurfaceRole::XdgToplevel;
|
||||||
}
|
}
|
||||||
false
|
self.ext.get().accepts_kb_focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_enter(&self, output: WlOutputId) {
|
fn send_enter(&self, output: WlOutputId) {
|
||||||
|
|
@ -747,6 +755,8 @@ pub enum WlSurfaceError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ClientError(Box<ClientError>),
|
ClientError(Box<ClientError>),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
ZwlrLayerSurfaceV1Error(Box<ZwlrLayerSurfaceV1Error>),
|
||||||
|
#[error(transparent)]
|
||||||
XdgSurfaceError(Box<XdgSurfaceError>),
|
XdgSurfaceError(Box<XdgSurfaceError>),
|
||||||
#[error("Could not process `destroy` request")]
|
#[error("Could not process `destroy` request")]
|
||||||
DestroyError(#[source] Box<DestroyError>),
|
DestroyError(#[source] Box<DestroyError>),
|
||||||
|
|
@ -784,13 +794,10 @@ efrom!(WlSurfaceError, FrameError);
|
||||||
efrom!(WlSurfaceError, SetOpaqueRegionError);
|
efrom!(WlSurfaceError, SetOpaqueRegionError);
|
||||||
efrom!(WlSurfaceError, SetInputRegionError);
|
efrom!(WlSurfaceError, SetInputRegionError);
|
||||||
efrom!(WlSurfaceError, CommitError);
|
efrom!(WlSurfaceError, CommitError);
|
||||||
efrom!(
|
efrom!(WlSurfaceError, SetBufferTransformError);
|
||||||
WlSurfaceError,
|
|
||||||
SetBufferTransformError,
|
|
||||||
SetBufferTransformError
|
|
||||||
);
|
|
||||||
efrom!(WlSurfaceError, SetBufferScaleError);
|
efrom!(WlSurfaceError, SetBufferScaleError);
|
||||||
efrom!(WlSurfaceError, DamageBufferError);
|
efrom!(WlSurfaceError, DamageBufferError);
|
||||||
|
efrom!(WlSurfaceError, ZwlrLayerSurfaceV1Error);
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum DestroyError {
|
pub enum DestroyError {
|
||||||
|
|
|
||||||
|
|
@ -263,9 +263,8 @@ impl SurfaceExt for WlSubsurface {
|
||||||
Ok(CommitAction::ContinueCommit)
|
Ok(CommitAction::ContinueCommit)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_commit(&self) {
|
fn post_commit(self: Rc<Self>) {
|
||||||
if let Some(v) = self.pending.node.take() {
|
if let Some(v) = self.pending.node.take() {
|
||||||
log::info!("post commit");
|
|
||||||
v.pending.set(false);
|
v.pending.set(false);
|
||||||
self.node.borrow_mut().replace(v);
|
self.node.borrow_mut().replace(v);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -443,7 +443,7 @@ impl SurfaceExt for XdgSurface {
|
||||||
Ok(CommitAction::ContinueCommit)
|
Ok(CommitAction::ContinueCommit)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_commit(&self) {
|
fn post_commit(self: Rc<Self>) {
|
||||||
if let Some(ext) = self.ext.get() {
|
if let Some(ext) = self.ext.get() {
|
||||||
ext.post_commit();
|
ext.post_commit();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ use std::fmt::{Debug, Formatter};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use backtrace::Backtrace;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, FromPrimitive)]
|
#[derive(Copy, Clone, Debug, FromPrimitive)]
|
||||||
|
|
|
||||||
533
src/ifs/wl_surface/zwlr_layer_surface_v1.rs
Normal file
533
src/ifs/wl_surface/zwlr_layer_surface_v1.rs
Normal file
|
|
@ -0,0 +1,533 @@
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use crate::client::{Client, ClientError, ClientId};
|
||||||
|
use crate::ifs::wl_output::{WlOutput, WlOutputGlobal};
|
||||||
|
use crate::ifs::wl_surface::{CommitAction, CommitContext, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError};
|
||||||
|
use crate::ifs::zwlr_layer_shell_v1::{OVERLAY, ZwlrLayerShellV1};
|
||||||
|
use crate::leaks::Tracker;
|
||||||
|
use crate::object::Object;
|
||||||
|
use crate::utils::buffd::MsgParser;
|
||||||
|
use crate::utils::buffd::MsgParserError;
|
||||||
|
use crate::wire::zwlr_layer_surface_v1::*;
|
||||||
|
use crate::wire::{WlSurfaceId, ZwlrLayerSurfaceV1Id};
|
||||||
|
use std::rc::Rc;
|
||||||
|
use thiserror::Error;
|
||||||
|
use i4config::Direction;
|
||||||
|
use crate::ifs::wl_surface::wl_subsurface::WlSubsurface;
|
||||||
|
use crate::{CloneCell, NumCell};
|
||||||
|
use crate::backend::{KeyState, ScrollAxis};
|
||||||
|
use crate::fixed::Fixed;
|
||||||
|
use crate::ifs::wl_seat::{Dnd, NodeSeatState, WlSeatGlobal};
|
||||||
|
use crate::rect::Rect;
|
||||||
|
use crate::render::Renderer;
|
||||||
|
use crate::tree::{ContainerNode, ContainerSplit, FindTreeResult, FloatNode, FoundNode, Node, NodeId, OutputNode, WorkspaceNode};
|
||||||
|
use crate::tree::walker::NodeVisitor;
|
||||||
|
use crate::utils::bitflags::BitflagsExt;
|
||||||
|
use crate::utils::linkedlist::LinkedNode;
|
||||||
|
|
||||||
|
const KI_NONE: u32 = 0;
|
||||||
|
#[allow(dead_code)]
|
||||||
|
const KI_EXCLUSIVE: u32 = 1;
|
||||||
|
const KI_ON_DEMAND: u32 = 2;
|
||||||
|
|
||||||
|
const TOP: u32 = 1;
|
||||||
|
const BOTTOM: u32 = 2;
|
||||||
|
const LEFT: u32 = 4;
|
||||||
|
const RIGHT: u32 = 8;
|
||||||
|
|
||||||
|
tree_id!(ZwlrLayerSurfaceV1NodeId);
|
||||||
|
pub struct ZwlrLayerSurfaceV1 {
|
||||||
|
pub id: ZwlrLayerSurfaceV1Id,
|
||||||
|
node_id: ZwlrLayerSurfaceV1NodeId,
|
||||||
|
pub shell: Rc<ZwlrLayerShellV1>,
|
||||||
|
pub client: Rc<Client>,
|
||||||
|
pub surface: Rc<WlSurface>,
|
||||||
|
pub output: Rc<OutputNode>,
|
||||||
|
pub namespace: String,
|
||||||
|
pub tracker: Tracker<Self>,
|
||||||
|
pos: Cell<Rect>,
|
||||||
|
mapped: Cell<bool>,
|
||||||
|
layer: Cell<u32>,
|
||||||
|
pending: Pending,
|
||||||
|
requested_serial: NumCell<u32>,
|
||||||
|
acked_serial: Cell<Option<u32>>,
|
||||||
|
size: Cell<(i32, i32)>,
|
||||||
|
anchor: Cell<u32>,
|
||||||
|
exclusive_zone: Cell<i32>,
|
||||||
|
margin: Cell<(i32, i32, i32, i32)>,
|
||||||
|
keyboard_interactivity: Cell<u32>,
|
||||||
|
link: Cell<Option<LinkedNode<Rc<Self>>>>,
|
||||||
|
seat_state: NodeSeatState,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Pending {
|
||||||
|
size: Cell<Option<(i32, i32)>>,
|
||||||
|
anchor: Cell<Option<u32>>,
|
||||||
|
exclusive_zone: Cell<Option<i32>>,
|
||||||
|
margin: Cell<Option<(i32, i32, i32, i32)>>,
|
||||||
|
keyboard_interactivity: Cell<Option<u32>>,
|
||||||
|
layer: Cell<Option<u32>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwlrLayerSurfaceV1 {
|
||||||
|
pub fn new(
|
||||||
|
id: ZwlrLayerSurfaceV1Id,
|
||||||
|
shell: &Rc<ZwlrLayerShellV1>,
|
||||||
|
surface: &Rc<WlSurface>,
|
||||||
|
output: &Rc<OutputNode>,
|
||||||
|
layer: u32,
|
||||||
|
namespace: &str,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
id,
|
||||||
|
node_id: shell.client.state.node_ids.next(),
|
||||||
|
shell: shell.clone(),
|
||||||
|
client: shell.client.clone(),
|
||||||
|
surface: surface.clone(),
|
||||||
|
output: output.clone(),
|
||||||
|
namespace: namespace.to_string(),
|
||||||
|
tracker: Default::default(),
|
||||||
|
pos: Cell::new(Default::default()),
|
||||||
|
mapped: Cell::new(false),
|
||||||
|
layer: Cell::new(layer),
|
||||||
|
pending: Default::default(),
|
||||||
|
requested_serial: Default::default(),
|
||||||
|
acked_serial: Cell::new(None),
|
||||||
|
size: Cell::new((0, 0)),
|
||||||
|
anchor: Cell::new(0),
|
||||||
|
exclusive_zone: Cell::new(0),
|
||||||
|
margin: Cell::new((0, 0, 0, 0)),
|
||||||
|
keyboard_interactivity: Cell::new(0),
|
||||||
|
link: Cell::new(None),
|
||||||
|
seat_state: Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install(self: &Rc<Self>) -> Result<(), ZwlrLayerSurfaceV1Error> {
|
||||||
|
self.surface.set_role(SurfaceRole::ZwlrLayerSurface)?;
|
||||||
|
if self.surface.ext.get().is_some() {
|
||||||
|
return Err(ZwlrLayerSurfaceV1Error::AlreadyAttached(self.surface.id));
|
||||||
|
}
|
||||||
|
self.surface.ext.set(self.clone());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_configure(&self, serial: u32, width: u32, height: u32) {
|
||||||
|
self.client.event(Configure {
|
||||||
|
self_id: self.id,
|
||||||
|
serial,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn send_closed(&self) {
|
||||||
|
self.client.event(Closed { self_id: self.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_size(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSizeError> {
|
||||||
|
let req: SetSize = self.client.parse(self, parser)?;
|
||||||
|
if req.width > u16::MAX as u32 || req.height > u16::MAX as u32 {
|
||||||
|
return Err(SetSizeError::ExcessiveSize);
|
||||||
|
}
|
||||||
|
self.pending.size.set(Some((req.width as _, req.height as _)));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_anchor(&self, parser: MsgParser<'_, '_>) -> Result<(), SetAnchorError> {
|
||||||
|
let req: SetAnchor = self.client.parse(self, parser)?;
|
||||||
|
if req.anchor & !(LEFT | RIGHT | TOP | BOTTOM) != 0 {
|
||||||
|
return Err(SetAnchorError::UnknownAnchor(req.anchor));
|
||||||
|
}
|
||||||
|
self.pending.anchor.set(Some(req.anchor));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_exclusive_zone(&self, parser: MsgParser<'_, '_>) -> Result<(), SetExclusiveZoneError> {
|
||||||
|
let req: SetExclusiveZone = self.client.parse(self, parser)?;
|
||||||
|
self.pending.exclusive_zone.set(Some(req.zone));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_margin(&self, parser: MsgParser<'_, '_>) -> Result<(), SetMarginError> {
|
||||||
|
let req: SetMargin = self.client.parse(self, parser)?;
|
||||||
|
self.pending.margin.set(Some((req.top, req.right, req.bottom, req.left)));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_keyboard_interactivity(&self, parser: MsgParser<'_, '_>) -> Result<(), SetKeyboardInteractivityError> {
|
||||||
|
let req: SetKeyboardInteractivity = self.client.parse(self, parser)?;
|
||||||
|
if req.keyboard_interactivity > KI_ON_DEMAND {
|
||||||
|
return Err(SetKeyboardInteractivityError::UnknownKi(req.keyboard_interactivity));
|
||||||
|
}
|
||||||
|
self.pending.keyboard_interactivity.set(Some(req.keyboard_interactivity));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_popup(&self, parser: MsgParser<'_, '_>) -> Result<(), GetPopupError> {
|
||||||
|
let _req: GetPopup = self.client.parse(self, parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ack_configure(&self, parser: MsgParser<'_, '_>) -> Result<(), AckConfigureError> {
|
||||||
|
let req: AckConfigure = self.client.parse(self, parser)?;
|
||||||
|
self.acked_serial.set(Some(req.serial));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||||
|
let _req: Destroy = self.client.parse(self, parser)?;
|
||||||
|
self.destroy_node(true);
|
||||||
|
self.client.remove_obj(self)?;
|
||||||
|
self.surface.unset_ext();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_layer(&self, parser: MsgParser<'_, '_>) -> Result<(), SetLayerError> {
|
||||||
|
let req: SetLayer = self.client.parse(self, parser)?;
|
||||||
|
if req.layer > OVERLAY {
|
||||||
|
return Err(SetLayerError::UnknownLayer(req.layer));
|
||||||
|
}
|
||||||
|
self.pending.layer.set(Some(req.layer));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pre_commit(&self) -> Result<(), ZwlrLayerSurfaceV1Error> {
|
||||||
|
let mut send_configure = false;
|
||||||
|
if let Some(size) = self.pending.size.take() {
|
||||||
|
self.size.set(size);
|
||||||
|
}
|
||||||
|
if let Some(anchor) = self.pending.anchor.take() {
|
||||||
|
self.anchor.set(anchor);
|
||||||
|
}
|
||||||
|
if let Some(ez) = self.pending.exclusive_zone.take() {
|
||||||
|
self.exclusive_zone.set(ez);
|
||||||
|
}
|
||||||
|
if let Some(margin) = self.pending.margin.take() {
|
||||||
|
self.margin.set(margin);
|
||||||
|
}
|
||||||
|
if let Some(ki) = self.pending.keyboard_interactivity.take() {
|
||||||
|
self.keyboard_interactivity.set(ki);
|
||||||
|
}
|
||||||
|
if let Some(layer) = self.pending.layer.take() {
|
||||||
|
self.layer.set(layer);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let (mut width, mut height) = self.size.get();
|
||||||
|
let anchor = self.anchor.get();
|
||||||
|
if width == 0 {
|
||||||
|
if !anchor.contains(LEFT | RIGHT) {
|
||||||
|
return Err(ZwlrLayerSurfaceV1Error::WidthZero);
|
||||||
|
}
|
||||||
|
send_configure = true;
|
||||||
|
width = self.output.global.position().width();
|
||||||
|
}
|
||||||
|
if height == 0 {
|
||||||
|
if !anchor.contains(TOP | BOTTOM) {
|
||||||
|
return Err(ZwlrLayerSurfaceV1Error::HeightZero);
|
||||||
|
}
|
||||||
|
send_configure = true;
|
||||||
|
height = self.output.global.position().height();
|
||||||
|
}
|
||||||
|
self.size.set((width, height));
|
||||||
|
}
|
||||||
|
if self.acked_serial.get().is_none() {
|
||||||
|
send_configure = true;
|
||||||
|
}
|
||||||
|
if send_configure {
|
||||||
|
let (width, height) = self.size.get();
|
||||||
|
let serial = self.requested_serial.fetch_add(1) + 1;
|
||||||
|
self.send_configure(serial, width as _, height as _);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn position(&self) -> Rect {
|
||||||
|
self.pos.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_position(&self) {
|
||||||
|
let (width, height) = self.size.get();
|
||||||
|
let mut anchor = self.anchor.get();
|
||||||
|
if anchor == 0 {
|
||||||
|
anchor = LEFT | RIGHT | TOP | BOTTOM;
|
||||||
|
}
|
||||||
|
let opos = self.output.position.get();
|
||||||
|
let mut x1 = opos.x1();
|
||||||
|
let mut y1 = opos.y1();
|
||||||
|
if anchor.contains(LEFT) {
|
||||||
|
if anchor.contains(RIGHT) {
|
||||||
|
x1 += (opos.width() - width) / 2;
|
||||||
|
}
|
||||||
|
} else if anchor.contains(RIGHT) {
|
||||||
|
x1 += opos.width() - width;
|
||||||
|
}
|
||||||
|
if anchor.contains(TOP) {
|
||||||
|
if anchor.contains(BOTTOM) {
|
||||||
|
y1 += (opos.height() - height) / 2;
|
||||||
|
}
|
||||||
|
} else if anchor.contains(BOTTOM) {
|
||||||
|
y1 += opos.height() - height;
|
||||||
|
}
|
||||||
|
self.pos.set(Rect::new_sized(x1, y1, width, height).unwrap());
|
||||||
|
self.client.state.tree_changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SurfaceExt for ZwlrLayerSurfaceV1 {
|
||||||
|
fn pre_commit(self: Rc<Self>, _ctx: CommitContext) -> Result<CommitAction, WlSurfaceError> {
|
||||||
|
self.deref().pre_commit()?;
|
||||||
|
Ok(CommitAction::ContinueCommit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn post_commit(self: Rc<Self>) {
|
||||||
|
let buffer = self.surface.buffer.get();
|
||||||
|
if self.mapped.get() {
|
||||||
|
if buffer.is_none() {
|
||||||
|
self.destroy_node(true);
|
||||||
|
} else {
|
||||||
|
let pos = self.pos.get();
|
||||||
|
let (width, height) = self.size.get();
|
||||||
|
if width != pos.width() || height != pos.height() {
|
||||||
|
self.compute_position();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if buffer.is_some() {
|
||||||
|
let layer = &self.output.layers[self.layer.get() as usize];
|
||||||
|
self.link.set(Some(layer.add_last(self.clone())));
|
||||||
|
self.mapped.set(true);
|
||||||
|
self.compute_position();
|
||||||
|
}
|
||||||
|
if self.mapped.get() {
|
||||||
|
match self.keyboard_interactivity.get() {
|
||||||
|
KI_NONE => {
|
||||||
|
let was_active = self.surface.seat_state.is_active();
|
||||||
|
self.surface.seat_state.release_kb_focus();
|
||||||
|
if was_active {
|
||||||
|
self.surface.active_changed(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
KI_ON_DEMAND => self.surface.seat_state.release_kb_grab(),
|
||||||
|
KI_EXCLUSIVE => {
|
||||||
|
let seats = self.client.state.globals.seats.lock();
|
||||||
|
for seat in seats.values() {
|
||||||
|
seat.grab(self.surface.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accepts_kb_focus(&self) -> bool {
|
||||||
|
self.keyboard_interactivity.get() != KI_NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Node for ZwlrLayerSurfaceV1 {
|
||||||
|
fn id(&self) -> NodeId {
|
||||||
|
self.node_id.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seat_state(&self) -> &NodeSeatState {
|
||||||
|
&self.seat_state
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy_node(&self, _detach: bool) {
|
||||||
|
self.link.set(None);
|
||||||
|
self.mapped.set(false);
|
||||||
|
self.surface.destroy_node(false);
|
||||||
|
self.seat_state.destroy_node(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor) {
|
||||||
|
visitor.visit_layer_surface(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_children(&self, visitor: &mut dyn NodeVisitor) {
|
||||||
|
self.surface.clone().visit(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||||
|
renderer.render_layer_surface(self, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn absolute_position(&self) -> Rect {
|
||||||
|
self.pos.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
|
tree.push(FoundNode {
|
||||||
|
node: self.surface.clone(),
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
});
|
||||||
|
self.surface.find_tree_at(x, y, tree)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_extents(self: Rc<Self>, _rect: &Rect) {
|
||||||
|
self.compute_position();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object_base! {
|
||||||
|
ZwlrLayerSurfaceV1, ZwlrLayerSurfaceV1Error;
|
||||||
|
|
||||||
|
SET_SIZE => set_size,
|
||||||
|
SET_ANCHOR => set_anchor,
|
||||||
|
SET_EXCLUSIVE_ZONE => set_exclusive_zone,
|
||||||
|
SET_MARGIN => set_margin,
|
||||||
|
SET_KEYBOARD_INTERACTIVITY => set_keyboard_interactivity,
|
||||||
|
GET_POPUP => get_popup,
|
||||||
|
ACK_CONFIGURE => ack_configure,
|
||||||
|
DESTROY => destroy,
|
||||||
|
SET_LAYER => set_layer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Object for ZwlrLayerSurfaceV1 {
|
||||||
|
fn num_requests(&self) -> u32 {
|
||||||
|
let last_req = match self.shell.version {
|
||||||
|
0..=1 => DESTROY,
|
||||||
|
_ => SET_LAYER,
|
||||||
|
};
|
||||||
|
last_req + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn break_loops(&self) {
|
||||||
|
self.destroy_node(true);
|
||||||
|
self.link.set(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_add_obj!(ZwlrLayerSurfaceV1);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ZwlrLayerSurfaceV1Error {
|
||||||
|
#[error("Could not process `set_size` request")]
|
||||||
|
SetSizeError(#[from] SetSizeError),
|
||||||
|
#[error("Could not process `set_anchor` request")]
|
||||||
|
SetAnchorError(#[from] SetAnchorError),
|
||||||
|
#[error("Could not process `set_exclusive_zone` request")]
|
||||||
|
SetExclusiveZoneError(#[from] SetExclusiveZoneError),
|
||||||
|
#[error("Could not process `set_margin` request")]
|
||||||
|
SetMarginError(#[from] SetMarginError),
|
||||||
|
#[error("Could not process `set_keyboard_interactivity` request")]
|
||||||
|
SetKeyboardInteractivityError(#[from] SetKeyboardInteractivityError),
|
||||||
|
#[error("Could not process `get_popup` request")]
|
||||||
|
GetPopupError(#[from] GetPopupError),
|
||||||
|
#[error("Could not process `ack_configure` request")]
|
||||||
|
AckConfigureError(#[from] AckConfigureError),
|
||||||
|
#[error("Could not process `destroy` request")]
|
||||||
|
DestroyError(#[from] DestroyError),
|
||||||
|
#[error("Could not process `set_layer` request")]
|
||||||
|
SetLayerError(#[from] SetLayerError),
|
||||||
|
#[error("Surface {0} cannot be turned into a zwlr_layer_surface because it already has an attached zwlr_layer_surface")]
|
||||||
|
AlreadyAttached(WlSurfaceId),
|
||||||
|
#[error("Width was set to 0 but anchor did not contain LEFT and RIGHT")]
|
||||||
|
WidthZero,
|
||||||
|
#[error("Height was set to 0 but anchor did not contain TOP and BOTTOM")]
|
||||||
|
HeightZero,
|
||||||
|
#[error(transparent)]
|
||||||
|
WlSurfaceError(Box<WlSurfaceError>),
|
||||||
|
}
|
||||||
|
efrom!(ZwlrLayerSurfaceV1Error, WlSurfaceError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SetSizeError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Surface size must not be larger than 65535x65535")]
|
||||||
|
ExcessiveSize,
|
||||||
|
}
|
||||||
|
efrom!(SetSizeError, MsgParserError);
|
||||||
|
efrom!(SetSizeError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SetAnchorError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Unknown anchor {0}")]
|
||||||
|
UnknownAnchor(u32),
|
||||||
|
}
|
||||||
|
efrom!(SetAnchorError, MsgParserError);
|
||||||
|
efrom!(SetAnchorError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SetExclusiveZoneError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(SetExclusiveZoneError, MsgParserError);
|
||||||
|
efrom!(SetExclusiveZoneError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SetMarginError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(SetMarginError, MsgParserError);
|
||||||
|
efrom!(SetMarginError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SetKeyboardInteractivityError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Unknown keyboard interactivity {0}")]
|
||||||
|
UnknownKi(u32),
|
||||||
|
}
|
||||||
|
efrom!(SetKeyboardInteractivityError, MsgParserError);
|
||||||
|
efrom!(SetKeyboardInteractivityError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum GetPopupError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(GetPopupError, MsgParserError);
|
||||||
|
efrom!(GetPopupError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum AckConfigureError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(AckConfigureError, MsgParserError);
|
||||||
|
efrom!(AckConfigureError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum DestroyError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(DestroyError, MsgParserError);
|
||||||
|
efrom!(DestroyError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SetLayerError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Unknown layer {0}")]
|
||||||
|
UnknownLayer(u32),
|
||||||
|
}
|
||||||
|
efrom!(SetLayerError, MsgParserError);
|
||||||
|
efrom!(SetLayerError, ClientError);
|
||||||
176
src/ifs/zwlr_layer_shell_v1.rs
Normal file
176
src/ifs/zwlr_layer_shell_v1.rs
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
use crate::client::{Client, ClientError};
|
||||||
|
use crate::globals::{Global, GlobalName};
|
||||||
|
use crate::ifs::wl_surface::zwlr_layer_surface_v1::{ZwlrLayerSurfaceV1, ZwlrLayerSurfaceV1Error};
|
||||||
|
use crate::leaks::Tracker;
|
||||||
|
use crate::object::Object;
|
||||||
|
use crate::utils::buffd::MsgParser;
|
||||||
|
use crate::utils::buffd::MsgParserError;
|
||||||
|
use crate::wire::zwlr_layer_shell_v1::*;
|
||||||
|
use crate::wire::ZwlrLayerShellV1Id;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const BACKGROUND: u32 = 0;
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const BOTTOM: u32 = 1;
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const TOP: u32 = 2;
|
||||||
|
pub const OVERLAY: u32 = 3;
|
||||||
|
|
||||||
|
pub struct ZwlrLayerShellV1Global {
|
||||||
|
name: GlobalName,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ZwlrLayerShellV1 {
|
||||||
|
pub id: ZwlrLayerShellV1Id,
|
||||||
|
pub client: Rc<Client>,
|
||||||
|
pub version: u32,
|
||||||
|
pub tracker: Tracker<Self>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwlrLayerShellV1Global {
|
||||||
|
pub fn new(name: GlobalName) -> Self {
|
||||||
|
Self { name }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_(
|
||||||
|
self: Rc<Self>,
|
||||||
|
id: ZwlrLayerShellV1Id,
|
||||||
|
client: &Rc<Client>,
|
||||||
|
version: u32,
|
||||||
|
) -> Result<(), ZwlrLayerShellV1Error> {
|
||||||
|
let obj = Rc::new(ZwlrLayerShellV1 {
|
||||||
|
id,
|
||||||
|
client: client.clone(),
|
||||||
|
version,
|
||||||
|
tracker: Default::default(),
|
||||||
|
});
|
||||||
|
track!(client, obj);
|
||||||
|
client.add_client_obj(&obj)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZwlrLayerShellV1 {
|
||||||
|
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||||
|
let _req: Destroy = self.client.parse(self, parser)?;
|
||||||
|
self.client.remove_obj(self)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_layer_surface(
|
||||||
|
self: &Rc<Self>,
|
||||||
|
parser: MsgParser<'_, '_>,
|
||||||
|
) -> Result<(), GetLayerSurfaceError> {
|
||||||
|
let req: GetLayerSurface = self.client.parse(&**self, parser)?;
|
||||||
|
let surface = self.client.lookup(req.surface)?;
|
||||||
|
let output = 'get_output: {
|
||||||
|
if req.output.is_some() {
|
||||||
|
self.client.lookup(req.output)?.global.node.get().unwrap()
|
||||||
|
} else {
|
||||||
|
for seat in self.client.state.seat_queue.rev_iter() {
|
||||||
|
if let Some(output) = seat.get_output() {
|
||||||
|
break 'get_output output.node.get().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let outputs = self.client.state.outputs.lock();
|
||||||
|
match outputs.values().next() {
|
||||||
|
Some(ou) => ou.node.get().unwrap(),
|
||||||
|
_ => return Err(GetLayerSurfaceError::NoOutputs),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if req.layer > OVERLAY {
|
||||||
|
return Err(GetLayerSurfaceError::UnknownLayer(req.layer));
|
||||||
|
}
|
||||||
|
let surface = Rc::new(ZwlrLayerSurfaceV1::new(
|
||||||
|
req.id,
|
||||||
|
self,
|
||||||
|
&surface,
|
||||||
|
&output,
|
||||||
|
req.layer,
|
||||||
|
req.namespace,
|
||||||
|
));
|
||||||
|
track!(self.client, surface);
|
||||||
|
self.client.add_client_obj(&surface)?;
|
||||||
|
surface.install()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global_base!(
|
||||||
|
ZwlrLayerShellV1Global,
|
||||||
|
ZwlrLayerShellV1,
|
||||||
|
ZwlrLayerShellV1Error
|
||||||
|
);
|
||||||
|
|
||||||
|
impl Global for ZwlrLayerShellV1Global {
|
||||||
|
fn singleton(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn version(&self) -> u32 {
|
||||||
|
4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_add_global!(ZwlrLayerShellV1Global);
|
||||||
|
|
||||||
|
object_base! {
|
||||||
|
ZwlrLayerShellV1, ZwlrLayerShellV1Error;
|
||||||
|
|
||||||
|
GET_LAYER_SURFACE => get_layer_surface,
|
||||||
|
DESTROY => destroy,
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_add_obj!(ZwlrLayerShellV1);
|
||||||
|
|
||||||
|
impl Object for ZwlrLayerShellV1 {
|
||||||
|
fn num_requests(&self) -> u32 {
|
||||||
|
let last_request = if self.version >= 3 {
|
||||||
|
DESTROY
|
||||||
|
} else {
|
||||||
|
GET_LAYER_SURFACE
|
||||||
|
};
|
||||||
|
last_request + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ZwlrLayerShellV1Error {
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Could not process a `destroy` request")]
|
||||||
|
DestroyError(#[from] DestroyError),
|
||||||
|
#[error("Could not process a `get_layer_surface` request")]
|
||||||
|
GetLayerSurfaceError(#[from] GetLayerSurfaceError),
|
||||||
|
}
|
||||||
|
efrom!(ZwlrLayerShellV1Error, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum DestroyError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
ParseError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(DestroyError, ParseError, MsgParserError);
|
||||||
|
efrom!(DestroyError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum GetLayerSurfaceError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
ParseError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Unknown layer {0}")]
|
||||||
|
UnknownLayer(u32),
|
||||||
|
#[error("There are no outputs")]
|
||||||
|
NoOutputs,
|
||||||
|
#[error(transparent)]
|
||||||
|
ZwlrLayerSurfaceV1Error(Box<ZwlrLayerSurfaceV1Error>),
|
||||||
|
}
|
||||||
|
efrom!(GetLayerSurfaceError, ParseError, MsgParserError);
|
||||||
|
efrom!(GetLayerSurfaceError, ClientError);
|
||||||
|
efrom!(GetLayerSurfaceError, ZwlrLayerSurfaceV1Error);
|
||||||
137
src/ifs/zxdg_output_manager_v1.rs
Normal file
137
src/ifs/zxdg_output_manager_v1.rs
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
use crate::client::{Client, ClientError};
|
||||||
|
use crate::globals::{Global, GlobalName};
|
||||||
|
use crate::leaks::Tracker;
|
||||||
|
use crate::object::Object;
|
||||||
|
use crate::utils::buffd::MsgParser;
|
||||||
|
use crate::utils::buffd::MsgParserError;
|
||||||
|
use crate::wire::zxdg_output_manager_v1::*;
|
||||||
|
use crate::wire::{ZxdgOutputManagerV1Id};
|
||||||
|
use std::rc::Rc;
|
||||||
|
use thiserror::Error;
|
||||||
|
use crate::ifs::zxdg_output_v1::ZxdgOutputV1;
|
||||||
|
|
||||||
|
pub struct ZxdgOutputManagerV1Global {
|
||||||
|
name: GlobalName,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ZxdgOutputManagerV1 {
|
||||||
|
pub id: ZxdgOutputManagerV1Id,
|
||||||
|
pub client: Rc<Client>,
|
||||||
|
pub version: u32,
|
||||||
|
pub tracker: Tracker<Self>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZxdgOutputManagerV1Global {
|
||||||
|
pub fn new(name: GlobalName) -> Self {
|
||||||
|
Self { name }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_(
|
||||||
|
self: Rc<Self>,
|
||||||
|
id: ZxdgOutputManagerV1Id,
|
||||||
|
client: &Rc<Client>,
|
||||||
|
version: u32,
|
||||||
|
) -> Result<(), ZxdgOutputManagerV1Error> {
|
||||||
|
let obj = Rc::new(ZxdgOutputManagerV1 {
|
||||||
|
id,
|
||||||
|
client: client.clone(),
|
||||||
|
version,
|
||||||
|
tracker: Default::default(),
|
||||||
|
});
|
||||||
|
track!(client, obj);
|
||||||
|
client.add_client_obj(&obj)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZxdgOutputManagerV1 {
|
||||||
|
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||||
|
let _req: Destroy = self.client.parse(self, parser)?;
|
||||||
|
self.client.remove_obj(self)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_xdg_output(
|
||||||
|
self: &Rc<Self>,
|
||||||
|
parser: MsgParser<'_, '_>,
|
||||||
|
) -> Result<(), GetXdgOutputError> {
|
||||||
|
let req: GetXdgOutput = self.client.parse(&**self, parser)?;
|
||||||
|
let output = self.client.lookup(req.output)?;
|
||||||
|
let xdg_output = Rc::new(ZxdgOutputV1 {
|
||||||
|
id: req.id,
|
||||||
|
version: self.version,
|
||||||
|
client: self.client.clone(),
|
||||||
|
output: output.clone(),
|
||||||
|
tracker: Default::default()
|
||||||
|
});
|
||||||
|
track!(self.client, xdg_output);
|
||||||
|
self.client.add_client_obj(&xdg_output)?;
|
||||||
|
xdg_output.send_updates();
|
||||||
|
output.xdg_outputs.set(req.id, xdg_output);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global_base!(
|
||||||
|
ZxdgOutputManagerV1Global,
|
||||||
|
ZxdgOutputManagerV1,
|
||||||
|
ZxdgOutputManagerV1Error
|
||||||
|
);
|
||||||
|
|
||||||
|
impl Global for ZxdgOutputManagerV1Global {
|
||||||
|
fn singleton(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn version(&self) -> u32 {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_add_global!(ZxdgOutputManagerV1Global);
|
||||||
|
|
||||||
|
object_base! {
|
||||||
|
ZxdgOutputManagerV1, ZxdgOutputManagerV1Error;
|
||||||
|
|
||||||
|
DESTROY => destroy,
|
||||||
|
GET_XDG_OUTPUT => get_xdg_output,
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_add_obj!(ZxdgOutputManagerV1);
|
||||||
|
|
||||||
|
impl Object for ZxdgOutputManagerV1 {
|
||||||
|
fn num_requests(&self) -> u32 {
|
||||||
|
GET_XDG_OUTPUT + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ZxdgOutputManagerV1Error {
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
#[error("Could not process a `destroy` request")]
|
||||||
|
DestroyError(#[from] DestroyError),
|
||||||
|
#[error("Could not process a `get_xdg_output` request")]
|
||||||
|
GetXdgOutputError(#[from] GetXdgOutputError),
|
||||||
|
}
|
||||||
|
efrom!(ZxdgOutputManagerV1Error, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum DestroyError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
ParseError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(DestroyError, ParseError, MsgParserError);
|
||||||
|
efrom!(DestroyError, ClientError);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum GetXdgOutputError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
ParseError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(GetXdgOutputError, ParseError, MsgParserError);
|
||||||
|
efrom!(GetXdgOutputError, ClientError);
|
||||||
107
src/ifs/zxdg_output_v1.rs
Normal file
107
src/ifs/zxdg_output_v1.rs
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
use thiserror::Error;
|
||||||
|
use crate::client::{Client, ClientError};
|
||||||
|
use crate::ifs::wl_output::{SEND_DONE_SINCE, WlOutput};
|
||||||
|
use crate::leaks::Tracker;
|
||||||
|
use crate::object::Object;
|
||||||
|
use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||||
|
use crate::wire::ZxdgOutputV1Id;
|
||||||
|
use crate::wire::zxdg_output_v1::*;
|
||||||
|
|
||||||
|
pub const NAME_SINCE: u32 = 2;
|
||||||
|
pub const DESCRIPTION_SINCE: u32 = 2;
|
||||||
|
pub const NO_DONE_SINCE: u32 = 3;
|
||||||
|
|
||||||
|
pub struct ZxdgOutputV1 {
|
||||||
|
pub id: ZxdgOutputV1Id,
|
||||||
|
pub version: u32,
|
||||||
|
pub client: Rc<Client>,
|
||||||
|
pub output: Rc<WlOutput>,
|
||||||
|
pub tracker: Tracker<Self>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZxdgOutputV1 {
|
||||||
|
pub fn send_logical_position(&self, x: i32, y: i32) {
|
||||||
|
self.client.event(LogicalPosition {
|
||||||
|
self_id: self.id,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_logical_size(&self, width: i32, height: i32) {
|
||||||
|
self.client.event(LogicalSize {
|
||||||
|
self_id: self.id,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_done(&self) {
|
||||||
|
self.client.event(Done {
|
||||||
|
self_id: self.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_name(&self, name: &str) {
|
||||||
|
self.client.event(Name {
|
||||||
|
self_id: self.id,
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_description(&self, description: &str) {
|
||||||
|
self.client.event(Description {
|
||||||
|
self_id: self.id,
|
||||||
|
description,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_updates(&self) {
|
||||||
|
let pos = self.output.global.position();
|
||||||
|
self.send_logical_position(pos.x1(), pos.y1());
|
||||||
|
self.send_logical_size(pos.width(), pos.height());
|
||||||
|
if self.version >= NO_DONE_SINCE || self.output.version < SEND_DONE_SINCE {
|
||||||
|
self.output.send_done();
|
||||||
|
} else {
|
||||||
|
self.send_done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(&self, msg: MsgParser) -> Result<(), DestroyError> {
|
||||||
|
let _req: Destroy = self.client.parse(self, msg)?;
|
||||||
|
self.output.xdg_outputs.remove(&self.id);
|
||||||
|
self.client.remove_obj(self)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object_base! {
|
||||||
|
ZxdgOutputV1, ZxdgOutputV1Error;
|
||||||
|
|
||||||
|
DESTROY => destroy,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Object for ZxdgOutputV1 {
|
||||||
|
fn num_requests(&self) -> u32 {
|
||||||
|
DESTROY + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_add_obj!(ZxdgOutputV1);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ZxdgOutputV1Error {
|
||||||
|
#[error("Could not process a `destroy` request")]
|
||||||
|
DestroyError(#[from] DestroyError),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum DestroyError {
|
||||||
|
#[error("Parsing failed")]
|
||||||
|
MsgParserError(#[source] Box<MsgParserError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
ClientError(Box<ClientError>),
|
||||||
|
}
|
||||||
|
efrom!(DestroyError, MsgParserError);
|
||||||
|
efrom!(DestroyError, ClientError);
|
||||||
|
|
@ -44,14 +44,14 @@ macro_rules! object_base {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interface(&self) -> crate::object::Interface {
|
fn interface(&self) -> crate::object::Interface {
|
||||||
crate::object::Interface::$oname
|
crate::wire::$oname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$ename> for crate::client::ObjectError {
|
impl From<$ename> for crate::client::ObjectError {
|
||||||
fn from(v: $ename) -> Self {
|
fn from(v: $ename) -> Self {
|
||||||
Self {
|
Self {
|
||||||
interface: crate::object::Interface::$oname,
|
interface: crate::wire::$oname,
|
||||||
error: Box::new(v),
|
error: Box::new(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,14 +79,14 @@ macro_rules! global_base {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interface(&self) -> crate::object::Interface {
|
fn interface(&self) -> crate::object::Interface {
|
||||||
crate::object::Interface::$ifname
|
crate::wire::$ifname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$ename> for crate::globals::GlobalError {
|
impl From<$ename> for crate::globals::GlobalError {
|
||||||
fn from(e: $ename) -> Self {
|
fn from(e: $ename) -> Self {
|
||||||
Self {
|
Self {
|
||||||
interface: crate::object::Interface::$ifname,
|
interface: crate::wire::$ifname,
|
||||||
error: Box::new(e),
|
error: Box::new(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +281,7 @@ macro_rules! dedicated_add_obj {
|
||||||
|
|
||||||
impl crate::client::WaylandObjectLookup for $idname {
|
impl crate::client::WaylandObjectLookup for $idname {
|
||||||
type Object = $oname;
|
type Object = $oname;
|
||||||
const INTERFACE: crate::object::Interface = crate::object::Interface::$oname;
|
const INTERFACE: crate::object::Interface = crate::wire::$oname;
|
||||||
|
|
||||||
fn lookup(client: &crate::client::Client, id: Self) -> Option<Rc<$oname>> {
|
fn lookup(client: &crate::client::Client, id: Self) -> Option<Rc<$oname>> {
|
||||||
client.objects.$field.get(&id)
|
client.objects.$field.get(&id)
|
||||||
|
|
|
||||||
|
|
@ -42,91 +42,11 @@ pub trait Object: ObjectBase + 'static {
|
||||||
fn break_loops(&self) {}
|
fn break_loops(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum Interface {
|
pub struct Interface(pub &'static str);
|
||||||
WlDisplay,
|
|
||||||
WlCallback,
|
|
||||||
WlCompositor,
|
|
||||||
WlOutput,
|
|
||||||
WlRegistry,
|
|
||||||
WlShm,
|
|
||||||
WlShmPool,
|
|
||||||
WlTouch,
|
|
||||||
WlPointer,
|
|
||||||
WlKeyboard,
|
|
||||||
WlSubcompositor,
|
|
||||||
WlDataDeviceManager,
|
|
||||||
WlDataDevice,
|
|
||||||
WlDataSource,
|
|
||||||
WlDataOffer,
|
|
||||||
XdgWmBase,
|
|
||||||
XdgPositioner,
|
|
||||||
WlSurface,
|
|
||||||
WlSubsurface,
|
|
||||||
XdgSurface,
|
|
||||||
XdgPopup,
|
|
||||||
XdgToplevel,
|
|
||||||
WlRegion,
|
|
||||||
WlBuffer,
|
|
||||||
WlSeat,
|
|
||||||
WlDrm,
|
|
||||||
ZwpLinuxDmabufV1,
|
|
||||||
ZwpLinuxDmabufFeedbackV1,
|
|
||||||
ZwpLinuxBufferParamsV1,
|
|
||||||
ZxdgDecorationManagerV1,
|
|
||||||
ZxdgToplevelDecorationV1,
|
|
||||||
OrgKdeKwinServerDecorationManager,
|
|
||||||
OrgKdeKwinServerDecoration,
|
|
||||||
ZwpPrimarySelectionDeviceManagerV1,
|
|
||||||
ZwpPrimarySelectionDeviceV1,
|
|
||||||
ZwpPrimarySelectionSourceV1,
|
|
||||||
ZwpPrimarySelectionOfferV1,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Interface {
|
impl Interface {
|
||||||
pub fn name(self) -> &'static str {
|
pub fn name(self) -> &'static str {
|
||||||
match self {
|
self.0
|
||||||
Interface::WlDisplay => "wl_display",
|
|
||||||
Interface::WlCallback => "wl_callback",
|
|
||||||
Interface::WlCompositor => "wl_compositor",
|
|
||||||
Interface::WlRegistry => "wl_registry",
|
|
||||||
Interface::WlShm => "wl_shm",
|
|
||||||
Interface::WlSubcompositor => "wl_subcompositor",
|
|
||||||
Interface::XdgWmBase => "xdg_wm_base",
|
|
||||||
Interface::WlSurface => "wl_surface",
|
|
||||||
Interface::WlSubsurface => "wl_subsurface",
|
|
||||||
Interface::WlShmPool => "wl_shm_pool",
|
|
||||||
Interface::WlRegion => "wl_region",
|
|
||||||
Interface::XdgSurface => "xdg_surface",
|
|
||||||
Interface::XdgPositioner => "xdg_positioner",
|
|
||||||
Interface::XdgPopup => "xdg_popup",
|
|
||||||
Interface::XdgToplevel => "xdg_toplevel",
|
|
||||||
Interface::WlBuffer => "wl_buffer",
|
|
||||||
Interface::WlOutput => "wl_output",
|
|
||||||
Interface::WlSeat => "wl_seat",
|
|
||||||
Interface::WlTouch => "wl_touch",
|
|
||||||
Interface::WlPointer => "wl_pointer",
|
|
||||||
Interface::WlKeyboard => "wl_keyboard",
|
|
||||||
Interface::WlDataDeviceManager => "wl_data_device_manager",
|
|
||||||
Interface::WlDataDevice => "wl_data_device",
|
|
||||||
Interface::WlDataSource => "wl_data_source",
|
|
||||||
Interface::WlDataOffer => "wl_data_offer",
|
|
||||||
Interface::ZwpLinuxDmabufV1 => "zwp_linux_dmabuf_v1",
|
|
||||||
Interface::ZwpLinuxDmabufFeedbackV1 => "zwp_linux_dmabuf_feedback_v1",
|
|
||||||
Interface::ZwpLinuxBufferParamsV1 => "zwp_linux_buffer_params_v1",
|
|
||||||
Interface::WlDrm => "wl_drm",
|
|
||||||
Interface::ZxdgDecorationManagerV1 => "zxdg_decoration_manager_v1",
|
|
||||||
Interface::ZxdgToplevelDecorationV1 => "zxdg_toplevel_decoration_v1",
|
|
||||||
Interface::OrgKdeKwinServerDecorationManager => {
|
|
||||||
"org_kde_kwin_server_decoration_manager"
|
|
||||||
}
|
|
||||||
Interface::OrgKdeKwinServerDecoration => "org_kde_kwin_server_decoration",
|
|
||||||
Interface::ZwpPrimarySelectionDeviceManagerV1 => {
|
|
||||||
"zwp_primary_selection_device_manager_v1"
|
|
||||||
}
|
|
||||||
Interface::ZwpPrimarySelectionDeviceV1 => "zwp_primary_selection_device_v1",
|
|
||||||
Interface::ZwpPrimarySelectionSourceV1 => "zwp_primary_selection_source_v1",
|
|
||||||
Interface::ZwpPrimarySelectionOfferV1 => "zwp_primary_selection_offer_v1",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ use crate::State;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
|
||||||
|
|
||||||
const NON_COLOR: Color = Color::from_rgbaf(0.2, 0.2, 0.2, 1.0);
|
const NON_COLOR: Color = Color::from_rgbaf(0.2, 0.2, 0.2, 1.0);
|
||||||
const CHILD_COLOR: Color = Color::from_rgbaf(0.8, 0.8, 0.8, 1.0);
|
const CHILD_COLOR: Color = Color::from_rgbaf(0.8, 0.8, 0.8, 1.0);
|
||||||
|
|
@ -42,9 +43,21 @@ pub struct Renderer<'a> {
|
||||||
|
|
||||||
impl Renderer<'_> {
|
impl Renderer<'_> {
|
||||||
pub fn render_output(&mut self, output: &OutputNode, x: i32, y: i32) {
|
pub fn render_output(&mut self, output: &OutputNode, x: i32, y: i32) {
|
||||||
|
macro_rules! render_layer {
|
||||||
|
($layer:expr) => {
|
||||||
|
for ls in $layer.iter() {
|
||||||
|
let pos = ls.position();
|
||||||
|
self.render_layer_surface(ls.deref(), pos.x1(), pos.y1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render_layer!(output.layers[0]);
|
||||||
|
render_layer!(output.layers[1]);
|
||||||
if let Some(ws) = output.workspace.get() {
|
if let Some(ws) = output.workspace.get() {
|
||||||
self.render_workspace(&ws, x, y);
|
self.render_workspace(&ws, x, y);
|
||||||
}
|
}
|
||||||
|
render_layer!(output.layers[2]);
|
||||||
|
render_layer!(output.layers[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_workspace(&mut self, workspace: &WorkspaceNode, x: i32, y: i32) {
|
pub fn render_workspace(&mut self, workspace: &WorkspaceNode, x: i32, y: i32) {
|
||||||
|
|
@ -392,4 +405,13 @@ impl Renderer<'_> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_layer_surface(&mut self, surface: &ZwlrLayerSurfaceV1, x: i32, y: i32) {
|
||||||
|
unsafe {
|
||||||
|
let body = surface.position();
|
||||||
|
with_scissor(&body, || {
|
||||||
|
self.render_surface(&surface.surface, x, y);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,9 @@ impl OutputHandler {
|
||||||
workspace: CloneCell::new(None),
|
workspace: CloneCell::new(None),
|
||||||
seat_state: Default::default(),
|
seat_state: Default::default(),
|
||||||
global: global.clone(),
|
global: global.clone(),
|
||||||
|
layers: Default::default(),
|
||||||
});
|
});
|
||||||
|
global.node.set(Some(on.clone()));
|
||||||
let workspace = Rc::new(WorkspaceNode {
|
let workspace = Rc::new(WorkspaceNode {
|
||||||
id: self.state.node_ids.next(),
|
id: self.state.node_ids.next(),
|
||||||
output: CloneCell::new(on.clone()),
|
output: CloneCell::new(on.clone()),
|
||||||
|
|
@ -60,6 +62,7 @@ impl OutputHandler {
|
||||||
global.update_properties();
|
global.update_properties();
|
||||||
ae.triggered().await;
|
ae.triggered().await;
|
||||||
}
|
}
|
||||||
|
global.node.set(None);
|
||||||
self.state.outputs.remove(&self.output.id());
|
self.state.outputs.remove(&self.output.id());
|
||||||
let _ = self.state.remove_global(&*global);
|
let _ = self.state.remove_global(&*global);
|
||||||
self.state
|
self.state
|
||||||
|
|
|
||||||
|
|
@ -345,7 +345,13 @@ impl ContainerNode {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let height = body.height() + add;
|
let height = body.height() + add;
|
||||||
(0, pos + title_height + 1, other_content_size, height, height)
|
(
|
||||||
|
0,
|
||||||
|
pos + title_height + 1,
|
||||||
|
other_content_size,
|
||||||
|
height,
|
||||||
|
height,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
body = Rect::new_sized(x1, y1, width, height).unwrap();
|
body = Rect::new_sized(x1, y1, width, height).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,11 @@ use crate::backend::{KeyState, OutputId, ScrollAxis};
|
||||||
use crate::client::{Client, ClientId};
|
use crate::client::{Client, ClientId};
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_output::WlOutputGlobal;
|
|
||||||
use crate::ifs::wl_seat::{Dnd, NodeSeatState, WlSeatGlobal};
|
use crate::ifs::wl_seat::{Dnd, NodeSeatState, WlSeatGlobal};
|
||||||
use crate::ifs::wl_surface::WlSurface;
|
use crate::ifs::wl_surface::WlSurface;
|
||||||
use crate::rect::Rect;
|
use crate::rect::Rect;
|
||||||
use crate::render::Renderer;
|
use crate::render::Renderer;
|
||||||
use crate::tree::walker::NodeVisitor;
|
use crate::tree::walker::NodeVisitor;
|
||||||
use crate::utils::clonecell::CloneCell;
|
|
||||||
use crate::utils::copyhashmap::CopyHashMap;
|
use crate::utils::copyhashmap::CopyHashMap;
|
||||||
use crate::utils::linkedlist::LinkedList;
|
use crate::utils::linkedlist::LinkedList;
|
||||||
use crate::xkbcommon::ModifierState;
|
use crate::xkbcommon::ModifierState;
|
||||||
|
|
@ -16,16 +14,17 @@ use crate::NumCell;
|
||||||
pub use container::*;
|
pub use container::*;
|
||||||
pub use float::*;
|
pub use float::*;
|
||||||
use i4config::Direction;
|
use i4config::Direction;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::fmt::{Debug, Display};
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
pub use workspace::*;
|
pub use workspace::*;
|
||||||
|
pub use output::*;
|
||||||
|
|
||||||
mod container;
|
mod container;
|
||||||
mod float;
|
mod float;
|
||||||
pub mod walker;
|
pub mod walker;
|
||||||
mod workspace;
|
mod workspace;
|
||||||
|
mod output;
|
||||||
|
|
||||||
pub struct NodeIds {
|
pub struct NodeIds {
|
||||||
next: NumCell<u32>,
|
next: NumCell<u32>,
|
||||||
|
|
@ -254,6 +253,14 @@ pub trait Node {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_output(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_output(self: Rc<Self>) -> Option<Rc<OutputNode>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn accepts_child(&self, node: &dyn Node) -> bool {
|
fn accepts_child(&self, node: &dyn Node) -> bool {
|
||||||
let _ = node;
|
let _ = node;
|
||||||
false
|
false
|
||||||
|
|
@ -422,87 +429,3 @@ impl Node for DisplayNode {
|
||||||
seat.set_known_cursor(KnownCursor::Default);
|
seat.set_known_cursor(KnownCursor::Default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree_id!(OutputNodeId);
|
|
||||||
pub struct OutputNode {
|
|
||||||
pub display: Rc<DisplayNode>,
|
|
||||||
pub id: OutputNodeId,
|
|
||||||
pub position: Cell<Rect>,
|
|
||||||
pub global: Rc<WlOutputGlobal>,
|
|
||||||
pub workspaces: RefCell<Vec<Rc<WorkspaceNode>>>,
|
|
||||||
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
|
||||||
pub seat_state: NodeSeatState,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for OutputNode {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("OutputNode").finish_non_exhaustive()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Node for OutputNode {
|
|
||||||
fn id(&self) -> NodeId {
|
|
||||||
self.id.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn seat_state(&self) -> &NodeSeatState {
|
|
||||||
&self.seat_state
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy_node(&self, detach: bool) {
|
|
||||||
if detach {
|
|
||||||
self.display.clone().remove_child(self);
|
|
||||||
}
|
|
||||||
let mut workspaces = self.workspaces.borrow_mut();
|
|
||||||
for workspace in workspaces.drain(..) {
|
|
||||||
workspace.destroy_node(false);
|
|
||||||
}
|
|
||||||
self.seat_state.destroy_node(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor) {
|
|
||||||
visitor.visit_output(&self);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_children(&self, visitor: &mut dyn NodeVisitor) {
|
|
||||||
let ws = self.workspaces.borrow_mut();
|
|
||||||
for ws in ws.deref() {
|
|
||||||
visitor.visit_workspace(ws);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn absolute_position(&self) -> Rect {
|
|
||||||
self.position.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
|
||||||
if let Some(ws) = self.workspace.get() {
|
|
||||||
tree.push(FoundNode {
|
|
||||||
node: ws.clone(),
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
});
|
|
||||||
ws.find_tree_at(x, y, tree);
|
|
||||||
}
|
|
||||||
FindTreeResult::AcceptsInput
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_child(self: Rc<Self>, _child: &dyn Node) {
|
|
||||||
self.workspace.set(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
|
|
||||||
seat.set_known_cursor(KnownCursor::Default);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
|
||||||
renderer.render_output(self, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
|
||||||
self.position.set(*rect);
|
|
||||||
if let Some(c) = self.workspace.get() {
|
|
||||||
c.change_extents(rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
117
src/tree/output.rs
Normal file
117
src/tree/output.rs
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
use std::cell::{Cell, RefCell};
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::{CloneCell, DisplayNode};
|
||||||
|
use crate::cursor::KnownCursor;
|
||||||
|
use crate::ifs::wl_output::WlOutputGlobal;
|
||||||
|
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||||
|
use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
|
||||||
|
use crate::rect::Rect;
|
||||||
|
use crate::render::Renderer;
|
||||||
|
use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode};
|
||||||
|
use crate::tree::walker::NodeVisitor;
|
||||||
|
use crate::utils::linkedlist::LinkedList;
|
||||||
|
|
||||||
|
tree_id!(OutputNodeId);
|
||||||
|
pub struct OutputNode {
|
||||||
|
pub display: Rc<DisplayNode>,
|
||||||
|
pub id: OutputNodeId,
|
||||||
|
pub position: Cell<Rect>,
|
||||||
|
pub global: Rc<WlOutputGlobal>,
|
||||||
|
pub workspaces: RefCell<Vec<Rc<WorkspaceNode>>>,
|
||||||
|
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
||||||
|
pub seat_state: NodeSeatState,
|
||||||
|
pub layers: [LinkedList<Rc<ZwlrLayerSurfaceV1>>; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for OutputNode {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("OutputNode").finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Node for OutputNode {
|
||||||
|
fn id(&self) -> NodeId {
|
||||||
|
self.id.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seat_state(&self) -> &NodeSeatState {
|
||||||
|
&self.seat_state
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy_node(&self, detach: bool) {
|
||||||
|
if detach {
|
||||||
|
self.display.clone().remove_child(self);
|
||||||
|
}
|
||||||
|
let mut workspaces = self.workspaces.borrow_mut();
|
||||||
|
for workspace in workspaces.drain(..) {
|
||||||
|
workspace.destroy_node(false);
|
||||||
|
}
|
||||||
|
self.seat_state.destroy_node(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor) {
|
||||||
|
visitor.visit_output(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_children(&self, visitor: &mut dyn NodeVisitor) {
|
||||||
|
let ws = self.workspaces.borrow_mut();
|
||||||
|
for ws in ws.deref() {
|
||||||
|
visitor.visit_workspace(ws);
|
||||||
|
}
|
||||||
|
for layers in &self.layers {
|
||||||
|
for surface in layers.iter() {
|
||||||
|
visitor.visit_layer_surface(surface.deref());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn absolute_position(&self) -> Rect {
|
||||||
|
self.position.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
|
if let Some(ws) = self.workspace.get() {
|
||||||
|
tree.push(FoundNode {
|
||||||
|
node: ws.clone(),
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
});
|
||||||
|
ws.find_tree_at(x, y, tree);
|
||||||
|
}
|
||||||
|
FindTreeResult::AcceptsInput
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_child(self: Rc<Self>, _child: &dyn Node) {
|
||||||
|
self.workspace.set(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
seat.set_known_cursor(KnownCursor::Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self, renderer: &mut Renderer, x: i32, y: i32) {
|
||||||
|
renderer.render_output(self, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_output(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_output(self: Rc<Self>) -> Option<Rc<OutputNode>> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
||||||
|
self.position.set(*rect);
|
||||||
|
if let Some(c) = self.workspace.get() {
|
||||||
|
c.change_extents(rect);
|
||||||
|
}
|
||||||
|
for layer in &self.layers {
|
||||||
|
for surface in layer.iter() {
|
||||||
|
surface.deref().clone().change_extents(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ use crate::ifs::wl_surface::WlSurface;
|
||||||
use crate::tree::{ContainerNode, FloatNode, Node, OutputNode, WorkspaceNode};
|
use crate::tree::{ContainerNode, FloatNode, Node, OutputNode, WorkspaceNode};
|
||||||
use crate::DisplayNode;
|
use crate::DisplayNode;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
|
||||||
|
|
||||||
pub trait NodeVisitorBase: Sized {
|
pub trait NodeVisitorBase: Sized {
|
||||||
fn visit_surface(&mut self, node: &Rc<WlSurface>) {
|
fn visit_surface(&mut self, node: &Rc<WlSurface>) {
|
||||||
|
|
@ -37,6 +38,10 @@ pub trait NodeVisitorBase: Sized {
|
||||||
fn visit_workspace(&mut self, node: &Rc<WorkspaceNode>) {
|
fn visit_workspace(&mut self, node: &Rc<WorkspaceNode>) {
|
||||||
node.visit_children(self);
|
node.visit_children(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_layer_surface(&mut self, node: &Rc<ZwlrLayerSurfaceV1>) {
|
||||||
|
node.visit_children(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NodeVisitor {
|
pub trait NodeVisitor {
|
||||||
|
|
@ -48,6 +53,7 @@ pub trait NodeVisitor {
|
||||||
fn visit_output(&mut self, node: &Rc<OutputNode>);
|
fn visit_output(&mut self, node: &Rc<OutputNode>);
|
||||||
fn visit_float(&mut self, node: &Rc<FloatNode>);
|
fn visit_float(&mut self, node: &Rc<FloatNode>);
|
||||||
fn visit_workspace(&mut self, node: &Rc<WorkspaceNode>);
|
fn visit_workspace(&mut self, node: &Rc<WorkspaceNode>);
|
||||||
|
fn visit_layer_surface(&mut self, node: &Rc<ZwlrLayerSurfaceV1>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: NodeVisitorBase> NodeVisitor for T {
|
impl<T: NodeVisitorBase> NodeVisitor for T {
|
||||||
|
|
@ -82,6 +88,10 @@ impl<T: NodeVisitorBase> NodeVisitor for T {
|
||||||
fn visit_workspace(&mut self, node: &Rc<WorkspaceNode>) {
|
fn visit_workspace(&mut self, node: &Rc<WorkspaceNode>) {
|
||||||
<T as NodeVisitorBase>::visit_workspace(self, node)
|
<T as NodeVisitorBase>::visit_workspace(self, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_layer_surface(&mut self, node: &Rc<ZwlrLayerSurfaceV1>) {
|
||||||
|
<T as NodeVisitorBase>::visit_layer_surface(self, node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn visit_containers<F: FnMut(&Rc<ContainerNode>)>(f: F) -> impl NodeVisitor {
|
// pub fn visit_containers<F: FnMut(&Rc<ContainerNode>)>(f: F) -> impl NodeVisitor {
|
||||||
|
|
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/wire.rs"));
|
include!(concat!(env!("OUT_DIR"), "/wire.rs"));
|
||||||
|
|
|
||||||
3
todo.md
3
todo.md
|
|
@ -5,10 +5,11 @@
|
||||||
- presentation time
|
- presentation time
|
||||||
- viewporter
|
- viewporter
|
||||||
- session lock
|
- session lock
|
||||||
- layer shell
|
- xwayland
|
||||||
|
|
||||||
# done
|
# done
|
||||||
|
|
||||||
|
- layer shell
|
||||||
- Float moving
|
- Float moving
|
||||||
- Float toggle
|
- Float toggle
|
||||||
- Container moving (kb)
|
- Container moving (kb)
|
||||||
|
|
|
||||||
12
wire/zwlr_layer_shell_v1.txt
Normal file
12
wire/zwlr_layer_shell_v1.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# requests
|
||||||
|
|
||||||
|
msg get_layer_surface = 0 {
|
||||||
|
id: id(zwlr_layer_surface_v1),
|
||||||
|
surface: id(wl_surface),
|
||||||
|
output: id(wl_output),
|
||||||
|
layer: u32,
|
||||||
|
namespace: str,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg destroy = 1 {
|
||||||
|
}
|
||||||
49
wire/zwlr_layer_surface_v1.txt
Normal file
49
wire/zwlr_layer_surface_v1.txt
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
# requests
|
||||||
|
|
||||||
|
msg set_size = 0 {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg set_anchor = 1 {
|
||||||
|
anchor: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg set_exclusive_zone = 2 {
|
||||||
|
zone: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg set_margin = 3 {
|
||||||
|
top: i32,
|
||||||
|
right: i32,
|
||||||
|
bottom: i32,
|
||||||
|
left: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg set_keyboard_interactivity = 4 {
|
||||||
|
keyboard_interactivity: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg get_popup = 5 {
|
||||||
|
popup: id(xdg_popup),
|
||||||
|
}
|
||||||
|
|
||||||
|
msg ack_configure = 6 {
|
||||||
|
serial: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg destroy = 7 { }
|
||||||
|
|
||||||
|
msg set_layer = 8 {
|
||||||
|
layer: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
# events
|
||||||
|
|
||||||
|
msg configure = 0 {
|
||||||
|
serial: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg closed = 1 { }
|
||||||
8
wire/zxdg_output_manager_v1.txt
Normal file
8
wire/zxdg_output_manager_v1.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# requests
|
||||||
|
|
||||||
|
msg destroy = 0 { }
|
||||||
|
|
||||||
|
msg get_xdg_output = 1 {
|
||||||
|
id: id(zxdg_output_v1),
|
||||||
|
output: id(wl_output),
|
||||||
|
}
|
||||||
25
wire/zxdg_output_v1.txt
Normal file
25
wire/zxdg_output_v1.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# requests
|
||||||
|
|
||||||
|
msg destroy = 0 { }
|
||||||
|
|
||||||
|
# events
|
||||||
|
|
||||||
|
msg logical_position = 0 {
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg logical_size = 1 {
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg done = 2 { }
|
||||||
|
|
||||||
|
msg name = 3 {
|
||||||
|
name: str,
|
||||||
|
}
|
||||||
|
|
||||||
|
msg description = 4 {
|
||||||
|
description: str,
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue