Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/src/platform/mac/mod.rs
1#![allow(deprecated)]
2 
3mod app;
4pub mod clipboard;
5pub mod delegate;
6mod event;
7pub(crate) mod fonts;
8mod geometry;
9mod keycode;
10mod menus;
11mod notification;
12pub(super) mod rendering;
13mod text_layout;
14pub mod utils;
15mod window;
16 
17pub use app::{App, AppExt};
18pub use delegate::{AppDelegate, IntegrationTestDelegate};
19pub use fonts::FontDB;
20pub use rendering::is_low_power_gpu_available;
21pub use window::Window;
22pub use window::WindowExt;
23 
24use clipboard::*;
25 
26use geometry::*;
27 
28use cocoa::{
29 base::{id, nil},
30 foundation::{NSAutoreleasePool, NSString},
31};
32use objc::{msg_send, sel, sel_impl};
33 
34/// Create an autoreleased NSString from a string reference.
35pub fn make_nsstring<S>(s: S) -> id
36where
37 S: AsRef<str>,
38{
39 unsafe { NSString::alloc(nil).init_str(s.as_ref()).autorelease() }
40}
41 
42/// Holds a Cocoa autorelease pool and drains it when the guard is dropped.
43///
44/// Many Cocoa APIs temporarily hold on to objects that only get freed when an
45/// enclosing autorelease pool is drained. AppKit's main event loop and GCD
46/// blocks create one of these pools around each callback, so most code doesn't
47/// have to think about it. But code that runs during app startup, on a thread
48/// Rust created itself, or in a tight loop inside a single event can't rely on
49/// the outer pool: objects accumulate in memory until that outer pool drains,
50/// which can be a long time.
51///
52/// Create a `AutoreleasePoolGuard` in that scope to open your own pool. The
53/// guard drains the pool automatically when it goes out of scope, whether the
54/// function returns normally, returns early via `?`, or unwinds due to a
55/// panic.
56pub struct AutoreleasePoolGuard(id);
57 
58impl AutoreleasePoolGuard {
59 /// Creates a fresh `NSAutoreleasePool` whose lifetime is tied to the guard.
60 pub fn new() -> Self {
61 // SAFETY: `NSAutoreleasePool::new` is infallible and produces a pool
62 // that is valid for the current thread until the guard drains it on
63 // `Drop`.
64 Self(unsafe { NSAutoreleasePool::new(nil) })
65 }
66}
67 
68impl Default for AutoreleasePoolGuard {
69 fn default() -> Self {
70 Self::new()
71 }
72}
73 
74impl Drop for AutoreleasePoolGuard {
75 fn drop(&mut self) {
76 // SAFETY: `self.0` was produced by `NSAutoreleasePool::new` in
77 // `Self::new` and is drained at most once here.
78 unsafe {
79 let _: () = msg_send![self.0, drain];
80 }
81 }
82}
83