Extract a Frame
struct from Window
Co-Authored-By: Marshall <marshall@zed.dev> Co-Authored-By: Nathan <nathan@zed.dev> Co-Authored-By: Piotr <piotr@zed.dev>
This commit is contained in:
parent
c67f78c065
commit
866df770cb
3 changed files with 136 additions and 118 deletions
|
@ -519,7 +519,7 @@ impl AppContext {
|
||||||
window_handle
|
window_handle
|
||||||
.update(self, |_, cx| {
|
.update(self, |_, 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.current_frame.focus_listeners);
|
||||||
let focused = focused
|
let focused = focused
|
||||||
.map(|id| FocusHandle::for_id(id, &cx.window.focus_handles).unwrap());
|
.map(|id| FocusHandle::for_id(id, &cx.window.focus_handles).unwrap());
|
||||||
let blurred = cx
|
let blurred = cx
|
||||||
|
@ -535,8 +535,8 @@ impl AppContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners.extend(cx.window.focus_listeners.drain(..));
|
listeners.extend(cx.window.current_frame.focus_listeners.drain(..));
|
||||||
cx.window.focus_listeners = listeners;
|
cx.window.current_frame.focus_listeners = listeners;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
|
@ -27,8 +27,8 @@ pub(crate) struct SceneBuilder {
|
||||||
polychrome_sprites: Vec<PolychromeSprite>,
|
polychrome_sprites: Vec<PolychromeSprite>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SceneBuilder {
|
impl Default for SceneBuilder {
|
||||||
pub fn new() -> SceneBuilder {
|
fn default() -> Self {
|
||||||
SceneBuilder {
|
SceneBuilder {
|
||||||
layers_by_order: BTreeMap::new(),
|
layers_by_order: BTreeMap::new(),
|
||||||
splitter: BspSplitter::new(),
|
splitter: BspSplitter::new(),
|
||||||
|
@ -40,6 +40,12 @@ impl SceneBuilder {
|
||||||
polychrome_sprites: Vec::new(),
|
polychrome_sprites: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SceneBuilder {
|
||||||
|
pub fn new() -> SceneBuilder {
|
||||||
|
SceneBuilder::default()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(&mut self) -> Scene {
|
pub fn build(&mut self) -> Scene {
|
||||||
// Map each layer id to a float between 0. and 1., with 1. closer to the viewer.
|
// Map each layer id to a float between 0. and 1., with 1. closer to the viewer.
|
||||||
|
|
|
@ -132,7 +132,12 @@ impl FocusHandle {
|
||||||
if self.id == ancestor_id {
|
if self.id == ancestor_id {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ancestor = cx.window.focus_parents_by_child.get(&ancestor_id).copied();
|
ancestor = cx
|
||||||
|
.window
|
||||||
|
.current_frame
|
||||||
|
.focus_parents_by_child
|
||||||
|
.get(&ancestor_id)
|
||||||
|
.copied();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
@ -175,19 +180,8 @@ pub struct Window {
|
||||||
pub(crate) layout_engine: TaffyLayoutEngine,
|
pub(crate) layout_engine: TaffyLayoutEngine,
|
||||||
pub(crate) root_view: Option<AnyView>,
|
pub(crate) root_view: Option<AnyView>,
|
||||||
pub(crate) element_id_stack: GlobalElementId,
|
pub(crate) element_id_stack: GlobalElementId,
|
||||||
prev_frame_element_states: HashMap<GlobalElementId, AnyBox>,
|
pub(crate) previous_frame: Frame,
|
||||||
element_states: HashMap<GlobalElementId, AnyBox>,
|
pub(crate) current_frame: Frame,
|
||||||
prev_frame_key_matchers: HashMap<GlobalElementId, KeyMatcher>,
|
|
||||||
key_matchers: HashMap<GlobalElementId, KeyMatcher>,
|
|
||||||
z_index_stack: StackingOrder,
|
|
||||||
content_mask_stack: Vec<ContentMask<Pixels>>,
|
|
||||||
element_offset_stack: Vec<Point<Pixels>>,
|
|
||||||
mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyListener)>>,
|
|
||||||
key_dispatch_stack: Vec<KeyDispatchStackFrame>,
|
|
||||||
freeze_key_dispatch_stack: bool,
|
|
||||||
focus_stack: Vec<FocusId>,
|
|
||||||
focus_parents_by_child: HashMap<FocusId, FocusId>,
|
|
||||||
pub(crate) focus_listeners: Vec<AnyFocusListener>,
|
|
||||||
pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
|
pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
|
||||||
default_prevented: bool,
|
default_prevented: bool,
|
||||||
mouse_position: Point<Pixels>,
|
mouse_position: Point<Pixels>,
|
||||||
|
@ -198,12 +192,27 @@ pub struct Window {
|
||||||
bounds_observers: SubscriberSet<(), AnyObserver>,
|
bounds_observers: SubscriberSet<(), AnyObserver>,
|
||||||
active: bool,
|
active: bool,
|
||||||
activation_observers: SubscriberSet<(), AnyObserver>,
|
activation_observers: SubscriberSet<(), AnyObserver>,
|
||||||
pub(crate) scene_builder: SceneBuilder,
|
|
||||||
pub(crate) dirty: bool,
|
pub(crate) dirty: bool,
|
||||||
pub(crate) last_blur: Option<Option<FocusId>>,
|
pub(crate) last_blur: Option<Option<FocusId>>,
|
||||||
pub(crate) focus: Option<FocusId>,
|
pub(crate) focus: Option<FocusId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub(crate) struct Frame {
|
||||||
|
element_states: HashMap<GlobalElementId, AnyBox>,
|
||||||
|
key_matchers: HashMap<GlobalElementId, KeyMatcher>,
|
||||||
|
mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyListener)>>,
|
||||||
|
pub(crate) focus_listeners: Vec<AnyFocusListener>,
|
||||||
|
key_dispatch_stack: Vec<KeyDispatchStackFrame>,
|
||||||
|
freeze_key_dispatch_stack: bool,
|
||||||
|
focus_parents_by_child: HashMap<FocusId, FocusId>,
|
||||||
|
pub(crate) scene_builder: SceneBuilder,
|
||||||
|
z_index_stack: StackingOrder,
|
||||||
|
content_mask_stack: Vec<ContentMask<Pixels>>,
|
||||||
|
element_offset_stack: Vec<Point<Pixels>>,
|
||||||
|
focus_stack: Vec<FocusId>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
handle: AnyWindowHandle,
|
handle: AnyWindowHandle,
|
||||||
|
@ -270,19 +279,8 @@ impl Window {
|
||||||
layout_engine: TaffyLayoutEngine::new(),
|
layout_engine: TaffyLayoutEngine::new(),
|
||||||
root_view: None,
|
root_view: None,
|
||||||
element_id_stack: GlobalElementId::default(),
|
element_id_stack: GlobalElementId::default(),
|
||||||
prev_frame_element_states: HashMap::default(),
|
previous_frame: Frame::default(),
|
||||||
element_states: HashMap::default(),
|
current_frame: Frame::default(),
|
||||||
prev_frame_key_matchers: HashMap::default(),
|
|
||||||
key_matchers: HashMap::default(),
|
|
||||||
z_index_stack: StackingOrder(SmallVec::new()),
|
|
||||||
content_mask_stack: Vec::new(),
|
|
||||||
element_offset_stack: Vec::new(),
|
|
||||||
mouse_listeners: HashMap::default(),
|
|
||||||
key_dispatch_stack: Vec::new(),
|
|
||||||
freeze_key_dispatch_stack: false,
|
|
||||||
focus_stack: Vec::new(),
|
|
||||||
focus_parents_by_child: HashMap::default(),
|
|
||||||
focus_listeners: Vec::new(),
|
|
||||||
focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
|
focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
|
||||||
default_prevented: true,
|
default_prevented: true,
|
||||||
mouse_position,
|
mouse_position,
|
||||||
|
@ -293,7 +291,6 @@ impl Window {
|
||||||
bounds_observers: SubscriberSet::new(),
|
bounds_observers: SubscriberSet::new(),
|
||||||
active: false,
|
active: false,
|
||||||
activation_observers: SubscriberSet::new(),
|
activation_observers: SubscriberSet::new(),
|
||||||
scene_builder: SceneBuilder::new(),
|
|
||||||
dirty: true,
|
dirty: true,
|
||||||
last_blur: None,
|
last_blur: None,
|
||||||
focus: None,
|
focus: None,
|
||||||
|
@ -667,8 +664,9 @@ impl<'a> WindowContext<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
|
handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
|
||||||
) {
|
) {
|
||||||
let order = self.window.z_index_stack.clone();
|
let order = self.window.current_frame.z_index_stack.clone();
|
||||||
self.window
|
self.window
|
||||||
|
.current_frame
|
||||||
.mouse_listeners
|
.mouse_listeners
|
||||||
.entry(TypeId::of::<Event>())
|
.entry(TypeId::of::<Event>())
|
||||||
.or_default()
|
.or_default()
|
||||||
|
@ -692,9 +690,9 @@ impl<'a> WindowContext<'a> {
|
||||||
/// Called during painting to invoke the given closure in a new stacking context. The given
|
/// Called during painting to invoke the given closure in a new stacking context. The given
|
||||||
/// z-index is interpreted relative to the previous call to `stack`.
|
/// z-index is interpreted relative to the previous call to `stack`.
|
||||||
pub fn stack<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
|
pub fn stack<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||||
self.window.z_index_stack.push(z_index);
|
self.window.current_frame.z_index_stack.push(z_index);
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
self.window.z_index_stack.pop();
|
self.window.current_frame.z_index_stack.pop();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,8 +710,8 @@ impl<'a> WindowContext<'a> {
|
||||||
let mut shadow_bounds = bounds;
|
let mut shadow_bounds = bounds;
|
||||||
shadow_bounds.origin += shadow.offset;
|
shadow_bounds.origin += shadow.offset;
|
||||||
shadow_bounds.dilate(shadow.spread_radius);
|
shadow_bounds.dilate(shadow.spread_radius);
|
||||||
window.scene_builder.insert(
|
window.current_frame.scene_builder.insert(
|
||||||
&window.z_index_stack,
|
&window.current_frame.z_index_stack,
|
||||||
Shadow {
|
Shadow {
|
||||||
order: 0,
|
order: 0,
|
||||||
bounds: shadow_bounds.scale(scale_factor),
|
bounds: shadow_bounds.scale(scale_factor),
|
||||||
|
@ -740,8 +738,8 @@ impl<'a> WindowContext<'a> {
|
||||||
let content_mask = self.content_mask();
|
let content_mask = self.content_mask();
|
||||||
|
|
||||||
let window = &mut *self.window;
|
let window = &mut *self.window;
|
||||||
window.scene_builder.insert(
|
window.current_frame.scene_builder.insert(
|
||||||
&window.z_index_stack,
|
&window.current_frame.z_index_stack,
|
||||||
Quad {
|
Quad {
|
||||||
order: 0,
|
order: 0,
|
||||||
bounds: bounds.scale(scale_factor),
|
bounds: bounds.scale(scale_factor),
|
||||||
|
@ -761,9 +759,10 @@ impl<'a> WindowContext<'a> {
|
||||||
path.content_mask = content_mask;
|
path.content_mask = content_mask;
|
||||||
path.color = color.into();
|
path.color = color.into();
|
||||||
let window = &mut *self.window;
|
let window = &mut *self.window;
|
||||||
window
|
window.current_frame.scene_builder.insert(
|
||||||
.scene_builder
|
&window.current_frame.z_index_stack,
|
||||||
.insert(&window.z_index_stack, path.scale(scale_factor));
|
path.scale(scale_factor),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Paint an underline into the scene for the current frame at the current z-index.
|
/// Paint an underline into the scene for the current frame at the current z-index.
|
||||||
|
@ -785,8 +784,8 @@ impl<'a> WindowContext<'a> {
|
||||||
};
|
};
|
||||||
let content_mask = self.content_mask();
|
let content_mask = self.content_mask();
|
||||||
let window = &mut *self.window;
|
let window = &mut *self.window;
|
||||||
window.scene_builder.insert(
|
window.current_frame.scene_builder.insert(
|
||||||
&window.z_index_stack,
|
&window.current_frame.z_index_stack,
|
||||||
Underline {
|
Underline {
|
||||||
order: 0,
|
order: 0,
|
||||||
bounds: bounds.scale(scale_factor),
|
bounds: bounds.scale(scale_factor),
|
||||||
|
@ -839,8 +838,8 @@ impl<'a> WindowContext<'a> {
|
||||||
};
|
};
|
||||||
let content_mask = self.content_mask().scale(scale_factor);
|
let content_mask = self.content_mask().scale(scale_factor);
|
||||||
let window = &mut *self.window;
|
let window = &mut *self.window;
|
||||||
window.scene_builder.insert(
|
window.current_frame.scene_builder.insert(
|
||||||
&window.z_index_stack,
|
&window.current_frame.z_index_stack,
|
||||||
MonochromeSprite {
|
MonochromeSprite {
|
||||||
order: 0,
|
order: 0,
|
||||||
bounds,
|
bounds,
|
||||||
|
@ -890,8 +889,8 @@ impl<'a> WindowContext<'a> {
|
||||||
let content_mask = self.content_mask().scale(scale_factor);
|
let content_mask = self.content_mask().scale(scale_factor);
|
||||||
let window = &mut *self.window;
|
let window = &mut *self.window;
|
||||||
|
|
||||||
window.scene_builder.insert(
|
window.current_frame.scene_builder.insert(
|
||||||
&window.z_index_stack,
|
&window.current_frame.z_index_stack,
|
||||||
PolychromeSprite {
|
PolychromeSprite {
|
||||||
order: 0,
|
order: 0,
|
||||||
bounds,
|
bounds,
|
||||||
|
@ -932,8 +931,8 @@ impl<'a> WindowContext<'a> {
|
||||||
let content_mask = self.content_mask().scale(scale_factor);
|
let content_mask = self.content_mask().scale(scale_factor);
|
||||||
|
|
||||||
let window = &mut *self.window;
|
let window = &mut *self.window;
|
||||||
window.scene_builder.insert(
|
window.current_frame.scene_builder.insert(
|
||||||
&window.z_index_stack,
|
&window.current_frame.z_index_stack,
|
||||||
MonochromeSprite {
|
MonochromeSprite {
|
||||||
order: 0,
|
order: 0,
|
||||||
bounds,
|
bounds,
|
||||||
|
@ -968,8 +967,8 @@ impl<'a> WindowContext<'a> {
|
||||||
let corner_radii = corner_radii.scale(scale_factor);
|
let corner_radii = corner_radii.scale(scale_factor);
|
||||||
|
|
||||||
let window = &mut *self.window;
|
let window = &mut *self.window;
|
||||||
window.scene_builder.insert(
|
window.current_frame.scene_builder.insert(
|
||||||
&window.z_index_stack,
|
&window.current_frame.z_index_stack,
|
||||||
PolychromeSprite {
|
PolychromeSprite {
|
||||||
order: 0,
|
order: 0,
|
||||||
bounds,
|
bounds,
|
||||||
|
@ -1014,7 +1013,7 @@ impl<'a> WindowContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.window.root_view = Some(root_view);
|
self.window.root_view = Some(root_view);
|
||||||
let scene = self.window.scene_builder.build();
|
let scene = self.window.current_frame.scene_builder.build();
|
||||||
|
|
||||||
self.window.platform_window.draw(scene);
|
self.window.platform_window.draw(scene);
|
||||||
let cursor_style = self
|
let cursor_style = self
|
||||||
|
@ -1030,39 +1029,21 @@ impl<'a> WindowContext<'a> {
|
||||||
self.window.dirty = false;
|
self.window.dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rotate the current frame and the previous frame, then clear the current frame.
|
||||||
|
/// We repopulate all state in the current frame during each paint.
|
||||||
fn start_frame(&mut self) {
|
fn start_frame(&mut self) {
|
||||||
self.text_system().start_frame();
|
self.text_system().start_frame();
|
||||||
|
|
||||||
let window = &mut *self.window;
|
let window = &mut *self.window;
|
||||||
|
mem::swap(&mut window.previous_frame, &mut window.current_frame);
|
||||||
// Move the current frame element states to the previous frame.
|
let frame = &mut window.current_frame;
|
||||||
// The new empty element states map will be populated for any element states we
|
frame.element_states.clear();
|
||||||
// reference during the upcoming frame.
|
frame.key_matchers.clear();
|
||||||
mem::swap(
|
frame.mouse_listeners.values_mut().for_each(Vec::clear);
|
||||||
&mut window.element_states,
|
frame.focus_listeners.clear();
|
||||||
&mut window.prev_frame_element_states,
|
frame.key_dispatch_stack.clear();
|
||||||
);
|
frame.focus_parents_by_child.clear();
|
||||||
window.element_states.clear();
|
frame.freeze_key_dispatch_stack = false;
|
||||||
|
|
||||||
// Make the current key matchers the previous, and then clear the current.
|
|
||||||
// An empty key matcher map will be created for every identified element in the
|
|
||||||
// upcoming frame.
|
|
||||||
mem::swap(
|
|
||||||
&mut window.key_matchers,
|
|
||||||
&mut window.prev_frame_key_matchers,
|
|
||||||
);
|
|
||||||
window.key_matchers.clear();
|
|
||||||
|
|
||||||
// Clear mouse event listeners, because elements add new element listeners
|
|
||||||
// when the upcoming frame is painted.
|
|
||||||
window.mouse_listeners.values_mut().for_each(Vec::clear);
|
|
||||||
|
|
||||||
// Clear focus state, because we determine what is focused when the new elements
|
|
||||||
// in the upcoming frame are initialized.
|
|
||||||
window.focus_listeners.clear();
|
|
||||||
window.key_dispatch_stack.clear();
|
|
||||||
window.focus_parents_by_child.clear();
|
|
||||||
window.freeze_key_dispatch_stack = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dispatch a mouse or keyboard event on the window.
|
/// Dispatch a mouse or keyboard event on the window.
|
||||||
|
@ -1126,6 +1107,7 @@ impl<'a> WindowContext<'a> {
|
||||||
if let Some(any_mouse_event) = event.mouse_event() {
|
if let Some(any_mouse_event) = event.mouse_event() {
|
||||||
if let Some(mut handlers) = self
|
if let Some(mut handlers) = self
|
||||||
.window
|
.window
|
||||||
|
.current_frame
|
||||||
.mouse_listeners
|
.mouse_listeners
|
||||||
.remove(&any_mouse_event.type_id())
|
.remove(&any_mouse_event.type_id())
|
||||||
{
|
{
|
||||||
|
@ -1160,18 +1142,20 @@ impl<'a> WindowContext<'a> {
|
||||||
// Just in case any handlers added new handlers, which is weird, but possible.
|
// Just in case any handlers added new handlers, which is weird, but possible.
|
||||||
handlers.extend(
|
handlers.extend(
|
||||||
self.window
|
self.window
|
||||||
|
.current_frame
|
||||||
.mouse_listeners
|
.mouse_listeners
|
||||||
.get_mut(&any_mouse_event.type_id())
|
.get_mut(&any_mouse_event.type_id())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|handlers| handlers.drain(..)),
|
.flat_map(|handlers| handlers.drain(..)),
|
||||||
);
|
);
|
||||||
self.window
|
self.window
|
||||||
|
.current_frame
|
||||||
.mouse_listeners
|
.mouse_listeners
|
||||||
.insert(any_mouse_event.type_id(), handlers);
|
.insert(any_mouse_event.type_id(), handlers);
|
||||||
}
|
}
|
||||||
} else if let Some(any_key_event) = event.keyboard_event() {
|
} else if let Some(any_key_event) = event.keyboard_event() {
|
||||||
let mut did_handle_action = false;
|
let mut did_handle_action = false;
|
||||||
let key_dispatch_stack = mem::take(&mut self.window.key_dispatch_stack);
|
let key_dispatch_stack = mem::take(&mut self.window.current_frame.key_dispatch_stack);
|
||||||
let key_event_type = any_key_event.type_id();
|
let key_event_type = any_key_event.type_id();
|
||||||
let mut context_stack = SmallVec::<[&DispatchContext; 16]>::new();
|
let mut context_stack = SmallVec::<[&DispatchContext; 16]>::new();
|
||||||
|
|
||||||
|
@ -1233,7 +1217,7 @@ impl<'a> WindowContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(context_stack);
|
drop(context_stack);
|
||||||
self.window.key_dispatch_stack = key_dispatch_stack;
|
self.window.current_frame.key_dispatch_stack = key_dispatch_stack;
|
||||||
return did_handle_action;
|
return did_handle_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1249,13 +1233,14 @@ impl<'a> WindowContext<'a> {
|
||||||
) -> KeyMatch {
|
) -> KeyMatch {
|
||||||
let key_match = self
|
let key_match = self
|
||||||
.window
|
.window
|
||||||
|
.current_frame
|
||||||
.key_matchers
|
.key_matchers
|
||||||
.get_mut(element_id)
|
.get_mut(element_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.match_keystroke(keystroke, context_stack);
|
.match_keystroke(keystroke, context_stack);
|
||||||
|
|
||||||
if key_match.is_some() {
|
if key_match.is_some() {
|
||||||
for matcher in self.window.key_matchers.values_mut() {
|
for matcher in self.window.current_frame.key_matchers.values_mut() {
|
||||||
matcher.clear_pending();
|
matcher.clear_pending();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1515,11 +1500,12 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
window.element_id_stack.push(id.into());
|
window.element_id_stack.push(id.into());
|
||||||
let global_id = window.element_id_stack.clone();
|
let global_id = window.element_id_stack.clone();
|
||||||
|
|
||||||
if window.key_matchers.get(&global_id).is_none() {
|
if window.current_frame.key_matchers.get(&global_id).is_none() {
|
||||||
window.key_matchers.insert(
|
window.current_frame.key_matchers.insert(
|
||||||
global_id.clone(),
|
global_id.clone(),
|
||||||
window
|
window
|
||||||
.prev_frame_key_matchers
|
.previous_frame
|
||||||
|
.key_matchers
|
||||||
.remove(&global_id)
|
.remove(&global_id)
|
||||||
.unwrap_or_else(|| KeyMatcher::new(keymap)),
|
.unwrap_or_else(|| KeyMatcher::new(keymap)),
|
||||||
);
|
);
|
||||||
|
@ -1539,9 +1525,12 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
f: impl FnOnce(&mut Self) -> R,
|
f: impl FnOnce(&mut Self) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
let mask = mask.intersect(&self.content_mask());
|
let mask = mask.intersect(&self.content_mask());
|
||||||
self.window_mut().content_mask_stack.push(mask);
|
self.window_mut()
|
||||||
|
.current_frame
|
||||||
|
.content_mask_stack
|
||||||
|
.push(mask);
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
self.window_mut().content_mask_stack.pop();
|
self.window_mut().current_frame.content_mask_stack.pop();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1557,15 +1546,19 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let offset = self.element_offset() + offset;
|
let offset = self.element_offset() + offset;
|
||||||
self.window_mut().element_offset_stack.push(offset);
|
self.window_mut()
|
||||||
|
.current_frame
|
||||||
|
.element_offset_stack
|
||||||
|
.push(offset);
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
self.window_mut().element_offset_stack.pop();
|
self.window_mut().current_frame.element_offset_stack.pop();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain the current element offset.
|
/// Obtain the current element offset.
|
||||||
fn element_offset(&self) -> Point<Pixels> {
|
fn element_offset(&self) -> Point<Pixels> {
|
||||||
self.window()
|
self.window()
|
||||||
|
.current_frame
|
||||||
.element_offset_stack
|
.element_offset_stack
|
||||||
.last()
|
.last()
|
||||||
.copied()
|
.copied()
|
||||||
|
@ -1587,9 +1580,15 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
self.with_element_id(id, |global_id, cx| {
|
self.with_element_id(id, |global_id, cx| {
|
||||||
if let Some(any) = cx
|
if let Some(any) = cx
|
||||||
.window_mut()
|
.window_mut()
|
||||||
|
.current_frame
|
||||||
.element_states
|
.element_states
|
||||||
.remove(&global_id)
|
.remove(&global_id)
|
||||||
.or_else(|| cx.window_mut().prev_frame_element_states.remove(&global_id))
|
.or_else(|| {
|
||||||
|
cx.window_mut()
|
||||||
|
.previous_frame
|
||||||
|
.element_states
|
||||||
|
.remove(&global_id)
|
||||||
|
})
|
||||||
{
|
{
|
||||||
// Using the extra inner option to avoid needing to reallocate a new box.
|
// Using the extra inner option to avoid needing to reallocate a new box.
|
||||||
let mut state_box = any
|
let mut state_box = any
|
||||||
|
@ -1600,11 +1599,15 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
.expect("element state is already on the stack");
|
.expect("element state is already on the stack");
|
||||||
let (result, state) = f(Some(state), cx);
|
let (result, state) = f(Some(state), cx);
|
||||||
state_box.replace(state);
|
state_box.replace(state);
|
||||||
cx.window_mut().element_states.insert(global_id, state_box);
|
cx.window_mut()
|
||||||
|
.current_frame
|
||||||
|
.element_states
|
||||||
|
.insert(global_id, state_box);
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
let (result, state) = f(None, cx);
|
let (result, state) = f(None, cx);
|
||||||
cx.window_mut()
|
cx.window_mut()
|
||||||
|
.current_frame
|
||||||
.element_states
|
.element_states
|
||||||
.insert(global_id, Box::new(Some(state)));
|
.insert(global_id, Box::new(Some(state)));
|
||||||
result
|
result
|
||||||
|
@ -1632,6 +1635,7 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
/// Obtain the current content mask.
|
/// Obtain the current content mask.
|
||||||
fn content_mask(&self) -> ContentMask<Pixels> {
|
fn content_mask(&self) -> ContentMask<Pixels> {
|
||||||
self.window()
|
self.window()
|
||||||
|
.current_frame
|
||||||
.content_mask_stack
|
.content_mask_stack
|
||||||
.last()
|
.last()
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -1716,9 +1720,9 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_z_index<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
|
pub fn with_z_index<R>(&mut self, z_index: u32, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||||
self.window.z_index_stack.push(z_index);
|
self.window.current_frame.z_index_stack.push(z_index);
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
self.window.z_index_stack.pop();
|
self.window.current_frame.z_index_stack.pop();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1873,11 +1877,14 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
listener: impl Fn(&mut V, &FocusEvent, &mut ViewContext<V>) + 'static,
|
listener: impl Fn(&mut V, &FocusEvent, &mut ViewContext<V>) + 'static,
|
||||||
) {
|
) {
|
||||||
let handle = self.view().downgrade();
|
let handle = self.view().downgrade();
|
||||||
self.window.focus_listeners.push(Box::new(move |event, cx| {
|
self.window
|
||||||
handle
|
.current_frame
|
||||||
.update(cx, |view, cx| listener(view, event, cx))
|
.focus_listeners
|
||||||
.log_err();
|
.push(Box::new(move |event, cx| {
|
||||||
}));
|
handle
|
||||||
|
.update(cx, |view, cx| listener(view, event, cx))
|
||||||
|
.log_err();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_key_listeners<R>(
|
pub fn with_key_listeners<R>(
|
||||||
|
@ -1885,8 +1892,8 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
key_listeners: impl IntoIterator<Item = (TypeId, KeyListener<V>)>,
|
key_listeners: impl IntoIterator<Item = (TypeId, KeyListener<V>)>,
|
||||||
f: impl FnOnce(&mut Self) -> R,
|
f: impl FnOnce(&mut Self) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
let old_stack_len = self.window.key_dispatch_stack.len();
|
let old_stack_len = self.window.current_frame.key_dispatch_stack.len();
|
||||||
if !self.window.freeze_key_dispatch_stack {
|
if !self.window.current_frame.freeze_key_dispatch_stack {
|
||||||
for (event_type, listener) in key_listeners {
|
for (event_type, listener) in key_listeners {
|
||||||
let handle = self.view().downgrade();
|
let handle = self.view().downgrade();
|
||||||
let listener = Box::new(
|
let listener = Box::new(
|
||||||
|
@ -1902,19 +1909,22 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
.flatten()
|
.flatten()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.window
|
self.window.current_frame.key_dispatch_stack.push(
|
||||||
.key_dispatch_stack
|
KeyDispatchStackFrame::Listener {
|
||||||
.push(KeyDispatchStackFrame::Listener {
|
|
||||||
event_type,
|
event_type,
|
||||||
listener,
|
listener,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
|
|
||||||
if !self.window.freeze_key_dispatch_stack {
|
if !self.window.current_frame.freeze_key_dispatch_stack {
|
||||||
self.window.key_dispatch_stack.truncate(old_stack_len);
|
self.window
|
||||||
|
.current_frame
|
||||||
|
.key_dispatch_stack
|
||||||
|
.truncate(old_stack_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -1929,16 +1939,17 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
return f(self);
|
return f(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.window.freeze_key_dispatch_stack {
|
if !self.window.current_frame.freeze_key_dispatch_stack {
|
||||||
self.window
|
self.window
|
||||||
|
.current_frame
|
||||||
.key_dispatch_stack
|
.key_dispatch_stack
|
||||||
.push(KeyDispatchStackFrame::Context(context));
|
.push(KeyDispatchStackFrame::Context(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
|
|
||||||
if !self.window.freeze_key_dispatch_stack {
|
if !self.window.previous_frame.freeze_key_dispatch_stack {
|
||||||
self.window.key_dispatch_stack.pop();
|
self.window.previous_frame.key_dispatch_stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -1949,20 +1960,21 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
f: impl FnOnce(&mut Self) -> R,
|
f: impl FnOnce(&mut Self) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
if let Some(parent_focus_id) = self.window.focus_stack.last().copied() {
|
if let Some(parent_focus_id) = self.window.current_frame.focus_stack.last().copied() {
|
||||||
self.window
|
self.window
|
||||||
|
.current_frame
|
||||||
.focus_parents_by_child
|
.focus_parents_by_child
|
||||||
.insert(focus_handle.id, parent_focus_id);
|
.insert(focus_handle.id, parent_focus_id);
|
||||||
}
|
}
|
||||||
self.window.focus_stack.push(focus_handle.id);
|
self.window.current_frame.focus_stack.push(focus_handle.id);
|
||||||
|
|
||||||
if Some(focus_handle.id) == self.window.focus {
|
if Some(focus_handle.id) == self.window.focus {
|
||||||
self.window.freeze_key_dispatch_stack = true;
|
self.window.current_frame.freeze_key_dispatch_stack = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
|
|
||||||
self.window.focus_stack.pop();
|
self.window.current_frame.focus_stack.pop();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue