Initial UU Mac Ctrl script

This commit is contained in:
youbin
2026-07-27 02:27:38 +08:00
commit 560e23a203
2 changed files with 202 additions and 0 deletions

81
README.md Normal file
View File

@@ -0,0 +1,81 @@
# UU Mac Ctrl
AutoHotkey v2 script for NetEase UU Remote. It maps the Windows `Ctrl` key to the Mac `Command` key only while the UU Remote window is active.
适用于在 Windows 上通过网易 UU 远程连接 Mac 时使用。脚本只在 UU 远程窗口生效,不会全局修改 Windows 快捷键。
## 功能
- 仅针对网易 UU 远程窗口生效
- 将左/右 `Ctrl` 映射为 Mac 的 `Command`
- 支持 `Ctrl+C`、`Ctrl+V`、`Ctrl+A`、`Ctrl+Z` 等常用 Mac 快捷键习惯
- `Shift+F12` 临时启用或停用映射
- `Shift+F11` 复制当前活动窗口信息,便于排查窗口匹配问题
## 依赖
- Windows
- AutoHotkey v2
- 网易 UU 远程
AutoHotkey v2 默认安装路径通常是:
```text
C:\Program Files\AutoHotkey\v2\AutoHotkey64.exe
```
## 使用方法
1. 安装 AutoHotkey v2。
2. 下载本仓库中的 `uu-mac-ctrl.ahk`。
3. 双击运行 `uu-mac-ctrl.ahk`。
4. 打开网易 UU 远程并连接 Mac。
5. 在远程 Mac 窗口中使用 Windows 的 `Ctrl` 快捷键,例如 `Ctrl+C`、`Ctrl+V`。
## 开机自启
可以在 Windows 启动目录中创建快捷方式,让脚本登录后自动运行。
启动目录路径:
```text
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
```
快捷方式目标示例:
```text
"C:\Program Files\AutoHotkey\v2\AutoHotkey64.exe" "C:\path\to\uu-mac-ctrl.ahk"
```
## 窗口匹配
脚本默认匹配网易 UU 远程的常见进程和窗口标题,包括:
- `GameViewer.exe`
- `GameViewerClient.exe`
- `GameViewer64.exe`
- `UURemote.exe`
- 包含 `UU远程`、`网易UU` 或 `GameViewer` 的窗口标题
如果 UU 远程升级后不生效,可以先激活 UU 远程窗口,然后按 `Shift+F11`。脚本会把当前窗口信息复制到剪贴板,再根据其中的 `Process` 或 `Class` 修改 `IsUURemoteActive()` 中的匹配规则。
## 可选模式
脚本默认使用完整按键映射:
```ahk
global MapWholeCtrlKey := true
```
如果完整映射和某些 Windows 行为冲突,可以改为:
```ahk
global MapWholeCtrlKey := false
```
这样会只转发常见快捷键,而不是把整个 `Ctrl` 键映射为 `Win` 键。
## 退出
在系统托盘中找到 AutoHotkey 图标,右键选择 `Exit` 即可退出脚本。

121
uu-mac-ctrl.ahk Normal file
View File

@@ -0,0 +1,121 @@
#Requires AutoHotkey v2.0
#SingleInstance Force
; Ctrl -> Mac Command for NetEase UU Remote only.
; Default target found on this machine:
; C:\Program Files\Netease\GameViewer\GameViewer.exe
SendMode "Input"
SetTitleMatchMode 2
global MapEnabled := true
global MapWholeCtrlKey := true
A_TrayMenu.Delete()
A_TrayMenu.Add("Toggle mapping (Shift+F12)", ToggleMapping)
A_TrayMenu.Add("Copy active window info (Shift+F11)", CopyActiveWindowInfo)
A_TrayMenu.Add()
A_TrayMenu.Add("Exit", (*) => ExitApp())
ShowHint("UU Mac Ctrl mapping is on")
#HotIf IsUURemoteActive() && MapWholeCtrlKey
LCtrl::LWin
RCtrl::RWin
#HotIf
; Safer fallback mode if full Ctrl remapping ever conflicts with the Windows shell.
; Change MapWholeCtrlKey above to false to use only these common Mac shortcuts.
#HotIf IsUURemoteActive() && !MapWholeCtrlKey
^a::MacCmd("a")
^c::MacCmd("c")
^f::MacCmd("f")
^n::MacCmd("n")
^o::MacCmd("o")
^p::MacCmd("p")
^q::MacCmd("q")
^s::MacCmd("s")
^t::MacCmd("t")
^v::MacCmd("v")
^w::MacCmd("w")
^x::MacCmd("x")
^z::MacCmd("z")
^+z::MacCmdShift("z")
^Tab::MacCmd("{Tab}")
^+Tab::MacCmdShift("{Tab}")
^Space::MacCmd("{Space}")
#HotIf
+F12::ToggleMapping()
+F11::CopyActiveWindowInfo()
IsUURemoteActive() {
global MapEnabled
if !MapEnabled
return false
hwnd := WinExist("A")
if !hwnd
return false
try {
exe := WinGetProcessName("ahk_id " hwnd)
title := WinGetTitle("ahk_id " hwnd)
className := WinGetClass("ahk_id " hwnd)
} catch {
return false
}
if RegExMatch(exe, "i)^(GameViewer|GameViewerClient|GameViewer64|UURemote|NeteaseUU.*)\.exe$")
return true
return InStr(title, "UU远程")
|| InStr(title, "网易UU")
|| InStr(title, "GameViewer")
|| InStr(className, "GameViewer")
}
MacCmd(key) {
Send("{LWin down}" . key . "{LWin up}")
}
MacCmdShift(key) {
Send("{LWin down}{Shift down}" . key . "{Shift up}{LWin up}")
}
ToggleMapping(*) {
global MapEnabled
MapEnabled := !MapEnabled
ShowHint("UU Mac Ctrl mapping is " . (MapEnabled ? "on" : "off"))
}
CopyActiveWindowInfo(*) {
hwnd := WinExist("A")
if !hwnd {
ShowHint("No active window found")
return
}
try {
title := WinGetTitle("ahk_id " hwnd)
exe := WinGetProcessName("ahk_id " hwnd)
className := WinGetClass("ahk_id " hwnd)
} catch as err {
ShowHint("Could not read active window: " . err.Message)
return
}
info := "Title: " . title . "`n"
. "Process: " . exe . "`n"
. "Class: " . className . "`n"
. "AHK target: ahk_exe " . exe . " ahk_class " . className
A_Clipboard := info
ShowHint("Active window info copied to clipboard")
}
ShowHint(text) {
ToolTip(text)
SetTimer(() => ToolTip(), -1800)
}