You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

现代macOS如何实现帧渲染时重置屏幕保护程序计时器功能?

macOS 动态重置屏幕保护计时器实现方案

在旧版本 macOS 中,开发者通常使用如下代码重置屏幕保护程序计时器:

UpdateSystemActivity(UsrActivity);

现代 macOS 版本中常见的推荐方案有两种:
第一种:

static IOPMAssertionID activity_assertion_id = kIOPMNullAssertionID;
IOReturn r = IOPMAssertionDeclareUserActivity(CFSTR("FractalUserActivity"),
               kIOPMUserActiveLocal, &activity_assertion_id);

第二种:

IOReturn result = IOPMAssertionCreateWithName(
            kIOPMAssertionTypeNoDisplaySleep,
            kIOPMAssertionLevelOn,
            CFSTR("FractalNewFrameActivity"),
            &power_assertion_id);
IOPMAssertionRelease(power_assertion_id);

但这两种方案都无法满足「每次渲染新帧重置屏保计时器,无新帧时按系统设置时长正常触发屏保」的需求:

  • IOPMAssertionDeclareUserActivity 从 macOS 10.13 开始仅重置系统睡眠计时器,不再影响屏保对应的显示空闲计时器
  • 频繁创建释放kIOPMAssertionTypeNoDisplaySleep断言没有重置计时器的效果,只有持续持有该断言才会强制阻止显示器休眠,不符合空闲后允许触发屏保的需求

可行解决方案

使用 CoreGraphics 框架提供的公开API CGDisplayResetActivity,每次渲染完成新帧后调用即可重置系统显示空闲计时器,完全适配用户自行设置的屏保触发时长,无需硬编码参数。

代码示例

#include <CoreGraphics/CoreGraphics.h>

// 每次渲染新帧后调用该方法即可重置屏保计时器
void reset_screensaver_timer() {
    // 单显示器场景直接传入主显示器ID
    CGDisplayResetActivity(kCGDirectMainDisplay);
    
    // 多显示器场景可遍历所有活跃显示器调用
    // uint32_t displayCount;
    // CGGetActiveDisplayList(0, NULL, &displayCount);
    // CGDirectDisplayID* displays = malloc(displayCount * sizeof(CGDirectDisplayID));
    // CGGetActiveDisplayList(displayCount, displays, &displayCount);
    // for (int i = 0; i < displayCount; i++) {
    //     CGDisplayResetActivity(displays[i]);
    // }
    // free(displays);
}

注意事项

  • 该API为系统公开API,可正常提交Mac App Store,无审核风险
  • 调用频率无需过高,每30秒调用一次即可满足绝大多数场景需求,不需要跟随帧率每秒调用数十次,减少不必要的性能消耗

内容的提问来源于stack exchange,提问作者Nicholas Pipitone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:45:04