Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions source/binding/Python/maa/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"RecordController",
"PlayCoverController",
"Win32Controller",
"KWinController",
"GamepadController",
"WlRootsController",
"AndroidNativeController",
Expand Down Expand Up @@ -1059,6 +1060,62 @@ def _set_wlroots_api_properties(self):
]


class KWinController(Controller):
"""KWin 控制器 (Linux Wayland) / KWin controller (Linux Wayland)

通过 PipeWire / xdg-desktop-portal 截图,通过 /dev/uinput 模拟输入。
Screencap via PipeWire / xdg-desktop-portal, input via /dev/uinput.
"""

def __init__(
self,
device_node: str,
screen_width: int,
screen_height: int,
use_win32_vk_code: bool = False,
):
"""创建 KWin 控制器 / Create KWin controller

Args:
device_node: uinput 设备节点路径 (如 "/dev/uinput") / uinput device node path
screen_width: 屏幕宽度(像素) / Screen width in pixels
screen_height: 屏幕高度(像素) / Screen height in pixels
use_win32_vk_code: 为 True 时按键被视为 Win32 VK 键码并转换为 Linux evdev 码;
默认 False,按原始 evdev 码处理
/ When True, key codes are interpreted as Win32 Virtual-Key codes and translated
to Linux evdev codes internally; default False passes raw evdev codes through

Raises:
RuntimeError: 如果创建失败
"""
super().__init__()
self._set_kwin_api_properties()

if not hasattr(Library.framework(), "MaaKWinControllerCreate"):
raise RuntimeError(
"MaaKWinControllerCreate API is not available in the current build."
)

self._handle = Library.framework().MaaKWinControllerCreate(
os.fsencode(os.fspath(device_node)),
screen_width,
screen_height,
MaaBool(use_win32_vk_code),
)

if not self._handle:
raise RuntimeError("Failed to create KWin controller.")

def _set_kwin_api_properties(self):
Library.framework().MaaKWinControllerCreate.restype = MaaControllerHandle
Library.framework().MaaKWinControllerCreate.argtypes = [
ctypes.c_char_p,
ctypes.c_int32,
ctypes.c_int32,
MaaBool,
]


class DbgController(Controller):
"""调试控制器,轮播图片截图,基本输入操作直接返回成功

Expand Down
39 changes: 38 additions & 1 deletion test/python/binding_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

from maa.library import Library
from maa.resource import Resource, ResourceEventSink
from maa.controller import DbgController, CustomController, Win32Controller, ControllerEventSink
from maa.controller import DbgController, CustomController, Win32Controller, KWinController, ControllerEventSink
from maa.tasker import Tasker, TaskerEventSink
from maa.toolkit import Toolkit
from maa.custom_action import CustomAction
Expand Down Expand Up @@ -835,6 +835,40 @@ def test_win32_relative_move():
print(" PASS: win32 relative_move")


def test_kwin_controller_create():
print("\n=== test_kwin_controller_create ===")

# KWinController 仅在 Linux 上可用,且需要 MaaKWinControllerCreate API 存在
try:
controller = KWinController(
device_node="/dev/uinput",
screen_width=1920,
screen_height=1080,
use_win32_vk_code=False,
)
print(f" KWinController created: {controller}")

# 检查连接前状态
print(f" connected: {controller.connected}")
print(f" uuid: {controller.uuid}")
print(f" info: {controller.info}")

# 验证 info 中的类型
info = controller.info
assert isinstance(info, dict), "info should be a dict"
assert "type" in info, "info should contain 'type'"
assert info["type"] == "KWin", "KWin controller type should be 'KWin'"

# 测试 post_inactive (空操作,应总是成功)
controller.post_inactive().wait()

print(" PASS: KWinController creation")

except RuntimeError as e:
# KWin 控制器创建可能因 API 缺失或缺少 /dev/uinput 权限等环境问题失败
print(f" SKIP: KWinController not available in this environment ({e})")


# ============================================================================
# 主入口
# ============================================================================
Expand Down Expand Up @@ -868,6 +902,9 @@ def test_win32_relative_move():
# 测试 Win32 relative_move 正路径
test_win32_relative_move()

# 测试 KWinController 创建
test_kwin_controller_create()

print("\n" + "=" * 50)
print("All binding tests passed!")
print("=" * 50)
Loading