Pull app / OS info out of GPUI, add Linux information, make fallible window initialization (#12869)

TODO:
- [x] Finish GPUI changes on other operating systems 

This is a largely internal change to how we report data to our
diagnostics and telemetry. This PR also includes an update to our blade
backend which allows us to report errors in a more useful way when
failing to initialize blade.


Release Notes:

- N/A

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Mikayla Maki 2024-06-11 11:43:12 -07:00 committed by GitHub
parent ec9e700e70
commit 80c14c9198
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
50 changed files with 571 additions and 550 deletions

View file

@ -27,13 +27,12 @@ use util::ResultExt;
use crate::{
current_platform, init_app_menus, Action, ActionRegistry, Any, AnyView, AnyWindowHandle,
AppMetadata, AssetCache, AssetSource, BackgroundExecutor, ClipboardItem, Context,
DispatchPhase, DisplayId, Entity, EventEmitter, ForegroundExecutor, Global, KeyBinding, Keymap,
Keystroke, LayoutId, Menu, MenuItem, OwnedMenu, PathPromptOptions, Pixels, Platform,
PlatformDisplay, Point, PromptBuilder, PromptHandle, PromptLevel, Render,
RenderablePromptHandle, Reservation, SharedString, SubscriberSet, Subscription, SvgRenderer,
Task, TextSystem, View, ViewContext, Window, WindowAppearance, WindowContext, WindowHandle,
WindowId,
AssetCache, AssetSource, BackgroundExecutor, ClipboardItem, Context, DispatchPhase, DisplayId,
Entity, EventEmitter, ForegroundExecutor, Global, KeyBinding, Keymap, Keystroke, LayoutId,
Menu, MenuItem, OwnedMenu, PathPromptOptions, Pixels, Platform, PlatformDisplay, Point,
PromptBuilder, PromptHandle, PromptLevel, Render, RenderablePromptHandle, Reservation,
SharedString, SubscriberSet, Subscription, SvgRenderer, Task, TextSystem, View, ViewContext,
Window, WindowAppearance, WindowContext, WindowHandle, WindowId,
};
mod async_context;
@ -169,11 +168,6 @@ impl App {
self
}
/// Returns metadata associated with the application
pub fn metadata(&self) -> AppMetadata {
self.0.borrow().app_metadata.clone()
}
/// Returns a handle to the [`BackgroundExecutor`] associated with this app, which can be used to spawn futures in the background.
pub fn background_executor(&self) -> BackgroundExecutor {
self.0.borrow().background_executor.clone()
@ -208,7 +202,6 @@ type NewViewListener = Box<dyn FnMut(AnyView, &mut WindowContext) + 'static>;
pub struct AppContext {
pub(crate) this: Weak<AppCell>,
pub(crate) platform: Rc<dyn Platform>,
app_metadata: AppMetadata,
text_system: Arc<TextSystem>,
flushing_effects: bool,
pending_updates: usize,
@ -261,17 +254,10 @@ impl AppContext {
let text_system = Arc::new(TextSystem::new(platform.text_system()));
let entities = EntityMap::new();
let app_metadata = AppMetadata {
os_name: platform.os_name(),
os_version: platform.os_version().ok(),
app_version: platform.app_version().ok(),
};
let app = Rc::new_cyclic(|this| AppCell {
app: RefCell::new(AppContext {
this: this.clone(),
platform: platform.clone(),
app_metadata,
text_system,
actions: Rc::new(ActionRegistry::default()),
flushing_effects: false,
@ -346,11 +332,6 @@ impl AppContext {
self.platform.quit();
}
/// Get metadata about the app and platform.
pub fn app_metadata(&self) -> AppMetadata {
self.app_metadata.clone()
}
/// Schedules all windows in the application to be redrawn. This can be called
/// multiple times in an update cycle and still result in a single redraw.
pub fn refresh(&mut self) {
@ -490,26 +471,26 @@ impl AppContext {
&mut self,
options: crate::WindowOptions,
build_root_view: impl FnOnce(&mut WindowContext) -> View<V>,
) -> WindowHandle<V> {
) -> anyhow::Result<WindowHandle<V>> {
self.update(|cx| {
let id = cx.windows.insert(None);
let handle = WindowHandle::new(id);
let mut window = Window::new(handle.into(), options, cx);
let root_view = build_root_view(&mut WindowContext::new(cx, &mut window));
window.root_view.replace(root_view.into());
cx.window_handles.insert(id, window.handle);
cx.windows.get_mut(id).unwrap().replace(window);
handle
match Window::new(handle.into(), options, cx) {
Ok(mut window) => {
let root_view = build_root_view(&mut WindowContext::new(cx, &mut window));
window.root_view.replace(root_view.into());
cx.window_handles.insert(id, window.handle);
cx.windows.get_mut(id).unwrap().replace(window);
Ok(handle)
}
Err(e) => {
cx.windows.remove(id);
return Err(e);
}
}
})
}
/// Returns Ok() if the platform supports opening windows.
/// This returns false (for example) on linux when we could
/// not establish a connection to X or Wayland.
pub fn can_open_windows(&self) -> anyhow::Result<()> {
self.platform.can_open_windows()
}
/// Instructs the platform to activate the application by bringing it to the foreground.
pub fn activate(&self, ignoring_other_apps: bool) {
self.platform.activate(ignoring_other_apps);
@ -616,6 +597,12 @@ impl AppContext {
self.platform.app_path()
}
/// On Linux, returns the name of the compositor in use.
/// Is blank on other platforms.
pub fn compositor_name(&self) -> &'static str {
self.platform.compositor_name()
}
/// Returns the file URL of the executable with the specified name in the application bundle
pub fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
self.platform.path_for_auxiliary_executable(name)