Fix window double borrows (#23739)
Fix bugs caused by the window context PR, where the window could be on the stack and is then requested from the App. This PR also adds derive macros for `AppContext` and `VisualContext` so that it's easy to define further contexts in API code, such as `editor::BlockContext`. Release Notes: - N/A
This commit is contained in:
parent
29bfb56739
commit
a7c549b85b
24 changed files with 465 additions and 297 deletions
|
@ -1236,15 +1236,9 @@ impl App {
|
|||
T: 'static,
|
||||
{
|
||||
let window_handle = window.handle;
|
||||
let (subscription, activate) = self.release_listeners.insert(
|
||||
handle.entity_id(),
|
||||
Box::new(move |entity, cx| {
|
||||
let entity = entity.downcast_mut().expect("invalid entity type");
|
||||
let _ = window_handle.update(cx, |_, window, cx| on_release(entity, window, cx));
|
||||
}),
|
||||
);
|
||||
activate();
|
||||
subscription
|
||||
self.observe_release(&handle, move |entity, cx| {
|
||||
let _ = window_handle.update(cx, |_, window, cx| on_release(entity, window, cx));
|
||||
})
|
||||
}
|
||||
|
||||
/// Register a callback to be invoked when a keystroke is received by the application
|
||||
|
|
|
@ -323,46 +323,32 @@ impl<'a, T: 'static> Context<'a, T> {
|
|||
pub fn on_release_in(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
on_release: impl FnOnce(&mut T, AnyWindowHandle, &mut App) + 'static,
|
||||
on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
|
||||
) -> Subscription {
|
||||
let window_handle = window.handle;
|
||||
let (subscription, activate) = self.release_listeners.insert(
|
||||
self.entity_id(),
|
||||
Box::new(move |this, cx| {
|
||||
let this = this.downcast_mut().expect("invalid entity type");
|
||||
on_release(this, window_handle, cx)
|
||||
}),
|
||||
);
|
||||
activate();
|
||||
subscription
|
||||
let entity = self.entity();
|
||||
self.app.observe_release_in(&entity, window, on_release)
|
||||
}
|
||||
|
||||
/// Register a callback to be invoked when the given Model or View is released.
|
||||
pub fn observe_release_in<V2>(
|
||||
pub fn observe_release_in<T2>(
|
||||
&self,
|
||||
observed: &Entity<V2>,
|
||||
observed: &Entity<T2>,
|
||||
window: &Window,
|
||||
mut on_release: impl FnMut(&mut T, &mut V2, &mut Window, &mut Context<'_, T>) + 'static,
|
||||
mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<'_, T>) + 'static,
|
||||
) -> Subscription
|
||||
where
|
||||
T: 'static,
|
||||
V2: 'static,
|
||||
T2: 'static,
|
||||
{
|
||||
let observer = self.weak_entity();
|
||||
let window_handle = window.handle;
|
||||
let (subscription, activate) = self.release_listeners.insert(
|
||||
observed.entity_id(),
|
||||
Box::new(move |observed, cx| {
|
||||
let observed = observed
|
||||
.downcast_mut()
|
||||
.expect("invalid observed entity type");
|
||||
let _ = window_handle.update(cx, |_, window, cx| {
|
||||
observer.update(cx, |this, cx| on_release(this, observed, window, cx))
|
||||
});
|
||||
}),
|
||||
);
|
||||
activate();
|
||||
subscription
|
||||
self.app
|
||||
.observe_release_in(observed, window, move |observed, window, cx| {
|
||||
observer
|
||||
.update(cx, |observer, cx| {
|
||||
on_release(observer, observed, window, cx)
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
}
|
||||
|
||||
/// Register a callback to be invoked when the window is resized.
|
||||
|
|
|
@ -129,7 +129,7 @@ pub use elements::*;
|
|||
pub use executor::*;
|
||||
pub use geometry::*;
|
||||
pub use global::*;
|
||||
pub use gpui_macros::{register_action, test, IntoElement, Render};
|
||||
pub use gpui_macros::{register_action, test, AppContext, IntoElement, Render, VisualContext};
|
||||
pub use http_client;
|
||||
pub use input::*;
|
||||
pub use interactive::*;
|
||||
|
|
|
@ -1271,7 +1271,7 @@ impl ClipboardItem {
|
|||
|
||||
for entry in self.entries.iter() {
|
||||
if let ClipboardEntry::String(ClipboardString { text, metadata: _ }) = entry {
|
||||
answer.push_str(text);
|
||||
answer.push_str(&text);
|
||||
any_entries = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ use crate::{
|
|||
AnyView, App, AppContext, Arena, Asset, AsyncWindowContext, AvailableSpace, Background, Bounds,
|
||||
BoxShadow, Context, Corners, CursorStyle, Decorations, DevicePixels, DispatchActionListener,
|
||||
DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter,
|
||||
FileDropEvent, Flatten, FontId, Global, GlobalElementId, GlyphId, GpuSpecs, Hsla, InputHandler,
|
||||
IsZero, KeyBinding, KeyContext, KeyDownEvent, KeyEvent, Keystroke, KeystrokeEvent, LayoutId,
|
||||
FileDropEvent, FontId, Global, GlobalElementId, GlyphId, GpuSpecs, Hsla, InputHandler, IsZero,
|
||||
KeyBinding, KeyContext, KeyDownEvent, KeyEvent, Keystroke, KeystrokeEvent, LayoutId,
|
||||
LineLayoutIndex, Modifiers, ModifiersChangedEvent, MonochromeSprite, MouseButton, MouseEvent,
|
||||
MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInput,
|
||||
PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render,
|
||||
|
@ -677,6 +677,9 @@ pub(crate) struct ElementStateBox {
|
|||
fn default_bounds(display_id: Option<DisplayId>, cx: &mut App) -> Bounds<Pixels> {
|
||||
const DEFAULT_WINDOW_OFFSET: Point<Pixels> = point(px(0.), px(35.));
|
||||
|
||||
// TODO, BUG: if you open a window with the currently active window
|
||||
// on the stack, this will erroneously select the 'unwrap_or_else'
|
||||
// code path
|
||||
cx.active_window()
|
||||
.and_then(|w| w.update(cx, |_, window, _| window.bounds()).ok())
|
||||
.map(|mut bounds| {
|
||||
|
@ -3775,11 +3778,12 @@ impl<V: 'static + Render> WindowHandle<V> {
|
|||
/// Get the root view out of this window.
|
||||
///
|
||||
/// This will fail if the window is closed or if the root view's type does not match `V`.
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn root<C>(&self, cx: &mut C) -> Result<Entity<V>>
|
||||
where
|
||||
C: AppContext,
|
||||
{
|
||||
Flatten::flatten(cx.update_window(self.any_handle, |root_view, _, _| {
|
||||
crate::Flatten::flatten(cx.update_window(self.any_handle, |root_view, _, _| {
|
||||
root_view
|
||||
.downcast::<V>()
|
||||
.map_err(|_| anyhow!("the type of the window's root view has changed"))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue