Windows 用 GetLastInputInfo 获取会话级空闲时间(毫秒),需初始化 LASTINPUTINFO.cbSize;Linux/macOS 无等价API,需依环境选轮询、X11/Wayland 或 IOKit 方案,跨平台应分条件编译而非强行统一。

Windows 下用 GetLastInputInfo 获取用户空闲时间
Windows 提供了 GetLastInputInfo 这个 API,它返回的是「最后一次键盘或鼠标输入距当前的时间(毫秒)」,本质就是系统空闲时间。注意:它只统计交互式输入(WM_INPUT 类事件),不包括服务、后台进程活动。
实操要点:
-
LASTINPUTINFO结构体必须初始化cbSize字段,否则调用失败且不报错 —— 这是最常见的坑 - 返回值为
FALSE时需用GetLastError()判断是否是权限问题(极少见)还是结构体未初始化 - 该函数不区分多用户会话,仅反映当前登录会话的空闲状态
- 精度约 10–16ms(取决于系统 timer resolution),不能用于亚毫秒级判断
LASTINPUTINFO li = {0};
li.cbSize = sizeof(li);
if (GetLastInputInfo(&li)) {
DWORD idle_ms = GetTickCount() - li.dwTime;
}Linux/macOS 下没有等价的系统 API,得靠轮询 /dev/input/event* 或 X11/Wayland 协议
Linux 没有内核级“用户空闲”概念。常见做法是监听输入设备事件,但要注意:
-
/dev/input/event*需要 root 权限或input用户组权限,普通用户默认无权读取 - X11 可用
XScreenSaverQueryInfo(需链接-lXss),但它依赖屏保扩展,Wayland 下完全不可用 - Wayland 没有标准空闲查询接口;某些 compositor(如 sway)提供
idle_inhibit_v1或 D-Bus 接口,但非通用 - macOS 可用 IOKit 的
IORegistryEntryCreateCFProperty查IOHIDSystem,但更常用的是私有 APICGEventSourceSecondsSinceLastEventType(需QuartzCore和ApplicationServices)
示例(macOS,需在 Info.plist 中声明隐私权限):
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
#include <ApplicationServices/ApplicationServices.h> double idle_sec = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType);
跨平台抽象要放弃“精确空闲”,转向“合理近似”
强行封装一个统一接口容易误导使用者。不同系统语义差异太大:
- Windows 的
GetLastInputInfo是会话级、低开销、可靠 - Linux/X11 的
XScreenSaverQueryInfo实际查的是屏保倒计时,可能被策略禁用或重置 - Linux systemd 用户会话可通过
loginctl show-user $USER -p IdleSinceHint获取(单位微秒),但依赖 logind,且不是实时更新 - 所有方案都无法感知触摸屏、手写笔、语音输入等现代交互方式(除非额外集成对应驱动或框架)
建议按目标平台分条件编译,不要试图用一个函数名掩盖底层鸿沟。
别忽略权限、沙箱和桌面环境限制
空闲检测在容器、Flatpak、macOS App Sandbox 或 Windows UWP 环境中大概率失效:
- Docker 容器默认无权访问
/dev/input/,且loginctl在非 host PID namespace 下无效 - macOS 10.15+ 要求
NSUserActivityUsageDescription+ 用户授权才能调用CGEventSourceSecondsSinceLastEventType - Wayland compositor 若未启用 idle protocol(如 Hyprland 默认关),D-Bus 查询直接返回空或超时
- 即使代码能编译运行,也要在真实部署环境里验证 —— 开发机上跑通不等于用户机器上可用
最常被忽略的一点:空闲时间不是安全指标。它无法防止恶意进程伪造输入、无法对抗辅助技术绕过,也不代表用户“离开座位”。把它当 UI 自动隐藏触发条件可以,当权限控制依据则非常危险。

















