1
0
Fork 0
forked from wry/wry

tree: map toplevel identifiers to toplevels

This commit is contained in:
Julian Orth 2024-10-10 12:43:43 +02:00
parent 43bb787d52
commit e6c3c9c1ed
9 changed files with 57 additions and 27 deletions

View file

@ -271,6 +271,7 @@ fn start_compositor2(
cpu_worker,
ui_drag_enabled: Cell::new(true),
ui_drag_threshold_squared: Cell::new(10),
toplevels: Default::default(),
});
state.tracker.register(ClientId::from_raw(0));
create_dummy_output(&state);

View file

@ -1227,7 +1227,7 @@ impl UiDragUsecase for TileDragUsecase {
return;
};
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
.clone()
.cnode_replace_child(src.tl_as_node(), placeholder.clone());

View file

@ -205,18 +205,21 @@ impl Xwindow {
if xsurface.xwindow.is_some() {
return Err(XWindowError::AlreadyAttached);
}
let tld = ToplevelData::new(
&data.state,
data.info.title.borrow_mut().clone().unwrap_or_default(),
Some(surface.client.clone()),
);
tld.pos.set(surface.extents.get());
let slf = Rc::new(Self {
id: data.state.node_ids.next(),
data: data.clone(),
display_link: Default::default(),
toplevel_data: tld,
x: xsurface,
let slf = Rc::new_cyclic(|weak| {
let tld = ToplevelData::new(
&data.state,
data.info.title.borrow_mut().clone().unwrap_or_default(),
Some(surface.client.clone()),
weak,
);
tld.pos.set(surface.extents.get());
Self {
id: data.state.node_ids.next(),
data: data.clone(),
display_link: Default::default(),
toplevel_data: tld,
x: xsurface,
}
});
slf.x.xwindow.set(Some(slf.clone()));
slf.x.surface.set_toplevel(Some(slf.clone()));

View file

@ -347,7 +347,7 @@ impl XdgSurfaceRequestHandler for XdgSurface {
);
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);
self.surface.client.add_client_obj(&toplevel)?;
self.ext.set(Some(toplevel.clone()));

View file

@ -38,7 +38,7 @@ use {
cell::{Cell, RefCell},
fmt::{Debug, Formatter},
mem,
rc::Rc,
rc::{Rc, Weak},
},
thiserror::Error,
};
@ -115,7 +115,7 @@ impl Debug for 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();
states.insert(STATE_TILED_LEFT);
states.insert(STATE_TILED_RIGHT);
@ -141,6 +141,7 @@ impl XdgToplevel {
state,
String::new(),
Some(surface.surface.client.clone()),
slf,
),
drag: Default::default(),
is_mapped: Cell::new(false),

View file

@ -78,6 +78,7 @@ use {
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, fdcloser::FdCloser,
hash_map_ext::HashMapExt, linkedlist::LinkedList, numcell::NumCell, queue::AsyncQueue,
refcounted::RefCounted, run_toplevel::RunToplevel,
toplevel_identifier::ToplevelIdentifier,
},
video::{
dmabuf::DmaBufIds,
@ -107,7 +108,7 @@ use {
mem,
num::Wrapping,
ops::DerefMut,
rc::Rc,
rc::{Rc, Weak},
sync::Arc,
time::Duration,
},
@ -220,6 +221,7 @@ pub struct State {
pub cpu_worker: Rc<CpuWorker>,
pub ui_drag_enabled: Cell<bool>,
pub ui_drag_threshold_squared: Cell<i32>,
pub toplevels: CopyHashMap<ToplevelIdentifier, Weak<dyn ToplevelNode>>,
}
// impl Drop for State {
@ -875,6 +877,7 @@ impl State {
self.ei_acceptor_future.take();
self.ei_clients.clear();
self.slow_ei_clients.clear();
self.toplevels.clear();
}
pub fn damage_hardware_cursors(&self, render: bool) {

View file

@ -213,7 +213,7 @@ impl ContainerNode {
let child_node_ref = child_node.clone();
let mut child_nodes = AHashMap::new();
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(),
split: Cell::new(split),
mono_child: CloneCell::new(None),
@ -238,7 +238,7 @@ impl ContainerNode {
state: state.clone(),
render_data: 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(),
});
child.tl_set_parent(slf.clone());

View file

@ -22,7 +22,7 @@ use {
std::{
cell::{Cell, RefCell},
ops::Deref,
rc::Rc,
rc::{Rc, Weak},
sync::Arc,
},
};
@ -48,13 +48,14 @@ pub async fn placeholder_render_textures(state: Rc<State>) {
}
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 {
id: state.node_ids.next(),
toplevel: ToplevelData::new(
state,
node.tl_data().title.borrow().clone(),
node.node_client(),
slf,
),
destroyed: Default::default(),
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 {
id: state.node_ids.next(),
toplevel: ToplevelData::new(state, String::new(), None),
toplevel: ToplevelData::new(state, String::new(), None, slf),
destroyed: Default::default(),
update_textures_scheduled: Default::default(),
state: state.clone(),

View file

@ -282,10 +282,18 @@ pub struct ToplevelData {
pub jay_screencasts: CopyHashMap<(ClientId, JayScreencastId), Rc<JayScreencast>>,
pub ext_copy_sessions:
CopyHashMap<(ClientId, ExtImageCopyCaptureSessionV1Id), Rc<ExtImageCopyCaptureSessionV1>>,
pub slf: Weak<dyn ToplevelNode>,
}
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_active: Cell::new(false),
client,
@ -307,12 +315,13 @@ impl ToplevelData {
wants_attention: Cell::new(false),
requested_attention: Cell::new(false),
app_id: Default::default(),
identifier: Cell::new(toplevel_identifier()),
identifier: Cell::new(id),
handles: Default::default(),
render_highlight: Default::default(),
jay_toplevels: Default::default(),
jay_screencasts: 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() {
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();
for handle in handles.drain_values() {
@ -476,7 +490,8 @@ impl ToplevelData {
log::warn!("Cannot fullscreen root container in a workspace");
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());
let mut kb_foci = Default::default();
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 highlight: Rect,
pub ty: TddType,