From a3cc0631076380f0bf83e2c87ffc3f630331bcf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=B0=8F=E7=99=BD?= <364772080@qq.com> Date: Wed, 11 Jun 2025 18:37:34 +0800 Subject: [PATCH] windows: Show error messages when zed failed to lanuch (#32537) Now, if either `WindowsPlatform` or `BladeRenderer` fails to initialize, a window will pop up to notify the user. ![image](https://github.com/user-attachments/assets/40fe7f1d-5218-4ee2-b4ec-0945fed2b743) Release Notes: - N/A --- crates/gpui/src/platform.rs | 6 +++++- crates/gpui/src/platform/blade/blade_renderer.rs | 2 +- crates/gpui/src/platform/windows/platform.rs | 16 ++++++++-------- crates/gpui/src/platform/windows/util.rs | 13 ++++++++++++- crates/gpui/src/platform/windows/window.rs | 9 +++++++-- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 4d7770b4a4..8bc5bf0862 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -142,7 +142,11 @@ pub fn guess_compositor() -> &'static str { #[cfg(target_os = "windows")] pub(crate) fn current_platform(_headless: bool) -> Rc { - Rc::new(WindowsPlatform::new()) + Rc::new( + WindowsPlatform::new() + .inspect_err(|err| show_error("Error: Zed failed to launch", err.to_string())) + .unwrap(), + ) } pub(crate) trait Platform: 'static { diff --git a/crates/gpui/src/platform/blade/blade_renderer.rs b/crates/gpui/src/platform/blade/blade_renderer.rs index 9cf65da5c9..6fe1cfc33c 100644 --- a/crates/gpui/src/platform/blade/blade_renderer.rs +++ b/crates/gpui/src/platform/blade/blade_renderer.rs @@ -342,7 +342,7 @@ impl BladeRenderer { let surface = context .gpu .create_surface_configured(window, surface_config) - .unwrap(); + .map_err(|err| anyhow::anyhow!("Failed to create surface: {err:?}"))?; let command_encoder = context.gpu.create_command_encoder(gpu::CommandEncoderDesc { name: "main", diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index 98defb44ee..bb65163e09 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -81,9 +81,9 @@ impl WindowsPlatformState { } impl WindowsPlatform { - pub(crate) fn new() -> Self { + pub(crate) fn new() -> Result { unsafe { - OleInitialize(None).expect("unable to initialize Windows OLE"); + OleInitialize(None).context("unable to initialize Windows OLE")?; } let (main_sender, main_receiver) = flume::unbounded::(); let main_thread_id_win32 = unsafe { GetCurrentThreadId() }; @@ -97,19 +97,19 @@ impl WindowsPlatform { let foreground_executor = ForegroundExecutor::new(dispatcher); let bitmap_factory = ManuallyDrop::new(unsafe { CoCreateInstance(&CLSID_WICImagingFactory, None, CLSCTX_INPROC_SERVER) - .expect("Error creating bitmap factory.") + .context("Error creating bitmap factory.")? }); let text_system = Arc::new( DirectWriteTextSystem::new(&bitmap_factory) - .expect("Error creating DirectWriteTextSystem"), + .context("Error creating DirectWriteTextSystem")?, ); let icon = load_icon().unwrap_or_default(); let state = RefCell::new(WindowsPlatformState::new()); let raw_window_handles = RwLock::new(SmallVec::new()); - let gpu_context = BladeContext::new().expect("Unable to init GPU context"); - let windows_version = WindowsVersion::new().expect("Error retrieve windows version"); + let gpu_context = BladeContext::new().context("Unable to init GPU context")?; + let windows_version = WindowsVersion::new().context("Error retrieve windows version")?; - Self { + Ok(Self { state, raw_window_handles, gpu_context, @@ -122,7 +122,7 @@ impl WindowsPlatform { bitmap_factory, validation_number, main_thread_id_win32, - } + }) } fn redraw_all(&self) { diff --git a/crates/gpui/src/platform/windows/util.rs b/crates/gpui/src/platform/windows/util.rs index aefde5e881..bf9e390ba8 100644 --- a/crates/gpui/src/platform/windows/util.rs +++ b/crates/gpui/src/platform/windows/util.rs @@ -8,7 +8,7 @@ use windows::{ }, Wdk::System::SystemServices::RtlGetVersion, Win32::{Foundation::*, Graphics::Dwm::*, UI::WindowsAndMessaging::*}, - core::BOOL, + core::{BOOL, HSTRING}, }; use crate::*; @@ -186,3 +186,14 @@ pub(crate) fn system_appearance() -> Result { fn is_color_light(color: &Color) -> bool { ((5 * color.G as u32) + (2 * color.R as u32) + color.B as u32) > (8 * 128) } + +pub(crate) fn show_error(title: &str, content: String) { + let _ = unsafe { + MessageBoxW( + None, + &HSTRING::from(content), + &HSTRING::from(title), + MB_ICONERROR | MB_SYSTEMMODAL, + ) + }; +} diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index 7f15ced16e..d79edd6783 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -1258,7 +1258,7 @@ mod windows_renderer { use std::num::NonZeroIsize; use windows::Win32::{Foundation::HWND, UI::WindowsAndMessaging::GWLP_HINSTANCE}; - use crate::get_window_long; + use crate::{get_window_long, show_error}; pub(super) fn init( context: &BladeContext, @@ -1270,7 +1270,12 @@ mod windows_renderer { size: Default::default(), transparent, }; - BladeRenderer::new(context, &raw, config) + BladeRenderer::new(context, &raw, config).inspect_err(|err| { + show_error( + "Error: Zed failed to initialize BladeRenderer", + err.to_string(), + ) + }) } struct RawWindow {