Fix flickering when interacting with the language server logs (#9390)

Fixes https://github.com/zed-industries/zed/issues/9340

The flickering was caused by the pane trying to restore focus on a
`FocusHandle` that wasn't being rendered anymore. This commit uses the
new `WeakFocusHandle` to avoid retaining a reference to focus handles
that don't exist anymore.

Release Notes:

- Fixed a bug that caused flickering when interacting with the language
server logs
([#9340](https://github.com/zed-industries/zed/issues/9340)).
This commit is contained in:
Antonio Scandurra
2024-03-15 11:15:07 +01:00
committed by GitHub
parent b9f7a37f5d
commit 5ae145145e
2 changed files with 55 additions and 10 deletions
+44 -1
View File
@@ -29,7 +29,7 @@ use std::{
rc::Rc,
sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Arc,
Arc, Weak,
},
time::{Duration, Instant},
};
@@ -155,6 +155,14 @@ impl FocusHandle {
}
}
/// Converts this focus handle into a weak variant, which does not prevent it from being released.
pub fn downgrade(&self) -> WeakFocusHandle {
WeakFocusHandle {
id: self.id,
handles: Arc::downgrade(&self.handles),
}
}
/// Moves the focus to the element associated with this handle.
pub fn focus(&self, cx: &mut WindowContext) {
cx.focus(self)
@@ -207,6 +215,41 @@ impl Drop for FocusHandle {
}
}
/// A weak reference to a focus handle.
#[derive(Clone, Debug)]
pub struct WeakFocusHandle {
pub(crate) id: FocusId,
handles: Weak<RwLock<SlotMap<FocusId, AtomicUsize>>>,
}
impl WeakFocusHandle {
/// Attempts to upgrade the [WeakFocusHandle] to a [FocusHandle].
pub fn upgrade(&self) -> Option<FocusHandle> {
let handles = self.handles.upgrade()?;
FocusHandle::for_id(self.id, &handles)
}
}
impl PartialEq for WeakFocusHandle {
fn eq(&self, other: &WeakFocusHandle) -> bool {
self.id == other.id
}
}
impl Eq for WeakFocusHandle {}
impl PartialEq<FocusHandle> for WeakFocusHandle {
fn eq(&self, other: &FocusHandle) -> bool {
self.id == other.id
}
}
impl PartialEq<WeakFocusHandle> for FocusHandle {
fn eq(&self, other: &WeakFocusHandle) -> bool {
self.id == other.id
}
}
/// FocusableView allows users of your view to easily
/// focus it (using cx.focus_view(view))
pub trait FocusableView: 'static + Render {