diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 72c65a4c33..255e85a527 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -3,6 +3,7 @@ authors = ["Nathan Sobo "] edition = "2021" name = "gpui" version = "0.1.0" +description = "A GPU-accelerated UI framework" [lib] path = "src/gpui.rs" @@ -11,6 +12,11 @@ doctest = false [features] test-support = ["backtrace", "dhat", "env_logger", "collections/test-support"] +[package.metadata.bundle.example.capture] +name = "Capture" +identifier = "rs.gpui.examples.Capture" +description = "An example of screen capture" + [dependencies] collections = { path = "../collections" } gpui_macros = { path = "../gpui_macros" } diff --git a/crates/gpui/build.rs b/crates/gpui/build.rs index 836d586c26..1c6cc11de0 100644 --- a/crates/gpui/build.rs +++ b/crates/gpui/build.rs @@ -9,6 +9,9 @@ fn main() { compile_context_predicate_parser(); compile_metal_shaders(); generate_shader_bindings(); + + // Support screen capture + println!("cargo:rustc-link-lib=framework=ScreenCaptureKit"); } fn generate_dispatch_bindings() { diff --git a/crates/gpui/examples/capture.rs b/crates/gpui/examples/capture.rs new file mode 100644 index 0000000000..27bb843ab9 --- /dev/null +++ b/crates/gpui/examples/capture.rs @@ -0,0 +1,78 @@ +use std::{slice, str}; + +use block::ConcreteBlock; +use cocoa::{ + base::id, + foundation::{NSString, NSUInteger}, +}; +use gpui::{actions, elements::*, keymap::Binding, Menu, MenuItem}; +use log::LevelFilter; +use objc::{class, msg_send, sel, sel_impl}; +use simplelog::SimpleLogger; + +#[allow(non_upper_case_globals)] +const NSUTF8StringEncoding: NSUInteger = 4; + +actions!(capture, [Quit]); + +fn main() { + SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger"); + + gpui::App::new(()).unwrap().run(|cx| { + cx.platform().activate(true); + cx.add_global_action(quit); + + cx.add_bindings([Binding::new("cmd-q", Quit, None)]); + cx.set_menus(vec![Menu { + name: "Zed", + items: vec![MenuItem::Action { + name: "Quit", + action: Box::new(Quit), + }], + }]); + + unsafe { + let block = ConcreteBlock::new(move |content: id, error: id| { + println!("got response with shareable content"); + dbg!(content); + dbg!(error); + dbg!(string_from_objc(msg_send![error, localizedDescription])); + }); + + let _: id = msg_send![ + class!(SCShareableContent), + getShareableContentWithCompletionHandler: block + ]; + } + + // cx.add_window(Default::default(), |_| ScreenCaptureView); + }); +} + +struct ScreenCaptureView; + +impl gpui::Entity for ScreenCaptureView { + type Event = (); +} + +impl gpui::View for ScreenCaptureView { + fn ui_name() -> &'static str { + "View" + } + + fn render(&mut self, _: &mut gpui::RenderContext) -> gpui::ElementBox { + Empty::new().boxed() + } +} + +pub unsafe fn string_from_objc(string: id) -> String { + let len = msg_send![string, lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; + let bytes = string.UTF8String() as *const u8; + str::from_utf8(slice::from_raw_parts(bytes, len)) + .unwrap() + .to_string() +} + +fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) { + cx.platform().quit(); +} diff --git a/crates/gpui/script/capture b/crates/gpui/script/capture new file mode 100755 index 0000000000..753e5108e7 --- /dev/null +++ b/crates/gpui/script/capture @@ -0,0 +1,4 @@ +#!/bin/bash + +cargo bundle --example capture +open ../../target/debug/examples/bundle/osx/Capture.app