拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ubuntu 安装 Oneko:X11 追鼠标猫原理与避坑

Ubuntu 安装 Oneko:X11 追鼠标猫原理与避坑

在 Ubuntu 上装一只追着鼠标指针跑的小猫 Oneko,这件事我第一次听说时的反应是"这有什么好折腾的",直到某天下午我在机房等一个三小时的编译,盯着屏幕发呆,才认真把它装上了。Oneko 是一个典型的 X11 桌面宠物:一只 32×32 的位图猫,平时懒洋洋待着,鼠标一动它就扭头追过来,你长时间不碰鼠标,它会趴下睡觉,偶尔挠挠地板、洗洗脸。它不联网、不占资源、不需要任何账号,一条apt命令或者十分钟的源码编译就能跑起来。

这篇东西写给三类人:第一类是刚装完 Ubuntu、想给桌面添点人味的新手,照着第 3 章的命令抄就行;第二类是正在学 X11 编程的人,Oneko 是一个非常好的"最小可读样本",全局指针查询、覆盖式窗口、位图遮罩这几件事它一个人全干了;第三类是被 Wayland 折腾过的人,看完第 2 章和第 5 章,你会明白为什么很多"老派桌面小玩具"在新会话模型下会突然失灵,以及遇到这种情况该怎么判断、怎么绕。

1. 一只位图猫的实现思路:Oneko 凭什么能追上光标

1.1 从 PC-9801 时代讲起:neko 到 oneko 的血统

要理解 Oneko,得先知道它不是凭空冒出来的。最早的 Neko(日语"猫")是 1989 年前后出现在 NEC PC-9801 系列机器上的一个小程序,作者是 Naoki Kobayashi,那个年代连图形桌面都是稀罕物,一只会追鼠标的猫在当时属于"技术炫耀"级别的存在。后来 X 窗口系统流行起来,有人把它移植成 xneko,再往后 Oneko 作为一个改进分支出现,补上了 X11 的 SHAPE 扩展支持,让猫不再是一个黑色方块背景上趴着的图,而是真正"抠"出来的剪影。

这段血统有个很实际的影响:Oneko 的代码风格非常老派,用的是 Xlib 裸接口、Imakefile 构建系统、XBM 单色位图,整套东西都是 1990 年代的审美。你如果直接去看它的源码,会看到大量XCreateWindow、XShapeCombineMask这种调用,没有 GTK,没有 Qt,没有 CMake。这既是它的优点——零依赖、编译飞快、逻辑一眼看穿,也是它的缺点——想换成彩色漂亮素材,基本等于重写。

顺便提醒一个搜索上的坑:想找资料的时候关键词就用oneko,别只搜neko。后者会撞上一大堆同名项目,尤其是近几年的编程语言、开源工具、甚至字体都有人叫这个名字,翻十页都翻不到你要的那只猫。Ubuntu 软件仓库里的包名就是oneko,这算是省事的地方。

1.2 核心机制:全局指针轮询、覆盖窗口和位图遮罩

Oneko 能工作,靠的是三件配合得很好的事,理解这三件事,后面所有的参数和故障排查你都能自己推导出来。

第一件是覆盖式窗口(override-redirect window)。正常的应用窗口都要向窗口管理器"报到",由它负责画标题栏、边框、位置约束、任务栏条目。Oneko 走的是另一条路:创建窗口时带上 override-redirect 标志,窗口管理器直接放手不管。结果就是这只猫没有边框、不占任务栏、Alt+Tab 也抓不到它,看起来像是"画在桌面上"的一部分。这也是为什么你没法用鼠标拖动这只猫——它压根不接受正常的窗口交互。

第二件是SHAPE 扩展。如果只有覆盖窗口,你看到的会是一个 32×32 的方块,方块里有一只猫。SHAPE 扩展允许给窗口指定一个形状蒙版:蒙版上为 1 的位置显示,为 0 的位置透明。Oneko 把 XBM 位图的点阵直接当成蒙版传进去,于是方块消失了,屏幕上只剩下一只猫的轮廓。同一条思路反过来用,还能控制"哪些区域接收鼠标点击",这个后面第 4 章会展开讲。

第三件是主循环。它的逻辑朴素到几乎不需要设计:每隔-time毫秒醒一次,用XQueryPointer问一次"光标现在在哪",算出猫和光标的相对位置,如果距离超过一个阈值就朝那个方向挪-speed个像素,同时把动画帧切到"跑"的状态;如果光标长时间不动(超过-idle秒),就切到"睡"的状态。整个过程就是"看—算—动"三步,没有任何事件订阅、没有信号槽。

这里有个设计选择值得说一下:X11 明明有MotionNotify事件可以监听指针移动,为什么 Oneko 要用轮询?因为在 X11 里,指针事件只会发给你自己的窗口,鼠标跑到别的窗口上时你就收不到了。想拿到全局的指针位置,最省事的办法就是主动去问。轮询的代价是空闲时也在消耗一点点 CPU,但换来的是极简的实现,这个取舍在 1990 年代完全合理,放到今天也依然能用。

1.3 在开发机上养猫的实际收益与代价

先把话说清楚,免得你装完觉得被坑。收益方面,最直接的是桌面有了生气,尤其是你整天对着终端的时候,右下角有只东西会动,心理上确实不一样;其次它是一个很好的教学道具,演示给同事看的时候顺便能讲清楚"什么是 override-redirect 窗口";再功利一点,如果你在做 X11 相关的开发,Oneko 的主循环代码不到两百行,一个下午就能通读,比啃文档效率高得多。

代价也得摆在明面上。第一,位图猫尺寸是固定的,2K、4K 屏上它小得像个像素点,系统缩放帮不上忙,因为位图不会跟着缩放。第二,在 Wayland 会话下它基本上废了,具体原因第 2 章讲。第三,-time参数如果调得太激进(比如 20 毫秒一帧),它会老老实实按你的要求疯狂轮询,笔记本电池会谢谢你。实测下来,默认参数下一只猫的 CPU 占用通常在 1% 以下,真正费电的是你把它调到高刷频率还开了两个实例。

提示:不要同时跑多个 oneko 实例。看起来是"两只猫"很热闹,实际上是两份独立的轮询循环在抢指针,还会互相叠加动画帧,观感很乱,排查问题时也容易误判成"程序出故障了"。用一个pgrep -a oneko随时确认现场有几只。

2. 上手前的环境盘点:X11 还是 Wayland 决定了这条路好不好走

2.1 三行命令确认你的会话类型

动手之前先花十秒钟确认一件事:你的桌面会话是 X11 还是 Wayland。这个判断直接决定了后面的体验是"装完就能玩"还是"折腾半天没反应"。

在图形界面里打开终端,依次敲:

echo $XDG_SESSION_TYPE echo $XDG_CURRENT_DESKTOP echo $DISPLAY

第一条输出x11或者wayland,这是最关键的。第二条告诉你桌面环境是 GNOME、KDE 还是别的。第三条输出类似:0或:1,说明当前会话有可用的 X 显示,后面写自启脚本时会用到这个值。

如果你看到的是wayland,先别放弃,也别急着骂。Wayland 会话里通常还有一个叫 XWayland 的兼容层,它能让老的 X11 程序跑起来,Oneko 也能被它拉起来,你会看到猫出现了。但问题在于,XQueryPointer在 XWayland 环境下只能看到 XWayland 自己管辖的窗口内部的指针位置,鼠标一旦移到原生的 Wayland 窗口或者桌面上,Oneko 就彻底失明了。表现出来的症状很典型:猫在原地趴着不动,或者只在某个窗口范围内追着你跑。

想要完整的全局跟随体验,最省事的路子是在登录界面点右下角的齿轮图标,选 "Ubuntu on Xorg",然后重新登录。这一个动作能省掉你后面所有的困惑。当然,如果你就是想在 Wayland 下实现同样的效果,那只能自己写一个原生程序,第 4 章会给出思路骨架。

2.2 依赖清单:apt 一条命令,还是源码编译要凑什么

走 apt 路线只需要一条命令:

sudo apt update sudo apt install -y oneko

如果提示E: Unable to locate package oneko,八成是软件源里的 universe 组件没启用。先sudo apt update刷新索引,再用apt-cache policy oneko看一眼能不能找到候选版本;还是找不到,就去软件和更新里确认社区维护的软件源是勾选状态。

走源码编译路线要准备的东西多一点,但也没多少:

sudo apt install -y build-essential xutils-dev libx11-dev libxext-dev

这四个包各自解决什么问题,值得逐个说清楚,因为缺哪个、报什么错,是完全不同的:

依赖包提供的工具/头文件缺失时的典型报错
build-essentialgcc、make、标准头文件make: command not found、cc1: fatal error
xutils-devimake、xmkmfxmkmf: command not found
libx11-devXlib.h、Xlib 链接库X11/Xlib.h: No such file or directory
libxext-devX11/extensions/shape.hX11/extensions/shape.h: No such file or directory

这里最容易被忽略的是xutils-dev。老版本的 Oneko 源码包用的是 Imakefile,这是 X11 早期的一套构建系统,靠imake读取模板生成 Makefile,比 autoconf 还早一代。你直接make会一脸茫然,因为压根没有 Makefile,得先跑xmkmf -a。知道这一点,能省掉至少二十分钟的搜索引擎时间。另外libxext-dev是 SHAPE 扩展的头文件,没有它编译到形状相关的那几行就断了,虽然理论上可以关掉 SHAPE 编译,但那样你得到的是一只方块猫,没什么意义。

2.3 三条路线怎么选:apt、源码编译、自己写

三条路都有人走,选哪条取决于你想得到什么。我给一个偏实用主义的对比:

路线上手成本能改什么Wayland 兼容适合谁
apt 安装1 分钟只能用命令行参数调行为依赖 XWayland,体验不完整想快速看到效果的新手
源码编译15-30 分钟可换位图、改默认参数、改尺寸同上想换皮、想读代码的人
自己写一个半天到两天完全可控,能上彩色图和缩放仍需处理会话模型差异想搞懂原理、或必须用 Wayland 的人

我的建议是按顺序来:先用 apt 跑通,确认会话是 X11、确认猫能正常追光标、把参数调到手感舒服,再决定要不要深入。很多人卡在第一步就去折腾源码,结果编译通过了但会话是 Wayland,照样不动,白忙一场。

3. 从安装到开机自启:可直接抄的完整流程

3.1 安装:两条命令跑通,或者五条命令编译

apt 路线按顺序执行:

sudo apt update sudo apt install -y oneko oneko -help | head -30

第三行的-help千万别跳过。不同发行版打包的 Oneko 版本略有差异,参数拼写和默认值都可能有出入,先看一眼实际支持的开关,后面调参才不会瞎猜。确认没问题后,直接在前台跑一次:

oneko

猫出现了,说明环境没问题,按Ctrl+C结束。想让它一直待着,用oneko &,或者用pkill oneko来收工。

源码路线:

sudo apt install -y build-essential xutils-dev libx11-dev libxext-dev tar xf oneko-*.tar.gz cd oneko-* xmkmf -a make sudo make install

xmkmf -a这一步是把 Imakefile 翻译成 Makefile,-a的意思是顺便处理子目录。跑完之后当前目录下会多出 Makefile,再make就正常编译了。安装完成后用command -v oneko确认二进制落在哪——老派项目经常装在/usr/local/bin,而 Debian 系的打包版本可能在/usr/games/下,这个路径后面写自启脚本时要用对,写错了就是静默失败,连报错都看不到。

3.2 参数调优:-time、-speed、-idle 到底改了什么

Oneko 的可调项不多,但每一个都直接对应你看到的行为。以常见默认值为参考(大概-time 125毫秒、-speed 4像素、-idle 10秒,具体以你机器上-help的输出为准):

  • -time:主循环的间隔,单位毫秒。数值越小,猫的动画越顺滑,但轮询越频繁,CPU 占用越高。这是"平滑度"旋钮。
  • -speed:每一帧猫移动的像素数。数值越大,追得越猛。这是"追赶速度"旋钮。
  • -idle:光标静止多少秒后,猫进入睡觉状态。这是"性格"旋钮。
  • -fg/-bg:前景色和背景色。只有在不支持 SHAPE 的环境下才看得出来,正常情况背景是抠掉的。
  • +shape/-shape:强制开关形状遮罩。不同版本的拼写可能反过来,务必用-help核对。
  • -position:指定猫的初始位置,多屏或者想让猫出生在角落时有用。

这里有个新手最容易绕进去的点:"猫追不上光标"和"猫抖得厉害"是两个不同的问题,别用一个参数去修。追不上是-speed太小,抖得厉害是-time太小。这两个参数在实现上是独立的:一个管"多久动一次",一个管"每次动多远"。

调参的时候用一张表对照着试,比盲改快得多:

使用场景-time-speed-idle实际观感
默认养老125410慢悠悠跟着,偶尔睡觉
跟手模式60620反应快,CPU 占用上来一点
笔记本省电20025大部分时间在睡,动了也慢
演示模式40830像只疯猫,适合录屏

命令行大概长这样:

oneko -time 80 -speed 6 -idle 30 &

调完之后想确认代价,用这条看 CPU:

ps -o pid,%cpu,%mem,cmd -C oneko

%cpu那一列如果长期超过 5,说明你把它逼得太紧了,回到-time 100以上会舒服很多。

3.3 开机自启:autostart 桌面项与 systemd 用户服务

让猫开机自动出现有两种做法,各有各的适用场景。

做法一:桌面自启项,适合只想在图形会话里跑、不关心日志的人。新建~/.config/autostart/oneko.desktop:

[Desktop Entry] Type=Application Name=oneko Comment=追着鼠标跑的小猫 Exec=sh -c "sleep 5; exec /usr/games/oneko -time 80 -speed 6" Terminal=false NoDisplay=true X-GNOME-Autostart-enabled=true

这里面有两个细节是经验,不是随便写的。第一个是sleep 5:会话刚登录的那几秒,显示服务和合成器还没完全就绪,太早启动 Oneko,它可能拿不到有效的显示连接,表现就是"猫一闪而过"或者干脆不出现,而自启项失败是不会弹窗告诉你的。第二个是用sh -c "...; exec oneko"而不是直接在 Exec 里写sleep 5 && oneko:加exec是让 shell 把进程身份交给 Oneko,这样注销会话时被终止的是猫本身,而不是留下一个孤儿进程挂在后台。少了这个exec,你会遇到"注销再登录,屏幕上有两只猫"的诡异现象。

做法二:systemd 用户服务,适合想要日志、自动重启、资源限制的人。新建~/.config/systemd/user/oneko.service:

[Unit] Description=Oneko desktop cat After=graphical-session.target PartOf=graphical-session.target [Service] Type=simple Environment=DISPLAY=:0 Environment=XAUTHORITY=%h/.Xauthority ExecStart=/usr/games/oneko -time 80 -speed 6 Restart=on-failure CPUQuota=5% [Install] WantedBy=graphical-session.target

启用并检查:

systemctl --user daemon-reload systemctl --user enable --now oneko.service systemctl --user status oneko.service journalctl --user -u oneko -f

DISPLAY=:0这一行要按你机器上的实际值改。在图形终端里echo $DISPLAY看一下,有些配置下是:1。XAUTHORITY同理,GDM 环境下有时候会被指到/run/user/1000/gdm/Xauthority这种临时路径,用echo $XAUTHORITY确认真实值。这两项写错的后果是一样的:服务能启动,但立刻退出,journalctl里会看到一句语焉不详的显示连接失败。CPUQuota=5%是给猫上的保险,万一哪天参数被改得激进,它最多也只能吃掉半个核。

两种做法的对比:

维度autostart 桌面项systemd 用户服务
配置难度低,写个文本文件中,需要确认 DISPLAY 和 XAUTHORITY
日志查看基本没有,难排查journalctl 直接看
崩溃后重启不会支持 Restart=on-failure
资源限制不支持支持 CPUQuota、MemoryMax
随会话退出会自动结束需要 PartOf 配合

3.4 多显示器、工作区和缩放下的表现

Oneko 是画在 X 的根窗口上的,而多显示器在 X11 里通常是一整块虚拟的大屏幕,所以猫可以自由地从主屏溜达到副屏,不需要任何额外配置。这点比很多现代桌面宠物都省事。

但有几个场景要注意。显示器热插拔之后,如果分辨率或排列方式变了,猫的坐标可能还停留在旧布局上,表现是它跑到一个已经不存在的区域里。处理办法就是重启一下:systemctl --user restart oneko或者pkill oneko && oneko &。

工作区切换方面,覆盖式窗口一般会"粘"在所有工作区上,你切到哪个工作区都能看到猫。这是预期行为不是 bug,如果你希望它只待在某个工作区,那就得改代码,Oneko 本身没有这个开关。

分数缩放是个容易被忽略的坑。GNOME 在 X11 下开 125% 或 150% 缩放时,指针坐标和物理像素之间不再是一一对应关系,猫的图形是固定 32 像素的位图,不会跟着缩放,于是会出现"猫的边缘和光标差了十来个像素"的偏移感。想让它对齐得比较准,把显示缩放设成 100%,或者干脆接受这点误差——毕竟它只是只猫,不是精密测量工具。

4. 进阶:换皮、改行为,以及自己写一只跨环境的猫

4.1 位图换皮:XBM 是怎么回事,能改到什么程度

Oneko 用的素材格式叫 XBM(X BitMap),这东西的本质不是图片文件,而是一段 C 语言代码。它长这样:

#define dot_width 8 #define dot_height 8 static unsigned char dot_bits[] = { 0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c };

0x3c展开成二进制是00111100,每一位对应一个像素,1 表示"这里有点",0 表示"这里是空的"。宽 8 高 8,八个字节依次往下排。整个文件只有黑白两种状态,颜色是由程序渲染时给的前景色决定的,形状则由这堆位决定。所以你能换的东西只有两样:轮廓和颜色。想换成彩色 PNG,靠改素材文件是做不到的,必须动源码,把绘制部分从"位图当蒙版"改成"窗口里贴一张带透明通道的图"。

先确认你机器上的位图在哪:

dpkg -L oneko | grep -i xbm

如果一条都没有,说明打包版本把位图直接编译进二进制了,那就只能下载源码改。如果有,你会看到一批文件,通常对应不同状态和朝向的帧。

想自己做一套轮廓,最方便的是用 GIMP:画一张 32×32 的黑白图,用"图像 → 模式 → 索引"把颜色数压到 2,然后导出为 XBM 格式。命令行党可以用 ImageMagick:

convert cat.png -resize 32x32 -threshold 50% cat.xbm

-threshold 50%这一步不能省。XBM 只有两级灰度,如果不先二值化,转换工具会把所有亮度非零的像素一律当成"亮",你得到的会是一坨看不出形状的黑块。这是换皮流程里最常见的翻车点,我头一次做的时候盯着一个黑色正方形看了半天,以为是编译出错。

说句实在话:XBM 是单色的,换皮折腾到最后往往只是换了个剪影,观感提升有限。真想让它好看,走下面这条自绘路线更值。

4.2 二十分钟写一只自己的猫(Python + Tk + Xlib)

如果你想搞清楚 Oneko 的每一行在干什么,最快的办法是自己写一只。下面这段代码大约六十行,实现了核心的三件事:查询全局指针位置、创建一个无边框置顶窗口、按固定速度朝光标移动。

#!/usr/bin/env python3 # 最小可运行的跟随程序:X11 会话下有效 import tkinter as tk from Xlib import display DISP = display.Display() class FollowCat: def __init__(self, root): self.root = root self.size = 48 self.step = 8 # 每帧移动的像素数 self.interval = 40 # 每帧间隔,毫秒 self.x, self.y = 200, 200 self.win = tk.Toplevel(root) self.win.overrideredirect(True) # 去掉标题栏和边框 self.win.attributes("-topmost", True) # 始终置顶 self.canvas = tk.Canvas(self.win, width=self.size, height=self.size, highlightthickness=0, bg="") self.canvas.pack() self.canvas.create_oval(6, 6, self.size - 6, self.size - 6, fill="#f5a623", outline="#7a4a00", width=2) self.tick() def pointer(self): p = DISP.screen().root.query_pointer() return p.root_x, p.root_y def tick(self): px, py = self.pointer() dx, dy = px - self.x, py - self.y dist = (dx * dx + dy * dy) ** 0.5 if dist > self.size: self.x += dx / dist * self.step self.y += dy / dist * self.step self.win.geometry(f"{self.size}x{self.size}+{int(self.x)}+{int(self.y)}") self.root.after(self.interval, self.tick) root = tk.Tk() root.withdraw() FollowCat(root) root.mainloop()

依赖两条命令装好:

sudo apt install -y python3-xlib python3-tk python3 follow_cat.py

代码里有几个点值得展开讲。query_pointer()拿到的是相对于根窗口的坐标,正好绕开了"事件只发给自己的窗口"这个限制,这就是 Oneko 轮询思路的 Python 版。overrideredirect(True)对应 X11 里的 override-redirect 标志,是"猫没有边框、不进任务栏"的根本原因。root.after(40, self.tick)就是主循环,把参数调小就是 Oneko 的-time调小。

最值得一提的是这行归一化:

self.x += dx / dist * self.step self.y += dy / dist * self.step

如果偷懒写成self.x += dx // 10、self.y += dy // 10,你会立刻发现一个问题:斜着走的时候猫比横着走快,因为对角线方向每帧位移是两个分量平方和开根号。Oneko 里也是这个处理思路,先算出方向单位向量,再乘以固定步长。这个细节看着小,但它决定了猫追光标时是不是"匀速",写桌面动画的人基本上都在这上面栽过一次。

最后提醒一句:把这段代码放到 Wayland 会话里跑,你会发现它同样不动。原因和第 2 章讲的一模一样,query_pointer()在 XWayland 下拿不到全局坐标。所以这段代码其实是个很好的实验工具——两分钟跑一遍,你对"Wayland 下为什么老程序会失灵"的理解会比看十篇文章都深。

4.3 和桌面环境共存的几个细节

猫跑起来之后,还有几件事是你迟早会撞上的。

任务栏和 Alt+Tab:这两处都看不到猫,这是覆盖式窗口的正常表现,不用管。反过来,如果你哪天想正常关掉它,pkill oneko是最快的路子,因为它不在任务栏里,右键退出是点不到的。

点击穿透:正常情况下,猫的窗口只在蒙版为 1 的像素位置拦截鼠标事件,边缘那些空的地方点下去会穿透到下面的窗口。但如果你发现猫确实挡住了操作——比如在它身上点按钮没反应——那说明这个版本的遮罩只做了绘制形状、没处理输入形状。通用解法是把输入区域设成一个空矩形,也就是允许所有点击穿透,这需要调用XShapeCombineRectangles并传一个空列表。有些分支版本做了这件事,老版本没有,具体得看你装的包。

截图和录屏:猫会被截进去,因为它本质上就是个窗口。开视频会议或者做演示前记得先pkill oneko。这个坑我踩过一次,线上演示时右下角一只猫在追光标,全场都看见了。

笔记本续航:如果你经常不插电用,把-time调到 150 以上、-idle调到 8 以下,猫会安静很多。或者在 systemd 服务里加CPUQuota=3%,让它连作妖的余地都没有。

5. 踩坑实录:猫不出来、闪退、跟不上,逐个排查

5.1 猫完全没出现

这是最高频的问题,按下面的顺序排查,基本两分钟内能定位:

  1. 在图形界面的终端里跑echo $DISPLAY。如果是空的,说明你当前不在图形会话里,或者在某个没继承显示变量的环境(比如 SSH 进来的会话)。解决办法是在本机的图形终端里运行,或者显式指定DISPLAY=:0 oneko。
  2. 用第 2.1 节的命令确认会话类型。wayland的话,先按 XWayland 的症状来判断,见 5.3。
  3. 在前台跑一次,别加&:oneko -time 125。终端里的报错信息是最直接的线索,常见的有Can't open display(显示变量问题)和形状扩展相关的报错(多半是会话类型问题)。
  4. 确认没有已经在跑的实例:pgrep -a oneko。开了两只的时候,它们会重叠在同一个位置附近,看起来像"没动"或者"画面很奇怪"。
  5. 如果是通过自启配置启动的,检查Exec里的二进制路径。把/usr/bin/oneko写成/usr/games/oneko或者反过来,都会导致静默失败,而且桌面自启项不会给你任何提示。想看日志,autostart 路线去翻~/.xsession-errors,systemd 路线直接journalctl --user -u oneko。

5.2 终端里能看到猫,关掉终端猫就消失了

这是经典的挂断信号问题。你在终端里敲oneko &,它就成了这个 shell 的子进程,shell 退出时会向子进程发 SIGHUP,猫就跟着走了。三种修法,按推荐程度排:

  • 上 systemd 用户服务(3.3 节的方案二),能看日志、能自动重启、能限资源,一劳永逸。
  • nohup oneko -time 80 >/dev/null 2>&1 &,简单粗暴。
  • oneko -time 80 & disown,把进程从 shell 的任务表里摘出去。

第二种和第三种适合临时用,重启之后就没了。真要长期养着,还是老老实实写服务文件。

5.3 猫只在自己窗口附近动,或者完全跟不上

这是 Wayland 会话的教科书症状。判断方法非常简单:把终端窗口拉到全屏,鼠标在终端里晃。如果猫只在终端范围内有反应,鼠标一移出终端它就不动了,那实锤了——它只能看到 XWayland 内部的事件。

解决方案只有两条路。第一条是切会话:注销,在登录界面点右下角齿轮,选 "Ubuntu on Xorg",重新登录。这是成本最低、效果最完整的做法。第二条是自己写:用 GTK 或 Qt 配合桌面环境支持的分层协议,做一个原生窗口,然后通过桌面环境提供的接口拿指针位置。工作量比 4.2 节那段六十行代码大得多,而且要处理不同桌面环境之间的差异,除非你有很明确的需求,否则不太值得。

顺带说一个反直觉的现象:有些人在 Wayland 下第一次跑 Oneko,猫居然动了,于是以为没问题。实际上那是因为他们的鼠标恰好一直在某个 XWayland 应用窗口里。这种"能跑但不完整"的状态最容易让人误判,所以判断时一定要把鼠标移到桌面空白处试试。

5.4 猫挡住点击,或者在高分屏上小得看不清

挡住点击:先确认是不是真的挡住了,用xwininfo点一下猫的位置能看到窗口信息。确认是猫在拦截事件的话,思路就是 4.3 节说的,把输入形状置空实现完全穿透。老版本的 Oneko 没有这个处理,如果你的包比较老,最省事的办法其实是把猫挪到屏幕角落,用-position参数指定初始位置,比如-position +50+50,具体语法看-help。

高分屏太小:位图是固定像素的,32×32 就是 32×32,系统缩放不会帮它放大,这是位图方案的硬伤。想在 4K 屏上看得清,只有重新编译一途:把 XBM 素材做成 64×64,同时改源码里所有和尺寸相关的常量,还要确保移动时的边界判断也跟着改,不然猫会走出屏幕或者卡在边缘抽搐。改一遍大概二十分钟,收益是它在高分屏上终于像个正常大小的宠物。

分数缩放导致的位置偏移:前面提过,缩放比例不是整数时,指针坐标和物理像素的对应关系会变,猫的图形和光标之间会有肉眼可见的错位。整数缩放(100%、200%)下这个问题基本不存在。

5.5 常见问题速查表

把上面这些整理成一张表,出问题的时候直接对着找:

现象最可能的原因处理方式
完全看不到猫不在图形会话,或$DISPLAY为空在图形终端里跑,或用DISPLAY=:0 oneko
猫只在某个窗口内活动Wayland 会话,只能读到 XWayland 事件切到 Xorg 会话,或自写原生程序
终端关掉猫就消失shell 退出时发了 SIGHUP用 systemd 服务或nohup、disown
开机后猫不出现自启脚本路径写错,或启动太早核对二进制路径,Exec里加sleep 5
注销再登录出现两只猫自启命令没加exec,留下孤儿进程改成sh -c "sleep 5; exec oneko ..."
猫追不上光标-speed太小调到 6 到 8 之间
猫抖动、画面不连贯-time太大调到 60 到 80 之间
猫挡住鼠标点击输入形状没置空挪到角落,或换支持穿透的版本
高分屏上猫极小XBM 位图尺寸固定重编 64×64 素材,或使用整数缩放
CPU 占用偏高-time太激进,或多实例调回 100 以上,pgrep清理重复实例

最后分享一个我自己的习惯:这台开发机上,Oneko 是通过 systemd 用户服务跑的,参数固定成-time 80 -speed 6 -idle 20,外加CPUQuota=3%。这个组合在我这儿跑了大半年,观感是"跟手但不烦人",资源占用低到可以忽略。另外我把它的源码留在~/src/oneko里没删,整个程序不大,主循环那两百来行 C 代码是我推荐给所有想入门 X11 的人的阅读材料——看完之后,XQueryPointer、XShapeCombineMask、override-redirect 这三个概念基本就刻在脑子里了,比啃手册快得多。

返回列表