深度可以!从终端检测会更直接。给你几个命令:
# 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