autocommit 2022-03-26 22:58:30 CET
This commit is contained in:
parent
3b1b843821
commit
707ff6066c
28 changed files with 2307 additions and 707 deletions
|
|
@ -66,10 +66,6 @@ impl NodeSeatState {
|
|||
self.dnd_targets.remove(&seat.id);
|
||||
}
|
||||
|
||||
// pub fn remove_pointer_grabs(&self) {
|
||||
// self.grabs.clear();
|
||||
// }
|
||||
|
||||
pub fn is_active(&self) -> bool {
|
||||
self.kb_foci.len() > 0
|
||||
}
|
||||
|
|
@ -85,7 +81,7 @@ impl NodeSeatState {
|
|||
seat.ungrab_kb();
|
||||
seat.keyboard_node.set(seat.state.root.clone());
|
||||
if let Some(tl) = seat.toplevel_focus_history.last() {
|
||||
seat.focus_node(tl.focus_surface(&seat));
|
||||
seat.focus_node(tl.focus_surface(seat.id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +194,11 @@ impl WlSeatGlobal {
|
|||
pub fn last_tiled_keyboard_toplevel(&self, new: &dyn Node) -> Option<Rc<dyn ToplevelNode>> {
|
||||
let is_container = new.is_container();
|
||||
for tl in self.toplevel_focus_history.rev_iter() {
|
||||
if !tl.parent_is_float() && (!is_container || !tl.is_contained_in(new.id())) {
|
||||
let parent_is_float = match tl.parent() {
|
||||
Some(pn) => pn.is_float(),
|
||||
_ => false,
|
||||
};
|
||||
if !parent_is_float && (!is_container || !tl.as_node().is_contained_in(new.id())) {
|
||||
return Some(tl.deref().clone());
|
||||
}
|
||||
}
|
||||
|
|
@ -214,8 +214,8 @@ impl WlSeatGlobal {
|
|||
|
||||
pub fn focus_toplevel(self: &Rc<Self>, n: Rc<dyn ToplevelNode>) {
|
||||
let node = self.toplevel_focus_history.add_last(n.clone());
|
||||
n.set_focus_history_link(self, node);
|
||||
self.focus_node(n.focus_surface(self));
|
||||
n.data().toplevel_history.insert(self.id, node);
|
||||
self.focus_node(n.focus_surface(self.id));
|
||||
}
|
||||
|
||||
fn ungrab_kb(self: &Rc<Self>) {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use crate::ifs::wl_callback::WlCallback;
|
|||
use crate::ifs::wl_seat::{Dnd, NodeSeatState, SeatId, WlSeatGlobal};
|
||||
use crate::ifs::wl_surface::cursor::CursorSurface;
|
||||
use crate::ifs::wl_surface::wl_subsurface::WlSubsurface;
|
||||
use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceError, XdgSurfaceRole};
|
||||
use crate::ifs::wl_surface::xdg_surface::{XdgSurfaceError};
|
||||
use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1Error;
|
||||
use crate::leaks::Tracker;
|
||||
use crate::object::Object;
|
||||
|
|
@ -20,7 +20,7 @@ use crate::pixman::Region;
|
|||
use crate::rect::Rect;
|
||||
use crate::render::Renderer;
|
||||
use crate::tree::walker::NodeVisitor;
|
||||
use crate::tree::{ContainerSplit, Node, NodeId};
|
||||
use crate::tree::{ContainerNode, ContainerSplit, Node, NodeId};
|
||||
use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||
use crate::utils::clonecell::CloneCell;
|
||||
use crate::utils::linkedlist::LinkedList;
|
||||
|
|
@ -37,6 +37,7 @@ use std::mem;
|
|||
use std::ops::{Deref, DerefMut};
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use crate::tree::toplevel::ToplevelNode;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const INVALID_SCALE: u32 = 0;
|
||||
|
|
@ -88,7 +89,7 @@ pub struct WlSurface {
|
|||
ext: CloneCell<Rc<dyn SurfaceExt>>,
|
||||
pub frame_requests: RefCell<Vec<Rc<WlCallback>>>,
|
||||
seat_state: NodeSeatState,
|
||||
xdg: CloneCell<Option<Rc<XdgSurface>>>,
|
||||
toplevel: CloneCell<Option<Rc<dyn ToplevelNode>>>,
|
||||
cursors: SmallMap<SeatId, Rc<CursorSurface>, 1>,
|
||||
pub dnd_icons: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
pub tracker: Tracker<Self>,
|
||||
|
|
@ -203,7 +204,7 @@ impl WlSurface {
|
|||
ext: CloneCell::new(client.state.none_surface_ext.clone()),
|
||||
frame_requests: RefCell::new(vec![]),
|
||||
seat_state: Default::default(),
|
||||
xdg: Default::default(),
|
||||
toplevel: Default::default(),
|
||||
cursors: Default::default(),
|
||||
dnd_icons: Default::default(),
|
||||
tracker: Default::default(),
|
||||
|
|
@ -242,10 +243,10 @@ impl WlSurface {
|
|||
}
|
||||
|
||||
pub fn accepts_kb_focus(&self) -> bool {
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
return xdg.role() == XdgSurfaceRole::XdgToplevel;
|
||||
match self.toplevel.get() {
|
||||
Some(tl) => tl.accepts_keyboard_focus(),
|
||||
_ => self.ext.get().accepts_kb_focus(),
|
||||
}
|
||||
self.ext.get().accepts_kb_focus()
|
||||
}
|
||||
|
||||
fn send_enter(&self, output: WlOutputId) {
|
||||
|
|
@ -255,19 +256,19 @@ impl WlSurface {
|
|||
})
|
||||
}
|
||||
|
||||
fn set_xdg_surface(&self, xdg: Option<Rc<XdgSurface>>) {
|
||||
fn set_toplevel(&self, tl: Option<Rc<dyn ToplevelNode>>) {
|
||||
let ch = self.children.borrow();
|
||||
if let Some(ch) = &*ch {
|
||||
for ss in ch.subsurfaces.values() {
|
||||
ss.surface.set_xdg_surface(xdg.clone());
|
||||
ss.surface.set_toplevel(tl.clone());
|
||||
}
|
||||
}
|
||||
if self.seat_state.is_active() {
|
||||
if let Some(xdg) = &xdg {
|
||||
xdg.surface_active_changed(true);
|
||||
if let Some(tl) = &tl {
|
||||
tl.surface_active_changed(true);
|
||||
}
|
||||
}
|
||||
self.xdg.set(xdg);
|
||||
self.toplevel.set(tl);
|
||||
}
|
||||
|
||||
pub fn set_role(&self, role: SurfaceRole) -> Result<(), WlSurfaceError> {
|
||||
|
|
@ -367,7 +368,7 @@ impl WlSurface {
|
|||
}
|
||||
self.buffer.set(None);
|
||||
self.frame_requests.borrow_mut().clear();
|
||||
self.xdg.set(None);
|
||||
self.toplevel.set(None);
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -588,7 +589,7 @@ impl Object for WlSurface {
|
|||
self.unset_ext();
|
||||
mem::take(self.frame_requests.borrow_mut().deref_mut());
|
||||
self.buffer.set(None);
|
||||
self.xdg.set(None);
|
||||
self.toplevel.set(None);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -611,18 +612,19 @@ impl Node for WlSurface {
|
|||
ss.surface.destroy_node(false);
|
||||
}
|
||||
}
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
let data = tl.data();
|
||||
let mut remove = vec![];
|
||||
for (seat, s) in &xdg.focus_surface {
|
||||
for (seat, s) in data.focus_surface.iter() {
|
||||
if s.id == self.id {
|
||||
remove.push(seat);
|
||||
}
|
||||
}
|
||||
for seat in remove {
|
||||
xdg.focus_surface.remove(&seat);
|
||||
data.focus_surface.remove(&seat);
|
||||
}
|
||||
if self.seat_state.is_active() {
|
||||
xdg.surface_active_changed(false);
|
||||
tl.surface_active_changed(false);
|
||||
}
|
||||
}
|
||||
self.seat_state.destroy_node(self);
|
||||
|
|
@ -642,39 +644,71 @@ impl Node for WlSurface {
|
|||
}
|
||||
|
||||
fn get_parent_mono(&self) -> Option<bool> {
|
||||
self.xdg.get().and_then(|x| x.get_mono())
|
||||
self.toplevel.get()
|
||||
.and_then(|t| t.parent())
|
||||
.and_then(|p| p.get_mono())
|
||||
}
|
||||
|
||||
fn get_parent_split(&self) -> Option<ContainerSplit> {
|
||||
self.xdg.get().and_then(|x| x.get_split())
|
||||
self.toplevel.get()
|
||||
.and_then(|t| t.parent())
|
||||
.and_then(|p| p.get_split())
|
||||
}
|
||||
|
||||
fn set_parent_mono(&self, mono: bool) {
|
||||
self.xdg.get().map(|x| x.set_mono(mono));
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
if let Some(pn) = tl.parent() {
|
||||
let node = if mono { Some(tl.as_node()) } else { None };
|
||||
pn.set_mono(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_parent_split(&self, split: ContainerSplit) {
|
||||
self.xdg.get().map(|x| x.set_split(split));
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
if let Some(pn) = tl.parent() {
|
||||
pn.set_split(split);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_split(self: Rc<Self>, split: ContainerSplit) {
|
||||
self.xdg.get().map(|x| x.create_split(split));
|
||||
let tl = match self.toplevel.get() {
|
||||
Some(tl) => tl,
|
||||
_ => return,
|
||||
};
|
||||
let ws = match tl.workspace() {
|
||||
Some(ws) => ws,
|
||||
_ => return,
|
||||
};
|
||||
let pn = match tl.parent() {
|
||||
Some(pn) => pn,
|
||||
_ => return,
|
||||
};
|
||||
let cn = ContainerNode::new(
|
||||
&self.client.state,
|
||||
&ws,
|
||||
pn.clone(),
|
||||
tl.clone().into_node(),
|
||||
split,
|
||||
);
|
||||
pn.replace_child(tl.as_node(), cn);
|
||||
}
|
||||
|
||||
fn move_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
let xdg = match self.xdg.get() {
|
||||
Some(x) => x,
|
||||
_ => return,
|
||||
};
|
||||
xdg.move_focus(seat, direction);
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
if let Some(pn) = tl.parent() {
|
||||
pn.move_focus_from_child(seat, tl.as_node(), direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn move_self(self: Rc<Self>, direction: Direction) {
|
||||
let xdg = match self.xdg.get() {
|
||||
Some(x) => x,
|
||||
_ => return,
|
||||
};
|
||||
xdg.move_self(direction);
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
if let Some(pn) = tl.parent() {
|
||||
pn.move_child(tl.into_node(), direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
|
|
@ -682,8 +716,8 @@ impl Node for WlSurface {
|
|||
}
|
||||
|
||||
fn active_changed(&self, active: bool) {
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
xdg.surface_active_changed(active);
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
tl.surface_active_changed(active);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -704,21 +738,22 @@ impl Node for WlSurface {
|
|||
}
|
||||
|
||||
fn focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
xdg.focus_surface.insert(seat.id(), self.clone());
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
tl.data().focus_surface.insert(seat.id(), self.clone());
|
||||
tl.activate();
|
||||
}
|
||||
seat.focus_surface(&self);
|
||||
}
|
||||
|
||||
fn focus_parent(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
xdg.focus_parent(seat);
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
tl.parent().map(|p| p.focus_self(seat));
|
||||
}
|
||||
}
|
||||
|
||||
fn toggle_floating(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
||||
if let Some(xdg) = self.xdg.get() {
|
||||
xdg.toggle_floating(seat);
|
||||
fn toggle_floating(self: Rc<Self>, _seat: &Rc<WlSeatGlobal>) {
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
tl.toggle_floating();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ pub mod xdg_popup;
|
|||
pub mod xdg_toplevel;
|
||||
|
||||
use crate::client::ClientError;
|
||||
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal};
|
||||
use crate::ifs::wl_seat::{NodeSeatState};
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_popup::{XdgPopup, XdgPopupError};
|
||||
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel;
|
||||
use crate::ifs::wl_surface::{
|
||||
|
|
@ -12,16 +12,14 @@ use crate::ifs::xdg_wm_base::XdgWmBase;
|
|||
use crate::leaks::Tracker;
|
||||
use crate::object::Object;
|
||||
use crate::rect::Rect;
|
||||
use crate::tree::{ContainerSplit, FindTreeResult, FoundNode, Node, WorkspaceNode};
|
||||
use crate::tree::{FindTreeResult, FoundNode, Node, WorkspaceNode};
|
||||
use crate::utils::buffd::MsgParser;
|
||||
use crate::utils::buffd::MsgParserError;
|
||||
use crate::utils::clonecell::CloneCell;
|
||||
use crate::utils::copyhashmap::CopyHashMap;
|
||||
use crate::utils::smallmap::SmallMap;
|
||||
use crate::wire::xdg_surface::*;
|
||||
use crate::wire::{WlSurfaceId, XdgPopupId, XdgSurfaceId};
|
||||
use crate::NumCell;
|
||||
use jay_config::Direction;
|
||||
use std::cell::Cell;
|
||||
use std::fmt::Debug;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -63,7 +61,6 @@ pub struct XdgSurface {
|
|||
ext: CloneCell<Option<Rc<dyn XdgSurfaceExt>>>,
|
||||
popups: CopyHashMap<XdgPopupId, Rc<XdgPopup>>,
|
||||
pending: PendingXdgSurfaceData,
|
||||
pub(super) focus_surface: SmallMap<SeatId, Rc<WlSurface>, 1>,
|
||||
seat_state: NodeSeatState,
|
||||
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
||||
pub tracker: Tracker<Self>,
|
||||
|
|
@ -75,43 +72,6 @@ struct PendingXdgSurfaceData {
|
|||
}
|
||||
|
||||
pub trait XdgSurfaceExt: Debug {
|
||||
fn focus_parent(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
let _ = seat;
|
||||
}
|
||||
|
||||
fn toggle_floating(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
||||
let _ = seat;
|
||||
}
|
||||
|
||||
fn get_mono(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
fn get_split(&self) -> Option<ContainerSplit> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_mono(&self, mono: bool) {
|
||||
let _ = mono;
|
||||
}
|
||||
|
||||
fn set_split(&self, split: ContainerSplit) {
|
||||
let _ = split;
|
||||
}
|
||||
|
||||
fn create_split(self: Rc<Self>, split: ContainerSplit) {
|
||||
let _ = split;
|
||||
}
|
||||
|
||||
fn move_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
let _ = seat;
|
||||
let _ = direction;
|
||||
}
|
||||
|
||||
fn move_self(self: Rc<Self>, direction: Direction) {
|
||||
let _ = direction;
|
||||
}
|
||||
|
||||
fn initial_configure(self: Rc<Self>) -> Result<(), XdgSurfaceError> {
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -120,17 +80,9 @@ pub trait XdgSurfaceExt: Debug {
|
|||
// nothing
|
||||
}
|
||||
|
||||
fn into_node(self: Rc<Self>) -> Option<Rc<dyn Node>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn extents_changed(&self) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
fn surface_active_changed(self: Rc<Self>, active: bool) {
|
||||
let _ = active;
|
||||
}
|
||||
}
|
||||
|
||||
impl XdgSurface {
|
||||
|
|
@ -148,7 +100,6 @@ impl XdgSurface {
|
|||
ext: Default::default(),
|
||||
popups: Default::default(),
|
||||
pending: Default::default(),
|
||||
focus_surface: Default::default(),
|
||||
seat_state: Default::default(),
|
||||
workspace: Default::default(),
|
||||
tracker: Default::default(),
|
||||
|
|
@ -168,48 +119,6 @@ impl XdgSurface {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn surface_active_changed(&self, active: bool) {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.surface_active_changed(active);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mono(&self) -> Option<bool> {
|
||||
self.ext.get().and_then(|e| e.get_mono())
|
||||
}
|
||||
|
||||
pub fn get_split(&self) -> Option<ContainerSplit> {
|
||||
self.ext.get().and_then(|e| e.get_split())
|
||||
}
|
||||
|
||||
pub fn set_mono(&self, mono: bool) {
|
||||
self.ext.get().map(|e| e.set_mono(mono));
|
||||
}
|
||||
|
||||
pub fn set_split(&self, split: ContainerSplit) {
|
||||
self.ext.get().map(|e| e.set_split(split));
|
||||
}
|
||||
|
||||
pub fn create_split(&self, split: ContainerSplit) {
|
||||
self.ext.get().map(|e| e.create_split(split));
|
||||
}
|
||||
|
||||
pub fn move_focus(&self, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.move_focus(seat, direction);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_self(&self, direction: Direction) {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.move_self(direction);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn role(&self) -> XdgSurfaceRole {
|
||||
self.role.get()
|
||||
}
|
||||
|
||||
fn set_workspace(&self, ws: &Rc<WorkspaceNode>) {
|
||||
self.workspace.set(Some(ws.clone()));
|
||||
let pu = self.popups.lock();
|
||||
|
|
@ -235,18 +144,6 @@ impl XdgSurface {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn focus_parent(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.focus_parent(seat);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_floating(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
if let Some(ext) = self.ext.get() {
|
||||
ext.toggle_floating(seat);
|
||||
}
|
||||
}
|
||||
|
||||
fn destroy_node(&self) {
|
||||
self.workspace.set(None);
|
||||
self.surface.destroy_node(false);
|
||||
|
|
@ -278,7 +175,6 @@ impl XdgSurface {
|
|||
return Err(XdgSurfaceError::AlreadyAttached(self.surface.id));
|
||||
}
|
||||
self.surface.ext.set(self.clone());
|
||||
self.surface.set_xdg_surface(Some(self.clone()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -293,8 +189,6 @@ impl XdgSurface {
|
|||
return Err(DestroyError::PopupsNotYetDestroyed);
|
||||
}
|
||||
}
|
||||
self.focus_surface.clear();
|
||||
self.surface.set_xdg_surface(None);
|
||||
self.surface.unset_ext();
|
||||
self.base.surfaces.remove(&self.id);
|
||||
self.surface.client.remove_obj(self)?;
|
||||
|
|
@ -318,7 +212,8 @@ impl XdgSurface {
|
|||
let toplevel = Rc::new(XdgToplevel::new(req.id, self));
|
||||
track!(self.surface.client, toplevel);
|
||||
self.surface.client.add_client_obj(&toplevel)?;
|
||||
self.ext.set(Some(toplevel));
|
||||
self.ext.set(Some(toplevel.clone()));
|
||||
self.surface.set_toplevel(Some(toplevel));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -422,7 +317,6 @@ impl Object for XdgSurface {
|
|||
}
|
||||
|
||||
fn break_loops(&self) {
|
||||
self.focus_surface.take();
|
||||
self.ext.take();
|
||||
self.popups.clear();
|
||||
self.workspace.set(None);
|
||||
|
|
|
|||
|
|
@ -353,10 +353,6 @@ impl XdgSurfaceExt for XdgPopup {
|
|||
}
|
||||
}
|
||||
|
||||
fn into_node(self: Rc<Self>) -> Option<Rc<dyn Node>> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn extents_changed(&self) {
|
||||
self.xdg.surface.client.state.tree_changed();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,21 @@ use crate::bugs::Bugs;
|
|||
use crate::client::{Client, ClientError};
|
||||
use crate::cursor::KnownCursor;
|
||||
use crate::fixed::Fixed;
|
||||
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal};
|
||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||
use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceError, XdgSurfaceExt};
|
||||
use crate::leaks::Tracker;
|
||||
use crate::object::Object;
|
||||
use crate::rect::Rect;
|
||||
use crate::render::Renderer;
|
||||
use crate::tree::walker::NodeVisitor;
|
||||
use crate::tree::{ContainerNode, ContainerSplit, FindTreeResult};
|
||||
use crate::tree::{FindTreeResult};
|
||||
use crate::tree::{FoundNode, Node, NodeId, ToplevelNodeId, WorkspaceNode};
|
||||
use crate::utils::buffd::MsgParser;
|
||||
use crate::utils::buffd::MsgParserError;
|
||||
use crate::utils::clonecell::CloneCell;
|
||||
use crate::utils::linkedlist::LinkedNode;
|
||||
use crate::utils::smallmap::SmallMap;
|
||||
use crate::wire::xdg_toplevel::*;
|
||||
use crate::wire::XdgToplevelId;
|
||||
use crate::{bugs, NumCell};
|
||||
use crate::{bugs};
|
||||
use ahash::{AHashMap, AHashSet};
|
||||
use jay_config::Direction;
|
||||
use num_derive::FromPrimitive;
|
||||
|
|
@ -27,9 +25,8 @@ use std::fmt::{Debug, Formatter};
|
|||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::tree::toplevel::ToplevelNode;
|
||||
use crate::tree::toplevel::{ToplevelData, ToplevelNode};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Copy, Clone, Debug, FromPrimitive)]
|
||||
|
|
@ -51,15 +48,10 @@ const STATE_MAXIMIZED: u32 = 1;
|
|||
const STATE_FULLSCREEN: u32 = 2;
|
||||
#[allow(dead_code)]
|
||||
const STATE_RESIZING: u32 = 3;
|
||||
#[allow(dead_code)]
|
||||
const STATE_ACTIVATED: u32 = 4;
|
||||
#[allow(dead_code)]
|
||||
const STATE_TILED_LEFT: u32 = 5;
|
||||
#[allow(dead_code)]
|
||||
const STATE_TILED_RIGHT: u32 = 6;
|
||||
#[allow(dead_code)]
|
||||
const STATE_TILED_TOP: u32 = 7;
|
||||
#[allow(dead_code)]
|
||||
const STATE_TILED_BOTTOM: u32 = 8;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
|
|
@ -77,8 +69,6 @@ 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<dyn ToplevelNode>>, 1>,
|
||||
active_surfaces: NumCell<u32>,
|
||||
pub decoration: Cell<Decoration>,
|
||||
bugs: Cell<&'static Bugs>,
|
||||
min_width: Cell<Option<i32>>,
|
||||
|
|
@ -87,6 +77,7 @@ pub struct XdgToplevel {
|
|||
max_height: Cell<Option<i32>>,
|
||||
title: RefCell<String>,
|
||||
pub tracker: Tracker<Self>,
|
||||
toplevel_data: ToplevelData,
|
||||
}
|
||||
|
||||
impl Debug for XdgToplevel {
|
||||
|
|
@ -110,8 +101,6 @@ impl XdgToplevel {
|
|||
parent: Default::default(),
|
||||
children: RefCell::new(Default::default()),
|
||||
states: RefCell::new(states),
|
||||
toplevel_history: Default::default(),
|
||||
active_surfaces: Default::default(),
|
||||
decoration: Cell::new(Decoration::Server),
|
||||
bugs: Cell::new(&bugs::NONE),
|
||||
min_width: Cell::new(None),
|
||||
|
|
@ -120,24 +109,7 @@ impl XdgToplevel {
|
|||
max_height: Cell::new(None),
|
||||
title: RefCell::new("".to_string()),
|
||||
tracker: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_active(self: &Rc<Self>, active: bool) {
|
||||
if let Some(parent) = self.parent_node.get() {
|
||||
parent.child_active_changed(&**self, active);
|
||||
}
|
||||
let changed = {
|
||||
let mut states = self.states.borrow_mut();
|
||||
match active {
|
||||
true => states.insert(STATE_ACTIVATED),
|
||||
false => states.remove(&STATE_ACTIVATED),
|
||||
}
|
||||
};
|
||||
if changed {
|
||||
let rect = self.xdg.absolute_desired_extents.get();
|
||||
self.send_configure_checked(rect.width(), rect.height());
|
||||
self.xdg.do_send_configure();
|
||||
toplevel_data: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -195,6 +167,7 @@ impl XdgToplevel {
|
|||
}
|
||||
}
|
||||
self.xdg.surface.client.remove_obj(self.deref())?;
|
||||
self.xdg.surface.set_toplevel(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -307,27 +280,15 @@ impl XdgToplevel {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn toggle_floating(self: &Rc<Self>) {
|
||||
let parent = match self.parent_node.get() {
|
||||
Some(p) => p,
|
||||
_ => return,
|
||||
};
|
||||
if parent.is_float() {
|
||||
parent.remove_child(&**self);
|
||||
self.map_tiled();
|
||||
} else if let Some(ws) = self.xdg.workspace.get() {
|
||||
parent.remove_child(&**self);
|
||||
self.map_floating(&ws);
|
||||
}
|
||||
}
|
||||
|
||||
fn notify_parent(&self) {
|
||||
let parent = match self.parent_node.get() {
|
||||
Some(p) => p,
|
||||
_ => return,
|
||||
};
|
||||
let extents = self.xdg.extents.get();
|
||||
parent.clone().child_active_changed(self, self.active_surfaces.get() > 0);
|
||||
parent
|
||||
.clone()
|
||||
.child_active_changed(self, self.toplevel_data.active_surfaces.get() > 0);
|
||||
parent.child_size_changed(self, extents.width(), extents.height());
|
||||
parent.child_title_changed(self, self.title.borrow_mut().deref());
|
||||
}
|
||||
|
|
@ -400,7 +361,7 @@ impl Node for XdgToplevel {
|
|||
self.xdg.surface.client.state.tree_changed();
|
||||
}
|
||||
}
|
||||
self.toplevel_history.take();
|
||||
self.toplevel_data.clear();
|
||||
self.xdg.destroy_node();
|
||||
self.xdg.seat_state.destroy_node(self)
|
||||
}
|
||||
|
|
@ -474,87 +435,72 @@ impl Node for XdgToplevel {
|
|||
}
|
||||
|
||||
impl ToplevelNode for XdgToplevel {
|
||||
fn data(&self) -> &ToplevelData {
|
||||
&self.toplevel_data
|
||||
}
|
||||
|
||||
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 workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||
self.xdg.workspace.get()
|
||||
}
|
||||
|
||||
fn as_node(&self) -> &dyn Node {
|
||||
self
|
||||
}
|
||||
|
||||
fn into_node(self: Rc<Self>) -> Rc<dyn Node> {
|
||||
self
|
||||
}
|
||||
|
||||
fn accepts_keyboard_focus(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_surface(&self) -> Rc<WlSurface> {
|
||||
self.xdg.surface.clone()
|
||||
}
|
||||
|
||||
fn set_active(&self, active: bool) {
|
||||
if let Some(parent) = self.parent_node.get() {
|
||||
parent.child_active_changed(self, active);
|
||||
}
|
||||
let changed = {
|
||||
let mut states = self.states.borrow_mut();
|
||||
match active {
|
||||
true => states.insert(STATE_ACTIVATED),
|
||||
false => states.remove(&STATE_ACTIVATED),
|
||||
}
|
||||
};
|
||||
if changed {
|
||||
let rect = self.xdg.absolute_desired_extents.get();
|
||||
self.send_configure_checked(rect.width(), rect.height());
|
||||
self.xdg.do_send_configure();
|
||||
}
|
||||
}
|
||||
|
||||
fn activate(&self) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
fn toggle_floating(self: Rc<Self>) {
|
||||
let parent = match self.parent_node.get() {
|
||||
Some(p) => p,
|
||||
_ => return,
|
||||
};
|
||||
if parent.is_float() {
|
||||
parent.remove_child(&*self);
|
||||
self.map_tiled();
|
||||
} else if let Some(ws) = self.xdg.workspace.get() {
|
||||
parent.remove_child(&*self);
|
||||
self.map_floating(&ws);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl XdgSurfaceExt for XdgToplevel {
|
||||
fn focus_parent(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
self.parent_node.get().map(|p| p.focus_self(seat));
|
||||
}
|
||||
|
||||
fn toggle_floating(self: Rc<Self>, _seat: &Rc<WlSeatGlobal>) {
|
||||
Self::toggle_floating(&self);
|
||||
}
|
||||
|
||||
fn get_mono(&self) -> Option<bool> {
|
||||
self.parent_node.get().and_then(|p| p.get_mono())
|
||||
}
|
||||
|
||||
fn get_split(&self) -> Option<ContainerSplit> {
|
||||
self.parent_node.get().and_then(|p| p.get_split())
|
||||
}
|
||||
|
||||
fn set_mono(&self, mono: bool) {
|
||||
let node = if mono {
|
||||
Some(self as &dyn Node)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.parent_node.get().map(move |p| p.set_mono(node));
|
||||
}
|
||||
|
||||
fn set_split(&self, split: ContainerSplit) {
|
||||
self.parent_node.get().map(|p| p.set_split(split));
|
||||
}
|
||||
|
||||
fn create_split(self: Rc<Self>, split: ContainerSplit) {
|
||||
let ws = match self.xdg.workspace.get() {
|
||||
Some(ws) => ws,
|
||||
_ => return,
|
||||
};
|
||||
let pn = match self.parent_node.get() {
|
||||
Some(pn) => pn,
|
||||
_ => return,
|
||||
};
|
||||
let cn = ContainerNode::new(
|
||||
&self.xdg.surface.client.state,
|
||||
&ws,
|
||||
pn.clone(),
|
||||
self.clone(),
|
||||
split,
|
||||
);
|
||||
pn.replace_child(&*self, cn);
|
||||
}
|
||||
|
||||
fn move_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
if let Some(pn) = self.parent_node.get() {
|
||||
pn.move_focus_from_child(seat, &*self, direction);
|
||||
}
|
||||
}
|
||||
|
||||
fn move_self(self: Rc<Self>, direction: Direction) {
|
||||
if let Some(pn) = self.parent_node.get() {
|
||||
pn.move_child(self, direction);
|
||||
}
|
||||
}
|
||||
|
||||
fn initial_configure(self: Rc<Self>) -> Result<(), XdgSurfaceError> {
|
||||
self.send_configure(0, 0);
|
||||
Ok(())
|
||||
|
|
@ -600,28 +546,12 @@ impl XdgSurfaceExt for XdgToplevel {
|
|||
}
|
||||
}
|
||||
|
||||
fn into_node(self: Rc<Self>) -> Option<Rc<dyn Node>> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn extents_changed(&self) {
|
||||
self.notify_parent();
|
||||
if self.parent_node.get().is_some() {
|
||||
self.xdg.surface.client.state.tree_changed();
|
||||
}
|
||||
}
|
||||
|
||||
fn surface_active_changed(self: Rc<Self>, active: bool) {
|
||||
if active {
|
||||
if self.active_surfaces.fetch_add(1) == 0 {
|
||||
self.set_active(true);
|
||||
}
|
||||
} else {
|
||||
if self.active_surfaces.fetch_sub(1) == 1 {
|
||||
self.set_active(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
|
|
|||
|
|
@ -5,28 +5,118 @@ 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::toplevel::ToplevelNode;
|
||||
use crate::tree::toplevel::{ToplevelData, ToplevelNode};
|
||||
use crate::tree::walker::NodeVisitor;
|
||||
use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode};
|
||||
use crate::utils::copyhashmap::CopyHashMap;
|
||||
use crate::utils::linkedlist::LinkedNode;
|
||||
use crate::utils::smallmap::SmallMap;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use crate::wire_xcon::CreateNotify;
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
use crate::{AsyncQueue, CloneCell, State};
|
||||
use crate::{AsyncQueue, CloneCell, State};
|
||||
use bstr::BString;
|
||||
use jay_config::Direction;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum XInputModel {
|
||||
None,
|
||||
Passive,
|
||||
Local,
|
||||
Global,
|
||||
}
|
||||
|
||||
impl Default for XInputModel {
|
||||
fn default() -> Self {
|
||||
Self::Passive
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct IcccmHints {
|
||||
pub flags: Cell<i32>,
|
||||
pub input: Cell<u32>,
|
||||
pub initial_state: Cell<i32>,
|
||||
pub icon_pixmap: Cell<u32>,
|
||||
pub icon_window: Cell<u32>,
|
||||
pub icon_x: Cell<i32>,
|
||||
pub icon_y: Cell<i32>,
|
||||
pub icon_mask: Cell<u32>,
|
||||
pub window_group: Cell<u32>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct SizeHints {
|
||||
pub flags: Cell<u32>,
|
||||
pub x: Cell<i32>,
|
||||
pub y: Cell<i32>,
|
||||
pub width: Cell<i32>,
|
||||
pub height: Cell<i32>,
|
||||
pub min_width: Cell<i32>,
|
||||
pub min_height: Cell<i32>,
|
||||
pub max_width: Cell<i32>,
|
||||
pub max_height: Cell<i32>,
|
||||
pub width_inc: Cell<i32>,
|
||||
pub height_inc: Cell<i32>,
|
||||
pub min_aspect_num: Cell<i32>,
|
||||
pub min_aspect_den: Cell<i32>,
|
||||
pub max_aspect_num: Cell<i32>,
|
||||
pub max_aspect_den: Cell<i32>,
|
||||
pub base_width: Cell<i32>,
|
||||
pub base_height: Cell<i32>,
|
||||
pub win_gravity: Cell<u32>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct MotifHints {
|
||||
pub flags: Cell<u32>,
|
||||
pub decorations: Cell<u32>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct XwindowInfo {
|
||||
pub has_alpha: Cell<bool>,
|
||||
pub override_redirect: Cell<bool>,
|
||||
pub extents: Cell<Rect>,
|
||||
pub instance: RefCell<Option<BString>>,
|
||||
pub class: RefCell<Option<BString>>,
|
||||
pub title: RefCell<Option<BString>>,
|
||||
pub role: RefCell<Option<BString>>,
|
||||
pub protocols: CopyHashMap<u32, ()>,
|
||||
pub window_types: CopyHashMap<u32, ()>,
|
||||
pub never_focus: Cell<bool>,
|
||||
pub utf8_title: Cell<bool>,
|
||||
pub icccm_hints: IcccmHints,
|
||||
pub normal_hints: SizeHints,
|
||||
pub motif_hints: MotifHints,
|
||||
pub startup_id: RefCell<Option<BString>>,
|
||||
pub fullscreen: Cell<bool>,
|
||||
pub modal: Cell<bool>,
|
||||
pub maximized_vert: Cell<bool>,
|
||||
pub maximized_horz: Cell<bool>,
|
||||
pub minimized: Cell<bool>,
|
||||
pub pid: Cell<Option<u32>>,
|
||||
pub input_model: Cell<XInputModel>,
|
||||
pub mapped: Cell<bool>,
|
||||
pub wants_floating: Cell<bool>,
|
||||
}
|
||||
|
||||
pub struct XwindowData {
|
||||
pub state: Rc<State>,
|
||||
pub window_id: u32,
|
||||
pub override_redirect: bool,
|
||||
pub extents: Cell<Rect>,
|
||||
pub client: Rc<Client>,
|
||||
pub surface_id: Cell<Option<WlSurfaceId>>,
|
||||
pub window: CloneCell<Option<Rc<Xwindow>>>,
|
||||
pub info: XwindowInfo,
|
||||
pub children: CopyHashMap<u32, Rc<XwindowData>>,
|
||||
pub parent: CloneCell<Option<Rc<XwindowData>>>,
|
||||
pub stack_link: RefCell<Option<LinkedNode<Rc<XwindowData>>>>,
|
||||
pub map_link: Cell<Option<LinkedNode<Rc<XwindowData>>>>,
|
||||
pub startup_info: RefCell<Vec<u8>>,
|
||||
pub destroyed: Cell<bool>,
|
||||
}
|
||||
|
||||
tree_id!(XwindowId);
|
||||
|
|
@ -35,12 +125,13 @@ pub struct Xwindow {
|
|||
pub seat_state: NodeSeatState,
|
||||
pub data: Rc<XwindowData>,
|
||||
pub surface: Rc<WlSurface>,
|
||||
pub parent: CloneCell<Option<Rc<dyn Node>>>,
|
||||
pub parent_node: CloneCell<Option<Rc<dyn Node>>>,
|
||||
pub focus_history: SmallMap<SeatId, LinkedNode<Rc<dyn ToplevelNode>>, 1>,
|
||||
pub events: Rc<AsyncQueue<XWaylandEvent>>,
|
||||
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
||||
pub display_link: RefCell<Option<LinkedNode<Rc<dyn Node>>>>,
|
||||
pub display_xlink: RefCell<Option<LinkedNode<Rc<Xwindow>>>>,
|
||||
pub toplevel_data: ToplevelData,
|
||||
}
|
||||
|
||||
impl XwindowData {
|
||||
|
|
@ -52,17 +143,43 @@ impl XwindowData {
|
|||
event.height as _,
|
||||
)
|
||||
.unwrap();
|
||||
log::info!("extents = {:?}", extents);
|
||||
Self {
|
||||
state: state.clone(),
|
||||
window_id: event.window,
|
||||
override_redirect: event.override_redirect != 0,
|
||||
extents: Cell::new(extents),
|
||||
client: client.clone(),
|
||||
surface_id: Cell::new(None),
|
||||
window: Default::default(),
|
||||
info: XwindowInfo {
|
||||
override_redirect: Cell::new(event.override_redirect != 0),
|
||||
extents: Cell::new(extents),
|
||||
..Default::default()
|
||||
},
|
||||
children: Default::default(),
|
||||
parent: Default::default(),
|
||||
stack_link: Default::default(),
|
||||
map_link: Default::default(),
|
||||
startup_info: Default::default(),
|
||||
destroyed: Cell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_ancestor_of(&self, mut other: Rc<Self>) -> bool {
|
||||
loop {
|
||||
if other.window_id == self.window_id {
|
||||
return true;
|
||||
}
|
||||
other = match other.parent.get() {
|
||||
Some(p) => p,
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Change {
|
||||
None,
|
||||
Map,
|
||||
Unmap,
|
||||
}
|
||||
|
||||
impl Xwindow {
|
||||
|
|
@ -76,12 +193,13 @@ impl Xwindow {
|
|||
seat_state: Default::default(),
|
||||
data: data.clone(),
|
||||
surface: surface.clone(),
|
||||
parent: Default::default(),
|
||||
parent_node: Default::default(),
|
||||
focus_history: Default::default(),
|
||||
events: events.clone(),
|
||||
workspace: Default::default(),
|
||||
display_link: Default::default(),
|
||||
display_xlink: Default::default(),
|
||||
toplevel_data: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,6 +210,7 @@ impl Xwindow {
|
|||
|
||||
pub fn break_loops(&self) {
|
||||
self.destroy_node(true);
|
||||
self.surface.set_toplevel(None);
|
||||
}
|
||||
|
||||
pub fn install(self: &Rc<Self>) -> Result<(), XWindowError> {
|
||||
|
|
@ -100,11 +219,12 @@ impl Xwindow {
|
|||
return Err(XWindowError::AlreadyAttached);
|
||||
}
|
||||
self.surface.ext.set(self.clone());
|
||||
self.surface.set_toplevel(Some(self.clone()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn notify_parent(&self) {
|
||||
let parent = match self.parent.get() {
|
||||
let parent = match self.parent_node.get() {
|
||||
Some(p) => p,
|
||||
_ => return,
|
||||
};
|
||||
|
|
@ -115,45 +235,47 @@ impl Xwindow {
|
|||
// parent.child_title_changed(self, self.title.borrow_mut().deref());
|
||||
}
|
||||
|
||||
fn managed_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);
|
||||
}
|
||||
pub fn is_mapped(&self) -> bool {
|
||||
self.parent_node.get().is_some() || self.display_link.borrow_mut().is_some()
|
||||
}
|
||||
|
||||
pub fn may_be_mapped(&self) -> bool {
|
||||
self.surface.buffer.get().is_some() && self.data.info.mapped.get()
|
||||
}
|
||||
|
||||
fn map_change(&self) -> Change {
|
||||
match (self.may_be_mapped(), self.is_mapped()) {
|
||||
(true, false) => Change::Map,
|
||||
(false, true) => Change::Unmap,
|
||||
_ => Change::None,
|
||||
}
|
||||
}
|
||||
|
||||
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()));
|
||||
pub fn map_status_changed(self: &Rc<Self>) {
|
||||
match self.map_change() {
|
||||
Change::None => {}
|
||||
Change::Unmap => self.destroy_node(true),
|
||||
Change::Map if self.data.info.override_redirect.get() => {
|
||||
*self.display_link.borrow_mut() = Some(self.data.state.root.stacked.add_last(self.clone()));
|
||||
*self.display_xlink.borrow_mut() = 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);
|
||||
}
|
||||
Change::Map if self.data.info.wants_floating.get() => {
|
||||
let ws = self.data.state.root.outputs.lock().iter().next().unwrap().1.workspace.get().unwrap();
|
||||
// todo
|
||||
let ext = self.data.info.extents.get();
|
||||
self.data.state.map_floating(self.clone(), ext.width(), ext.height(), &ws);
|
||||
},
|
||||
Change::Map => {
|
||||
self.data.state.map_tiled(self.clone())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SurfaceExt for Xwindow {
|
||||
fn post_commit(self: Rc<Self>) {
|
||||
if self.data.override_redirect {
|
||||
self.unmanaged_post_commit();
|
||||
} else {
|
||||
self.managed_post_commit();
|
||||
}
|
||||
self.map_status_changed();
|
||||
}
|
||||
|
||||
fn on_surface_destroy(&self) -> Result<(), WlSurfaceError> {
|
||||
|
|
@ -185,11 +307,12 @@ impl Node for Xwindow {
|
|||
self.display_link.borrow_mut().take();
|
||||
self.workspace.take();
|
||||
self.focus_history.clear();
|
||||
if let Some(parent) = self.parent.take() {
|
||||
if let Some(parent) = self.parent_node.take() {
|
||||
parent.remove_child(self);
|
||||
}
|
||||
self.surface.destroy_node(false);
|
||||
self.seat_state.destroy_node(self);
|
||||
self.toplevel_data.clear();
|
||||
}
|
||||
|
||||
fn visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor) {
|
||||
|
|
@ -201,7 +324,7 @@ impl Node for Xwindow {
|
|||
}
|
||||
|
||||
fn is_contained_in(&self, other: NodeId) -> bool {
|
||||
if let Some(parent) = self.parent.get() {
|
||||
if let Some(parent) = self.parent_node.get() {
|
||||
if parent.id() == other {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -215,7 +338,7 @@ impl Node for Xwindow {
|
|||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
self.data.extents.get()
|
||||
self.data.info.extents.get()
|
||||
}
|
||||
|
||||
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||
|
|
@ -247,7 +370,7 @@ impl Node for Xwindow {
|
|||
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
||||
let nw = rect.width();
|
||||
let nh = rect.height();
|
||||
let de = self.data.extents.replace(*rect);
|
||||
let de = self.data.info.extents.replace(*rect);
|
||||
if de.width() != nw || de.height() != nh {
|
||||
self.events.push(XWaylandEvent::Configure(self.clone()));
|
||||
}
|
||||
|
|
@ -258,7 +381,7 @@ impl Node for Xwindow {
|
|||
}
|
||||
|
||||
fn set_parent(self: Rc<Self>, parent: Rc<dyn Node>) {
|
||||
self.parent.set(Some(parent));
|
||||
self.parent_node.set(Some(parent));
|
||||
self.notify_parent();
|
||||
}
|
||||
|
||||
|
|
@ -268,21 +391,47 @@ impl Node for Xwindow {
|
|||
}
|
||||
|
||||
impl ToplevelNode for Xwindow {
|
||||
fn data(&self) -> &ToplevelData {
|
||||
&self.toplevel_data
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||
self.parent.get()
|
||||
self.parent_node.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 workspace(&self) -> Option<Rc<WorkspaceNode>> {
|
||||
self.workspace.get()
|
||||
}
|
||||
|
||||
fn as_node(&self) -> &dyn Node {
|
||||
self
|
||||
}
|
||||
|
||||
fn into_node(self: Rc<Self>) -> Rc<dyn Node> {
|
||||
self
|
||||
}
|
||||
|
||||
fn accepts_keyboard_focus(&self) -> bool {
|
||||
self.data.info.icccm_hints.input.get() != 0
|
||||
}
|
||||
|
||||
fn default_surface(&self) -> Rc<WlSurface> {
|
||||
self.surface.clone()
|
||||
}
|
||||
|
||||
fn set_active(&self, active: bool) {
|
||||
if let Some(pn) = self.parent_node.get() {
|
||||
pn.child_active_changed(self, active);
|
||||
}
|
||||
}
|
||||
|
||||
fn activate(&self) {
|
||||
self.events.push(XWaylandEvent::Activate(self.data.clone()));
|
||||
}
|
||||
|
||||
fn toggle_floating(self: Rc<Self>) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue