1
0
Fork 0
forked from wry/wry

foreign-toplevel: store weak references

This commit is contained in:
Julian Orth 2024-10-08 22:28:44 +02:00
parent 3f9b75e470
commit 9a084a53aa
3 changed files with 31 additions and 14 deletions

View file

@ -3,7 +3,7 @@ use {
client::{Client, ClientError},
leaks::Tracker,
object::{Object, Version},
tree::ToplevelNode,
tree::ToplevelOpt,
wire::{ext_foreign_toplevel_handle_v1::*, ExtForeignToplevelHandleV1Id},
},
std::rc::Rc,
@ -14,16 +14,15 @@ pub struct ExtForeignToplevelHandleV1 {
pub id: ExtForeignToplevelHandleV1Id,
pub client: Rc<Client>,
pub tracker: Tracker<Self>,
pub toplevel: Rc<dyn ToplevelNode>,
pub toplevel: ToplevelOpt,
pub version: Version,
}
impl ExtForeignToplevelHandleV1 {
fn detach(&self) {
self.toplevel
.tl_data()
.handles
.remove(&(self.client.id, self.id));
if let Some(tl) = self.toplevel.get() {
tl.tl_data().handles.remove(&(self.client.id, self.id));
}
}
}

View file

@ -8,7 +8,7 @@ use {
},
leaks::Tracker,
object::{Object, Version},
tree::{NodeVisitorBase, ToplevelNode},
tree::{NodeVisitorBase, ToplevelOpt},
wire::{
ext_foreign_toplevel_list_v1::*, ExtForeignToplevelHandleV1Id,
ExtForeignToplevelListV1Id,
@ -105,10 +105,7 @@ impl ExtForeignToplevelListV1 {
});
}
pub fn publish_toplevel(
&self,
tl: &Rc<dyn ToplevelNode>,
) -> Option<Rc<ExtForeignToplevelHandleV1>> {
pub fn publish_toplevel(&self, tl: ToplevelOpt) -> Option<Rc<ExtForeignToplevelHandleV1>> {
let id: ExtForeignToplevelHandleV1Id = match self.client.new_id() {
Ok(i) => i,
Err(e) => {
@ -120,7 +117,7 @@ impl ExtForeignToplevelListV1 {
id,
client: self.client.clone(),
tracker: Default::default(),
toplevel: tl.clone(),
toplevel: tl,
version: self.version,
});
track!(self.client, handle);

View file

@ -29,7 +29,7 @@ use {
std::{
cell::{Cell, RefCell},
ops::Deref,
rc::Rc,
rc::{Rc, Weak},
},
};
@ -226,6 +226,23 @@ pub struct FullscreenedData {
pub workspace: Rc<WorkspaceNode>,
}
#[derive(Clone)]
pub struct ToplevelOpt {
toplevel: Weak<dyn ToplevelNode>,
identifier: ToplevelIdentifier,
}
impl ToplevelOpt {
pub fn get(&self) -> Option<Rc<dyn ToplevelNode>> {
let tl = self.toplevel.upgrade()?;
if tl.tl_data().identifier.get() == self.identifier {
Some(tl)
} else {
None
}
}
}
pub struct ToplevelData {
pub self_active: Cell<bool>,
pub client: Option<Rc<Client>>,
@ -372,7 +389,11 @@ impl ToplevelData {
title: &str,
app_id: &str,
) {
let handle = match list.publish_toplevel(toplevel) {
let opt = ToplevelOpt {
toplevel: Rc::downgrade(toplevel),
identifier: self.identifier.get(),
};
let handle = match list.publish_toplevel(opt) {
None => return,
Some(handle) => handle,
};