mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-10 14:06:11 +03:00
WIP
This commit is contained in:
parent
24086191af
commit
03937a9f89
@ -6,6 +6,7 @@ pub use async_context::*;
|
||||
pub use entity_map::*;
|
||||
pub use model_context::*;
|
||||
use refineable::Refineable;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{
|
||||
current_platform, image_cache::ImageCache, AssetSource, Context, DisplayId, Executor,
|
||||
@ -21,7 +22,7 @@ use slotmap::SlotMap;
|
||||
use std::{
|
||||
any::{type_name, Any, TypeId},
|
||||
mem,
|
||||
sync::{Arc, Weak},
|
||||
sync::{atomic::Ordering::SeqCst, Arc, Weak},
|
||||
};
|
||||
use util::http::{self, HttpClient};
|
||||
|
||||
@ -170,6 +171,7 @@ impl AppContext {
|
||||
fn flush_effects(&mut self) {
|
||||
loop {
|
||||
self.release_dropped_entities();
|
||||
self.release_dropped_focus_handles();
|
||||
if let Some(effect) = self.pending_effects.pop_front() {
|
||||
match effect {
|
||||
Effect::Notify { emitter } => self.apply_notify_effect(emitter),
|
||||
@ -194,7 +196,7 @@ impl AppContext {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
.collect::<SmallVec<[_; 8]>>();
|
||||
|
||||
for dirty_window_id in dirty_window_ids {
|
||||
self.update_window(dirty_window_id, |cx| cx.draw()).unwrap();
|
||||
@ -218,6 +220,32 @@ impl AppContext {
|
||||
}
|
||||
}
|
||||
|
||||
fn release_dropped_focus_handles(&mut self) {
|
||||
let window_ids = self.windows.keys().collect::<SmallVec<[_; 8]>>();
|
||||
for window_id in window_ids {
|
||||
self.update_window(window_id, |cx| {
|
||||
let mut blur_window = false;
|
||||
let focus = cx.window.focus;
|
||||
cx.window.focus_handles.write().retain(|handle_id, count| {
|
||||
if count.load(SeqCst) == 0 {
|
||||
if focus == Some(handle_id) {
|
||||
blur_window = true;
|
||||
}
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
|
||||
if blur_window {
|
||||
cx.window.focus = None;
|
||||
cx.blur();
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_notify_effect(&mut self, emitter: EntityId) {
|
||||
self.pending_notifications.remove(&emitter);
|
||||
self.observers
|
||||
@ -235,8 +263,12 @@ impl AppContext {
|
||||
self.update_window(window_id, |cx| {
|
||||
if cx.window.focus == focused {
|
||||
let mut listeners = mem::take(&mut cx.window.focus_listeners);
|
||||
let focused = focused.map(FocusHandle::new);
|
||||
let blurred = cx.window.last_blur.unwrap().map(FocusHandle::new);
|
||||
let focused = focused.map(|id| FocusHandle::for_id(id, &cx.window.focus_handles));
|
||||
let blurred = cx
|
||||
.window
|
||||
.last_blur
|
||||
.unwrap()
|
||||
.map(|id| FocusHandle::for_id(id, &cx.window.focus_handles));
|
||||
let event = FocusEvent { focused, blurred };
|
||||
for listener in &listeners {
|
||||
listener(&event, cx);
|
||||
|
@ -12,6 +12,8 @@ use crate::{
|
||||
use anyhow::Result;
|
||||
use collections::HashMap;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use parking_lot::{RwLock, RwLockUpgradableReadGuard};
|
||||
use slotmap::SlotMap;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
@ -20,9 +22,12 @@ use std::{
|
||||
future::Future,
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
sync::Arc,
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering::SeqCst},
|
||||
Arc, Weak,
|
||||
},
|
||||
};
|
||||
use util::{post_inc, ResultExt};
|
||||
use util::ResultExt;
|
||||
|
||||
#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default)]
|
||||
pub struct StackingOrder(pub(crate) SmallVec<[u32; 16]>);
|
||||
@ -50,17 +55,34 @@ type AnyKeyDownListener =
|
||||
type AnyKeyUpListener =
|
||||
Box<dyn Fn(&KeyUpEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FocusId(usize);
|
||||
slotmap::new_key_type! { pub struct FocusId; }
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone)]
|
||||
pub struct FocusHandle {
|
||||
pub(crate) id: FocusId,
|
||||
handles: Weak<RwLock<SlotMap<FocusId, AtomicUsize>>>,
|
||||
}
|
||||
|
||||
impl FocusHandle {
|
||||
pub(crate) fn new(id: FocusId) -> Self {
|
||||
Self { id }
|
||||
pub(crate) fn new(handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>) -> Self {
|
||||
let id = handles.write().insert(AtomicUsize::new(1));
|
||||
Self {
|
||||
id,
|
||||
handles: Arc::downgrade(handles),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn for_id(
|
||||
id: FocusId,
|
||||
handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
|
||||
) -> Self {
|
||||
let lock = handles.upgradable_read();
|
||||
let ref_count = lock.get(id).expect("all focus handles dropped for id");
|
||||
ref_count.fetch_add(1, SeqCst);
|
||||
Self {
|
||||
id,
|
||||
handles: Arc::downgrade(handles),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_focused(&self, cx: &WindowContext) -> bool {
|
||||
@ -90,6 +112,22 @@ impl FocusHandle {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for FocusHandle {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FocusHandle {}
|
||||
|
||||
impl Drop for FocusHandle {
|
||||
fn drop(&mut self) {
|
||||
if let Some(handles) = self.handles.upgrade() {
|
||||
handles.read().get(self.id).unwrap().fetch_sub(1, SeqCst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Window {
|
||||
handle: AnyWindowHandle,
|
||||
platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
|
||||
@ -109,6 +147,7 @@ pub struct Window {
|
||||
focus_stack: Vec<FocusStackFrame>,
|
||||
focus_parents_by_child: HashMap<FocusId, FocusId>,
|
||||
pub(crate) focus_listeners: Vec<AnyFocusListener>,
|
||||
pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
|
||||
propagate_event: bool,
|
||||
mouse_position: Point<Pixels>,
|
||||
scale_factor: f32,
|
||||
@ -116,7 +155,6 @@ pub struct Window {
|
||||
pub(crate) dirty: bool,
|
||||
pub(crate) last_blur: Option<Option<FocusId>>,
|
||||
pub(crate) focus: Option<FocusId>,
|
||||
next_focus_id: FocusId,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
@ -185,9 +223,9 @@ impl Window {
|
||||
scale_factor,
|
||||
scene_builder: SceneBuilder::new(),
|
||||
dirty: true,
|
||||
focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
|
||||
last_blur: None,
|
||||
focus: None,
|
||||
next_focus_id: FocusId(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -235,12 +273,13 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||
}
|
||||
|
||||
pub fn focus_handle(&mut self) -> FocusHandle {
|
||||
let id = FocusId(post_inc(&mut self.window.next_focus_id.0));
|
||||
FocusHandle { id }
|
||||
FocusHandle::new(&self.window.focus_handles)
|
||||
}
|
||||
|
||||
pub fn focused(&self) -> Option<FocusHandle> {
|
||||
self.window.focus.map(|id| FocusHandle::new(id))
|
||||
self.window
|
||||
.focus
|
||||
.map(|id| FocusHandle::for_id(id, &self.window.focus_handles))
|
||||
}
|
||||
|
||||
pub fn focus(&mut self, handle: &FocusHandle) {
|
||||
|
Loading…
Reference in New Issue
Block a user