Skip to content

feat: macos utils#1214

Merged
MistEO merged 9 commits intomainfrom
feat/macos_utils
Mar 21, 2026
Merged

feat: macos utils#1214
MistEO merged 9 commits intomainfrom
feat/macos_utils

Conversation

@neko-para
Copy link
Copy Markdown
Contributor

@neko-para neko-para commented Mar 18, 2026

#1116 的补充

先看看接口有没有问题, 没问题我就补binding那边的了

由 Sourcery 提供的总结

在 MaaToolkit 中新增 macOS 专用的权限管理工具,并相应更新 macOS 构建时的链接设置。

新功能:

  • 引入 macOS 权限枚举和 C API,用于检查、请求以及打开与屏幕捕捉和辅助功能相关的系统权限设置。

增强内容:

  • 为新的权限 API 增加 macOS 的 Objective-C++ 实现,以及非 Apple 平台上的桩(stub)实现。
  • 调整 MaaToolkit 在 macOS 下的链接方式,使其在使用 ScreenCaptureKit 的同时链接 Cocoa,并清理相关的 CMake 配置。
Original summary in English

Summary by Sourcery

向 MaaToolkit 添加 macOS 特定的权限管理 API,并通过 C、Python 和 NodeJS 绑定对外暴露,同时更新 macOS 的构建和测试相关配置。

New Features:

  • 引入 MaaMacOSPermission 枚举和 C API,用于检查、请求以及显示(reveal)用于屏幕捕获和辅助功能的 macOS 系统权限。
  • 在 Python 工具包封装和 NodeJS 全局绑定中暴露 macOS 权限实用工具,包括在 NodeJS 中以异步方式请求权限。

Enhancements:

  • 在 Apple 平台上使用 Cocoa 实现 macOS 权限处理,并在非 Apple 平台上提供带日志输出的桩实现(stubbed behavior)。
  • 重构 macOS 测试应用,使其使用新的 MaaToolkit macOS 权限 API,而不是本地的辅助实现。

Build:

  • 调整 MaaToolkit 的 macOS CMake 配置,使其链接 ScreenCaptureKitCocoa 框架,并整理相关的安装规则。

Documentation:

  • 记录说明 MaaFramework 本身不直接处理 macOS 权限流程,并指引客户端参考 MaaToolkit 的辅助工具和示例测试来获取实现指导。
Original summary in English

Summary by Sourcery

Add macOS-specific permission management APIs to MaaToolkit and expose them through C, Python, and NodeJS bindings while updating macOS build and test wiring.

New Features:

  • Introduce MaaMacOSPermission enum and C APIs to check, request, and reveal macOS system permissions for screen capture and accessibility.
  • Expose macOS permission utilities in the Python toolkit wrapper and NodeJS global bindings, including async permission requests in NodeJS.

Enhancements:

  • Implement macOS permission handling using Cocoa on Apple platforms and provide stubbed behavior with logging on non-Apple platforms.
  • Refactor the macOS test application to use the new MaaToolkit macOS permission APIs instead of local helper implementations.

Build:

  • Adjust MaaToolkit macOS CMake configuration to link against ScreenCaptureKit and Cocoa frameworks and tidy related install rules.

Documentation:

  • Document that MaaFramework does not handle macOS permission flows directly and point clients to MaaToolkit helpers and example tests for implementation guidance.

新功能:

  • 引入 MaaMacOSPermission 枚举和 C API,用于检查、请求以及打开 macOS 屏幕录制和辅助功能权限的设置界面。
  • 在 NodeJS 全局绑定和 Python Toolkit 封装中暴露 macOS 权限工具,包括在 NodeJS 中支持异步权限请求。

增强改进:

  • 调整 MaaToolkit 在 macOS 上的链接方式,使其在使用 ScreenCaptureKit 的同时链接 Cocoa,并清理相关的 CMake 配置。
  • 为新的 macOS 权限 API 添加非 macOS 平台的桩实现(stub),并增加相应的错误日志和异常处理。
Original summary in English

Summary by Sourcery

向 MaaToolkit 添加 macOS 特定的权限管理 API,并通过 C、Python 和 NodeJS 绑定对外暴露,同时更新 macOS 的构建和测试相关配置。

New Features:

  • 引入 MaaMacOSPermission 枚举和 C API,用于检查、请求以及显示(reveal)用于屏幕捕获和辅助功能的 macOS 系统权限。
  • 在 Python 工具包封装和 NodeJS 全局绑定中暴露 macOS 权限实用工具,包括在 NodeJS 中以异步方式请求权限。

Enhancements:

  • 在 Apple 平台上使用 Cocoa 实现 macOS 权限处理,并在非 Apple 平台上提供带日志输出的桩实现(stubbed behavior)。
  • 重构 macOS 测试应用,使其使用新的 MaaToolkit macOS 权限 API,而不是本地的辅助实现。

Build:

  • 调整 MaaToolkit 的 macOS CMake 配置,使其链接 ScreenCaptureKitCocoa 框架,并整理相关的安装规则。

Documentation:

  • 记录说明 MaaFramework 本身不直接处理 macOS 权限流程,并指引客户端参考 MaaToolkit 的辅助工具和示例测试来获取实现指导。
Original summary in English

Summary by Sourcery

Add macOS-specific permission management APIs to MaaToolkit and expose them through C, Python, and NodeJS bindings while updating macOS build and test wiring.

New Features:

  • Introduce MaaMacOSPermission enum and C APIs to check, request, and reveal macOS system permissions for screen capture and accessibility.
  • Expose macOS permission utilities in the Python toolkit wrapper and NodeJS global bindings, including async permission requests in NodeJS.

Enhancements:

  • Implement macOS permission handling using Cocoa on Apple platforms and provide stubbed behavior with logging on non-Apple platforms.
  • Refactor the macOS test application to use the new MaaToolkit macOS permission APIs instead of local helper implementations.

Build:

  • Adjust MaaToolkit macOS CMake configuration to link against ScreenCaptureKit and Cocoa frameworks and tidy related install rules.

Documentation:

  • Document that MaaFramework does not handle macOS permission flows directly and point clients to MaaToolkit helpers and example tests for implementation guidance.

新功能:

  • 在 MaaToolkit 中引入 macOS 权限枚举和 C API,用于检查、请求以及打开屏幕录制和辅助功能等系统权限。
  • 将 macOS 权限操作暴露给 Python 和 NodeJS 绑定,包括类型定义以及在 NodeJS 中的异步请求处理。

改进:

  • 使用 Cocoa 框架实现 macOS 特定的权限处理逻辑,并在非 Apple 平台上提供桩(stub)行为。
  • 调整 macOS 上 MaaToolkit 的 CMake 配置,使其链接到 Cocoa 而不是单独的 CoreFoundation/Foundation 库,并整理安装规则。
Original summary in English

Summary by Sourcery

向 MaaToolkit 添加 macOS 特定的权限管理 API,并通过 C、Python 和 NodeJS 绑定对外暴露,同时更新 macOS 的构建和测试相关配置。

New Features:

  • 引入 MaaMacOSPermission 枚举和 C API,用于检查、请求以及显示(reveal)用于屏幕捕获和辅助功能的 macOS 系统权限。
  • 在 Python 工具包封装和 NodeJS 全局绑定中暴露 macOS 权限实用工具,包括在 NodeJS 中以异步方式请求权限。

Enhancements:

  • 在 Apple 平台上使用 Cocoa 实现 macOS 权限处理,并在非 Apple 平台上提供带日志输出的桩实现(stubbed behavior)。
  • 重构 macOS 测试应用,使其使用新的 MaaToolkit macOS 权限 API,而不是本地的辅助实现。

Build:

  • 调整 MaaToolkit 的 macOS CMake 配置,使其链接 ScreenCaptureKitCocoa 框架,并整理相关的安装规则。

Documentation:

  • 记录说明 MaaFramework 本身不直接处理 macOS 权限流程,并指引客户端参考 MaaToolkit 的辅助工具和示例测试来获取实现指导。
Original summary in English

Summary by Sourcery

Add macOS-specific permission management APIs to MaaToolkit and expose them through C, Python, and NodeJS bindings while updating macOS build and test wiring.

New Features:

  • Introduce MaaMacOSPermission enum and C APIs to check, request, and reveal macOS system permissions for screen capture and accessibility.
  • Expose macOS permission utilities in the Python toolkit wrapper and NodeJS global bindings, including async permission requests in NodeJS.

Enhancements:

  • Implement macOS permission handling using Cocoa on Apple platforms and provide stubbed behavior with logging on non-Apple platforms.
  • Refactor the macOS test application to use the new MaaToolkit macOS permission APIs instead of local helper implementations.

Build:

  • Adjust MaaToolkit macOS CMake configuration to link against ScreenCaptureKit and Cocoa frameworks and tidy related install rules.

Documentation:

  • Document that MaaFramework does not handle macOS permission flows directly and point clients to MaaToolkit helpers and example tests for implementation guidance.

新功能:

  • 引入 MaaMacOSPermission 枚举和 C API,用于检查、请求以及打开 macOS 屏幕录制和辅助功能权限的设置界面。
  • 在 NodeJS 全局绑定和 Python Toolkit 封装中暴露 macOS 权限工具,包括在 NodeJS 中支持异步权限请求。

增强改进:

  • 调整 MaaToolkit 在 macOS 上的链接方式,使其在使用 ScreenCaptureKit 的同时链接 Cocoa,并清理相关的 CMake 配置。
  • 为新的 macOS 权限 API 添加非 macOS 平台的桩实现(stub),并增加相应的错误日志和异常处理。
Original summary in English

Summary by Sourcery

向 MaaToolkit 添加 macOS 特定的权限管理 API,并通过 C、Python 和 NodeJS 绑定对外暴露,同时更新 macOS 的构建和测试相关配置。

New Features:

  • 引入 MaaMacOSPermission 枚举和 C API,用于检查、请求以及显示(reveal)用于屏幕捕获和辅助功能的 macOS 系统权限。
  • 在 Python 工具包封装和 NodeJS 全局绑定中暴露 macOS 权限实用工具,包括在 NodeJS 中以异步方式请求权限。

Enhancements:

  • 在 Apple 平台上使用 Cocoa 实现 macOS 权限处理,并在非 Apple 平台上提供带日志输出的桩实现(stubbed behavior)。
  • 重构 macOS 测试应用,使其使用新的 MaaToolkit macOS 权限 API,而不是本地的辅助实现。

Build:

  • 调整 MaaToolkit 的 macOS CMake 配置,使其链接 ScreenCaptureKitCocoa 框架,并整理相关的安装规则。

Documentation:

  • 记录说明 MaaFramework 本身不直接处理 macOS 权限流程,并指引客户端参考 MaaToolkit 的辅助工具和示例测试来获取实现指导。
Original summary in English

Summary by Sourcery

Add macOS-specific permission management APIs to MaaToolkit and expose them through C, Python, and NodeJS bindings while updating macOS build and test wiring.

New Features:

  • Introduce MaaMacOSPermission enum and C APIs to check, request, and reveal macOS system permissions for screen capture and accessibility.
  • Expose macOS permission utilities in the Python toolkit wrapper and NodeJS global bindings, including async permission requests in NodeJS.

Enhancements:

  • Implement macOS permission handling using Cocoa on Apple platforms and provide stubbed behavior with logging on non-Apple platforms.
  • Refactor the macOS test application to use the new MaaToolkit macOS permission APIs instead of local helper implementations.

Build:

  • Adjust MaaToolkit macOS CMake configuration to link against ScreenCaptureKit and Cocoa frameworks and tidy related install rules.

Documentation:

  • Document that MaaFramework does not handle macOS permission flows directly and point clients to MaaToolkit helpers and example tests for implementation guidance.

@neko-para neko-para requested a review from MistEO March 18, 2026 12:34
Copy link
Copy Markdown
Member

@MistEO MistEO left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其他应该没啥问题

@neko-para neko-para marked this pull request as ready for review March 19, 2026 05:44
@neko-para neko-para requested a review from MistEO March 19, 2026 05:44
@neko-para
Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • MaaToolkit/MacOS/MaaToolkitMacOS.h 中有两个连续的 #pragma once 指令;你可以删除重复的那一个,让这个头文件更干净。
  • MacOSPermission.mm 中的 switch 语句在遇到未知的 MaaMacOSPermission 值时会直接落到 return false;建议添加带有日志或断言的 default 分支,这样无效的枚举值就能被暴露出来,而不会被静默地当成「无权限」处理。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `MaaToolkit/MacOS/MaaToolkitMacOS.h` there are two consecutive `#pragma once` directives; you can drop the duplicate to keep the header clean.
- The `switch` statements in `MacOSPermission.mm` fall through to `return false` for unknown `MaaMacOSPermission` values; consider adding a default case with logging or an assertion so invalid enum values are surfaced rather than silently treated as "no permission".

## Individual Comments

### Comment 1
<location path="source/MaaToolkit/MacOS/MacOSPermission.mm" line_range="32-25" />
<code_context>
+    }
+}
+
+bool MacOSCheckPermission(MaaMacOSPermission perm)
+{
+    switch (perm) {
+    case MaaMacOSPermissionScreenCapture:
+        return CGPreflightScreenCaptureAccess();
+    case MaaMacOSPermissionAccessibility:
+        return AXIsProcessTrusted();
+    }
+    return false;
+}
+
</code_context>
<issue_to_address>
**suggestion:** Consider handling or logging unexpected `MaaMacOSPermission` values explicitly in the switch statements.

These three functions (`MacOSCheckPermission`, `MacOSRequestPermission`, `MacOSRevealPermissionSettings`) currently fall through to `return false` for any value outside the known enum cases. Adding a `default` that logs (or asserts in debug) would surface unexpected enum values and make enum/implementation mismatches easier to detect instead of silently treating them as "no".

Suggested implementation:

```
bool MacOSCheckPermission(MaaMacOSPermission perm)
{
    switch (perm) {
    case MaaMacOSPermissionScreenCapture:
        return CGPreflightScreenCaptureAccess();
    case MaaMacOSPermissionAccessibility:
        return AXIsProcessTrusted();
    default:
        NSLog(@"[MaaToolkit][MacOSPermission] Unexpected MaaMacOSPermission value in MacOSCheckPermission: %d",
              static_cast<int>(perm));
#ifdef DEBUG
        NSAssert(false, @"Unexpected MaaMacOSPermission value in MacOSCheckPermission: %d",
                 static_cast<int>(perm));
#endif
        break;
    }
    return false;
}

```

You should apply the same pattern to `MacOSRequestPermission` and `MacOSRevealPermissionSettings`:

- In each function’s `switch (perm)`:
  - Add a `default:` case that:
    - Logs the unexpected enum value (e.g. with `NSLog` and `static_cast<int>(perm)` to avoid `%d` with enum types).
    - Optionally `NSAssert(false, ...)` under `#ifdef DEBUG` (or whatever debug/assert macro your codebase uses).
    - Uses `break;` so that the function still falls through to the existing `return false;` after the `switch`.
- Ensure you do not remove the existing `return false;` after the `switch`, so behavior for unexpected values remains "no" but is now visible in logs (and in debug builds, via an assertion).
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得这些 review 有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论下点 👍 或 👎,我会根据你的反馈改进后续的 review。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • In MaaToolkit/MacOS/MaaToolkitMacOS.h there are two consecutive #pragma once directives; you can drop the duplicate to keep the header clean.
  • The switch statements in MacOSPermission.mm fall through to return false for unknown MaaMacOSPermission values; consider adding a default case with logging or an assertion so invalid enum values are surfaced rather than silently treated as "no permission".
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `MaaToolkit/MacOS/MaaToolkitMacOS.h` there are two consecutive `#pragma once` directives; you can drop the duplicate to keep the header clean.
- The `switch` statements in `MacOSPermission.mm` fall through to `return false` for unknown `MaaMacOSPermission` values; consider adding a default case with logging or an assertion so invalid enum values are surfaced rather than silently treated as "no permission".

## Individual Comments

### Comment 1
<location path="source/MaaToolkit/MacOS/MacOSPermission.mm" line_range="32-25" />
<code_context>
+    }
+}
+
+bool MacOSCheckPermission(MaaMacOSPermission perm)
+{
+    switch (perm) {
+    case MaaMacOSPermissionScreenCapture:
+        return CGPreflightScreenCaptureAccess();
+    case MaaMacOSPermissionAccessibility:
+        return AXIsProcessTrusted();
+    }
+    return false;
+}
+
</code_context>
<issue_to_address>
**suggestion:** Consider handling or logging unexpected `MaaMacOSPermission` values explicitly in the switch statements.

These three functions (`MacOSCheckPermission`, `MacOSRequestPermission`, `MacOSRevealPermissionSettings`) currently fall through to `return false` for any value outside the known enum cases. Adding a `default` that logs (or asserts in debug) would surface unexpected enum values and make enum/implementation mismatches easier to detect instead of silently treating them as "no".

Suggested implementation:

```
bool MacOSCheckPermission(MaaMacOSPermission perm)
{
    switch (perm) {
    case MaaMacOSPermissionScreenCapture:
        return CGPreflightScreenCaptureAccess();
    case MaaMacOSPermissionAccessibility:
        return AXIsProcessTrusted();
    default:
        NSLog(@"[MaaToolkit][MacOSPermission] Unexpected MaaMacOSPermission value in MacOSCheckPermission: %d",
              static_cast<int>(perm));
#ifdef DEBUG
        NSAssert(false, @"Unexpected MaaMacOSPermission value in MacOSCheckPermission: %d",
                 static_cast<int>(perm));
#endif
        break;
    }
    return false;
}

```

You should apply the same pattern to `MacOSRequestPermission` and `MacOSRevealPermissionSettings`:

- In each function’s `switch (perm)`:
  - Add a `default:` case that:
    - Logs the unexpected enum value (e.g. with `NSLog` and `static_cast<int>(perm)` to avoid `%d` with enum types).
    - Optionally `NSAssert(false, ...)` under `#ifdef DEBUG` (or whatever debug/assert macro your codebase uses).
    - Uses `break;` so that the function still falls through to the existing `return false;` after the `switch`.
- Ensure you do not remove the existing `return false;` after the `switch`, so behavior for unexpected values remains "no" but is now visible in logs (and in debug builds, via an assertion).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • MaaToolkitMacOS.h 中,你连续写了两个 #pragma once 指令;第二个是多余的,可以移除以提高代码清晰度。
  • MaaToolkit.cppm 中,你用新的 macOS 权限 API 替换了原先导出的 MaaToolkitProjectInterface*;如果这不是有意为之,建议重新导出原有的 project interface,并在其后追加新的 macOS 导出,以避免破坏现有模块使用方。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `MaaToolkitMacOS.h` you have two consecutive `#pragma once` directives; the second one is redundant and can be removed for clarity.
- In `MaaToolkit.cppm` you replaced the `MaaToolkitProjectInterface*` exports with the new macOS permission APIs; if this wasn’t intentional, consider re‑adding the project interface exports and simply appending the new macOS exports to avoid breaking existing module consumers.

## Individual Comments

### Comment 1
<location path="include/MaaToolkit/MaaToolkitDef.h" line_range="11-17" />
<code_context>
 typedef struct MaaToolkitDesktopWindow MaaToolkitDesktopWindow;
 typedef struct MaaToolkitDesktopWindowList MaaToolkitDesktopWindowList;
+
+enum MaaMacOSPermissionEnum
+{
+    MaaMacOSPermissionScreenCapture = 1,
+    MaaMacOSPermissionAccessibility = 2
+};
+
+typedef int32_t MaaMacOSPermission;
</code_context>
<issue_to_address>
**issue (bug_risk):** Align enum underlying type with MaaMacOSPermission typedef to avoid ABI/type mismatches

`MaaMacOSPermissionEnum` currently defaults to `int` as its underlying type, while `MaaMacOSPermission` is explicitly `int32_t`. This mismatch can cause ABI issues, especially across FFI boundaries. Please either declare the enum with an explicit underlying type (`enum MaaMacOSPermissionEnum : int32_t { ... };`) or make `MaaMacOSPermission` a typedef of the enum (`typedef MaaMacOSPermissionEnum MaaMacOSPermission;`) to keep them aligned.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • In MaaToolkitMacOS.h you have two consecutive #pragma once directives; the second one is redundant and can be removed for clarity.
  • In MaaToolkit.cppm you replaced the MaaToolkitProjectInterface* exports with the new macOS permission APIs; if this wasn’t intentional, consider re‑adding the project interface exports and simply appending the new macOS exports to avoid breaking existing module consumers.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `MaaToolkitMacOS.h` you have two consecutive `#pragma once` directives; the second one is redundant and can be removed for clarity.
- In `MaaToolkit.cppm` you replaced the `MaaToolkitProjectInterface*` exports with the new macOS permission APIs; if this wasn’t intentional, consider re‑adding the project interface exports and simply appending the new macOS exports to avoid breaking existing module consumers.

## Individual Comments

### Comment 1
<location path="include/MaaToolkit/MaaToolkitDef.h" line_range="11-17" />
<code_context>
 typedef struct MaaToolkitDesktopWindow MaaToolkitDesktopWindow;
 typedef struct MaaToolkitDesktopWindowList MaaToolkitDesktopWindowList;
+
+enum MaaMacOSPermissionEnum
+{
+    MaaMacOSPermissionScreenCapture = 1,
+    MaaMacOSPermissionAccessibility = 2
+};
+
+typedef int32_t MaaMacOSPermission;
</code_context>
<issue_to_address>
**issue (bug_risk):** Align enum underlying type with MaaMacOSPermission typedef to avoid ABI/type mismatches

`MaaMacOSPermissionEnum` currently defaults to `int` as its underlying type, while `MaaMacOSPermission` is explicitly `int32_t`. This mismatch can cause ABI issues, especially across FFI boundaries. Please either declare the enum with an explicit underlying type (`enum MaaMacOSPermissionEnum : int32_t { ... };`) or make `MaaMacOSPermission` a typedef of the enum (`typedef MaaMacOSPermissionEnum MaaMacOSPermission;`) to keep them aligned.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +11 to +17
enum MaaMacOSPermissionEnum
{
MaaMacOSPermissionScreenCapture = 1,
MaaMacOSPermissionAccessibility = 2
};

typedef int32_t MaaMacOSPermission;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): 将枚举的底层类型与 MaaMacOSPermission 的 typedef 对齐,以避免 ABI/类型不匹配

MaaMacOSPermissionEnum 目前默认使用 int 作为其底层类型,而 MaaMacOSPermission 明确为 int32_t。这种不匹配可能会导致 ABI 问题,尤其是在跨 FFI 边界时。请考虑要么为该枚举显式指定底层类型(enum MaaMacOSPermissionEnum : int32_t { ... };),要么让 MaaMacOSPermission 成为该枚举的 typedef(typedef MaaMacOSPermissionEnum MaaMacOSPermission;),以保持它们的一致性。

Original comment in English

issue (bug_risk): Align enum underlying type with MaaMacOSPermission typedef to avoid ABI/type mismatches

MaaMacOSPermissionEnum currently defaults to int as its underlying type, while MaaMacOSPermission is explicitly int32_t. This mismatch can cause ABI issues, especially across FFI boundaries. Please either declare the enum with an explicit underlying type (enum MaaMacOSPermissionEnum : int32_t { ... };) or make MaaMacOSPermission a typedef of the enum (typedef MaaMacOSPermissionEnum MaaMacOSPermission;) to keep them aligned.

@YJBeetle
Copy link
Copy Markdown
Contributor

记得改文档这里

> MaaFramework 不负责权限申请和引导,Client需要自行实现相关功能。可以参考 [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test)

@YJBeetle
Copy link
Copy Markdown
Contributor

YJBeetle commented Mar 19, 2026

另外苹果的权限有个鬼畜的点在于: 给应用权限后 ,如果你不重启 ,其实是有权限的 ,直接去调对应的东西都没问题;但是你调用检查权限会得到没有权限的结果 , 于是这逻辑就很难说应该继续还是应该重启。

std::cout << "是否重新检查?(Y/n): ";
std::string choice;
std::getline(std::cin, choice);
if (choice == "n" || choice == "N") {
std::cout << "请在授予权限后重启应用。" << std::endl;
exit(0);
}

@MistEO MistEO requested a review from Copilot March 20, 2026 04:19
@MistEO
Copy link
Copy Markdown
Member

MistEO commented Mar 20, 2026

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了两个问题,并留下了一些总体反馈:

  • source/modules/MaaToolkit.cppm 中,MacOS 权限相关的导出替换了现有的 MaaToolkitProjectInterface* 导出,而不是与其并列新增;如果这种替换并非有意为之,将会在静默的情况下把项目接口 API 从 C++20 模块中移除,很可能会破坏现有的使用方。
  • 目前 MaaToolkit 的 macOS 权限 C API 在权限被实际拒绝时和在非 Apple 平台(存根分支)被调用时都会返回 false,这会让调用方很难区分真实的权限状态与“不支持的平台”错误;建议增加一个单独的错误信号(例如专用枚举、错误码,或可通过日志访问的标志),以便各语言绑定可以对这些情况做差异化处理。
给 AI Agent 的提示
Please address the comments from this code review:

## Overall Comments
- In `source/modules/MaaToolkit.cppm` the MacOS permission exports replace the existing `MaaToolkitProjectInterface*` exports instead of being added alongside them; if that replacement is unintentional, it will silently drop the project interface APIs from the C++20 module and likely break existing consumers.
- The MaaToolkit macOS permission C APIs currently return `false` both when permissions are actually denied and when called on non-Apple platforms (stub branch), which makes it hard for callers to distinguish a genuine permission state from an unsupported-platform error; consider adding a separate error signal (e.g., a dedicated enum, error code, or log-accessible flag) so bindings can handle these cases differently.

## Individual Comments

### Comment 1
<location path="source/binding/NodeJS/src/apis/global.d.ts" line_range="6-7" />
<code_context>

             resize_image(image: ArrayBuffer, width: number, height: number): ArrayBuffer
+
+            macos_check_permission(perm: MacOSPermission): boolean
+            macos_request_permission(perm: MacOSPermission): Promise<boolean>
+            macos_reveal_permission_settings(perm: MacOSPermission): boolean
         }
     }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** TypeScript 声明没有体现这些 API 在某些构建/平台上可能不可用

在原生代码中,当工具包不可用时,这些函数会抛出(`throw_toolkit_unavailable`),并且它们实际上仅适用于 macOS,但 TS 类型把它们呈现为始终可用、返回布尔值的 API。

如果这些函数可能在非 macOS / 无工具包的构建上运行,建议在类型定义中体现这一点(例如通过带文档的能力标志或带类型的错误/联合类型),以避免调用方误以为这些 API 在所有环境中都可用。

```suggestion
        const Global: {
            get version_from_macro(): string
            config_init_option(user_path: string, default_json?: string): void

            resize_image(image: ArrayBuffer, width: number, height: number): ArrayBuffer

            /**
             * Indicates whether the macOS permissions toolkit is available on this build/platform.
             *
             * When `false` or `undefined`, the macOS-specific permission APIs below may not be
             * present and native calls may throw a toolkit-unavailable error if invoked indirectly.
             */
            readonly macos_permissions_available?: boolean

            /**
             * Check the current status of a macOS permission.
             *
             * This API is only available when `macos_permissions_available === true` and on
             * supported macOS builds. Callers should feature-detect by checking
             * `macos_permissions_available` and that this function is defined before calling.
             */
            macos_check_permission?: (perm: MacOSPermission) => boolean

            /**
             * Request a macOS permission from the user.
             *
             * This API is only available when `macos_permissions_available === true` and on
             * supported macOS builds. Callers should feature-detect by checking
             * `macos_permissions_available` and that this function is defined before calling.
             */
            macos_request_permission?: (perm: MacOSPermission) => Promise<boolean>

            /**
             * Reveal the system settings UI for managing a macOS permission.
             *
             * This API is only available when `macos_permissions_available === true` and on
             * supported macOS builds. Callers should feature-detect by checking
             * `macos_permissions_available` and that this function is defined before calling.
             */
            macos_reveal_permission_settings?: (perm: MacOSPermission) => boolean
        }
```
</issue_to_address>

### Comment 2
<location path="docs/en_us/2.4-ControlMethods.md" line_range="138" />
<code_context>

+> [!TIP]
+>
+> MaaFramework is not responsible for requesting or guiding permissions; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).
+
 ### MacOS Screencap
</code_context>
<issue_to_address>
**nitpick (typo):** 建议对短语 "requesting or guiding permissions" 进行润色,以使语法更自然。

你可以改成类似这样的话:“requesting permissions or guiding users through permission prompts”,既能让句子读起来更自然,又能保留原有含义。

```suggestion
> MaaFramework is not responsible for requesting permissions or guiding users through permission prompts; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).
```
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的代码评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据这些反馈改进后续的评审。
Original comment in English

Hey - I've found 2 issues, and left some high level feedback:

  • In source/modules/MaaToolkit.cppm the MacOS permission exports replace the existing MaaToolkitProjectInterface* exports instead of being added alongside them; if that replacement is unintentional, it will silently drop the project interface APIs from the C++20 module and likely break existing consumers.
  • The MaaToolkit macOS permission C APIs currently return false both when permissions are actually denied and when called on non-Apple platforms (stub branch), which makes it hard for callers to distinguish a genuine permission state from an unsupported-platform error; consider adding a separate error signal (e.g., a dedicated enum, error code, or log-accessible flag) so bindings can handle these cases differently.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `source/modules/MaaToolkit.cppm` the MacOS permission exports replace the existing `MaaToolkitProjectInterface*` exports instead of being added alongside them; if that replacement is unintentional, it will silently drop the project interface APIs from the C++20 module and likely break existing consumers.
- The MaaToolkit macOS permission C APIs currently return `false` both when permissions are actually denied and when called on non-Apple platforms (stub branch), which makes it hard for callers to distinguish a genuine permission state from an unsupported-platform error; consider adding a separate error signal (e.g., a dedicated enum, error code, or log-accessible flag) so bindings can handle these cases differently.

## Individual Comments

### Comment 1
<location path="source/binding/NodeJS/src/apis/global.d.ts" line_range="6-7" />
<code_context>

             resize_image(image: ArrayBuffer, width: number, height: number): ArrayBuffer
+
+            macos_check_permission(perm: MacOSPermission): boolean
+            macos_request_permission(perm: MacOSPermission): Promise<boolean>
+            macos_reveal_permission_settings(perm: MacOSPermission): boolean
         }
     }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** TypeScript declarations don’t indicate that these APIs may be unavailable on some builds/platforms

In native code these functions can throw (`throw_toolkit_unavailable`) when the toolkit isn’t available, and they’re effectively macOS-only, but the TS types present them as always-available boolean-returning APIs.

If these may run on non-macOS/toolkit-less builds, consider reflecting that in the typings (e.g. a documented capability flag or a typed error/union) so callers don’t assume universal availability.

```suggestion
        const Global: {
            get version_from_macro(): string
            config_init_option(user_path: string, default_json?: string): void

            resize_image(image: ArrayBuffer, width: number, height: number): ArrayBuffer

            /**
             * Indicates whether the macOS permissions toolkit is available on this build/platform.
             *
             * When `false` or `undefined`, the macOS-specific permission APIs below may not be
             * present and native calls may throw a toolkit-unavailable error if invoked indirectly.
             */
            readonly macos_permissions_available?: boolean

            /**
             * Check the current status of a macOS permission.
             *
             * This API is only available when `macos_permissions_available === true` and on
             * supported macOS builds. Callers should feature-detect by checking
             * `macos_permissions_available` and that this function is defined before calling.
             */
            macos_check_permission?: (perm: MacOSPermission) => boolean

            /**
             * Request a macOS permission from the user.
             *
             * This API is only available when `macos_permissions_available === true` and on
             * supported macOS builds. Callers should feature-detect by checking
             * `macos_permissions_available` and that this function is defined before calling.
             */
            macos_request_permission?: (perm: MacOSPermission) => Promise<boolean>

            /**
             * Reveal the system settings UI for managing a macOS permission.
             *
             * This API is only available when `macos_permissions_available === true` and on
             * supported macOS builds. Callers should feature-detect by checking
             * `macos_permissions_available` and that this function is defined before calling.
             */
            macos_reveal_permission_settings?: (perm: MacOSPermission) => boolean
        }
```
</issue_to_address>

### Comment 2
<location path="docs/en_us/2.4-ControlMethods.md" line_range="138" />
<code_context>

+> [!TIP]
+>
+> MaaFramework is not responsible for requesting or guiding permissions; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).
+
 ### MacOS Screencap
</code_context>
<issue_to_address>
**nitpick (typo):** Consider clarifying the phrase "requesting or guiding permissions" for more natural grammar.

You could instead say something like: "requesting permissions or guiding users through permission prompts" to make the sentence flow more naturally while preserving the meaning.

```suggestion
> MaaFramework is not responsible for requesting permissions or guiding users through permission prompts; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 6 to 7
const Global: {
get version_from_macro(): string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): TypeScript 声明没有体现这些 API 在某些构建/平台上可能不可用

在原生代码中,当工具包不可用时,这些函数会抛出(throw_toolkit_unavailable),并且它们实际上仅适用于 macOS,但 TS 类型把它们呈现为始终可用、返回布尔值的 API。

如果这些函数可能在非 macOS / 无工具包的构建上运行,建议在类型定义中体现这一点(例如通过带文档的能力标志或带类型的错误/联合类型),以避免调用方误以为这些 API 在所有环境中都可用。

Suggested change
const Global: {
get version_from_macro(): string
const Global: {
get version_from_macro(): string
config_init_option(user_path: string, default_json?: string): void
resize_image(image: ArrayBuffer, width: number, height: number): ArrayBuffer
/**
* Indicates whether the macOS permissions toolkit is available on this build/platform.
*
* When `false` or `undefined`, the macOS-specific permission APIs below may not be
* present and native calls may throw a toolkit-unavailable error if invoked indirectly.
*/
readonly macos_permissions_available?: boolean
/**
* Check the current status of a macOS permission.
*
* This API is only available when `macos_permissions_available === true` and on
* supported macOS builds. Callers should feature-detect by checking
* `macos_permissions_available` and that this function is defined before calling.
*/
macos_check_permission?: (perm: MacOSPermission) => boolean
/**
* Request a macOS permission from the user.
*
* This API is only available when `macos_permissions_available === true` and on
* supported macOS builds. Callers should feature-detect by checking
* `macos_permissions_available` and that this function is defined before calling.
*/
macos_request_permission?: (perm: MacOSPermission) => Promise<boolean>
/**
* Reveal the system settings UI for managing a macOS permission.
*
* This API is only available when `macos_permissions_available === true` and on
* supported macOS builds. Callers should feature-detect by checking
* `macos_permissions_available` and that this function is defined before calling.
*/
macos_reveal_permission_settings?: (perm: MacOSPermission) => boolean
}
Original comment in English

suggestion (bug_risk): TypeScript declarations don’t indicate that these APIs may be unavailable on some builds/platforms

In native code these functions can throw (throw_toolkit_unavailable) when the toolkit isn’t available, and they’re effectively macOS-only, but the TS types present them as always-available boolean-returning APIs.

If these may run on non-macOS/toolkit-less builds, consider reflecting that in the typings (e.g. a documented capability flag or a typed error/union) so callers don’t assume universal availability.

Suggested change
const Global: {
get version_from_macro(): string
const Global: {
get version_from_macro(): string
config_init_option(user_path: string, default_json?: string): void
resize_image(image: ArrayBuffer, width: number, height: number): ArrayBuffer
/**
* Indicates whether the macOS permissions toolkit is available on this build/platform.
*
* When `false` or `undefined`, the macOS-specific permission APIs below may not be
* present and native calls may throw a toolkit-unavailable error if invoked indirectly.
*/
readonly macos_permissions_available?: boolean
/**
* Check the current status of a macOS permission.
*
* This API is only available when `macos_permissions_available === true` and on
* supported macOS builds. Callers should feature-detect by checking
* `macos_permissions_available` and that this function is defined before calling.
*/
macos_check_permission?: (perm: MacOSPermission) => boolean
/**
* Request a macOS permission from the user.
*
* This API is only available when `macos_permissions_available === true` and on
* supported macOS builds. Callers should feature-detect by checking
* `macos_permissions_available` and that this function is defined before calling.
*/
macos_request_permission?: (perm: MacOSPermission) => Promise<boolean>
/**
* Reveal the system settings UI for managing a macOS permission.
*
* This API is only available when `macos_permissions_available === true` and on
* supported macOS builds. Callers should feature-detect by checking
* `macos_permissions_available` and that this function is defined before calling.
*/
macos_reveal_permission_settings?: (perm: MacOSPermission) => boolean
}


> [!TIP]
>
> MaaFramework is not responsible for requesting or guiding permissions; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (typo): 建议对短语 "requesting or guiding permissions" 进行润色,以使语法更自然。

你可以改成类似这样的话:“requesting permissions or guiding users through permission prompts”,既能让句子读起来更自然,又能保留原有含义。

Suggested change
> MaaFramework is not responsible for requesting or guiding permissions; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).
> MaaFramework is not responsible for requesting permissions or guiding users through permission prompts; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).
Original comment in English

nitpick (typo): Consider clarifying the phrase "requesting or guiding permissions" for more natural grammar.

You could instead say something like: "requesting permissions or guiding users through permission prompts" to make the sentence flow more naturally while preserving the meaning.

Suggested change
> MaaFramework is not responsible for requesting or guiding permissions; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).
> MaaFramework is not responsible for requesting permissions or guiding users through permission prompts; clients must implement these functionalities themselves. MaaToolkit provides a set of helper functions for this purpose; please refer to [test/macos_test](https://github.com/MaaXYZ/MaaFramework/tree/main/test/macos_test).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds macOS-specific permission helper APIs to MaaToolkit (screen capture + accessibility), wires them through the C API surface, and exposes them to the Python and NodeJS bindings, while updating macOS linking and the macOS test app to use the new toolkit APIs.

Changes:

  • Add MaaMacOSPermission enum + C APIs to check/request/reveal macOS permission settings, with macOS implementation.
  • Expose the new APIs in Python (maa.toolkit.Toolkit) and NodeJS (maa.Global), including async request in NodeJS.
  • Update build/docs/tests: adjust MaaToolkit’s macOS framework linking, update docs guidance, and remove the macos_test’s local permission implementation.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/macos_test/main.cpp Switch macos_test to use MaaToolkit macOS permission APIs instead of local helpers.
test/macos_test/MacOSPermission.mm Remove local Objective-C++ permission implementation from the test app.
test/macos_test/MacOSPermission.h Remove local permission declarations from the test app.
test/macos_test/CMakeLists.txt Stop building the removed local permission sources into the test target.
source/modules/MaaToolkit.cppm Export the new macOS permission APIs from the C++ module interface.
source/binding/Python/maa/toolkit.py Add Python Toolkit wrappers + ctypes signatures for macOS permission APIs.
source/binding/Python/maa/define.py Add Python-side MaaMacOSPermission type + enum.
source/binding/NodeJS/src/apis/global.d.ts Add NodeJS typings for macOS permission functions.
source/binding/NodeJS/src/apis/global.cpp Implement NodeJS bindings for macOS permission APIs (toolkit-guarded; async request).
source/MaaToolkit/MacOS/MacOSPermission.mm New Objective-C++ implementation for permission check/request/reveal on macOS.
source/MaaToolkit/MacOS/MacOSPermission.h New internal header for macOS permission helpers.
source/MaaToolkit/CMakeLists.txt Adjust MaaToolkit macOS framework linking and minor formatting cleanup.
source/MaaToolkit/API/MaaToolkitMacOS.cpp New C API entry points with non-macOS stubs and logging.
include/MaaToolkit/MacOS/MaaToolkitMacOS.h New public header declaring the MaaToolkit macOS permission C APIs.
include/MaaToolkit/MaaToolkitDef.h Add MaaMacOSPermission enum/type to MaaToolkit public defs.
include/MaaToolkit/MaaToolkitAPI.h Expose macOS permission API header via the main MaaToolkitAPI umbrella header.
docs/en_us/2.4-ControlMethods.md Document that clients should handle permissions and point to the macos_test for reference; fix list formatting.

Comment on lines +46 to +50
// MacOS/MaaToolkitMacOSPermission.h

export using ::MaaToolkitProjectInterfaceRegisterCustomRecognition;
export using ::MaaToolkitProjectInterfaceRegisterCustomAction;
export using ::MaaToolkitProjectInterfaceRunCli;
export using ::MaaToolkitMacOSCheckPermission;
export using ::MaaToolkitMacOSRequestPermission;
export using ::MaaToolkitMacOSRevealPermissionSettings;
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The section comment references MacOS/MaaToolkitMacOSPermission.h, but the public header added/exported in this PR is MacOS/MaaToolkitMacOS.h (via include/MaaToolkit/MaaToolkitAPI.h). Please update the comment to match the actual header to avoid confusion when navigating the module exports.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,70 @@
#include "MacOSPermission.h"

#import <Cocoa/Cocoa.h>
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MacOSPermission.mm uses CGPreflightScreenCaptureAccess / CGRequestScreenCaptureAccess and AXIsProcessTrusted*, but it only imports <Cocoa/Cocoa.h>. These symbols are declared in CoreGraphics/ApplicationServices headers on many SDKs, so this can fail to compile depending on header transitive-includes. Add explicit imports for the frameworks providing these APIs (e.g., #import <CoreGraphics/CoreGraphics.h> and #import <ApplicationServices/ApplicationServices.h>).

Suggested change
#import <Cocoa/Cocoa.h>
#import <Cocoa/Cocoa.h>
#import <CoreGraphics/CoreGraphics.h>
#import <ApplicationServices/ApplicationServices.h>

Copilot uses AI. Check for mistakes.
Comment on lines 27 to 32
if(APPLE)
# macOS frameworks for ScreenCaptureKit
find_library(SCREEN_CAPTURE_KIT ScreenCaptureKit REQUIRED)
find_library(CORE_FOUNDATION CoreFoundation REQUIRED)
find_library(FOUNDATION Foundation REQUIRED)
target_link_libraries(MaaToolkit PRIVATE
${SCREEN_CAPTURE_KIT}
${CORE_FOUNDATION}
${FOUNDATION}
)
find_library(COCOA Cocoa REQUIRED)
target_link_libraries(MaaToolkit PRIVATE ${SCREEN_CAPTURE_KIT} ${COCOA})
endif()
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MaaToolkit now implements macOS permission helpers that call CoreGraphics/ApplicationServices APIs (screen capture + accessibility), but the macOS link list only adds ScreenCaptureKit and Cocoa. To avoid relying on transitive framework dependencies and potential link errors, explicitly link the framework that provides the AX/CG symbols (e.g., ApplicationServices, consistent with source/MaaMacOSControlUnit/CMakeLists.txt).

Copilot uses AI. Check for mistakes.
@MistEO MistEO merged commit 8e3feac into main Mar 21, 2026
19 checks passed
@MistEO MistEO deleted the feat/macos_utils branch March 21, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants