tree: map toplevel identifiers to toplevels
This commit is contained in:
parent
43bb787d52
commit
e6c3c9c1ed
9 changed files with 57 additions and 27 deletions
|
|
@ -271,6 +271,7 @@ fn start_compositor2(
|
||||||
cpu_worker,
|
cpu_worker,
|
||||||
ui_drag_enabled: Cell::new(true),
|
ui_drag_enabled: Cell::new(true),
|
||||||
ui_drag_threshold_squared: Cell::new(10),
|
ui_drag_threshold_squared: Cell::new(10),
|
||||||
|
toplevels: Default::default(),
|
||||||
});
|
});
|
||||||
state.tracker.register(ClientId::from_raw(0));
|
state.tracker.register(ClientId::from_raw(0));
|
||||||
create_dummy_output(&state);
|
create_dummy_output(&state);
|
||||||
|
|
|
||||||
|
|
@ -1227,7 +1227,7 @@ impl UiDragUsecase for TileDragUsecase {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let detach = || {
|
let detach = || {
|
||||||
let placeholder = Rc::new(PlaceholderNode::new_empty(&seat.state));
|
let placeholder = Rc::new_cyclic(|weak| PlaceholderNode::new_empty(&seat.state, weak));
|
||||||
src_parent
|
src_parent
|
||||||
.clone()
|
.clone()
|
||||||
.cnode_replace_child(src.tl_as_node(), placeholder.clone());
|
.cnode_replace_child(src.tl_as_node(), placeholder.clone());
|
||||||
|
|
|
||||||
|
|
@ -205,18 +205,21 @@ impl Xwindow {
|
||||||
if xsurface.xwindow.is_some() {
|
if xsurface.xwindow.is_some() {
|
||||||
return Err(XWindowError::AlreadyAttached);
|
return Err(XWindowError::AlreadyAttached);
|
||||||
}
|
}
|
||||||
let tld = ToplevelData::new(
|
let slf = Rc::new_cyclic(|weak| {
|
||||||
&data.state,
|
let tld = ToplevelData::new(
|
||||||
data.info.title.borrow_mut().clone().unwrap_or_default(),
|
&data.state,
|
||||||
Some(surface.client.clone()),
|
data.info.title.borrow_mut().clone().unwrap_or_default(),
|
||||||
);
|
Some(surface.client.clone()),
|
||||||
tld.pos.set(surface.extents.get());
|
weak,
|
||||||
let slf = Rc::new(Self {
|
);
|
||||||
id: data.state.node_ids.next(),
|
tld.pos.set(surface.extents.get());
|
||||||
data: data.clone(),
|
Self {
|
||||||
display_link: Default::default(),
|
id: data.state.node_ids.next(),
|
||||||
toplevel_data: tld,
|
data: data.clone(),
|
||||||
x: xsurface,
|
display_link: Default::default(),
|
||||||
|
toplevel_data: tld,
|
||||||
|
x: xsurface,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
slf.x.xwindow.set(Some(slf.clone()));
|
slf.x.xwindow.set(Some(slf.clone()));
|
||||||
slf.x.surface.set_toplevel(Some(slf.clone()));
|
slf.x.surface.set_toplevel(Some(slf.clone()));
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,7 @@ impl XdgSurfaceRequestHandler for XdgSurface {
|
||||||
);
|
);
|
||||||
return Err(XdgSurfaceError::AlreadyConstructed);
|
return Err(XdgSurfaceError::AlreadyConstructed);
|
||||||
}
|
}
|
||||||
let toplevel = Rc::new(XdgToplevel::new(req.id, slf));
|
let toplevel = Rc::new_cyclic(|weak| XdgToplevel::new(req.id, slf, weak));
|
||||||
track!(self.surface.client, toplevel);
|
track!(self.surface.client, toplevel);
|
||||||
self.surface.client.add_client_obj(&toplevel)?;
|
self.surface.client.add_client_obj(&toplevel)?;
|
||||||
self.ext.set(Some(toplevel.clone()));
|
self.ext.set(Some(toplevel.clone()));
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ use {
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
fmt::{Debug, Formatter},
|
fmt::{Debug, Formatter},
|
||||||
mem,
|
mem,
|
||||||
rc::Rc,
|
rc::{Rc, Weak},
|
||||||
},
|
},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
|
|
@ -115,7 +115,7 @@ impl Debug for XdgToplevel {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XdgToplevel {
|
impl XdgToplevel {
|
||||||
pub fn new(id: XdgToplevelId, surface: &Rc<XdgSurface>) -> Self {
|
pub fn new(id: XdgToplevelId, surface: &Rc<XdgSurface>, slf: &Weak<Self>) -> Self {
|
||||||
let mut states = AHashSet::new();
|
let mut states = AHashSet::new();
|
||||||
states.insert(STATE_TILED_LEFT);
|
states.insert(STATE_TILED_LEFT);
|
||||||
states.insert(STATE_TILED_RIGHT);
|
states.insert(STATE_TILED_RIGHT);
|
||||||
|
|
@ -141,6 +141,7 @@ impl XdgToplevel {
|
||||||
state,
|
state,
|
||||||
String::new(),
|
String::new(),
|
||||||
Some(surface.surface.client.clone()),
|
Some(surface.surface.client.clone()),
|
||||||
|
slf,
|
||||||
),
|
),
|
||||||
drag: Default::default(),
|
drag: Default::default(),
|
||||||
is_mapped: Cell::new(false),
|
is_mapped: Cell::new(false),
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ use {
|
||||||
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, fdcloser::FdCloser,
|
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, fdcloser::FdCloser,
|
||||||
hash_map_ext::HashMapExt, linkedlist::LinkedList, numcell::NumCell, queue::AsyncQueue,
|
hash_map_ext::HashMapExt, linkedlist::LinkedList, numcell::NumCell, queue::AsyncQueue,
|
||||||
refcounted::RefCounted, run_toplevel::RunToplevel,
|
refcounted::RefCounted, run_toplevel::RunToplevel,
|
||||||
|
toplevel_identifier::ToplevelIdentifier,
|
||||||
},
|
},
|
||||||
video::{
|
video::{
|
||||||
dmabuf::DmaBufIds,
|
dmabuf::DmaBufIds,
|
||||||
|
|
@ -107,7 +108,7 @@ use {
|
||||||
mem,
|
mem,
|
||||||
num::Wrapping,
|
num::Wrapping,
|
||||||
ops::DerefMut,
|
ops::DerefMut,
|
||||||
rc::Rc,
|
rc::{Rc, Weak},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
},
|
},
|
||||||
|
|
@ -220,6 +221,7 @@ pub struct State {
|
||||||
pub cpu_worker: Rc<CpuWorker>,
|
pub cpu_worker: Rc<CpuWorker>,
|
||||||
pub ui_drag_enabled: Cell<bool>,
|
pub ui_drag_enabled: Cell<bool>,
|
||||||
pub ui_drag_threshold_squared: Cell<i32>,
|
pub ui_drag_threshold_squared: Cell<i32>,
|
||||||
|
pub toplevels: CopyHashMap<ToplevelIdentifier, Weak<dyn ToplevelNode>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Drop for State {
|
// impl Drop for State {
|
||||||
|
|
@ -875,6 +877,7 @@ impl State {
|
||||||
self.ei_acceptor_future.take();
|
self.ei_acceptor_future.take();
|
||||||
self.ei_clients.clear();
|
self.ei_clients.clear();
|
||||||
self.slow_ei_clients.clear();
|
self.slow_ei_clients.clear();
|
||||||
|
self.toplevels.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn damage_hardware_cursors(&self, render: bool) {
|
pub fn damage_hardware_cursors(&self, render: bool) {
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ impl ContainerNode {
|
||||||
let child_node_ref = child_node.clone();
|
let child_node_ref = child_node.clone();
|
||||||
let mut child_nodes = AHashMap::new();
|
let mut child_nodes = AHashMap::new();
|
||||||
child_nodes.insert(child.node_id(), child_node);
|
child_nodes.insert(child.node_id(), child_node);
|
||||||
let slf = Rc::new(Self {
|
let slf = Rc::new_cyclic(|weak| Self {
|
||||||
id: state.node_ids.next(),
|
id: state.node_ids.next(),
|
||||||
split: Cell::new(split),
|
split: Cell::new(split),
|
||||||
mono_child: CloneCell::new(None),
|
mono_child: CloneCell::new(None),
|
||||||
|
|
@ -238,7 +238,7 @@ impl ContainerNode {
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
render_data: Default::default(),
|
render_data: Default::default(),
|
||||||
scroller: Default::default(),
|
scroller: Default::default(),
|
||||||
toplevel_data: ToplevelData::new(state, Default::default(), None),
|
toplevel_data: ToplevelData::new(state, Default::default(), None, weak),
|
||||||
attention_requests: Default::default(),
|
attention_requests: Default::default(),
|
||||||
});
|
});
|
||||||
child.tl_set_parent(slf.clone());
|
child.tl_set_parent(slf.clone());
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ use {
|
||||||
std::{
|
std::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
rc::Rc,
|
rc::{Rc, Weak},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -48,13 +48,14 @@ pub async fn placeholder_render_textures(state: Rc<State>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlaceholderNode {
|
impl PlaceholderNode {
|
||||||
pub fn new_for(state: &Rc<State>, node: Rc<dyn ToplevelNode>) -> Self {
|
pub fn new_for(state: &Rc<State>, node: Rc<dyn ToplevelNode>, slf: &Weak<Self>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: state.node_ids.next(),
|
id: state.node_ids.next(),
|
||||||
toplevel: ToplevelData::new(
|
toplevel: ToplevelData::new(
|
||||||
state,
|
state,
|
||||||
node.tl_data().title.borrow().clone(),
|
node.tl_data().title.borrow().clone(),
|
||||||
node.node_client(),
|
node.node_client(),
|
||||||
|
slf,
|
||||||
),
|
),
|
||||||
destroyed: Default::default(),
|
destroyed: Default::default(),
|
||||||
update_textures_scheduled: Cell::new(false),
|
update_textures_scheduled: Cell::new(false),
|
||||||
|
|
@ -63,10 +64,10 @@ impl PlaceholderNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_empty(state: &Rc<State>) -> Self {
|
pub fn new_empty(state: &Rc<State>, slf: &Weak<Self>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: state.node_ids.next(),
|
id: state.node_ids.next(),
|
||||||
toplevel: ToplevelData::new(state, String::new(), None),
|
toplevel: ToplevelData::new(state, String::new(), None, slf),
|
||||||
destroyed: Default::default(),
|
destroyed: Default::default(),
|
||||||
update_textures_scheduled: Default::default(),
|
update_textures_scheduled: Default::default(),
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
|
|
|
||||||
|
|
@ -282,10 +282,18 @@ pub struct ToplevelData {
|
||||||
pub jay_screencasts: CopyHashMap<(ClientId, JayScreencastId), Rc<JayScreencast>>,
|
pub jay_screencasts: CopyHashMap<(ClientId, JayScreencastId), Rc<JayScreencast>>,
|
||||||
pub ext_copy_sessions:
|
pub ext_copy_sessions:
|
||||||
CopyHashMap<(ClientId, ExtImageCopyCaptureSessionV1Id), Rc<ExtImageCopyCaptureSessionV1>>,
|
CopyHashMap<(ClientId, ExtImageCopyCaptureSessionV1Id), Rc<ExtImageCopyCaptureSessionV1>>,
|
||||||
|
pub slf: Weak<dyn ToplevelNode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToplevelData {
|
impl ToplevelData {
|
||||||
pub fn new(state: &Rc<State>, title: String, client: Option<Rc<Client>>) -> Self {
|
pub fn new<T: ToplevelNode>(
|
||||||
|
state: &Rc<State>,
|
||||||
|
title: String,
|
||||||
|
client: Option<Rc<Client>>,
|
||||||
|
slf: &Weak<T>,
|
||||||
|
) -> Self {
|
||||||
|
let id = toplevel_identifier();
|
||||||
|
state.toplevels.set(id, slf.clone());
|
||||||
Self {
|
Self {
|
||||||
self_active: Cell::new(false),
|
self_active: Cell::new(false),
|
||||||
client,
|
client,
|
||||||
|
|
@ -307,12 +315,13 @@ impl ToplevelData {
|
||||||
wants_attention: Cell::new(false),
|
wants_attention: Cell::new(false),
|
||||||
requested_attention: Cell::new(false),
|
requested_attention: Cell::new(false),
|
||||||
app_id: Default::default(),
|
app_id: Default::default(),
|
||||||
identifier: Cell::new(toplevel_identifier()),
|
identifier: Cell::new(id),
|
||||||
handles: Default::default(),
|
handles: Default::default(),
|
||||||
render_highlight: Default::default(),
|
render_highlight: Default::default(),
|
||||||
jay_toplevels: Default::default(),
|
jay_toplevels: Default::default(),
|
||||||
jay_screencasts: Default::default(),
|
jay_screencasts: Default::default(),
|
||||||
ext_copy_sessions: Default::default(),
|
ext_copy_sessions: Default::default(),
|
||||||
|
slf: slf.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,7 +368,12 @@ impl ToplevelData {
|
||||||
for screencast in self.ext_copy_sessions.lock().drain_values() {
|
for screencast in self.ext_copy_sessions.lock().drain_values() {
|
||||||
screencast.stop();
|
screencast.stop();
|
||||||
}
|
}
|
||||||
self.identifier.set(toplevel_identifier());
|
{
|
||||||
|
let id = toplevel_identifier();
|
||||||
|
let prev = self.identifier.replace(id);
|
||||||
|
self.state.toplevels.remove(&prev);
|
||||||
|
self.state.toplevels.set(id, self.slf.clone());
|
||||||
|
}
|
||||||
{
|
{
|
||||||
let mut handles = self.handles.lock();
|
let mut handles = self.handles.lock();
|
||||||
for handle in handles.drain_values() {
|
for handle in handles.drain_values() {
|
||||||
|
|
@ -476,7 +490,8 @@ impl ToplevelData {
|
||||||
log::warn!("Cannot fullscreen root container in a workspace");
|
log::warn!("Cannot fullscreen root container in a workspace");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let placeholder = Rc::new(PlaceholderNode::new_for(state, node.clone()));
|
let placeholder =
|
||||||
|
Rc::new_cyclic(|weak| PlaceholderNode::new_for(state, node.clone(), weak));
|
||||||
parent.cnode_replace_child(node.tl_as_node(), placeholder.clone());
|
parent.cnode_replace_child(node.tl_as_node(), placeholder.clone());
|
||||||
let mut kb_foci = Default::default();
|
let mut kb_foci = Default::default();
|
||||||
if ws.visible.get() {
|
if ws.visible.get() {
|
||||||
|
|
@ -599,6 +614,12 @@ impl ToplevelData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for ToplevelData {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.state.toplevels.remove(&self.identifier.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct TileDragDestination {
|
pub struct TileDragDestination {
|
||||||
pub highlight: Rect,
|
pub highlight: Rect,
|
||||||
pub ty: TddType,
|
pub ty: TddType,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue