Checkpoint

This commit is contained in:
Antonio Scandurra 2023-10-18 18:39:29 +02:00
parent 03937a9f89
commit a0634fa79e
2 changed files with 31 additions and 19 deletions

View file

@ -238,7 +238,6 @@ impl AppContext {
}); });
if blur_window { if blur_window {
cx.window.focus = None;
cx.blur(); cx.blur();
} }
}) })
@ -263,12 +262,14 @@ impl AppContext {
self.update_window(window_id, |cx| { self.update_window(window_id, |cx| {
if cx.window.focus == focused { if cx.window.focus == focused {
let mut listeners = mem::take(&mut cx.window.focus_listeners); let mut listeners = mem::take(&mut cx.window.focus_listeners);
let focused = focused.map(|id| FocusHandle::for_id(id, &cx.window.focus_handles)); let focused =
focused.map(|id| FocusHandle::for_id(id, &cx.window.focus_handles).unwrap());
let blurred = cx let blurred = cx
.window .window
.last_blur .last_blur
.take()
.unwrap() .unwrap()
.map(|id| FocusHandle::for_id(id, &cx.window.focus_handles)); .and_then(|id| FocusHandle::for_id(id, &cx.window.focus_handles));
let event = FocusEvent { focused, blurred }; let event = FocusEvent { focused, blurred };
for listener in &listeners { for listener in &listeners {
listener(&event, cx); listener(&event, cx);

View file

@ -12,7 +12,7 @@ use crate::{
use anyhow::Result; use anyhow::Result;
use collections::HashMap; use collections::HashMap;
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use parking_lot::{RwLock, RwLockUpgradableReadGuard}; use parking_lot::RwLock;
use slotmap::SlotMap; use slotmap::SlotMap;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ use std::{
@ -24,7 +24,7 @@ use std::{
mem, mem,
sync::{ sync::{
atomic::{AtomicUsize, Ordering::SeqCst}, atomic::{AtomicUsize, Ordering::SeqCst},
Arc, Weak, Arc,
}, },
}; };
use util::ResultExt; use util::ResultExt;
@ -57,10 +57,9 @@ type AnyKeyUpListener =
slotmap::new_key_type! { pub struct FocusId; } slotmap::new_key_type! { pub struct FocusId; }
#[derive(Clone)]
pub struct FocusHandle { pub struct FocusHandle {
pub(crate) id: FocusId, pub(crate) id: FocusId,
handles: Weak<RwLock<SlotMap<FocusId, AtomicUsize>>>, handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
} }
impl FocusHandle { impl FocusHandle {
@ -68,20 +67,24 @@ impl FocusHandle {
let id = handles.write().insert(AtomicUsize::new(1)); let id = handles.write().insert(AtomicUsize::new(1));
Self { Self {
id, id,
handles: Arc::downgrade(handles), handles: handles.clone(),
} }
} }
pub(crate) fn for_id( pub(crate) fn for_id(
id: FocusId, id: FocusId,
handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>, handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
) -> Self { ) -> Option<Self> {
let lock = handles.upgradable_read(); let lock = handles.read();
let ref_count = lock.get(id).expect("all focus handles dropped for id"); let ref_count = lock.get(id)?;
ref_count.fetch_add(1, SeqCst); if ref_count.load(SeqCst) == 0 {
Self { None
id, } else {
handles: Arc::downgrade(handles), ref_count.fetch_add(1, SeqCst);
Some(Self {
id,
handles: handles.clone(),
})
} }
} }
@ -112,6 +115,12 @@ impl FocusHandle {
} }
} }
impl Clone for FocusHandle {
fn clone(&self) -> Self {
Self::for_id(self.id, &self.handles).unwrap()
}
}
impl PartialEq for FocusHandle { impl PartialEq for FocusHandle {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.id == other.id self.id == other.id
@ -122,9 +131,11 @@ impl Eq for FocusHandle {}
impl Drop for FocusHandle { impl Drop for FocusHandle {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(handles) = self.handles.upgrade() { self.handles
handles.read().get(self.id).unwrap().fetch_sub(1, SeqCst); .read()
} .get(self.id)
.unwrap()
.fetch_sub(1, SeqCst);
} }
} }
@ -279,7 +290,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
pub fn focused(&self) -> Option<FocusHandle> { pub fn focused(&self) -> Option<FocusHandle> {
self.window self.window
.focus .focus
.map(|id| FocusHandle::for_id(id, &self.window.focus_handles)) .and_then(|id| FocusHandle::for_id(id, &self.window.focus_handles))
} }
pub fn focus(&mut self, handle: &FocusHandle) { pub fn focus(&mut self, handle: &FocusHandle) {