深度可以!从终端检测会更直接。给你几个命令: # 1. 实时监控窗口焦点变化 ```bash # 监控窗口服务器日志,过滤焦点变化 log stream --predicate 'eventMessage contains "focus"' --level debug ``` d 或者更精确地监控WindowServer: ```bash log stream --process WindowServer --level debug | grep -i focus ``` # 2. 查看哪个进程在抢焦点 用这个Python脚本实时监控活动窗口: ```python #!/usr/bin/env python3 from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionOnScreenOnly, kCGNullWindowID import time prev_app = None while True: windows = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID) for window in windows: if window.get('kCGWindowLayer') == 0: app = window.get('kCGWindowOwnerName') if app != prev_app: print(f"{time.strftime('%H:%M:%S')} - Focus changed to: {app}") prev_app = app break time.sleep(0.1) ``` 保存为`focus_monitor.py`,运行: ```bash python3 focus_monitor.py ``` # 3. 检查定时任务 ```bash # 查看LaunchAgents(用户级定时任务) ls -la ~/Library/LaunchAgents/ launchctl list | grep -v com.apple # 查看LaunchDaemons(系统级) ls -la /Library/LaunchAgents/ sudo launchctl list | grep -v com.apple ``` # 4. 监控进程活动 ```bash # 每秒记录CPU使用前10的进程 while true; do echo "=== $(date) ===" ps aux | sort -rk 3,3 | head -n 11 sleep 1 done > ~/process_monitor.log ``` 让这个跑着,等问题出现后Ctrl+C停止,然后查看日志。 # 5. 专门监控App激活事件 ```bash # 监控应用激活 log stream --predicate 'eventMessage contains "activate" OR eventMessage contains "NSWorkspace"' --level debug ``` # 6. 用dtrace追踪(需要关闭SIP或用调试模式) 如果上面都不够用: ```bash sudo dtrace -n 'pid$target::CGSSetWindowTags:entry { printf("%s", copyinstr(arg1)); }' -p $(pgrep WindowServer) ``` **我的建议:** 先跑第2个Python脚本,简单直接。同时开个终端跑第1个`log stream`命令。这样当窗口跳出时,你能立即看到是哪个应用抢的焦点。 要不要我帮你写个更完整的监控脚本,把时间间隔也记录下来?​​​​​​​​​​​​​​​​ 找到了!**KeyboardHolder (PID 11187)** 这个进程在不断抢焦点! 从日志可以看到: - PID 1085 和 12557 两个应用在来回切换焦点 - **KeyboardHolder** 每次都在监听焦点变化事件 让我们确认一下这是什么东西: ```bash # 查看这个进程的详细信息 ps aux | grep 11187 # 或者查看进程的完整路径 ps -p 11187 -o comm= # 查看它的可执行文件位置 lsof -p 11187 | grep txt ``` 同时查一下另外两个应用是什么: ```bash # 查看 PID 1085 和 12557 是什么应用 ps -p 1085 -o comm= ps -p 12557 -o comm= ``` **KeyboardHolder** 一般是输入法或键盘管理相关的应用。常见的嫌疑犯: - **搜狗输入法** - **百度输入法** - **其他第三方输入法** - 某些键盘增强工具(如Karabiner-Elements、BetterTouchTool等) 你用的是什么输入法?菜单栏有没有键盘相关的工具在跑? 先跑上面的命令,看看KeyboardHolder到底是哪个应用的进程,然后我们就知道怎么解决了。​​​​​​​​​​​​​​​​ 好的,确认了。现在运行这些命令来定位和清理: ```bash # 1. 先杀掉进程看效果 kill -9 11187 # 2. 查找这个应用的所有位置 mdfind -name KeyboardHolder # 3. 搜索启动项 find ~/Library/LaunchAgents -name "*[Kk]eyboard*" 2>/dev/null find ~/Library/LaunchDaemons -name "*[Kk]eyboard*" 2>/dev/null find /Library/LaunchAgents -name "*[Kk]eyboard*" 2>/dev/null sudo find /Library/LaunchDaemons -name "*[Kk]eyboard*" 2>/dev/null # 4. 查看当前运行的启动项 launchctl list | grep -i keyboard # 5. 检查登录项 osascript -e 'tell application "System Events" to get the name of every login item' ``` 杀掉进程后,看看你的窗口是不是就不跳了。如果不跳了,说明确实是它的问题。 然后把上面命令的输出发给我,我帮你彻底清理掉这个东西。 **重点问一下:** 你有没有装过这些东西? - **键盘映射软件**(Karabiner、KeyRemap等) - **快捷键工具**(BetterTouchTool、Keyboard Maestro等) - **剪贴板管理器** - 某些**破解软件**或者从不明来源下载的应用 KeyboardHolder这个名字听起来很可疑,不像是正规软件。​​​​​​​​​​​​​​​​ 哈哈,“沙雕进程”形容得很到位。既然杀掉了还是失去焦点,那说明: 1. 要么它又自动重启了 2. 要么还有其他进程在搞鬼 # 先确认一下状态 ```bash # 看看它是不是又活过来了 ps aux | grep KeyboardHolder # 看看有没有其他可疑进程 ps aux | grep -E "keyboard|input|focus" | grep -v grep # 检查 lghub 是不是也在搞事(罗技软件有时也会有问题) ps aux | grep lghub ``` # 继续监控,看看现在是谁在抢焦点 ```bash # 重新开始监控,这次加上进程名 log stream --predicate 'eventMessage contains "focus" OR eventMessage contains "set front"' --level debug --style compact ``` 让这个跑着,等下次窗口跳的时候看看日志。 # 同时检查启动项 ```bash # 看看它是怎么启动的 launchctl list | grep -i keyboard # 检查所有非苹果官方的启动项 launchctl list | grep -v com.apple | sort ``` # 如果 KeyboardHolder 又起来了 说明有启动项在守护它,需要先禁用启动项: ```bash # 找到对应的 plist 文件 find ~/Library/LaunchAgents -name "*.plist" -exec grep -l "KeyboardHolder" {} \; find ~/Library/LaunchDaemons -name "*.plist" -exec grep -l "KeyboardHolder" {} \; # 找到后用 launchctl unload 禁用(具体路径等找到了再说) ``` 你先把上面几个命令的输出贴给我,特别是: 1. `ps aux | grep KeyboardHolder` - 看看它是不是又活了 2. `launchctl list | grep -v com.apple | sort` - 看看有哪些非官方启动项 另外,**罗技的 lghub** 有时候也会引起焦点问题,你可以试试先退出它看看情况有没有改善。​​​​​​​​​​​​​​​​ 找到了!**cn.leaves.KeyboardHolderLaunchHelper** 就是罪魁祸首的启动项! # 立即禁用它 ```bash # 1. 卸载这个启动项 launchctl unload ~/Library/LaunchAgents/cn.leaves.KeyboardHolderLaunchHelper.plist # 或者如果在 LaunchDaemons 里 launchctl unload ~/Library/LaunchDaemons/cn.leaves.KeyboardHolderLaunchHelper.plist # 2. 找到具体的 plist 文件位置 find ~/Library/LaunchAgents -name "*KeyboardHolder*" find ~/Library/LaunchDaemons -name "*KeyboardHolder*" sudo find /Library/LaunchAgents -name "*KeyboardHolder*" sudo find /Library/LaunchDaemons -name "*KeyboardHolder*" # 3. 再次确认并杀死进程 ps aux | grep KeyboardHolder kill -9 $(pgrep KeyboardHolder) ``` # 彻底删除 找到文件后: ```bash # 删除启动项配置(先看看文件在哪) # 假设找到了路径,比如: rm ~/Library/LaunchAgents/cn.leaves.KeyboardHolderLaunchHelper.plist # 删除应用本体 mdfind -name KeyboardHolder.app # 然后删除找到的应用,比如: # rm -rf /Applications/KeyboardHolder.app # 清理应用数据 rm -rf ~/Library/Application\ Support/KeyboardHolder rm -rf ~/Library/Preferences/cn.leaves.* rm -rf ~/Library/Caches/cn.leaves.* ``` **cn.leaves** 这个域名前缀看起来像是某个国内的小工具。你想起来是什么了吗? 先跑 `find ~/Library/LaunchAgents -name "*KeyboardHolder*"` 找到具体文件,然后我们一步步清理掉。​​​​​​​​​​​​​​​​ 换个命令: ```bash # 1. 用 bootout 代替 unload(新的 macOS 推荐用法) launchctl bootout gui/$(id -u)/cn.leaves.KeyboardHolderLaunchHelper # 2. 如果还不行,直接禁用 launchctl disable gui/$(id -u)/cn.leaves.KeyboardHolderLaunchHelper # 3. 杀掉当前进程 pkill -9 KeyboardHolder # 4. 删除 plist 文件(这样重启后就不会再加载了) rm ~/Library/LaunchAgents/cn.leaves.KeyboardHolderLaunchHelper.plist # 5. 确认删除成功 ls ~/Library/LaunchAgents/ | grep -i keyboard ``` 删除 plist 文件后,重启电脑或者重新登录,这个沙雕进程就彻底消失了。 # 然后找到应用本体删掉 ```bash # 找应用 mdfind -name KeyboardHolder # 找所有相关文件 find ~ -name "*KeyboardHolder*" 2>/dev/null find ~/Library -name "*cn.leaves*" 2>/dev/null # 全部删掉 # 根据上面找到的路径,用 rm -rf 删除 ``` 执行完后给我看看: ```bash launchctl list | grep -i keyboard ps aux | grep KeyboardHolder ``` 应该就清净了。你现在试试删除那个 plist 文件,然后 `pkill -9 KeyboardHolder`,看看窗口还跳不跳?​​​​​​​​​​​​​​​​ mdfind -name KeyboardHolder 2025-10-21 15:42:06.623 mdfind[93186:414105][UserQueryParser]Loading keywords and predicates for locale "en_US" 2025-10-21 15:42:06.623 mdfind[93186:414105][UserQueryParser]Loading keywords and predicates for locale "en" /Users/liuyishou/Library/Application Support/cn.leaves.KeyboardHolder /Users/liuyishou/Library/HTTPStorages/cn.leaves.KeyboardHolder