autocommit 2022-02-24 18:24:14 CET
This commit is contained in:
parent
7d28d30666
commit
6e466360a8
18 changed files with 185 additions and 65 deletions
|
|
@ -12,6 +12,7 @@ use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError, OutBufferSwap
|
|||
use crate::utils::numcell::NumCell;
|
||||
use crate::utils::queue::AsyncQueue;
|
||||
use crate::wire::WlRegistryId;
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
use crate::ErrorFmt;
|
||||
use ahash::AHashMap;
|
||||
pub use error::{ClientError, ObjectError};
|
||||
|
|
@ -22,7 +23,6 @@ use std::mem;
|
|||
use std::ops::DerefMut;
|
||||
use std::rc::Rc;
|
||||
use uapi::{c, OwnedFd};
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
|
||||
mod error;
|
||||
mod objects;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,9 @@ impl ForkerProxy {
|
|||
wmfd: Rc<OwnedFd>,
|
||||
waylandfd: Rc<OwnedFd>,
|
||||
) -> Result<OwnedFd, ForkerError> {
|
||||
self.fds.borrow_mut().extend([stderr, dfd, listenfd, wmfd, waylandfd]);
|
||||
self.fds
|
||||
.borrow_mut()
|
||||
.extend([stderr, dfd, listenfd, wmfd, waylandfd]);
|
||||
let id = self.next_id.fetch_add(1);
|
||||
self.outgoing.push(ServerMessage::Xwayland { id });
|
||||
self.pidfd(id).await
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ use crate::utils::buffd::MsgParser;
|
|||
use crate::utils::buffd::MsgParserError;
|
||||
use crate::wire::wl_compositor::*;
|
||||
use crate::wire::WlCompositorId;
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
|
||||
pub struct WlCompositorGlobal {
|
||||
name: GlobalName,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
use crate::client::{Client, ClientError};
|
||||
use crate::drm::dma::{DmaBuf, DmaBufPlane};
|
||||
use crate::drm::INVALID_MODIFIER;
|
||||
use crate::globals::{Global, GlobalName};
|
||||
use crate::ifs::wl_buffer::WlBuffer;
|
||||
use crate::leaks::Tracker;
|
||||
use crate::object::Object;
|
||||
use crate::utils::buffd::MsgParser;
|
||||
use crate::utils::buffd::MsgParserError;
|
||||
use crate::wire::wl_drm::*;
|
||||
use crate::wire::WlDrmId;
|
||||
use crate::RenderError;
|
||||
use bstr::ByteSlice;
|
||||
use std::ffi::CString;
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use crate::drm::dma::{DmaBuf, DmaBufPlane};
|
||||
use crate::drm::INVALID_MODIFIER;
|
||||
use crate::ifs::wl_buffer::WlBuffer;
|
||||
use crate::RenderError;
|
||||
|
||||
const PRIME: u32 = 1;
|
||||
|
||||
|
|
@ -150,12 +150,7 @@ impl WlDrm {
|
|||
}
|
||||
}
|
||||
let img = ctx.dmabuf_img(&dmabuf)?;
|
||||
let buffer = Rc::new(WlBuffer::new_dmabuf(
|
||||
req.id,
|
||||
&self.client,
|
||||
format,
|
||||
&img,
|
||||
));
|
||||
let buffer = Rc::new(WlBuffer::new_dmabuf(req.id, &self.client, format, &img));
|
||||
track!(self.client, buffer);
|
||||
self.client.add_client_obj(&buffer)?;
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ use crate::ifs::wl_seat::wl_touch::WlTouch;
|
|||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::leaks::Tracker;
|
||||
use crate::object::{Object, ObjectId};
|
||||
use crate::tree::toplevel::ToplevelNode;
|
||||
use crate::tree::{ContainerSplit, FloatNode, FoundNode, Node};
|
||||
use crate::utils::asyncevent::AsyncEvent;
|
||||
use crate::utils::buffd::MsgParser;
|
||||
|
|
@ -49,7 +50,6 @@ use std::ops::{Deref, DerefMut};
|
|||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use uapi::{c, Errno, OwnedFd};
|
||||
use crate::tree::toplevel::ToplevelNode;
|
||||
|
||||
const POINTER: u32 = 1;
|
||||
const KEYBOARD: u32 = 2;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use crate::ifs::wl_seat::{wl_keyboard, wl_pointer, Dnd, SeatId, WlSeat, WlSeatGl
|
|||
use crate::ifs::wl_surface::xdg_surface::xdg_popup::XdgPopup;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::object::ObjectId;
|
||||
use crate::tree::toplevel::ToplevelNode;
|
||||
use crate::tree::{FloatNode, Node};
|
||||
use crate::utils::clonecell::CloneCell;
|
||||
use crate::utils::smallmap::SmallMap;
|
||||
|
|
@ -21,7 +22,6 @@ use i4config::keyboard::ModifiedKeySym;
|
|||
use smallvec::SmallVec;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use crate::tree::toplevel::ToplevelNode;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct NodeSeatState {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
pub mod cursor;
|
||||
pub mod wl_subsurface;
|
||||
pub mod xdg_surface;
|
||||
pub mod zwlr_layer_surface_v1;
|
||||
pub mod xwindow;
|
||||
pub mod zwlr_layer_surface_v1;
|
||||
|
||||
use crate::backend::{KeyState, ScrollAxis};
|
||||
use crate::client::{Client, ClientError, RequestParser};
|
||||
|
|
|
|||
|
|
@ -345,6 +345,8 @@ impl XdgSurfaceExt for XdgPopup {
|
|||
}
|
||||
} else {
|
||||
if wl.take().is_some() {
|
||||
drop(wl);
|
||||
drop(dl);
|
||||
self.destroy_node(true);
|
||||
self.send_popup_done();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ use std::mem;
|
|||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
use thiserror::Error;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::tree::toplevel::ToplevelNode;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Copy, Clone, Debug, FromPrimitive)]
|
||||
pub enum ResizeEdge {
|
||||
|
|
|
|||
|
|
@ -1,27 +1,29 @@
|
|||
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::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode};
|
||||
use crate::utils::linkedlist::LinkedNode;
|
||||
use crate::utils::smallmap::SmallMap;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
use crate::{AsyncQueue, CloneCell, State};
|
||||
use i4config::Direction;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use x11rb::protocol::xproto::{CreateNotifyEvent, Window};
|
||||
|
||||
pub struct XwindowData {
|
||||
pub state: Rc<State>,
|
||||
pub window_id: Window,
|
||||
pub override_redirect: bool,
|
||||
pub extents: Cell<Rect>,
|
||||
pub client: Rc<Client>,
|
||||
pub surface_id: Cell<Option<WlSurfaceId>>,
|
||||
pub window: CloneCell<Option<Rc<Xwindow>>>,
|
||||
|
|
@ -36,15 +38,20 @@ pub struct Xwindow {
|
|||
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>>>,
|
||||
pub display_link: RefCell<Option<LinkedNode<Rc<dyn Node>>>>,
|
||||
pub display_xlink: RefCell<Option<LinkedNode<Rc<Xwindow>>>>,
|
||||
}
|
||||
|
||||
impl XwindowData {
|
||||
pub fn new(state: &Rc<State>, window_id: Window, client: &Rc<Client>) -> Self {
|
||||
pub fn new(state: &Rc<State>, event: &CreateNotifyEvent, client: &Rc<Client>) -> Self {
|
||||
let extents = Rect::new_sized(event.x as _, event.y as _, event.width as _, event.height as _).unwrap();
|
||||
log::info!("extents = {:?}", extents);
|
||||
Self {
|
||||
state: state.clone(),
|
||||
window_id,
|
||||
window_id: event.window,
|
||||
override_redirect: event.override_redirect,
|
||||
extents: Cell::new(extents),
|
||||
client: client.clone(),
|
||||
surface_id: Cell::new(None),
|
||||
window: Default::default(),
|
||||
|
|
@ -53,7 +60,11 @@ impl XwindowData {
|
|||
}
|
||||
|
||||
impl Xwindow {
|
||||
pub fn new(data: &Rc<XwindowData>, surface: &Rc<WlSurface>, events: &Rc<AsyncQueue<XWaylandEvent>>) -> Self {
|
||||
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(),
|
||||
|
|
@ -62,8 +73,9 @@ impl Xwindow {
|
|||
parent: Default::default(),
|
||||
focus_history: Default::default(),
|
||||
events: events.clone(),
|
||||
extents: Default::default(),
|
||||
workspace: Default::default(),
|
||||
display_link: Default::default(),
|
||||
display_xlink: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,10 +108,8 @@ impl Xwindow {
|
|||
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>) {
|
||||
fn managed_post_commit(self: &Rc<Self>) {
|
||||
let parent = self.parent.get();
|
||||
if self.surface.buffer.get().is_some() {
|
||||
if parent.is_none() {
|
||||
|
|
@ -107,17 +117,46 @@ impl SurfaceExt for Xwindow {
|
|||
}
|
||||
} else {
|
||||
if parent.is_some() {
|
||||
self.destroy_node(true);
|
||||
self.destroy_node(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn unmanaged_post_commit(self: &Rc<Self>) {
|
||||
let mut dl = self.display_link.borrow_mut();
|
||||
let mut dxl = self.display_xlink.borrow_mut();
|
||||
if self.surface.buffer.get().is_some() {
|
||||
if dl.is_none() {
|
||||
*dl = Some(self.data.state.root.stacked.add_last(self.clone()));
|
||||
*dxl = Some(self.data.state.root.xstacked.add_last(self.clone()));
|
||||
self.data.state.tree_changed();
|
||||
}
|
||||
} else {
|
||||
if dl.is_some() {
|
||||
drop(dl);
|
||||
drop(dxl);
|
||||
self.destroy_node(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SurfaceExt for Xwindow {
|
||||
fn post_commit(self: Rc<Self>) {
|
||||
if self.data.override_redirect {
|
||||
self.unmanaged_post_commit();
|
||||
} else {
|
||||
self.managed_post_commit();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
self.events
|
||||
.push(XWaylandEvent::SurfaceDestroyed(self.surface.id));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -136,6 +175,8 @@ impl Node for Xwindow {
|
|||
}
|
||||
|
||||
fn destroy_node(&self, _detach: bool) {
|
||||
self.display_xlink.borrow_mut().take();
|
||||
self.display_link.borrow_mut().take();
|
||||
self.workspace.take();
|
||||
self.focus_history.clear();
|
||||
if let Some(parent) = self.parent.take() {
|
||||
|
|
@ -168,7 +209,7 @@ impl Node for Xwindow {
|
|||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
self.extents.get()
|
||||
self.data.extents.get()
|
||||
}
|
||||
|
||||
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||
|
|
@ -200,7 +241,7 @@ impl Node for Xwindow {
|
|||
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
||||
let nw = rect.width();
|
||||
let nh = rect.height();
|
||||
let de = self.extents.replace(*rect);
|
||||
let de = self.data.extents.replace(*rect);
|
||||
if de.width() != nw || de.height() != nh {
|
||||
self.events.push(XWaylandEvent::Configure(self.clone()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use crate::render::sys::{glDisable, glEnable, GL_BLEND};
|
|||
use crate::render::Texture;
|
||||
use crate::theme::Color;
|
||||
use crate::tree::{
|
||||
ContainerFocus, ContainerNode, ContainerSplit, FloatNode, OutputNode, WorkspaceNode,
|
||||
ContainerFocus, ContainerNode, ContainerSplit, FloatNode, Node, OutputNode, WorkspaceNode,
|
||||
};
|
||||
use crate::State;
|
||||
use std::ops::Deref;
|
||||
|
|
@ -58,6 +58,10 @@ impl Renderer<'_> {
|
|||
}
|
||||
render_layer!(output.layers[2]);
|
||||
render_layer!(output.layers[3]);
|
||||
for stacked in output.display.xstacked.iter() {
|
||||
let pos = stacked.absolute_position();
|
||||
stacked.render(self, pos.x1(), pos.y1());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_workspace(&mut self, workspace: &WorkspaceNode, x: i32, y: i32) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use crate::client::{Client, ClientId};
|
|||
use crate::cursor::KnownCursor;
|
||||
use crate::fixed::Fixed;
|
||||
use crate::ifs::wl_seat::{Dnd, NodeSeatState, WlSeatGlobal};
|
||||
use crate::ifs::wl_surface::xwindow::Xwindow;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::rect::Rect;
|
||||
use crate::render::Renderer;
|
||||
|
|
@ -23,9 +24,9 @@ pub use workspace::*;
|
|||
mod container;
|
||||
mod float;
|
||||
mod output;
|
||||
pub mod toplevel;
|
||||
pub mod walker;
|
||||
mod workspace;
|
||||
pub mod toplevel;
|
||||
|
||||
pub struct NodeIds {
|
||||
next: NumCell<u32>,
|
||||
|
|
@ -337,6 +338,7 @@ pub struct DisplayNode {
|
|||
pub id: NodeId,
|
||||
pub outputs: CopyHashMap<OutputId, Rc<OutputNode>>,
|
||||
pub stacked: LinkedList<Rc<dyn Node>>,
|
||||
pub xstacked: LinkedList<Rc<Xwindow>>,
|
||||
pub seat_state: NodeSeatState,
|
||||
}
|
||||
|
||||
|
|
@ -346,6 +348,7 @@ impl DisplayNode {
|
|||
id,
|
||||
outputs: Default::default(),
|
||||
stacked: Default::default(),
|
||||
xstacked: Default::default(),
|
||||
seat_state: Default::default(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::rc::Rc;
|
||||
use crate::ifs::wl_seat::WlSeatGlobal;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::tree::Node;
|
||||
use crate::utils::linkedlist::LinkedNode;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub trait ToplevelNode: Node {
|
||||
fn parent(&self) -> Option<Rc<dyn Node>>;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use crate::ifs::wl_surface::xdg_surface::xdg_popup::XdgPopup;
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel;
|
||||
use crate::ifs::wl_surface::xwindow::Xwindow;
|
||||
use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::tree::{ContainerNode, FloatNode, Node, OutputNode, WorkspaceNode};
|
||||
use crate::DisplayNode;
|
||||
use std::rc::Rc;
|
||||
use crate::ifs::wl_surface::xwindow::Xwindow;
|
||||
|
||||
pub trait NodeVisitorBase: Sized {
|
||||
fn visit_surface(&mut self, node: &Rc<WlSurface>) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
mod xsocket;
|
||||
mod xwm;
|
||||
|
||||
use crate::client::ClientError;
|
||||
use crate::forker::ForkerProxy;
|
||||
use crate::ifs::wl_surface::xwindow::Xwindow;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::utils::tri::Try;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use crate::xwayland::xsocket::allocate_socket;
|
||||
use crate::xwayland::xwm::Wm;
|
||||
use crate::{AsyncError, AsyncQueue, ErrorFmt, ForkerError, State};
|
||||
|
|
@ -11,11 +15,7 @@ use std::error::Error;
|
|||
use std::num::ParseIntError;
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use uapi::{c, Errno, OwnedFd, pipe2};
|
||||
use crate::client::ClientError;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::ifs::wl_surface::xwindow::Xwindow;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use uapi::{c, pipe2, Errno, OwnedFd};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum XWaylandError {
|
||||
|
|
@ -63,6 +63,14 @@ enum XWaylandError {
|
|||
CreateXWindow(#[source] Box<dyn Error>),
|
||||
#[error("Could not acquire a selection")]
|
||||
SelectionOwner(#[source] Box<dyn Error>),
|
||||
#[error("Could not load the resource database")]
|
||||
ResourceDatabase(#[source] Box<dyn Error>),
|
||||
#[error("Could not acquire a cursor handle")]
|
||||
CursorHandle(#[source] Box<dyn Error>),
|
||||
#[error("Could not load the default cursor")]
|
||||
LoadCursor(#[source] Box<dyn Error>),
|
||||
#[error("Could not set the cursor of the root window")]
|
||||
SetCursor(#[source] Box<dyn Error>),
|
||||
#[error("composite_redirect_subwindows failed")]
|
||||
CompositeRedirectSubwindows(#[source] Box<dyn Error>),
|
||||
#[error("Could not spawn the Xwayland client")]
|
||||
|
|
@ -128,7 +136,11 @@ async fn run(
|
|||
Ok(w) => w,
|
||||
Err(e) => return Err(XWaylandError::Socketpair(e.into())),
|
||||
};
|
||||
let client = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC | c::SOCK_NONBLOCK, 0);
|
||||
let client = uapi::socketpair(
|
||||
c::AF_UNIX,
|
||||
c::SOCK_STREAM | c::SOCK_CLOEXEC | c::SOCK_NONBLOCK,
|
||||
0,
|
||||
);
|
||||
let (client1, client2) = match client {
|
||||
Ok(w) => w,
|
||||
Err(e) => return Err(XWaylandError::Socketpair(e.into())),
|
||||
|
|
@ -149,7 +161,9 @@ async fn run(
|
|||
};
|
||||
let client_id = state.clients.id();
|
||||
let queue = Rc::new(AsyncQueue::new());
|
||||
let client = state.clients.spawn2(client_id, state, client1, 9999, 9999, Some(queue.clone()));
|
||||
let client = state
|
||||
.clients
|
||||
.spawn2(client_id, state, client1, 9999, 9999, Some(queue.clone()));
|
||||
let client = match client {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(XWaylandError::SpawnClient(e)),
|
||||
|
|
|
|||
|
|
@ -1,24 +1,27 @@
|
|||
use std::error::Error;
|
||||
use crate::async_engine::AsyncFd;
|
||||
use crate::client::Client;
|
||||
use crate::ifs::wl_surface::xwindow::{Xwindow, XwindowData};
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use crate::xwayland::{XWaylandError, XWaylandEvent};
|
||||
use crate::{AsyncQueue, ErrorFmt, State};
|
||||
use ahash::AHashMap;
|
||||
use futures::FutureExt;
|
||||
use std::error::Error;
|
||||
use std::os::unix::io::FromRawFd;
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::rc::Rc;
|
||||
use ahash::AHashMap;
|
||||
use futures::FutureExt;
|
||||
use uapi::OwnedFd;
|
||||
use x11rb::atom_manager;
|
||||
use x11rb::connection::Connection;
|
||||
use x11rb::cursor::Handle;
|
||||
use x11rb::errors::ConnectionError;
|
||||
use x11rb::protocol::composite::{ConnectionExt as _, Redirect};
|
||||
use x11rb::protocol::xproto::{ChangeWindowAttributesAux, CreateWindowAux, ConnectionExt as _, EventMask, Window, WindowClass, ClientMessageEvent, CreateNotifyEvent, DestroyNotifyEvent, ConfigureWindowAux, MapRequestEvent, ConfigureRequestEvent};
|
||||
use x11rb::protocol::xproto::{ChangeWindowAttributesAux, ClientMessageEvent, ConfigureNotifyEvent, ConfigureRequestEvent, ConfigureWindowAux, ConnectionExt as _, CreateNotifyEvent, CreateWindowAux, DestroyNotifyEvent, EventMask, MapRequestEvent, Window, WindowClass};
|
||||
use x11rb::protocol::Event;
|
||||
use x11rb::resource_manager::Database;
|
||||
use x11rb::rust_connection::{DefaultStream, RustConnection};
|
||||
use crate::client::Client;
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use crate::ifs::wl_surface::xwindow::{Xwindow, XwindowData};
|
||||
use crate::rect::Rect;
|
||||
|
||||
atom_manager! {
|
||||
pub Atoms: AtomsCookie {
|
||||
|
|
@ -119,7 +122,12 @@ impl Drop for Wm {
|
|||
}
|
||||
|
||||
impl Wm {
|
||||
pub(super) fn get(state: &Rc<State>, client: Rc<Client>, socket: OwnedFd, queue: Rc<AsyncQueue<XWaylandEvent>>) -> Result<Self, XWaylandError> {
|
||||
pub(super) fn get(
|
||||
state: &Rc<State>,
|
||||
client: Rc<Client>,
|
||||
socket: OwnedFd,
|
||||
queue: Rc<AsyncQueue<XWaylandEvent>>,
|
||||
) -> Result<Self, XWaylandError> {
|
||||
let socket_dup = match uapi::fcntl_dupfd_cloexec(socket.raw(), 0) {
|
||||
Ok(s) => state.eng.fd(&Rc::new(s))?,
|
||||
Err(e) => return Err(XWaylandError::Dupfd(e.into())),
|
||||
|
|
@ -153,7 +161,10 @@ impl Wm {
|
|||
}
|
||||
}
|
||||
{
|
||||
let res = try { c.composite_redirect_subwindows(root, Redirect::MANUAL)?.check()? };
|
||||
let res = try {
|
||||
c.composite_redirect_subwindows(root, Redirect::MANUAL)?
|
||||
.check()?
|
||||
};
|
||||
if let Err(e) = res {
|
||||
return Err(XWaylandError::CompositeRedirectSubwindows(e));
|
||||
}
|
||||
|
|
@ -188,6 +199,26 @@ impl Wm {
|
|||
return Err(XWaylandError::SelectionOwner(e));
|
||||
}
|
||||
}
|
||||
{
|
||||
let rdb = match Database::new_from_default(&c) {
|
||||
Ok(rdb) => rdb,
|
||||
Err(e) => return Err(XWaylandError::ResourceDatabase(e.into())),
|
||||
};
|
||||
let handle: Res<Handle> = try { Handle::new(&c, 0, &rdb)?.reply()? };
|
||||
let handle = match handle {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Err(XWaylandError::CursorHandle(e)),
|
||||
};
|
||||
let cursor = match handle.load_cursor(&c, "left_ptr") {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(XWaylandError::LoadCursor(e.into())),
|
||||
};
|
||||
let cwa = ChangeWindowAttributesAux::new().cursor(cursor);
|
||||
let res: Res<_> = try { c.change_window_attributes(root, &cwa)?.check()? };
|
||||
if let Err(e) = res {
|
||||
return Err(XWaylandError::SetCursor(e));
|
||||
}
|
||||
}
|
||||
Ok(Self {
|
||||
state: state.clone(),
|
||||
c,
|
||||
|
|
@ -231,7 +262,7 @@ impl Wm {
|
|||
}
|
||||
|
||||
fn send_configure(&mut self, window: Rc<Xwindow>) {
|
||||
let extents = window.extents.get();
|
||||
let extents = window.data.extents.get();
|
||||
let cfg = ConfigureWindowAux::new()
|
||||
.x(extents.x1())
|
||||
.y(extents.y1())
|
||||
|
|
@ -239,10 +270,12 @@ impl Wm {
|
|||
.height(extents.height() as u32)
|
||||
.border_width(0);
|
||||
let res: Res<()> = try {
|
||||
self.c.configure_window(window.data.window_id, &cfg)?.check()?;
|
||||
self.c
|
||||
.configure_window(window.data.window_id, &cfg)?
|
||||
.check()?;
|
||||
};
|
||||
if let Err(e) = res {
|
||||
log::error!("Could not configure window: {}", ErrorFmt(&*e));
|
||||
log::error!("Could not configure window: {}", ErrorFmt(&*e));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +286,10 @@ impl Wm {
|
|||
}
|
||||
let window = Rc::new(Xwindow::new(&data, &surface, &self.queue));
|
||||
if let Err(e) = window.install() {
|
||||
log::error!("Could not attach the xwindow to the surface: {}", ErrorFmt(e));
|
||||
log::error!(
|
||||
"Could not attach the xwindow to the surface: {}",
|
||||
ErrorFmt(e)
|
||||
);
|
||||
return;
|
||||
}
|
||||
data.window.set(Some(window.clone()));
|
||||
|
|
@ -286,10 +322,11 @@ impl Wm {
|
|||
match event {
|
||||
Event::MapRequest(event) => self.handle_map_request(event),
|
||||
Event::ConfigureRequest(event) => self.handle_configure_request(event),
|
||||
Event::ConfigureNotify(event) => self.handle_configure_notify(event),
|
||||
Event::ClientMessage(event) => self.handle_client_message(event),
|
||||
Event::CreateNotify(event) => self.handle_create_notify(event),
|
||||
Event::DestroyNotify(event) => self.handle_destroy_notify(event),
|
||||
_ => { },
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +344,7 @@ impl Wm {
|
|||
}
|
||||
|
||||
fn handle_create_notify(&mut self, event: CreateNotifyEvent) {
|
||||
let data = Rc::new(XwindowData::new(&self.state, event.window, &self.client));
|
||||
let data = Rc::new(XwindowData::new(&self.state, &event, &self.client));
|
||||
self.windows.insert(event.window, data);
|
||||
}
|
||||
|
||||
|
|
@ -324,6 +361,25 @@ impl Wm {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_configure_notify(&mut self, event: ConfigureNotifyEvent) {
|
||||
let data = match self.windows.get(&event.window) {
|
||||
Some(d) => d,
|
||||
_ => return,
|
||||
};
|
||||
if data.override_redirect {
|
||||
let extents = Rect::new_sized(
|
||||
event.x as _,
|
||||
event.y as _,
|
||||
event.width as _,
|
||||
event.height as _,
|
||||
).unwrap();
|
||||
let changed = data.extents.replace(extents) != extents;
|
||||
if changed {
|
||||
self.state.tree_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_configure_request(&mut self, event: ConfigureRequestEvent) {
|
||||
let data = match self.windows.get(&event.window) {
|
||||
Some(d) => d,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue