WIP

Antonio Scandurra created

Change summary

crates/capture/src/main.rs                  | 16 +++++++-
crates/gpui/src/app.rs                      | 23 ++----------
crates/gpui/src/platform.rs                 | 13 ++++--
crates/gpui/src/platform/mac.rs             |  1 
crates/gpui/src/platform/mac/platform.rs    | 42 +++++++++++++---------
crates/gpui/src/platform/mac/status_item.rs | 25 +++++++++++++
crates/gpui/src/platform/test.rs            | 18 ++++++---
crates/zed/src/main.rs                      |  2 +
8 files changed, 89 insertions(+), 51 deletions(-)

Detailed changes

crates/capture/src/main.rs 🔗

@@ -116,15 +116,25 @@ impl gpui::View for ScreenCaptureView {
 
     fn render(&mut self, _: &mut gpui::RenderContext<Self>) -> gpui::ElementBox {
         let image_buffer = self.image_buffer.clone();
-        Canvas::new(move |bounds, _, cx| {
+        let canvas = Canvas::new(move |bounds, _, cx| {
             if let Some(image_buffer) = image_buffer.clone() {
                 cx.scene.push_surface(Surface {
                     bounds,
                     image_buffer,
                 });
             }
-        })
-        .boxed()
+        });
+
+        if let Some(image_buffer) = self.image_buffer.as_ref() {
+            canvas
+                .constrained()
+                .with_width(image_buffer.width() as f32)
+                .with_height(image_buffer.height() as f32)
+                .aligned()
+                .boxed()
+        } else {
+            canvas.boxed()
+        }
     }
 }
 

crates/gpui/src/app.rs 🔗

@@ -1926,27 +1926,12 @@ impl MutableAppContext {
         })
     }
 
-    // pub fn add_status_bar_item<I, M, F1, F2>(
-    //     &mut self,
-    //     build_item: F1,
-    //     build_menu: F2,
-    //     menu_bounds: Vector2F,
-    // ) where
+    // pub fn add_status_bar_item<I, F>(&mut self, build_item: F)
+    // where
     //     I: View,
-    //     M: View,
-    //     F1: FnOnce(&mut ViewContext<I>) -> I,
-    //     F2: FnOnce(&mut ViewContext<M>) -> M,
+    //     F: FnOnce(&mut ViewContext<I>) -> I,
     // {
-    //     self.add_window(
-    //         WindowOptions {
-    //             bounds: menu_bounds,
-    //             titlebar: None,
-    //             title: None,
-    //             titlebar_appears_transparent: true,
-    //             traffic_light_position: (),
-    //         },
-    //         build_root_view,
-    //     )
+    //     mem::forget(self.platform.add_status_item());
     // }
 
     pub fn replace_root_view<T, F>(&mut self, window_id: usize, build_root_view: F) -> ViewHandle<T>

crates/gpui/src/platform.rs 🔗

@@ -39,6 +39,11 @@ pub trait Platform: Send + Sync {
     fn fonts(&self) -> Arc<dyn FontSystem>;
 
     fn activate(&self, ignoring_other_apps: bool);
+    fn hide(&self);
+    fn hide_other_apps(&self);
+    fn unhide_other_apps(&self);
+    fn quit(&self);
+
     fn open_window(
         &self,
         id: usize,
@@ -46,10 +51,8 @@ pub trait Platform: Send + Sync {
         executor: Rc<executor::Foreground>,
     ) -> Box<dyn Window>;
     fn key_window_id(&self) -> Option<usize>;
-    fn hide(&self);
-    fn hide_other_apps(&self);
-    fn unhide_other_apps(&self);
-    fn quit(&self);
+
+    fn add_status_item(&self) -> Box<dyn StatusItem>;
 
     fn write_to_clipboard(&self, item: ClipboardItem);
     fn read_from_clipboard(&self) -> Option<ClipboardItem>;
@@ -133,6 +136,8 @@ pub trait WindowContext {
     fn present_scene(&mut self, scene: Scene);
 }
 
+pub trait StatusItem {}
+
 #[derive(Debug)]
 pub struct WindowOptions<'a> {
     pub bounds: WindowBounds,

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

@@ -7,6 +7,7 @@ mod image_cache;
 mod platform;
 mod renderer;
 mod sprite_cache;
+mod status_item;
 mod window;
 
 use cocoa::base::{BOOL, NO, YES};

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

@@ -1,4 +1,6 @@
-use super::{event::key_to_native, BoolExt as _, Dispatcher, FontSystem, Window};
+use super::{
+    event::key_to_native, status_item::StatusItem, BoolExt as _, Dispatcher, FontSystem, Window,
+};
 use crate::{
     executor, keymap,
     platform::{self, CursorStyle},
@@ -439,23 +441,6 @@ impl platform::Platform for MacPlatform {
         }
     }
 
-    fn open_window(
-        &self,
-        id: usize,
-        options: platform::WindowOptions,
-        executor: Rc<executor::Foreground>,
-    ) -> Box<dyn platform::Window> {
-        Box::new(Window::open(id, options, executor, self.fonts()))
-    }
-
-    fn key_window_id(&self) -> Option<usize> {
-        Window::key_window_id()
-    }
-
-    fn fonts(&self) -> Arc<dyn platform::FontSystem> {
-        self.fonts.clone()
-    }
-
     fn hide(&self) {
         unsafe {
             let app = NSApplication::sharedApplication(nil);
@@ -497,6 +482,27 @@ impl platform::Platform for MacPlatform {
         }
     }
 
+    fn open_window(
+        &self,
+        id: usize,
+        options: platform::WindowOptions,
+        executor: Rc<executor::Foreground>,
+    ) -> Box<dyn platform::Window> {
+        Box::new(Window::open(id, options, executor, self.fonts()))
+    }
+
+    fn key_window_id(&self) -> Option<usize> {
+        Window::key_window_id()
+    }
+
+    fn add_status_item(&self) -> Box<dyn platform::StatusItem> {
+        Box::new(StatusItem::add())
+    }
+
+    fn fonts(&self) -> Arc<dyn platform::FontSystem> {
+        self.fonts.clone()
+    }
+
     fn write_to_clipboard(&self, item: ClipboardItem) {
         unsafe {
             self.pasteboard.clearContents();

crates/gpui/src/platform/mac/status_item.rs 🔗

@@ -0,0 +1,25 @@
+use cocoa::{
+    appkit::{NSSquareStatusItemLength, NSStatusBar},
+    base::{id, nil},
+};
+use core_foundation::base::TCFType;
+use core_graphics::color::CGColor;
+use objc::{msg_send, sel, sel_impl};
+
+pub struct StatusItem(id);
+
+impl StatusItem {
+    pub fn add() -> Self {
+        unsafe {
+            let status_bar = NSStatusBar::systemStatusBar(nil);
+            let native_item: id =
+                msg_send![status_bar, statusItemWithLength: NSSquareStatusItemLength];
+            let button: id = msg_send![native_item, button];
+            let layer: id = msg_send![button, layer];
+            let _: () = msg_send![layer, setBackgroundColor: CGColor::rgb(1., 0., 0., 1.).as_concrete_TypeRef()];
+            StatusItem(native_item)
+        }
+    }
+}
+
+impl crate::StatusItem for StatusItem {}

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

@@ -120,6 +120,14 @@ impl super::Platform for Platform {
 
     fn activate(&self, _ignoring_other_apps: bool) {}
 
+    fn hide(&self) {}
+
+    fn hide_other_apps(&self) {}
+
+    fn unhide_other_apps(&self) {}
+
+    fn quit(&self) {}
+
     fn open_window(
         &self,
         _: usize,
@@ -136,13 +144,9 @@ impl super::Platform for Platform {
         None
     }
 
-    fn hide(&self) {}
-
-    fn hide_other_apps(&self) {}
-
-    fn unhide_other_apps(&self) {}
-
-    fn quit(&self) {}
+    fn add_status_item(&self) -> Box<dyn crate::StatusItem> {
+        todo!()
+    }
 
     fn write_to_clipboard(&self, item: ClipboardItem) {
         *self.current_clipboard_item.lock() = Some(item);

crates/zed/src/main.rs 🔗

@@ -87,6 +87,8 @@ fn main() {
     });
 
     app.run(move |cx| {
+        std::mem::forget(cx.platform().add_status_item());
+
         let client = client::Client::new(http.clone());
         let mut languages = LanguageRegistry::new(login_shell_env_loaded);
         languages.set_language_server_download_dir(zed::paths::LANGUAGES_DIR.clone());