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:
Mikayla Maki 2025-01-27 13:56:29 -08:00 committed by GitHub
parent 29bfb56739
commit a7c549b85b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 465 additions and 297 deletions

View file

@ -81,49 +81,62 @@ pub fn open_prompt_library(
make_completion_provider: Arc<dyn Fn() -> Box<dyn CompletionProvider>>,
cx: &mut App,
) -> Task<Result<WindowHandle<PromptLibrary>>> {
let existing_window = cx
.windows()
.into_iter()
.find_map(|window| window.downcast::<PromptLibrary>());
if let Some(existing_window) = existing_window {
existing_window
.update(cx, |_, window, _| window.activate_window())
.ok();
Task::ready(Ok(existing_window))
} else {
let store = PromptStore::global(cx);
cx.spawn(|cx| async move {
let store = store.await?;
cx.update(|cx| {
let app_id = ReleaseChannel::global(cx).app_id();
let bounds = Bounds::centered(None, size(px(1024.0), px(768.0)), cx);
cx.open_window(
WindowOptions {
titlebar: Some(TitlebarOptions {
title: Some("Prompt Library".into()),
appears_transparent: cfg!(target_os = "macos"),
traffic_light_position: Some(point(px(9.0), px(9.0))),
}),
app_id: Some(app_id.to_owned()),
window_bounds: Some(WindowBounds::Windowed(bounds)),
..Default::default()
},
|window, cx| {
cx.new(|cx| {
PromptLibrary::new(
store,
language_registry,
inline_assist_delegate,
make_completion_provider,
window,
cx,
)
})
},
)
})?
})
}
let store = PromptStore::global(cx);
cx.spawn(|cx| async move {
// We query windows in spawn so that all windows have been returned to GPUI
let existing_window = cx
.update(|cx| {
let existing_window = cx
.windows()
.into_iter()
.find_map(|window| window.downcast::<PromptLibrary>());
if let Some(existing_window) = existing_window {
existing_window
.update(cx, |_, window, _| window.activate_window())
.ok();
Some(existing_window)
} else {
None
}
})
.ok()
.flatten();
if let Some(existing_window) = existing_window {
return Ok(existing_window);
}
let store = store.await?;
cx.update(|cx| {
let app_id = ReleaseChannel::global(cx).app_id();
let bounds = Bounds::centered(None, size(px(1024.0), px(768.0)), cx);
cx.open_window(
WindowOptions {
titlebar: Some(TitlebarOptions {
title: Some("Prompt Library".into()),
appears_transparent: cfg!(target_os = "macos"),
traffic_light_position: Some(point(px(9.0), px(9.0))),
}),
app_id: Some(app_id.to_owned()),
window_bounds: Some(WindowBounds::Windowed(bounds)),
..Default::default()
},
|window, cx| {
cx.new(|cx| {
PromptLibrary::new(
store,
language_registry,
inline_assist_delegate,
make_completion_provider,
window,
cx,
)
})
},
)
})?
})
}
pub struct PromptLibrary {