1
0
Fork 0
forked from wry/wry

autocommit 2022-02-24 16:30:11 CET

This commit is contained in:
Julian Orth 2022-02-24 16:30:11 +01:00
parent 666e475032
commit 7d28d30666
39 changed files with 1670 additions and 209 deletions

View file

@ -231,12 +231,6 @@ impl XdgSurface {
}
}
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);

View file

@ -27,8 +27,10 @@ use std::fmt::{Debug, Formatter};
use std::mem;
use std::ops::Deref;
use std::rc::Rc;
use backtrace::Backtrace;
use thiserror::Error;
use crate::ifs::wl_surface::WlSurface;
use crate::tree::toplevel::ToplevelNode;
#[derive(Copy, Clone, Debug, FromPrimitive)]
pub enum ResizeEdge {
@ -75,7 +77,7 @@ pub struct XdgToplevel {
pub parent: CloneCell<Option<Rc<XdgToplevel>>>,
pub children: RefCell<AHashMap<XdgToplevelId, Rc<XdgToplevel>>>,
states: RefCell<AHashSet<u32>>,
pub toplevel_history: SmallMap<SeatId, LinkedNode<Rc<XdgToplevel>>, 1>,
pub toplevel_history: SmallMap<SeatId, LinkedNode<Rc<dyn ToplevelNode>>, 1>,
active_surfaces: NumCell<u32>,
pub decoration: Cell<Decoration>,
bugs: Cell<&'static Bugs>,
@ -139,13 +141,6 @@ impl XdgToplevel {
}
}
pub fn parent_is_float(&self) -> bool {
if let Some(parent) = self.parent_node.get() {
return parent.is_float();
}
false
}
fn send_configure_checked(&self, mut width: i32, mut height: i32) {
width = width.max(1);
height = height.max(1);
@ -429,7 +424,7 @@ impl Node for XdgToplevel {
}
fn do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, _direction: Direction) {
seat.focus_toplevel(&self);
seat.focus_toplevel(self);
}
fn absolute_position(&self) -> Rect {
@ -441,7 +436,7 @@ impl Node for XdgToplevel {
}
fn pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, _x: Fixed, _y: Fixed) {
seat.enter_toplevel(&self);
seat.enter_toplevel(self);
}
fn pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
@ -478,6 +473,27 @@ impl Node for XdgToplevel {
}
}
impl ToplevelNode for XdgToplevel {
fn parent(&self) -> Option<Rc<dyn Node>> {
self.parent_node.get()
}
fn focus_surface(&self, seat: &WlSeatGlobal) -> Rc<WlSurface> {
self.xdg
.focus_surface
.get(&seat.id())
.unwrap_or_else(|| self.xdg.surface.clone())
}
fn set_focus_history_link(&self, seat: &WlSeatGlobal, link: LinkedNode<Rc<dyn ToplevelNode>>) {
self.toplevel_history.insert(seat.id(), link);
}
fn as_node(&self) -> &dyn Node {
self
}
}
impl XdgSurfaceExt for XdgToplevel {
fn focus_parent(&self, seat: &Rc<WlSeatGlobal>) {
self.parent_node.get().map(|p| p.focus_self(seat));
@ -564,7 +580,7 @@ impl XdgSurfaceExt for XdgToplevel {
{
let seats = surface.client.state.globals.lock_seats();
for seat in seats.values() {
seat.focus_toplevel(&self);
seat.focus_toplevel(self.clone());
}
}
surface.client.state.tree_changed();

View file

@ -0,0 +1,247 @@
use std::cell::Cell;
use std::rc::Rc;
use thiserror::Error;
use x11rb::protocol::xproto::Window;
use i4config::Direction;
use crate::client::Client;
use crate::{AsyncQueue, CloneCell, State};
use crate::cursor::KnownCursor;
use crate::fixed::Fixed;
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal};
use crate::ifs::wl_surface::{SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError};
use crate::rect::Rect;
use crate::render::Renderer;
use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode};
use crate::tree::toplevel::ToplevelNode;
use crate::tree::walker::NodeVisitor;
use crate::utils::linkedlist::LinkedNode;
use crate::utils::smallmap::SmallMap;
use crate::wire::WlSurfaceId;
use crate::xwayland::XWaylandEvent;
pub struct XwindowData {
pub state: Rc<State>,
pub window_id: Window,
pub client: Rc<Client>,
pub surface_id: Cell<Option<WlSurfaceId>>,
pub window: CloneCell<Option<Rc<Xwindow>>>,
}
tree_id!(XwindowId);
pub struct Xwindow {
pub id: XwindowId,
pub seat_state: NodeSeatState,
pub data: Rc<XwindowData>,
pub surface: Rc<WlSurface>,
pub parent: CloneCell<Option<Rc<dyn Node>>>,
pub focus_history: SmallMap<SeatId, LinkedNode<Rc<dyn ToplevelNode>>, 1>,
pub events: Rc<AsyncQueue<XWaylandEvent>>,
pub extents: Cell<Rect>,
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
}
impl XwindowData {
pub fn new(state: &Rc<State>, window_id: Window, client: &Rc<Client>) -> Self {
Self {
state: state.clone(),
window_id,
client: client.clone(),
surface_id: Cell::new(None),
window: Default::default(),
}
}
}
impl Xwindow {
pub fn new(data: &Rc<XwindowData>, surface: &Rc<WlSurface>, events: &Rc<AsyncQueue<XWaylandEvent>>) -> Self {
Self {
id: data.state.node_ids.next(),
seat_state: Default::default(),
data: data.clone(),
surface: surface.clone(),
parent: Default::default(),
focus_history: Default::default(),
events: events.clone(),
extents: Default::default(),
workspace: Default::default(),
}
}
pub fn destroy(&self) {
self.break_loops();
self.data.window.take();
}
pub fn break_loops(&self) {
self.destroy_node(true);
}
pub fn install(self: &Rc<Self>) -> Result<(), XWindowError> {
self.surface.set_role(SurfaceRole::XSurface)?;
if self.surface.ext.get().is_some() {
return Err(XWindowError::AlreadyAttached);
}
self.surface.ext.set(self.clone());
Ok(())
}
fn notify_parent(&self) {
let parent = match self.parent.get() {
Some(p) => p,
_ => return,
};
let extents = self.surface.extents.get();
// let extents = self.xdg.extents.get();
// parent.child_active_changed(self, self.active_surfaces.get() > 0);
parent.child_size_changed(self, extents.width(), extents.height());
// parent.child_title_changed(self, self.title.borrow_mut().deref());
}
}
impl SurfaceExt for Xwindow {
fn post_commit(self: Rc<Self>) {
let parent = self.parent.get();
if self.surface.buffer.get().is_some() {
if parent.is_none() {
self.data.state.map_tiled(self.clone());
}
} else {
if parent.is_some() {
self.destroy_node(true);
}
}
}
fn on_surface_destroy(&self) -> Result<(), WlSurfaceError> {
self.destroy_node(true);
self.surface.unset_ext();
self.data.window.set(None);
self.data.surface_id.set(None);
self.events.push(XWaylandEvent::SurfaceDestroyed(self.surface.id));
Ok(())
}
fn extents_changed(&self) {
self.notify_parent();
}
}
impl Node for Xwindow {
fn id(&self) -> NodeId {
self.id.into()
}
fn seat_state(&self) -> &NodeSeatState {
&self.seat_state
}
fn destroy_node(&self, _detach: bool) {
self.workspace.take();
self.focus_history.clear();
if let Some(parent) = self.parent.take() {
parent.remove_child(self);
}
self.surface.destroy_node(false);
self.seat_state.destroy_node(self);
}
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor) {
visitor.visit_xwindow(&self);
}
fn visit_children(&self, visitor: &mut dyn NodeVisitor) {
visitor.visit_surface(&self.surface);
}
fn is_contained_in(&self, other: NodeId) -> bool {
if let Some(parent) = self.parent.get() {
if parent.id() == other {
return true;
}
return parent.is_contained_in(other);
}
false
}
fn do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, _direction: Direction) {
seat.focus_toplevel(self);
}
fn absolute_position(&self) -> Rect {
self.extents.get()
}
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
if let Some(buffer) = self.surface.buffer.get() {
if x < buffer.rect.width() && y < buffer.rect.height() {
tree.push(FoundNode {
node: self.surface.clone(),
x,
y,
});
return FindTreeResult::AcceptsInput;
}
}
FindTreeResult::Other
}
fn pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, _x: Fixed, _y: Fixed) {
seat.enter_toplevel(self);
}
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_surface(&self.surface, x, y)
}
fn change_extents(self: Rc<Self>, rect: &Rect) {
let nw = rect.width();
let nh = rect.height();
let de = self.extents.replace(*rect);
if de.width() != nw || de.height() != nh {
self.events.push(XWaylandEvent::Configure(self.clone()));
}
}
fn set_workspace(self: Rc<Self>, ws: &Rc<WorkspaceNode>) {
self.workspace.set(Some(ws.clone()));
}
fn set_parent(self: Rc<Self>, parent: Rc<dyn Node>) {
self.parent.set(Some(parent));
self.notify_parent();
}
fn client(&self) -> Option<Rc<Client>> {
Some(self.data.client.clone())
}
}
impl ToplevelNode for Xwindow {
fn parent(&self) -> Option<Rc<dyn Node>> {
self.parent.get()
}
fn focus_surface(&self, _seat: &WlSeatGlobal) -> Rc<WlSurface> {
self.surface.clone()
}
fn set_focus_history_link(&self, seat: &WlSeatGlobal, link: LinkedNode<Rc<dyn ToplevelNode>>) {
self.focus_history.insert(seat.id(), link);
}
fn as_node(&self) -> &dyn Node {
self
}
}
#[derive(Debug, Error)]
pub enum XWindowError {
#[error("The surface is already attached")]
AlreadyAttached,
#[error(transparent)]
WlSurfaceError(#[from] WlSurfaceError),
}

View file

@ -1,29 +1,26 @@
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::client::{Client, ClientError};
use crate::ifs::wl_seat::NodeSeatState;
use crate::ifs::wl_surface::{
CommitAction, CommitContext, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError,
};
use crate::ifs::zwlr_layer_shell_v1::{ZwlrLayerShellV1, OVERLAY};
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::tree::{FindTreeResult, FoundNode, Node, NodeId, OutputNode};
use crate::utils::bitflags::BitflagsExt;
use crate::utils::buffd::MsgParser;
use crate::utils::buffd::MsgParserError;
use crate::utils::linkedlist::LinkedNode;
use crate::wire::zwlr_layer_surface_v1::*;
use crate::wire::{WlSurfaceId, ZwlrLayerSurfaceV1Id};
use crate::NumCell;
use std::cell::Cell;
use std::ops::Deref;
use std::rc::Rc;
use thiserror::Error;
const KI_NONE: u32 = 0;
#[allow(dead_code)]
@ -100,7 +97,7 @@ impl ZwlrLayerSurfaceV1 {
margin: Cell::new((0, 0, 0, 0)),
keyboard_interactivity: Cell::new(0),
link: Cell::new(None),
seat_state: Default::default()
seat_state: Default::default(),
}
}
@ -132,7 +129,9 @@ impl ZwlrLayerSurfaceV1 {
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 _)));
self.pending
.size
.set(Some((req.width as _, req.height as _)));
Ok(())
}
@ -153,16 +152,25 @@ impl ZwlrLayerSurfaceV1 {
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)));
self.pending
.margin
.set(Some((req.top, req.right, req.bottom, req.left)));
Ok(())
}
fn set_keyboard_interactivity(&self, parser: MsgParser<'_, '_>) -> Result<(), SetKeyboardInteractivityError> {
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));
return Err(SetKeyboardInteractivityError::UnknownKi(
req.keyboard_interactivity,
));
}
self.pending.keyboard_interactivity.set(Some(req.keyboard_interactivity));
self.pending
.keyboard_interactivity
.set(Some(req.keyboard_interactivity));
Ok(())
}
@ -271,7 +279,8 @@ impl ZwlrLayerSurfaceV1 {
} else if anchor.contains(BOTTOM) {
y1 += opos.height() - height;
}
self.pos.set(Rect::new_sized(x1, y1, width, height).unwrap());
self.pos
.set(Rect::new_sized(x1, y1, width, height).unwrap());
self.client.state.tree_changed();
}
}
@ -308,7 +317,7 @@ impl SurfaceExt for ZwlrLayerSurfaceV1 {
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();
@ -362,7 +371,7 @@ impl Node for ZwlrLayerSurfaceV1 {
tree.push(FoundNode {
node: self.surface.clone(),
x,
y
y,
});
self.surface.find_tree_at(x, y, tree)
}