Report an error when trying to open ui in linux::headless (#11952)

Conrad Irwin created

Release Notes:

- N/A

Change summary

crates/gpui/src/app.rs                            | 7 +++++++
crates/gpui/src/platform.rs                       | 3 +++
crates/gpui/src/platform/linux/headless/client.rs | 4 ++++
crates/gpui/src/platform/linux/platform.rs        | 7 +++++++
crates/zed/src/main.rs                            | 4 ++++
5 files changed, 25 insertions(+)

Detailed changes

crates/gpui/src/app.rs 🔗

@@ -502,6 +502,13 @@ impl AppContext {
         })
     }
 
+    /// 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);

crates/gpui/src/platform.rs 🔗

@@ -108,6 +108,9 @@ pub(crate) trait Platform: 'static {
     fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>>;
     fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>>;
     fn active_window(&self) -> Option<AnyWindowHandle>;
+    fn can_open_windows(&self) -> anyhow::Result<()> {
+        Ok(())
+    }
     fn open_window(
         &self,
         handle: AnyWindowHandle,

crates/gpui/src/platform/linux/headless/client.rs 🔗

@@ -68,6 +68,10 @@ impl LinuxClient for HeadlessClient {
         None
     }
 
+    fn can_open_windows(&self) -> anyhow::Result<()> {
+        return Err(anyhow::anyhow!("neither DISPLAY, nor WAYLAND_DISPLAY found. You can still run zed for remote development with --dev-server-token."));
+    }
+
     fn open_window(
         &self,
         _handle: AnyWindowHandle,

crates/gpui/src/platform/linux/platform.rs 🔗

@@ -55,6 +55,9 @@ pub trait LinuxClient {
     fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>>;
     fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>>;
     fn display(&self, id: DisplayId) -> Option<Rc<dyn PlatformDisplay>>;
+    fn can_open_windows(&self) -> anyhow::Result<()> {
+        Ok(())
+    }
     fn open_window(
         &self,
         handle: AnyWindowHandle,
@@ -132,6 +135,10 @@ impl<P: LinuxClient + 'static> Platform for P {
         });
     }
 
+    fn can_open_windows(&self) -> anyhow::Result<()> {
+        self.can_open_windows()
+    }
+
     fn quit(&self) {
         self.with_common(|common| common.signal.stop());
     }

crates/zed/src/main.rs 🔗

@@ -124,6 +124,10 @@ fn init_ui(app_state: Arc<AppState>, cx: &mut AppContext) -> Result<()> {
         }
     };
 
+    if let Err(err) = cx.can_open_windows() {
+        return Err(err);
+    }
+
     SystemAppearance::init(cx);
     load_embedded_fonts(cx);