diff --git a/docs/en_us/2.2-IntegratedInterfaceOverview.md b/docs/en_us/2.2-IntegratedInterfaceOverview.md index 83c4a7a01c..8e960839c0 100644 --- a/docs/en_us/2.2-IntegratedInterfaceOverview.md +++ b/docs/en_us/2.2-IntegratedInterfaceOverview.md @@ -1012,34 +1012,55 @@ Get window at specified index in window list - `window`: Window -Get window handle +Get window handle (common field) > [!NOTE] > -> - On Win32, the returned value is a native `HWND`. -> - On macOS, the returned value represents the window `windowID` (`CGWindowID` / `SCWindow.windowID`). It is force-cast to `void*` at the API layer, so it is not a Cocoa `NSWindow*` pointer. +> - On Win32, the returned value is a native `HWND` (cast to `uint64`). +> - On macOS, the returned value is the window `windowID` (`CGWindowID` / `SCWindow.windowID`). +> - On Linux, the returned value is the Wayland window ID. -### MaaToolkitDesktopWindowGetClassName +### MaaToolkitDesktopWindowGetWindowName - `window`: Window -Get window class name +Get window name (common field) > [!NOTE] > -> - On Win32, the returned value is the window class name. -> - On macOS, the returned value is the Bundle ID (`SCWindow.owningApplication.bundleIdentifier`). +> - On Win32, the returned value is the window name. +> - On macOS, the returned value is the window title (`SCWindow.title`). +> - On Linux, the returned value is the Wayland socket name. -### MaaToolkitDesktopWindowGetWindowName +### MaaToolkitDesktopWindowGetWin32ClassName - `window`: Window -Get window name +Get window class name (Win32-specific field) -> [!NOTE] -> -> - On Win32, the returned value is the window name. -> - On macOS, the returned value is the window title (`SCWindow.title`). +### MaaToolkitDesktopWindowGetMacOSPID + +- `window`: Window + +Get process ID (macOS-specific field) + +### MaaToolkitDesktopWindowGetMacOSBundleID + +- `window`: Window + +Get application bundle ID (macOS-specific field, `SCWindow.owningApplication.bundleIdentifier`) + +### MaaToolkitDesktopWindowGetMacOSApplicationName + +- `window`: Window + +Get application name (macOS-specific field, `SCWindow.owningApplication.applicationName`) + +### MaaToolkitDesktopWindowGetLinuxSocketPath + +- `window`: Window + +Get Wayland socket path (Linux-specific field) ## MaaAgentClientAPI.h diff --git "a/docs/zh_cn/2.2-\351\233\206\346\210\220\346\216\245\345\217\243\344\270\200\350\247\210.md" "b/docs/zh_cn/2.2-\351\233\206\346\210\220\346\216\245\345\217\243\344\270\200\350\247\210.md" index 6d1774b5c8..c51dac2ce3 100644 --- "a/docs/zh_cn/2.2-\351\233\206\346\210\220\346\216\245\345\217\243\344\270\200\350\247\210.md" +++ "b/docs/zh_cn/2.2-\351\233\206\346\210\220\346\216\245\345\217\243\344\270\200\350\247\210.md" @@ -1011,34 +1011,55 @@ - `window`: 窗口 -获取窗口句柄 +获取窗口句柄(通用字段) > [!NOTE] > -> - Win32 下,返回值语义为原生 `HWND`。 -> - macOS 下,返回值语义为窗口的 `windowID`(`CGWindowID` / `SCWindow.windowID`),在接口层会强制转换为 `void*` 返回,因此它不是 Cocoa `NSWindow*` 指针。 +> - Win32 下,返回值语义为原生 `HWND`(转换为 `uint64`)。 +> - macOS 下,返回值语义为窗口的 `windowID`(`CGWindowID` / `SCWindow.windowID`)。 +> - Linux 下,返回值语义为 Wayland 窗口 ID。 -### MaaToolkitDesktopWindowGetClassName +### MaaToolkitDesktopWindowGetWindowName - `window`: 窗口 -获取窗口类名 +获取窗口名称(通用字段) > [!NOTE] > -> - Win32 下,返回值语义为窗口类名。 -> - macOS 下,返回值语义为应用包名(`SCWindow.owningApplication.bundleIdentifier`)。 +> - Win32 下,返回值语义为窗口名称。 +> - macOS 下,返回值语义为窗口标题(`SCWindow.title`)。 +> - Linux 下,返回值语义为 Wayland socket 名称。 -### MaaToolkitDesktopWindowGetWindowName +### MaaToolkitDesktopWindowGetWin32ClassName - `window`: 窗口 -获取窗口名称 +获取窗口类名(Win32 专有字段) -> [!NOTE] -> -> - Win32 下,返回值语义为窗口名称。 -> - macOS 下,返回值语义为窗口标题(`SCWindow.title`)。 +### MaaToolkitDesktopWindowGetMacOSPID + +- `window`: 窗口 + +获取进程 ID(macOS 专有字段) + +### MaaToolkitDesktopWindowGetMacOSBundleID + +- `window`: 窗口 + +获取应用包名(macOS 专有字段,`SCWindow.owningApplication.bundleIdentifier`) + +### MaaToolkitDesktopWindowGetMacOSApplicationName + +- `window`: 窗口 + +获取应用程序名称(macOS 专有字段,`SCWindow.owningApplication.applicationName`) + +### MaaToolkitDesktopWindowGetLinuxSocketPath + +- `window`: 窗口 + +获取 Wayland socket 路径(Linux 专有字段) ## MaaAgentClientAPI.h diff --git a/include/MaaToolkit/DesktopWindow/MaaToolkitDesktopWindow.h b/include/MaaToolkit/DesktopWindow/MaaToolkitDesktopWindow.h index 9cabe593f2..0b06f9e7b1 100644 --- a/include/MaaToolkit/DesktopWindow/MaaToolkitDesktopWindow.h +++ b/include/MaaToolkit/DesktopWindow/MaaToolkitDesktopWindow.h @@ -17,17 +17,20 @@ extern "C" MAA_TOOLKIT_API MaaSize MaaToolkitDesktopWindowListSize(const MaaToolkitDesktopWindowList* list); MAA_TOOLKIT_API const MaaToolkitDesktopWindow* MaaToolkitDesktopWindowListAt(const MaaToolkitDesktopWindowList* list, MaaSize index); - // Win32: HWND - // macOS: CGWindowID (SCWindow.windowID), force-cast to void*, NOT NSWindow* - MAA_TOOLKIT_API void* MaaToolkitDesktopWindowGetHandle(const MaaToolkitDesktopWindow* window); + // 通用字段 + MAA_TOOLKIT_API uint64_t MaaToolkitDesktopWindowGetHandle(const MaaToolkitDesktopWindow* window); + MAA_TOOLKIT_API const char* MaaToolkitDesktopWindowGetWindowName(const MaaToolkitDesktopWindow* window); - // Win32: window class name - // macOS: bundle identifier (SCWindow.owningApplication.bundleIdentifier) - MAA_TOOLKIT_API const char* MaaToolkitDesktopWindowGetClassName(const MaaToolkitDesktopWindow* window); + // Win32 专有字段 + MAA_TOOLKIT_API const char* MaaToolkitDesktopWindowGetWin32ClassName(const MaaToolkitDesktopWindow* window); - // Win32: window name - // macOS: window title (SCWindow.title) - MAA_TOOLKIT_API const char* MaaToolkitDesktopWindowGetWindowName(const MaaToolkitDesktopWindow* window); + // MacOS 专有字段 + MAA_TOOLKIT_API int32_t MaaToolkitDesktopWindowGetMacOSPID(const MaaToolkitDesktopWindow* window); // macOS 进程ID + MAA_TOOLKIT_API const char* MaaToolkitDesktopWindowGetMacOSBundleID(const MaaToolkitDesktopWindow* window); // macOS Bundle ID + MAA_TOOLKIT_API const char* MaaToolkitDesktopWindowGetMacOSApplicationName(const MaaToolkitDesktopWindow* window); // macOS 应用程序名称 + + // Linux 专有字段 + MAA_TOOLKIT_API const char* MaaToolkitDesktopWindowGetLinuxSocketPath(const MaaToolkitDesktopWindow* window); #ifdef __cplusplus } diff --git a/sample/cpp/main.cpp b/sample/cpp/main.cpp index abd0fee1b5..d8a932df87 100644 --- a/sample/cpp/main.cpp +++ b/sample/cpp/main.cpp @@ -126,11 +126,11 @@ MaaController* create_win32_controller() for (size_t i = 0; i < size; ++i) { auto window_handle = MaaToolkitDesktopWindowListAt(list_handle, i); - std::string class_name = MaaToolkitDesktopWindowGetClassName(window_handle); std::string window_name = MaaToolkitDesktopWindowGetWindowName(window_handle); + std::string class_name = MaaToolkitDesktopWindowGetWin32ClassName(window_handle); if (window_name.find("二重螺旋") != std::string::npos) { - hwnd = MaaToolkitDesktopWindowGetHandle(window_handle); + hwnd = reinterpret_cast(MaaToolkitDesktopWindowGetHandle(window_handle)); break; } } @@ -169,7 +169,7 @@ MaaController* create_macos_controller() std::string window_name = MaaToolkitDesktopWindowGetWindowName(window_handle); if (window_name.find("关于本机") != std::string::npos) { - window_id = reinterpret_cast(MaaToolkitDesktopWindowGetHandle(window_handle)); + window_id = MaaToolkitDesktopWindowGetHandle(window_handle); break; } } diff --git a/source/MaaPiCli/CLI/interactor.cpp b/source/MaaPiCli/CLI/interactor.cpp index 1ae7f88362..682ab4e5ab 100644 --- a/source/MaaPiCli/CLI/interactor.cpp +++ b/source/MaaPiCli/CLI/interactor.cpp @@ -776,9 +776,9 @@ bool Interactor::select_win32_hwnd(const MAA_PROJECT_INTERFACE_NS::InterfaceData Configuration::Win32Config rt_config; auto window_handle = MaaToolkitDesktopWindowListAt(list_handle, i); - rt_config.hwnd = MaaToolkitDesktopWindowGetHandle(window_handle); - rt_config.class_name = MAA_NS::to_u16(MaaToolkitDesktopWindowGetClassName(window_handle)); + rt_config.hwnd = reinterpret_cast(MaaToolkitDesktopWindowGetHandle(window_handle)); rt_config.window_name = MAA_NS::to_u16(MaaToolkitDesktopWindowGetWindowName(window_handle)); + rt_config.class_name = MAA_NS::to_u16(MaaToolkitDesktopWindowGetWin32ClassName(window_handle)); if (boost::regex_search(rt_config.class_name, *class_regex) && boost::regex_search(rt_config.window_name, *window_regex)) { matched_config.emplace_back(std::move(rt_config)); @@ -836,9 +836,9 @@ void Interactor::select_gamepad(const MAA_PROJECT_INTERFACE_NS::InterfaceData::C Configuration::GamepadConfig rt_config; auto window_handle = MaaToolkitDesktopWindowListAt(list_handle, i); - rt_config.hwnd = MaaToolkitDesktopWindowGetHandle(window_handle); - rt_config.class_name = MAA_NS::to_u16(MaaToolkitDesktopWindowGetClassName(window_handle)); + rt_config.hwnd = reinterpret_cast(MaaToolkitDesktopWindowGetHandle(window_handle)); rt_config.window_name = MAA_NS::to_u16(MaaToolkitDesktopWindowGetWindowName(window_handle)); + rt_config.class_name = MAA_NS::to_u16(MaaToolkitDesktopWindowGetWin32ClassName(window_handle)); if (boost::regex_search(rt_config.class_name, *class_regex) && boost::regex_search(rt_config.window_name, *window_regex)) { matched_config.emplace_back(std::move(rt_config)); @@ -927,9 +927,7 @@ void Interactor::select_macos(const MAA_PROJECT_INTERFACE_NS::InterfaceData::Con std::string window_name = MaaToolkitDesktopWindowGetWindowName(window_handle); if (boost::regex_search(MAA_NS::to_u16(window_name), *title_regex)) { - void* hwnd = MaaToolkitDesktopWindowGetHandle(window_handle); - // On macOS, hwnd is (void*)(uintptr_t)windowID, so extract uint32_t - uint32_t window_id = static_cast(reinterpret_cast(hwnd)); + uint32_t window_id = MaaToolkitDesktopWindowGetHandle(window_handle); matched_windows.emplace_back(window_id, window_name); } } @@ -1054,7 +1052,7 @@ void Interactor::select_wlroots_auto_detect() auto id = MaaToolkitDesktopWindowGetHandle(compositor); std::string name = MaaToolkitDesktopWindowGetWindowName(compositor); - std::string path = MaaToolkitDesktopWindowGetClassName(compositor); + std::string path = MaaToolkitDesktopWindowGetLinuxSocketPath(compositor); std::cout << MAA_NS::utf8_to_crt(std::format("\t{}. {}\n\t\t{}\n\t\t{}\n", i + 1, id, name, path)); } @@ -1065,7 +1063,7 @@ void Interactor::select_wlroots_auto_detect() auto compositor = MaaToolkitDesktopWindowListAt(list_handle, index); - wlr_config.wlr_socket_path = MaaToolkitDesktopWindowGetClassName(compositor); + wlr_config.wlr_socket_path = MaaToolkitDesktopWindowGetLinuxSocketPath(compositor); } void Interactor::select_wlroots_manual_input() diff --git a/source/MaaToolkit/API/MaaToolkitBufferTypes.hpp b/source/MaaToolkit/API/MaaToolkitBufferTypes.hpp index a9627e30c9..0a684e5f32 100644 --- a/source/MaaToolkit/API/MaaToolkitBufferTypes.hpp +++ b/source/MaaToolkit/API/MaaToolkitBufferTypes.hpp @@ -22,8 +22,15 @@ struct MaaToolkitDesktopWindow { public: virtual ~MaaToolkitDesktopWindow() = default; - - virtual void* handle() const = 0; - virtual const std::string& class_name() const = 0; + // 通用字段 + virtual uint64_t handle() const = 0; virtual const std::string& window_name() const = 0; + // Win32 字段 + virtual const std::string& win32_class_name() const = 0; + // MacOS 字段 + virtual int32_t macos_pid() const = 0; // macOS 进程ID + virtual const std::string& macos_bundle_id() const = 0; // macOS Bundle ID + virtual const std::string& macos_application_name() const = 0; // macOS 应用程序名称 + // Linux 字段 + virtual const std::string& linux_socket_path() const = 0; }; diff --git a/source/MaaToolkit/API/MaaToolkitDesktopWindow.cpp b/source/MaaToolkit/API/MaaToolkitDesktopWindow.cpp index 35c65e555e..00a1df9886 100644 --- a/source/MaaToolkit/API/MaaToolkitDesktopWindow.cpp +++ b/source/MaaToolkit/API/MaaToolkitDesktopWindow.cpp @@ -73,32 +73,76 @@ const MaaToolkitDesktopWindow* MaaToolkitDesktopWindowListAt(const MaaToolkitDes return &list->at(index); } -void* MaaToolkitDesktopWindowGetHandle(const MaaToolkitDesktopWindow* window) +// 通用字段 +uint64_t MaaToolkitDesktopWindowGetHandle(const MaaToolkitDesktopWindow* window) { if (!window) { LogError << "window is null"; - return nullptr; + return 0; } return window->handle(); } -const char* MaaToolkitDesktopWindowGetClassName(const MaaToolkitDesktopWindow* window) +const char* MaaToolkitDesktopWindowGetWindowName(const MaaToolkitDesktopWindow* window) { if (!window) { LogError << "window is null"; return ""; } - return window->class_name().c_str(); + return window->window_name().c_str(); } -const char* MaaToolkitDesktopWindowGetWindowName(const MaaToolkitDesktopWindow* window) +// Win32 专有字段 +const char* MaaToolkitDesktopWindowGetWin32ClassName(const MaaToolkitDesktopWindow* window) { if (!window) { LogError << "window is null"; return ""; } - return window->window_name().c_str(); + return window->win32_class_name().c_str(); +} + +// MacOS 专有字段 +int32_t MaaToolkitDesktopWindowGetMacOSPID(const MaaToolkitDesktopWindow* window) +{ + if (!window) { + LogError << "window is null"; + return 0; + } + + return window->macos_pid(); +} + +const char* MaaToolkitDesktopWindowGetMacOSBundleID(const MaaToolkitDesktopWindow* window) +{ + if (!window) { + LogError << "window is null"; + return ""; + } + + return window->macos_bundle_id().c_str(); +} + +const char* MaaToolkitDesktopWindowGetMacOSApplicationName(const MaaToolkitDesktopWindow* window) +{ + if (!window) { + LogError << "window is null"; + return ""; + } + + return window->macos_application_name().c_str(); +} + +// Linux 专有字段 +const char* MaaToolkitDesktopWindowGetLinuxSocketPath(const MaaToolkitDesktopWindow* window) +{ + if (!window) { + LogError << "window is null"; + return ""; + } + + return window->linux_socket_path().c_str(); } diff --git a/source/MaaToolkit/DesktopWindow/DesktopWindowBuffer.hpp b/source/MaaToolkit/DesktopWindow/DesktopWindowBuffer.hpp index a68045c6fc..73496f0be1 100644 --- a/source/MaaToolkit/DesktopWindow/DesktopWindowBuffer.hpp +++ b/source/MaaToolkit/DesktopWindow/DesktopWindowBuffer.hpp @@ -12,35 +12,123 @@ MAA_TOOLKIT_NS_BEGIN struct DesktopWindow { +#ifdef _WIN32 void* hwnd = nullptr; - std::wstring class_name; - std::wstring window_name; + std::string class_name; + std::string window_name; MEO_TOJSON(hwnd, class_name, window_name); +#endif // _WIN32 + +#if defined(__APPLE__) + uint32_t window_id = 0; // macOS 窗口ID + std::string title; // macOS 窗口标题 + int32_t pid = 0; // macOS 进程ID + std::string bundle_id; // macOS Bundle ID + std::string application_name; // macOS 应用程序名称 + + MEO_TOJSON(window_id, title, pid, bundle_id, application_name); +#endif // __APPLE__ + +#if defined(__linux__) && !defined(ANDROID) + uint32_t wayland_id = 0; + std::string wayland_socket_name; + std::string wayland_socket_path; + + MEO_TOJSON(wayland_id, wayland_socket_name, wayland_socket_path); +#endif // __linux__ && !ANDROID }; class DesktopWindowBuffer : public MaaToolkitDesktopWindow { public: DesktopWindowBuffer(const DesktopWindow& window) - : hwnd_(window.hwnd) - , class_name_(from_u16(window.class_name)) - , window_name_(from_u16(window.window_name)) + : window_(window) { } virtual ~DesktopWindowBuffer() override = default; - virtual void* handle() const override { return hwnd_; } + // 通用字段 + virtual uint64_t handle() const override + { +#ifdef _WIN32 + return reinterpret_cast(window_.hwnd); +#elif defined(__APPLE__) + return window_.window_id; +#elif defined(__linux__) && !defined(ANDROID) + return window_.wayland_id; +#endif + return 0; + } + + virtual const std::string& window_name() const override + { +#ifdef _WIN32 + return window_.window_name; +#elif defined(__APPLE__) + return window_.title; +#elif defined(__linux__) && !defined(ANDROID) + return window_.wayland_socket_name; +#endif + static const std::string kEmpty; + return kEmpty; + } + + // Win32 专有字段 + virtual const std::string& win32_class_name() const override + { +#ifdef _WIN32 + return window_.class_name; +#endif + LogError << "Only available on Win32"; + static const std::string kEmpty; + return kEmpty; + } + + // MacOS 专有字段 + virtual int32_t macos_pid() const override + { +#ifdef __APPLE__ + return window_.pid; +#endif + LogError << "Only available on MacOS"; + return 0; + } - virtual const std::string& class_name() const override { return class_name_; } + virtual const std::string& macos_bundle_id() const override + { +#ifdef __APPLE__ + return window_.bundle_id; +#endif + LogError << "Only available on MacOS"; + static const std::string kEmpty; + return kEmpty; + } - virtual const std::string& window_name() const override { return window_name_; } + virtual const std::string& macos_application_name() const override + { +#ifdef __APPLE__ + return window_.application_name; +#endif + LogError << "Only available on MacOS"; + static const std::string kEmpty; + return kEmpty; + } + + // Linux 专有字段 + virtual const std::string& linux_socket_path() const override + { +#if defined(__linux__) && !defined(ANDROID) + return window_.wayland_socket_path; +#endif + LogError << "Only available on Linux"; + static const std::string kEmpty; + return kEmpty; + } private: - void* hwnd_ = nullptr; - std::string class_name_; - std::string window_name_; + DesktopWindow window_; }; MAA_TOOLKIT_NS_END diff --git a/source/MaaToolkit/DesktopWindow/DesktopWindowLinuxFinder.cpp b/source/MaaToolkit/DesktopWindow/DesktopWindowLinuxFinder.cpp index cab4b1dca8..5198bbaf4e 100644 --- a/source/MaaToolkit/DesktopWindow/DesktopWindowLinuxFinder.cpp +++ b/source/MaaToolkit/DesktopWindow/DesktopWindowLinuxFinder.cpp @@ -47,9 +47,7 @@ std::vector DesktopWindowLinuxFinder::find_all() const continue; } result.emplace_back( - DesktopWindow { .hwnd = reinterpret_cast(static_cast(id)), - .class_name = MAA_NS::to_u16(entry.path().string()), - .window_name = MAA_NS::to_u16(filename.string()) }); + DesktopWindow { .wayland_id = id, .wayland_socket_name = filename.string(), .wayland_socket_path = entry.path().string() }); wl_display_disconnect(display); } diff --git a/source/MaaToolkit/DesktopWindow/DesktopWindowMacOSFinder.mm b/source/MaaToolkit/DesktopWindow/DesktopWindowMacOSFinder.mm index ed635df98e..f58208cbce 100644 --- a/source/MaaToolkit/DesktopWindow/DesktopWindowMacOSFinder.mm +++ b/source/MaaToolkit/DesktopWindow/DesktopWindowMacOSFinder.mm @@ -36,23 +36,33 @@ if (!window.isOnScreen) { continue; } - - std::wstring class_name; - if (window.owningApplication) { - NSString* bundleId = window.owningApplication.bundleIdentifier ? window.owningApplication.bundleIdentifier : @""; - class_name = MAA_NS::to_u16([bundleId UTF8String]); + // 跳过非顶级窗口 + if (window.windowLayer != 0) { + continue; } - NSString* title = window.title ? window.title : @""; - std::wstring window_name = MAA_NS::to_u16([title UTF8String]); + uint32_t window_id = window.windowID; + + NSString* nsTitle = window.title ? window.title : @""; + std::string title = [nsTitle UTF8String]; - // 将CGWindowID转换为void* - void* hwnd = (void*)(uintptr_t)window.windowID; + int32_t pid = window.owningApplication.processID; + + std::string bundle_id; + std::string application_name; + if (window.owningApplication) { + NSString* nsBundleId = window.owningApplication.bundleIdentifier ? window.owningApplication.bundleIdentifier : @""; + bundle_id = [nsBundleId UTF8String]; + NSString* nsApplicationName = window.owningApplication.applicationName ? window.owningApplication.applicationName : @""; + application_name = [nsApplicationName UTF8String]; + } captured_windows.emplace_back(DesktopWindow { - .hwnd = hwnd, - .class_name = class_name, - .window_name = window_name, + .window_id = window_id, + .title = title, + .pid = pid, + .bundle_id = bundle_id, + .application_name = application_name, }); } diff --git a/source/MaaToolkit/DesktopWindow/DesktopWindowWin32Finder.cpp b/source/MaaToolkit/DesktopWindow/DesktopWindowWin32Finder.cpp index 188377c822..ef9b3ccde5 100644 --- a/source/MaaToolkit/DesktopWindow/DesktopWindowWin32Finder.cpp +++ b/source/MaaToolkit/DesktopWindow/DesktopWindowWin32Finder.cpp @@ -25,12 +25,11 @@ std::vector DesktopWindowWin32Finder::find_all() const std::wstring window_name(256, '\0'); GetWindowTextW(hwnd, window_name.data(), static_cast(window_name.size())); - windows.emplace_back( - DesktopWindow { - .hwnd = hwnd, - .class_name = class_name, - .window_name = window_name, - }); + windows.emplace_back(DesktopWindow { + .hwnd = hwnd, + .class_name = from_u16(class_name), + .window_name = from_u16(window_name), + }); } #ifdef MAA_DEBUG diff --git a/source/binding/NodeJS/src/apis/controller.cpp b/source/binding/NodeJS/src/apis/controller.cpp index 10738a1016..ee4bc56bd6 100644 --- a/source/binding/NodeJS/src/apis/controller.cpp +++ b/source/binding/NodeJS/src/apis/controller.cpp @@ -413,14 +413,13 @@ maajs::PromiseType AdbControllerImpl::find(maajs::EnvType env, maajs::OptionalPa result.reserve(size); for (size_t i = 0; i < size; i++) { auto dev = MaaToolkitAdbDeviceListAt(lst, i); - result.push_back( - std::make_tuple( - std::string(MaaToolkitAdbDeviceGetName(dev)), - std::string(MaaToolkitAdbDeviceGetAdbPath(dev)), - std::string(MaaToolkitAdbDeviceGetAddress(dev)), - MaaToolkitAdbDeviceGetScreencapMethods(dev), - MaaToolkitAdbDeviceGetInputMethods(dev), - std::string(MaaToolkitAdbDeviceGetConfig(dev)))); + result.push_back(std::make_tuple( + std::string(MaaToolkitAdbDeviceGetName(dev)), + std::string(MaaToolkitAdbDeviceGetAdbPath(dev)), + std::string(MaaToolkitAdbDeviceGetAddress(dev)), + MaaToolkitAdbDeviceGetScreencapMethods(dev), + MaaToolkitAdbDeviceGetInputMethods(dev), + std::string(MaaToolkitAdbDeviceGetConfig(dev)))); } MaaToolkitAdbDeviceListDestroy(lst); @@ -481,11 +480,10 @@ maajs::PromiseType Win32ControllerImpl::find(maajs::EnvType env) result.reserve(size); for (size_t i = 0; i < size; i++) { auto dev = MaaToolkitDesktopWindowListAt(lst, i); - result.push_back( - std::make_tuple( - reinterpret_cast(MaaToolkitDesktopWindowGetHandle(dev)), - std::string(MaaToolkitDesktopWindowGetClassName(dev)), - std::string(MaaToolkitDesktopWindowGetWindowName(dev)))); + result.push_back(std::make_tuple( + MaaToolkitDesktopWindowGetHandle(dev), + std::string(MaaToolkitDesktopWindowGetWindowName(dev)), + std::string(MaaToolkitDesktopWindowGetWin32ClassName(dev)))); } MaaToolkitDesktopWindowListDestroy(lst); @@ -538,11 +536,12 @@ maajs::PromiseType MacOSControllerImpl::find(maajs::EnvType env) result.reserve(size); for (size_t i = 0; i < size; i++) { auto dev = MaaToolkitDesktopWindowListAt(lst, i); - result.push_back( - std::make_tuple( - reinterpret_cast(MaaToolkitDesktopWindowGetHandle(dev)), - std::string(MaaToolkitDesktopWindowGetClassName(dev)), - std::string(MaaToolkitDesktopWindowGetWindowName(dev)))); + result.push_back(std::make_tuple( + MaaToolkitDesktopWindowGetHandle(dev), + std::string(MaaToolkitDesktopWindowGetWindowName(dev)), + MaaToolkitDesktopWindowGetMacOSPID(dev), + std::string(MaaToolkitDesktopWindowGetMacOSBundleID(dev)), + std::string(MaaToolkitDesktopWindowGetMacOSApplicationName(dev)))); } MaaToolkitDesktopWindowListDestroy(lst); @@ -671,11 +670,10 @@ maajs::PromiseType WlRootsControllerImpl::find(maajs::EnvType env) result.reserve(size); for (size_t i = 0; i < size; i++) { auto dev = MaaToolkitDesktopWindowListAt(lst, i); - result.push_back( - std::make_tuple( - reinterpret_cast(MaaToolkitDesktopWindowGetHandle(dev)), - std::string(MaaToolkitDesktopWindowGetClassName(dev)), - std::string(MaaToolkitDesktopWindowGetWindowName(dev)))); + result.push_back(std::make_tuple( + reinterpret_cast(MaaToolkitDesktopWindowGetHandle(dev)), + std::string(MaaToolkitDesktopWindowGetWindowName(dev)), + std::string(MaaToolkitDesktopWindowGetLinuxSocketPath(dev)))); } MaaToolkitDesktopWindowListDestroy(lst); diff --git a/source/binding/NodeJS/src/apis/controller.h b/source/binding/NodeJS/src/apis/controller.h index 358ae382bd..3b7903515e 100644 --- a/source/binding/NodeJS/src/apis/controller.h +++ b/source/binding/NodeJS/src/apis/controller.h @@ -119,7 +119,7 @@ struct Win32ControllerImpl : public ControllerImpl static void init_proto(maajs::ObjectType proto, maajs::FunctionType ctor); }; -using MacOSDevice = std::tuple; +using MacOSDevice = std::tuple; using MacOSControllerCtorParam = std::tuple; struct MacOSControllerImpl : public ControllerImpl diff --git a/source/binding/Python/maa/toolkit.py b/source/binding/Python/maa/toolkit.py index f7b64fae33..d052b55263 100644 --- a/source/binding/Python/maa/toolkit.py +++ b/source/binding/Python/maa/toolkit.py @@ -40,14 +40,22 @@ class DesktopWindow: Obtained via Toolkit.find_desktop_windows. Attributes: - hwnd: 窗口句柄 / Window handle - class_name: 窗口类名 / Window class name - window_name: 窗口标题 / Window title + handle: 窗口句柄(uint64)/ Window handle (uint64) + window_name: 窗口名称 / Window name + win32_class_name: 窗口类名(Win32 专有)/ Window class name (Win32 only) + macos_pid: 进程ID(macOS 专有)/ Process ID (macOS only) + macos_bundle_id: Bundle ID(macOS 专有)/ Bundle ID (macOS only) + macos_application_name: 应用程序名称(macOS 专有)/ Application name (macOS only) + linux_socket_path: Wayland socket 路径(Linux 专有)/ Wayland socket path (Linux only) """ - hwnd: ctypes.c_void_p - class_name: str + handle: int window_name: str + win32_class_name: str + macos_pid: int + macos_bundle_id: str + macos_application_name: str + linux_socket_path: str class Toolkit: @@ -165,19 +173,49 @@ def find_desktop_windows() -> List[DesktopWindow]: window_handle = Library.toolkit().MaaToolkitDesktopWindowListAt( list_handle, i ) - hwnd = Library.toolkit().MaaToolkitDesktopWindowGetHandle(window_handle) - class_name = ( - Library.toolkit() - .MaaToolkitDesktopWindowGetClassName(window_handle) - .decode() + handle = int( + Library.toolkit().MaaToolkitDesktopWindowGetHandle(window_handle) ) window_name = ( Library.toolkit() .MaaToolkitDesktopWindowGetWindowName(window_handle) .decode() ) + win32_class_name = ( + Library.toolkit() + .MaaToolkitDesktopWindowGetWin32ClassName(window_handle) + .decode() + ) + macos_pid = int( + Library.toolkit().MaaToolkitDesktopWindowGetMacOSPID(window_handle) + ) + macos_bundle_id = ( + Library.toolkit() + .MaaToolkitDesktopWindowGetMacOSBundleID(window_handle) + .decode() + ) + macos_application_name = ( + Library.toolkit() + .MaaToolkitDesktopWindowGetMacOSApplicationName(window_handle) + .decode() + ) + linux_socket_path = ( + Library.toolkit() + .MaaToolkitDesktopWindowGetLinuxSocketPath(window_handle) + .decode() + ) - windows.append(DesktopWindow(hwnd, class_name, window_name)) + windows.append( + DesktopWindow( + handle, + window_name, + win32_class_name, + macos_pid, + macos_bundle_id, + macos_application_name, + linux_socket_path, + ) + ) Library.toolkit().MaaToolkitDesktopWindowListDestroy(list_handle) return windows @@ -341,18 +379,38 @@ def _set_api_properties(): MaaSize, ] - Library.toolkit().MaaToolkitDesktopWindowGetHandle.restype = ctypes.c_void_p + Library.toolkit().MaaToolkitDesktopWindowGetHandle.restype = ctypes.c_uint64 Library.toolkit().MaaToolkitDesktopWindowGetHandle.argtypes = [ MaaToolkitDesktopWindowHandle ] - Library.toolkit().MaaToolkitDesktopWindowGetClassName.restype = ctypes.c_char_p - Library.toolkit().MaaToolkitDesktopWindowGetClassName.argtypes = [ + Library.toolkit().MaaToolkitDesktopWindowGetWindowName.restype = ctypes.c_char_p + Library.toolkit().MaaToolkitDesktopWindowGetWindowName.argtypes = [ MaaToolkitDesktopWindowHandle ] - Library.toolkit().MaaToolkitDesktopWindowGetWindowName.restype = ctypes.c_char_p - Library.toolkit().MaaToolkitDesktopWindowGetWindowName.argtypes = [ + Library.toolkit().MaaToolkitDesktopWindowGetWin32ClassName.restype = ctypes.c_char_p + Library.toolkit().MaaToolkitDesktopWindowGetWin32ClassName.argtypes = [ + MaaToolkitDesktopWindowHandle + ] + + Library.toolkit().MaaToolkitDesktopWindowGetMacOSPID.restype = ctypes.c_int32 + Library.toolkit().MaaToolkitDesktopWindowGetMacOSPID.argtypes = [ + MaaToolkitDesktopWindowHandle + ] + + Library.toolkit().MaaToolkitDesktopWindowGetMacOSBundleID.restype = ctypes.c_char_p + Library.toolkit().MaaToolkitDesktopWindowGetMacOSBundleID.argtypes = [ + MaaToolkitDesktopWindowHandle + ] + + Library.toolkit().MaaToolkitDesktopWindowGetMacOSApplicationName.restype = ctypes.c_char_p + Library.toolkit().MaaToolkitDesktopWindowGetMacOSApplicationName.argtypes = [ + MaaToolkitDesktopWindowHandle + ] + + Library.toolkit().MaaToolkitDesktopWindowGetLinuxSocketPath.restype = ctypes.c_char_p + Library.toolkit().MaaToolkitDesktopWindowGetLinuxSocketPath.argtypes = [ MaaToolkitDesktopWindowHandle ] diff --git a/test/macos_test/main.cpp b/test/macos_test/main.cpp index e03b335ee7..95e8af0913 100644 --- a/test/macos_test/main.cpp +++ b/test/macos_test/main.cpp @@ -72,7 +72,7 @@ void runMaaTest(const std::string& windowTitle) for (size_t i = 0; i < size; ++i) { auto w = MaaToolkitDesktopWindowListAt(winlist, i); std::string name = MaaToolkitDesktopWindowGetWindowName(w); - uint32_t currentWindowID = reinterpret_cast(MaaToolkitDesktopWindowGetHandle(w)); + uint32_t currentWindowID = MaaToolkitDesktopWindowGetHandle(w); if (name.find(windowTitle) != std::string::npos) { windowID = currentWindowID; diff --git a/tools/ImageCropper/main.py b/tools/ImageCropper/main.py index 82554f48d1..f05bda7696 100644 --- a/tools/ImageCropper/main.py +++ b/tools/ImageCropper/main.py @@ -98,26 +98,28 @@ def parse_args() -> Controller: if len(window_list): max_len = 40 for i, w in enumerate(window_list): - c = w.class_name[:max_len - 3] + '...' if len(w.class_name) > max_len else w.class_name - print(f"{w.hwnd:>19} {c:>{max_len}} | {i:>3} | {w.window_name}") + c = w.win32_class_name[:max_len - 3] + '...' if len(w.win32_class_name) > max_len else w.win32_class_name + print(f"{w.handle:>19} {c:>{max_len}} | {i:>3} | {w.window_name}") print(str.format("{:->19} {:->{}} | {:->3} | {}", " hWnd", " class name", max_len, "num", "window name")) i = int(input("Please select the window (ENTER to pass): ")) if 0 <= i < len(window_list): device_serial = window_list[i].window_name - return Win32Controller(hWnd=window_list[i].hwnd, + return Win32Controller(hWnd=window_list[i].handle, screencap_method=win32_screencap_method) elif t == 3: window_list = Toolkit.find_desktop_windows() if len(window_list): max_len = 40 for i, w in enumerate(window_list): - c = w.class_name[:max_len - 3] + '...' if len(w.class_name) > max_len else w.class_name - print(f"{w.hwnd:>19} {c:>{max_len}} | {i:>3} | {w.window_name}") - print(str.format("{:->19} {:->{}} | {:->3} | {}", " hwnd", " class name", max_len, "num", "window name")) + # macOS 使用 macos_application_name 作为主要显示名称 + app_name = w.macos_application_name[:max_len - 3] + '...' if len(w.macos_application_name) > max_len else w.macos_application_name + title = w.window_name[:20] + '...' if len(w.window_name) > 20 else w.window_name + print(f"{w.handle:>10} {app_name:>{max_len}} | {i:>3} | {title}") + print(str.format("{:->10} {:->{}} | {:->3} | {}", " window_id", " application", max_len, "num", "title")) i = int(input("Please select the window (ENTER to pass): ")) if 0 <= i < len(window_list): device_serial = window_list[i].window_name - return MacOSController(window_id=window_list[i].hwnd, + return MacOSController(window_id=window_list[i].handle, screencap_method=macos_screencap_method) return None