app.rs

 1use super::{BoolExt as _, Dispatcher, FontSystem, Window};
 2use crate::{executor, platform};
 3use anyhow::Result;
 4use cocoa::{
 5    appkit::{NSPasteboard, NSPasteboardTypeString},
 6    base::{id, nil},
 7    foundation::NSData,
 8};
 9use objc::{class, msg_send, sel, sel_impl};
10use std::{ffi::c_void, rc::Rc, sync::Arc};
11
12pub struct App {
13    dispatcher: Arc<Dispatcher>,
14    fonts: Arc<FontSystem>,
15}
16
17impl App {
18    pub fn new() -> Self {
19        Self {
20            dispatcher: Arc::new(Dispatcher),
21            fonts: Arc::new(FontSystem::new()),
22        }
23    }
24}
25
26impl platform::App for App {
27    fn dispatcher(&self) -> Arc<dyn platform::Dispatcher> {
28        self.dispatcher.clone()
29    }
30
31    fn activate(&self, ignoring_other_apps: bool) {
32        unsafe {
33            let app: id = msg_send![class!(NSApplication), sharedApplication];
34            let _: () = msg_send![app, activateIgnoringOtherApps: ignoring_other_apps.to_objc()];
35        }
36    }
37
38    fn open_window(
39        &self,
40        options: platform::WindowOptions,
41        executor: Rc<executor::Foreground>,
42    ) -> Result<Box<dyn platform::Window>> {
43        Ok(Box::new(Window::open(options, executor, self.fonts())?))
44    }
45
46    fn fonts(&self) -> Arc<dyn platform::FontSystem> {
47        self.fonts.clone()
48    }
49
50    fn copy(&self, text: &str) {
51        unsafe {
52            let data = NSData::dataWithBytes_length_(
53                nil,
54                text.as_ptr() as *const c_void,
55                text.len() as u64,
56            );
57            let pasteboard = NSPasteboard::generalPasteboard(nil);
58            pasteboard.clearContents();
59            pasteboard.setData_forType(data, NSPasteboardTypeString);
60        }
61    }
62}