Skip to content

Commit 75d9e12

Browse files
1313Copilot
andcommitted
docs: update README and MIGRATION for 2.x
- Bump install snippets from version "1" to "2" - Document 2.0 breaking changes: Send + Sync handlers, #[non_exhaustive] PixelFormat / SCStreamErrorCode, PixelFormat::Unknown(FourCharCode) - Add 2.1 buffer-reuse APIs (bgra_data_into / rgba_data_into) and the native-BGRA fast-path note to the Performance section - Surface ContentSnapshot, AudioInputDevice, FourCharCode in API tables - Mention the new presenter_overlay_content_rect frame-info attachment - Add a 1.x -> 2.0 and 2.0 -> 2.1 migration section to MIGRATION.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent daa544a commit 75d9e12

2 files changed

Lines changed: 180 additions & 8 deletions

File tree

README.md

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,30 @@ Add to your `Cargo.toml`:
5959

6060
```toml
6161
[dependencies]
62-
screencapturekit = "1"
62+
screencapturekit = "2"
6363
```
6464

6565
For async support:
6666

6767
```toml
6868
[dependencies]
69-
screencapturekit = { version = "1", features = ["async"] }
69+
screencapturekit = { version = "2", features = ["async"] }
7070
```
7171

7272
For latest macOS features:
7373

7474
```toml
7575
[dependencies]
76-
screencapturekit = { version = "1", features = ["macos_26_0"] }
76+
screencapturekit = { version = "2", features = ["macos_26_0"] }
7777
```
7878

79+
> **Upgrading from 1.x?** See [`docs/MIGRATION.md`](docs/MIGRATION.md#migrating-from-1x-to-20)
80+
> for the full list of 2.0 breaking changes — most notable are the new
81+
> `Send + Sync` bound on output / delegate traits, the `#[non_exhaustive]`
82+
> attribute on `PixelFormat` and `SCStreamErrorCode`, and the new
83+
> `PixelFormat::Unknown(FourCharCode)` variant for codes the binding does
84+
> not yet name.
85+
7986
## 🚀 Quick Start
8087

8188
### Basic Screen Capture
@@ -91,6 +98,10 @@ impl SCStreamOutputTrait for Handler {
9198
}
9299
}
93100

101+
// Note: as of 2.0, `SCStreamOutputTrait` (and `SCStreamDelegateTrait`)
102+
// require `Send + Sync` — handlers run on Apple's dispatch queues and may
103+
// be invoked concurrently from arbitrary threads.
104+
94105
fn main() -> Result<(), Box<dyn std::error::Error>> {
95106
// Get available displays
96107
let content = SCShareableContent::get()?;
@@ -463,6 +474,8 @@ config.set_should_be_opaque(true);
463474
| `SCDisplay` | Display information (resolution, ID, frame) |
464475
| `SCWindow` | Window information (title, bounds, owner, layer) |
465476
| `SCRunningApplication` | Application information (name, bundle ID, PID) |
477+
| `ContentSnapshot` | Plain-data batch of all displays, windows, applications (one FFI round-trip) |
478+
| `AudioInputDevice` | Microphone enumeration via `AVFoundation` (used with `with_microphone_capture_device_id`) |
466479

467480
### Media Types
468481

@@ -491,12 +504,16 @@ config.set_should_be_opaque(true);
491504

492505
| Type | Description |
493506
|------|-------------|
494-
| `PixelFormat` | BGRA, `YCbCr420v`, `YCbCr420f`, l10r (10-bit) |
507+
| `PixelFormat` | BGRA, `YCbCr420v`, `YCbCr420f`, l10r (10-bit), `Unknown(FourCharCode)` for forward-compat |
508+
| `FourCharCode` | Apple OSType four-char code helper used by `PixelFormat::Unknown` |
495509
| `SCPresenterOverlayAlertSetting` | Privacy alert behavior |
496510
| `SCCaptureDynamicRange` | HDR/SDR modes (macOS 15.0+) |
497511
| `SCScreenshotConfiguration` | Advanced screenshot config (macOS 26.0+) |
498512
| `SCScreenshotDynamicRange` | SDR/HDR screenshot output (macOS 26.0+) |
499513

514+
> **2.0 note:** `PixelFormat` and `SCStreamErrorCode` are `#[non_exhaustive]`.
515+
> `match` arms over either of them must include a wildcard `_ => …` arm.
516+
500517
## 🏃 Examples
501518

502519
The [`examples/`](examples/) directory contains focused API demonstrations:
@@ -744,14 +761,16 @@ for w in &windows {
744761
```
745762

746763
Same idea on a video sample buffer — read every attachment in one CF→Swift
747-
bridge cast instead of one cast per attribute:
764+
bridge cast instead of one cast per attribute (this includes the new-in-2.0
765+
`presenter_overlay_content_rect` field for Presenter Overlay layouts):
748766

749767
```rust,no_run
750768
# use screencapturekit::cm::CMSampleBuffer;
751769
# fn example(sample: &CMSampleBuffer) {
752770
if let Some(info) = sample.frame_info() {
753-
println!("status={:?} time={:?} content={:?}",
754-
info.frame_status, info.display_time, info.content_rect);
771+
println!("status={:?} time={:?} content={:?} overlay={:?}",
772+
info.frame_status, info.display_time, info.content_rect,
773+
info.presenter_overlay_content_rect);
755774
}
756775
# }
757776
```
@@ -774,17 +793,46 @@ let pixels = img.bgra_data()?; // ~5% faster than rgba_data() at 1080p
774793
# }
775794
```
776795

796+
For sustained screenshot loops, the new (2.1+) `*_data_into` variants
797+
write into a caller-supplied buffer so you only pay the
798+
`width × height × 4` byte allocation once instead of per frame
799+
(~33 MB / call at 4K):
800+
801+
```rust,no_run
802+
# #[cfg(feature = "macos_14_0")]
803+
# fn example(
804+
# filter: &screencapturekit::stream::content_filter::SCContentFilter,
805+
# config: &screencapturekit::stream::configuration::SCStreamConfiguration,
806+
# ) -> Result<(), Box<dyn std::error::Error>> {
807+
use screencapturekit::screenshot_manager::SCScreenshotManager;
808+
let mut buffer: Vec<u8> = vec![0; 1920 * 1080 * 4];
809+
for _ in 0..100 {
810+
let img = SCScreenshotManager::capture_image(filter, config)?;
811+
img.bgra_data_into(&mut buffer)?; // reuse the same allocation
812+
// ... process `buffer` ...
813+
}
814+
# Ok(())
815+
# }
816+
```
817+
777818
See [`examples/24_batched_apis_showcase.rs`](examples/24_batched_apis_showcase.rs)
778819
for a side-by-side comparison that benchmarks all three APIs against the
779820
legacy per-element pattern on your machine.
780821

781822
## 🔄 Migration
782823

783824
Upgrading from an older version? See [`docs/MIGRATION.md`](docs/MIGRATION.md) for:
784-
- API changes between versions
825+
- API changes between versions (including the **1.x → 2.0** upgrade path)
785826
- Code examples for common migrations
786827
- Deprecated API replacements
787828

829+
**Highlights of 2.0 breaking changes:**
830+
- `SCStreamOutputTrait` and `SCStreamDelegateTrait` now require `Send + Sync`
831+
- `PixelFormat` is `#[non_exhaustive]` and gained a `Unknown(FourCharCode)` variant
832+
- `SCStreamErrorCode` is `#[non_exhaustive]`
833+
- `PartialEq` / `Hash` for `PixelFormat` now normalise through `FourCharCode`
834+
- Every `macos_*` Cargo feature now propagates to the Swift bridge build (build will fail loudly if SDK detection fails)
835+
788836
## 🤝 Contributing
789837

790838
Contributions welcome! Please:

docs/MIGRATION.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,130 @@
22

33
This guide helps you migrate between major versions of `screencapturekit-rs`.
44

5+
## Migrating from 1.x to 2.0
6+
7+
Version 2.0 hardens the FFI boundary. Most projects can upgrade by
8+
bumping the dependency and addressing a handful of compile errors —
9+
no design-level rework is required.
10+
11+
### Cargo.toml
12+
13+
```diff
14+
[dependencies]
15+
-screencapturekit = "1"
16+
+screencapturekit = "2"
17+
```
18+
19+
### `Send + Sync` bound on output / delegate traits
20+
21+
`SCStreamOutputTrait` and `SCStreamDelegateTrait` (and the `Fn(...)` closure
22+
overloads) now require `Send + Sync`. Apple's dispatch queues may invoke the
23+
handler concurrently from arbitrary threads, so any state owned by the
24+
handler must be thread-safe.
25+
26+
**Before (1.x):**
27+
```rust,ignore
28+
struct Handler { count: std::cell::Cell<usize> } // !Sync — compiles in 1.x
29+
impl SCStreamOutputTrait for Handler { /* ... */ }
30+
```
31+
32+
**After (2.0):**
33+
```rust,ignore
34+
use std::sync::atomic::{AtomicUsize, Ordering};
35+
36+
struct Handler { count: AtomicUsize } // Send + Sync
37+
impl SCStreamOutputTrait for Handler {
38+
fn did_output_sample_buffer(&self, _: CMSampleBuffer, _: SCStreamOutputType) {
39+
self.count.fetch_add(1, Ordering::Relaxed);
40+
}
41+
}
42+
```
43+
44+
For closures: replace `Cell` / `Rc` with `Arc<Atomic*>` /
45+
`Arc<Mutex<...>>` / `Arc<RwLock<...>>`.
46+
47+
### `PixelFormat::Unknown(FourCharCode)`
48+
49+
`PixelFormat` is now `#[non_exhaustive]` and surfaces unrecognised codes
50+
via a new `Unknown(FourCharCode)` variant instead of mapping them to
51+
`BGRA`. This means **every `match` over `PixelFormat` must include a
52+
wildcard arm**:
53+
54+
**Before (1.x):**
55+
```rust,ignore
56+
match config.pixel_format() {
57+
PixelFormat::BGRA => { /* ... */ }
58+
PixelFormat::YCbCr420v => { /* ... */ }
59+
PixelFormat::YCbCr420f => { /* ... */ }
60+
PixelFormat::L10R => { /* ... */ }
61+
}
62+
```
63+
64+
**After (2.0):**
65+
```rust,ignore
66+
match config.pixel_format() {
67+
PixelFormat::BGRA => { /* ... */ }
68+
PixelFormat::YCbCr420v => { /* ... */ }
69+
PixelFormat::YCbCr420f => { /* ... */ }
70+
PixelFormat::L10R => { /* ... */ }
71+
PixelFormat::Unknown(code) => eprintln!("unrecognised pixel format: {code}"),
72+
_ => { /* future variants */ }
73+
}
74+
```
75+
76+
`PartialEq` / `Hash` are now normalised through `FourCharCode`, so two
77+
representations of the same OSType (e.g. `PixelFormat::BGRA` vs
78+
`PixelFormat::Unknown(FourCharCode::from_bytes(*b"BGRA"))`) compare equal.
79+
80+
### `SCStreamErrorCode` is `#[non_exhaustive]`
81+
82+
`match` arms over `SCStreamErrorCode` (typically inside an
83+
`SCError::StreamError { code, .. }` arm) now require a wildcard:
84+
85+
```rust,ignore
86+
match err_code {
87+
SCStreamErrorCode::UserStopped => { /* graceful */ }
88+
SCStreamErrorCode::UserDeclined => { /* permission */ }
89+
_ => { /* anything Apple adds in a future macOS */ }
90+
}
91+
```
92+
93+
### Build-time SDK enforcement
94+
95+
The build script no longer silently degrades when xcrun / SDK detection
96+
fails — it bails with a clear error pointing at `xcode-select`. Make sure
97+
Xcode Command Line Tools are installed and selected:
98+
99+
```bash
100+
xcode-select --install
101+
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
102+
```
103+
104+
Every `macos_*` Cargo feature is also forwarded to the Swift compile, so
105+
a feature only enabled on the Rust side (which used to silently miss the
106+
matching Swift symbols) will now produce a coherent linker error.
107+
108+
### New APIs you can opt into
109+
110+
- `SCContentSharingPicker::is_active()` / `set_is_active()` — query and
111+
toggle the picker's idle state without recreating it.
112+
- `SCContentSharingPicker::default_configuration()` — read the system
113+
default `SCContentSharingPickerConfiguration` so user-facing pickers
114+
match macOS defaults.
115+
- `CMSampleBuffer::presenter_overlay_content_rect()` (and the matching
116+
field on `frame_info()`) — the new Presenter Overlay layout rect.
117+
118+
## Migrating from 2.0 to 2.1
119+
120+
2.1 is fully backwards-compatible with 2.0 — no source changes required.
121+
New optional APIs:
122+
123+
- `CGImage::rgba_data_into(&mut [u8])` and `bgra_data_into(&mut [u8])`
124+
render into a caller-supplied buffer to amortise the per-call
125+
`width*height*4` byte allocation across many screenshots.
126+
- Native-BGRA fast path in `SCScreenshotManager` skips the channel swap
127+
for downstreams that accept BGRA directly (Metal / wgpu / ffmpeg).
128+
5129
## Migrating from 0.x to 1.0
6130

7131
Version 1.0 introduced a complete API redesign with builder patterns, async support, and new macOS features.

0 commit comments

Comments
 (0)