
先说结论在 Ubuntu 22.04 下碰到的双屏触摸屏错位绝大多数不是触摸屏硬件坏了也不是显卡驱动没装好而是 Xorg 把触摸设备默认当成了“覆盖整张桌面”的绝对定位设备。双屏扩展之后桌面坐标范围变宽物理触摸屏仍然按自己那块面板的分辨率上报坐标于是点击左边屏幕光标却跳到右边、点击屏幕上半部分光标落在下半部分、甚至触摸点沿对角线乱跑。解决思路其实很清晰用xinput map-to-output把触摸设备绑定到对应的显示器输出再用Coordinate Transformation Matrix做方向和偏移修正。这篇文章是我自己在一台双屏触控一体机上折腾两周后的完整记录适合正在用 Ubuntu 22.04 接外接触摸屏、工控一体机、触控显示器或者被“触摸点和响应位置不一致”折磨的人参考。下面所有命令基于 Xorg 会话如果你登录的是默认 Wayland 会话先切回“Ubuntu on Xorg”再操作。1. 先搞清楚坐标为什么会对不上1.1 触摸绝对定位与多显示器桌面坐标的矛盾触摸屏和鼠标最大的区别在于鼠标是相对设备报的是“相对位移”触摸屏是绝对设备上报的是“绝对坐标”。在单屏情况下这个绝对坐标天然对应唯一一块屏幕基本不会出问题。但当你插上第二块显示器并设置成扩展模式后Xorg 会把两块屏拼接成一张更大的桌面桌面左上角是主显示器的左上角桌面总宽度是两块屏逻辑宽度之和。触摸屏固件不知道这个“拼接桌面”的存在只知道按照自己的面板坐标上报触点位置。于是系统就把触摸屏上报的坐标放到整张大桌面的坐标系里去解释结果自然出现错位。举个最直观的例子你的主屏 1920x1080 在左边外接触摸副屏 1920x1080 在右边。桌面总宽度变成了 3840。触摸副屏出厂坐标范围是 0 到 1920但 Xorg 认为这个坐标是相对整张大桌面而言的所以当手点在副屏正中间物理 x 约 960时系统会把这个点放到大桌面 x960 的位置也就是主屏中间而不是副屏中间。这就是“点副屏、光标跑主屏”的本质原因。1.2 哪些错位现象说明是映射问题我见过不少群里朋友把这类问题误判成“触控驱动不对”或者“触摸屏坏”。你可以对照一下这些典型现象点击 A 屏幕光标出现在 B 屏幕且位置基本成比例对应。触摸上下方向反了左右方向正常。点击屏幕中间光标出现在屏幕边缘或点击边缘光标跑到中间。单屏显示时完全正常一旦设置成双屏扩展就乱套。触摸屏刚开机时正常休眠唤醒后错位。如果命中其中两三条基本可以断定是坐标映射或设备绑定问题跟屏幕面板和触摸 IC 关系不大。解决办法不是重装系统而是让 Xorg 知道“这块触摸屏只属于某一块显示器输出”。1.3 Wayland 和 Xorg 先选对Ubuntu 22.04 桌面版默认登录会话其实是 GNOME Wayland但xinput map-to-output这套工具是 X11 体系下的东西在 Wayland 会话下不会正常工作。尴尬的是很多触控一体机安装系统时一路默认回车进入的就是 Wayland 会话然后折腾半天 xinput 发现没反应。在 GDM 登录界面右下角有一个齿轮状图标点开之后选“Ubuntu on Xorg”再输入密码登录才是 Xorg 会话。这一步很关键我建议你在开始排查前先确认一下省得后面所有命令都打在空气上。2. 检查设备拿到显示器编号和触屏 ID2.1 用 xrandr 看当前输出布局拿到 Xorg 会话后打开终端先运行xrandr输出会列出当前所有显示输出类似这样Screen 0: minimum 320 x 200, current 3840 x 1080 eDP-1 connected primary 1920x108000 0mm x 0mm HDMI-1 connected 1920x108019200 0mm x 0mm这里eDP-1通常是笔记本内置屏HDMI-1是外接触摸屏。后面那个00和19200表示这块显示器在大桌面里的坐标位置单位是像素。如果你的副屏在左侧输出可能长这样HDMI-1 connected 1920x108000 eDP-1 connected primary 1920x108019200不管实际位置怎么排xinput的map-to-output都认输出名所以只要确认副屏对应的输出名是 HDMI-1 还是 DP-1 即可。2.2 用 xinput 确认触摸设备名称接着运行xinput list输出里会有一大堆设备重点找带touchscreen、Touch、ILITEK、ELAN、Goodix这类关键词的项。比如⎡ Virtual core pointer id2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id4 [slave pointer (2)] ⎜ ↳ ILITEK ILITEK-TP id10 [slave pointer (2)] ⎜ ↳ MX Master 3 id12 [slave pointer (2)]这里的ILITEK ILITEK-TP就是触摸屏设备它的 id 是 10。但需要注意的是id 在每次重启或重新插拔设备后可能发生改变所以后面写脚本时最好用设备名字不要用 id。如果你想进一步确认这个设备确实是绝对报点的触摸屏可以运行xinput --list-props 10查看Device Enabled和Coordinate Transformation Matrix这两个属性。正常情况下未做任何处理的触摸设备矩阵类似Coordinate Transformation Matrix (154): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.0000002.3 保存一份设备属性快照在动手改之前我习惯先把当前设备属性和显示器布局存下来。一是为了方便回滚二是为了排查时对照前后差异。比如xrandr --verbose xrandr-before.txt xinput list --long xinput-before.txt xinput --list-props ILITEK ILITEK-TP touch-props-before.txt这些文件没啥技术含量但实际问题排查时非常有价值。尤其是当你同时接了两块触摸屏改了 A 屏设置发现 B 屏也跟着乱回溯快照就能快速确认自己改了什么。3. 核心解决把触屏绑定到目标显示器3.1 一条命令完成映射当你确认了触摸设备名和显示器输出名之后核心解决命令只有一行xinput map-to-output ILITEK ILITEK-TP HDMI-1如果设备名带空格必须用引号括起来。这个命令的含义是把触摸设备ILITEK ILITEK-TP上报的绝对坐标重新映射到输出HDMI-1对应的桌面区域上。映射之后触摸坐标不再去覆盖整个拼接桌面而是只在 HDMI-1 这块屏的范围内解析。执行命令后你不需要重启 Xorg也不需要注销触摸点应该立刻回到正确位置。如果还没对先检查输出名是否填错或者当前登录的 session 是否还是 Wayland。3.2 扩展模式和镜像模式的不同处理双屏最常见的配置是扩展模式也就是两块屏显示不同内容。这时候一块物理触摸屏就映射到它对应物理屏幕的输出名上。如果你有两块触摸屏那就分别执行xinput map-to-output ILITEK ILITEK-TP-A HDMI-1 xinput map-to-output ELAN Touchscreen DP-1如果你用的是镜像模式两块屏显示相同内容情况会稍微特殊一点。理论上触摸屏映射到任意一个输出都可能正常但实际中我更建议映射到主输出也就是xrandr里标着primary的那块。因为镜像模式本身在 Xorg 里的坐标空间并不是一直固定的映射到 primary 输出能避免很多边角问题。如果你的触摸屏是扩展屏上物理存在的触摸面板那么请使用扩展模式别在镜像模式下强行要求触控和视觉完全一致那是给自己挖坑。3.3 方向不对时的旋转矩阵触控错位还有一种常见情况是方向不对。比如把一块竖屏触摸屏物理安装成了 90 度方向但系统还不知道这时候触摸物理坐标轴和显示坐标轴就对不上。常见做法是修改Coordinate Transformation Matrix这个属性。先看默认矩阵1 0 0 0 1 0 0 0 1表示 x、y 不做任何变换。如果你需要将触摸方向顺时针旋转 90 度运行xinput set-prop ILITEK ILITEK-TP Coordinate Transformation Matrix 0 -1 1 1 0 0 0 0 1如果需要旋转 180 度xinput set-prop ILITEK ILITEK-TP Coordinate Transformation Matrix -1 0 1 0 -1 1 0 0 1如果需要逆时针旋转 90 度xinput set-prop ILITEK ILITEK-TP Coordinate Transformation Matrix 0 1 0 -1 0 1 0 0 1这里不展开讲矩阵原理你只需要知道这个矩阵控制的是“真实触摸坐标到显示坐标的线性变换”。实际项目里先搞定map-to-output再调方向否则方向校正和显示器映射叠加在一起会很难排查。3.4 重启后配置失效怎么办xinput的命令都是临时生效注销重启就会丢。要让映射持久化最简单的办法是写一个启动脚本再用桌面环境的“开机自启动”功能调用。先创建脚本比如/usr/local/bin/touchscreen-map.sh#!/usr/bin/env bash export DISPLAY:0 export XAUTHORITY$(ls /home/你的用户名/.Xauthority 2/dev/null) sleep 3 xinput map-to-output ILITEK ILITEK-TP HDMI-1 xinput set-prop ILITEK ILITEK-TP Coordinate Transformation Matrix 0 -1 1 1 0 0 0 0 1然后给脚本加执行权限sudo chmod x /usr/local/bin/touchscreen-map.sh接着建立桌面自启动项在~/.config/autostart/touchscreen-map.desktop里写[Desktop Entry] TypeApplication NameTouchscreen Map Exec/usr/local/bin/touchscreen-map.sh X-GNOME-Autostart-enabledtrue脚本里开头sleep 3是为了等桌面完全起来否则 X 环境变量可能还没就绪。XAUTHORITY那段是为了让脚本拿到当前用户的 X 授权不然xinput会报unable to open display。实际用户名和XAUTHORITY路径要按你自己的环境改。4. 校准与微调把最后那几像素偏差也修掉4.1 xinput-calibrator 能用吗很多人会想到以前在 Ubuntu 上常用的校准工具xinput-calibratorsudo apt install xinput-calibrator装完后运行xinput-calibrator --device ILITEK ILITEK-TP然后用触控笔依次点几个十字点。这个工具在老系统上确实好用但在 Ubuntu 22.04 默认使用 libinput 的情况下它生成的配置文件往往是给evdev驱动用的效果时灵时不灵。我的建议是如果xinput-calibrator在你的设备上校准完没有明显改善就别在它身上浪费太多时间改用下一节的手工矩阵校准反而更可控。4.2 手工用变换矩阵做偏移修正所谓偏移修正就是让触摸坐标整体向左、右、上、下平移几个像素或者做一点缩放。矩阵里前三个参数控制 x 方向后三个控制 y 方向a b c d e f 0 0 1其中c是 x 方向的平移量f是 y 方向的平移量。注意这里的位置是归一化的实际像素要除以目标显示器的分辨率。举个例子你的副屏是 1920x1080映射完成后手指点屏幕中心光标却落在中心偏右 20 像素的位置。也就是触摸输入整体比实际视觉偏右了 20 像素。要把光标往左挪 20 像素需要把 x 方向平移量设成-20 / 1920 -0.0104167。执行xinput set-prop ILITEK ILITEK-TP Coordinate Transformation Matrix 1 0 -0.0104167 0 1 0 0 0 1同理如果光标整体偏下 10 像素就把f设成-10 / 1080 -0.0092593。如果触摸范围比屏幕显示范围大了一圈还可以通过调整矩阵里的a和e来缩放。这类微调没有统一答案建议先用map-to-output和旋转矩阵把“大方向”调对再对着屏幕上的某个固定点反复试把偏移压到可以接受的范围内。4.3 校准顺序和原则在校准过程中我总结出一个固定顺序能少走很多弯路先确认登录的是 Xorg 会话。用xrandr确认显示输出布局。用xinput map-to-output把触摸设备绑定到对应输出。用旋转矩阵修正方向问题。最后通过平移缩放矩阵微调边缘偏移。顺序很重要。如果在大方向都没正确之前就去做微调你会在不同矩阵参数之间来回试最后自己都不确定到底调了什么。5. 常见问题与排查技巧实录5.1 常见现象速查表下面是我实际折腾和帮别人排查时遇到频率最高的问题整理成速查表方便对照现象可能原因解决思路点 A 屏光标跑到 B 屏触摸设备没有映射到对应输出用xrandr查输出名再执行xinput map-to-output点击后光标沿对角线移动方向矩阵错误或屏幕物理安装方向不同按 90/180/270 度设置Coordinate Transformation Matrix重启后触控错位恢复没有持久化配置写脚本加入 GNOME 自启动登录界面/锁屏界面错位GDM 的 X 会话和用户会话不共用配置用户会话内设置不影响 GDM不影响系统使用则忽略必要时给 GDM 单独配置两块触摸屏串台A 触摸设备被映射到了 B 输出分别映射两个设备到各自输出命令执行后没反应当前是 Wayland 会话注销后选择Ubuntu on Xorg再登录屏幕边缘点击不精准触摸膜和玻璃贴合存在偏差用变换矩阵做平移缩放微调5.2 两个触屏互相串台的场景我遇到过一个比较极端的场景一台设备上同时接了内置触摸屏和外接 USB 触摸屏插上之后两个屏互相串台点内置屏外接屏有反应点外接屏内置屏有反应。这个问题的本质就是两块触摸设备都没有被正确绑定到各自的输出。解决方法是先用xinput list把两块触摸屏的名字都找出来然后用两条map-to-output分别绑定。如果设备名字太相似难以区分可以先只插一块屏执行xinput list确认名字再换另一块屏确认。也可以运行xinput test 设备名然后在对应的触摸屏上点一下观察终端里哪个设备的坐标在变化这样能快速锁定物理设备和输入设备名的对应关系。这个技巧在工业触摸一体机上特别实用。5.3 登录界面和锁屏界面错位的处理很多朋友在用户桌面上设置好之后发现锁屏界面触摸位置又不对了。这个问题是因为 GDM 登录界面的 X server 和用户 session 不是同一个你在用户 session 里执行的xinput命令不会传给 GDM。如果只是偶尔锁屏重启我建议别纠结直接忽略如果一定要在登录界面也正确触控需要给 GDM 写配置或者借助 udev 规则在设备接入时自动设置但配置成本较高容易牵连正常桌面会话。从实际部署角度看绝大多数场景只需要保证用户 session 内部正确就行。6. 一点实操心得在我自己的 Ubuntu 22.04 双屏触控项目里最坑的其实不是xinput命令本身而是“以为点副屏没问题就万事大吉”的心态。实际操作中触摸屏经过map-to-output之后可能看着好了但边缘会有 3 到 5 像素的偏差这种偏差在办公软件里感觉不明显但在需要精确点击按钮的工业软件里会让人抓狂。所以我的建议是大方向用xinput map-to-output解决最终手感靠Coordinate Transformation Matrix微调这两者缺一不可。另外如果你手头的触摸屏在 Windows 下也出现类似错位那大概率是触摸屏硬件本身的坐标原点或者贴合参数有问题Ubuntu 这边能做的只是软件补偿不能完全修复硬件层级的偏差。还有一个小技巧改完矩阵后先不要着急重启用xinput --list-props确认当前生效值再拿一张图片或者一个窗口在屏幕上拖动测试这样比单纯点图标更容易看出细微偏移。希望这篇记录能帮你少走点弯路。我自己在这块踩过的坑不少尤其是第一次遇到双屏触控错位时差点把一台好好的触摸一体机返厂维修。现在回头看一行xinput map-to-output就解决了一大半问题。如果你的设备情况比较特殊也欢迎根据这篇思路往下推核心点永远是先看显示输出名再看触摸设备名最后调整矩阵。