mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-15 03:37:04 -04:00
control: keep channel responsive when window is covered (disable App Nap); fail fast on occluded screenshots
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
9f0cfb3373
commit
214345df13
4 files changed
+31
No files matched your search
@@ -21,3 +21,5 @@ rfd = { workspace = true }
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
# Same winit as eframe: macOS event-loop options (no app activation when driven by an agent).
|
||||
winit = { version = "0.30", default-features = false }
|
||||
# Keep the control channel responsive when the window is covered (App Nap / occlusion throttling).
|
||||
objc2-foundation = { version = "0.3", default-features = false, features = ["std", "NSProcessInfo", "NSString", "NSObject"] }
|
||||
@@ -70,6 +70,7 @@ fn main() -> eframe::Result {
|
||||
app.hooks.pick_open_project =
|
||||
Some(Box::new(|| rfd::FileDialog::new().add_filter("EffectCraft Project", &["ecproj"]).pick_file().map(|p| p.to_string_lossy().to_string())));
|
||||
if let Some(port) = control_port {
|
||||
disable_app_nap();
|
||||
let rx = control_server::start(port, cc.egui_ctx.clone());
|
||||
app = app.with_control(rx);
|
||||
}
|
||||
@@ -91,3 +92,17 @@ fn agent_event_loop(agent: bool) -> Option<eframe::EventLoopBuilderHook> {
|
||||
let _ = agent;
|
||||
None
|
||||
}
|
||||
|
||||
/// Agents drive the app while its window is covered or on another Space. macOS App Nap would
|
||||
/// throttle the event loop then, stalling the control channel; opt out for `--control` runs.
|
||||
fn disable_app_nap() {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use objc2_foundation::{NSActivityOptions, NSProcessInfo, NSString};
|
||||
let info = NSProcessInfo::processInfo();
|
||||
let reason = NSString::from_str("EffectCraft control channel");
|
||||
let opts = NSActivityOptions::UserInitiatedAllowingIdleSystemSleep | NSActivityOptions::LatencyCritical;
|
||||
// Leaked on purpose: the activity lasts for the life of the process.
|
||||
std::mem::forget(info.beginActivityWithOptions_reason(opts, &reason));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user