资讯动态

RK 11.0 多屏模式鼠标进入方式修改:TaoToken 配置骨架与 displayId 验证

发布时间:2026/9/27 16:01:06 来源:尧图企业网站定制
1. RK 11.0 多屏鼠标进入方式到底卡在哪RK 11.0 多屏模式下鼠标进入方式修改说白了就是解决一个很具体的体验问题主屏在左、副屏在右鼠标从主屏最右侧滑出去应该出现在副屏最左侧从副屏最左侧滑回来应该出现在主屏最右侧。听起来像系统本来就该做的事但 RK 默认的sys.mouse.presentation1逻辑并不是按左右排列来设计的它只判断鼠标是否碰到屏幕四周边缘碰到就切displayId切过去之后PointerController还会把光标重置到新屏正中央。这套默认行为在上下排列或者单屏场景下问题不大一旦变成 HDMI 副屏在右侧的横排布局用户就会觉得鼠标“跳”了——明明从右边出去结果光标出现在副屏中间还得再找一遍。更麻烦的是 HDMI 热插拔副屏拔掉后如果displayId还停在副屏上鼠标会直接失去功能因为那个 display 已经不存在了。所以这篇要解决的是三件事第一把鼠标进入方式改成按左右边缘定向切换第二切换后光标落在目标屏的对应侧而不是居中第三HDMI 拔插时displayId能安全回落到主屏 0。同时我会给出一套可复制的配置骨架把 RK 侧参数和 TaoToken 的统一 Key/API 通道接起来方便你在调试阶段用模型对话快速核对displayId与 HDMI 状态。适合谁看正在做 RK 11.0 多屏产品、需要改CursorInputMapper或PointerController的嵌入式/系统开发同学以及想用统一 API 通道辅助排查多屏输入问题的工程师。下面所有路径和代码都基于 AOSP 风格目录你可以直接对照自己的工程改。2. 前置准备TaoToken 统一 Key 与 API 通道在动CursorInputMapper.cpp之前先把调试通道搭好。多屏鼠标问题往往不是一次改完就对的你需要反复验证displayId、hdmi.plugged、光标坐标这三组值。与其每次 adb 敲一堆命令不如用一个统一的模型对话入口来帮你读日志、比对配置。TaoToken 在这里的角色是统一 Key/API 通道你申请一个 Key就能通过同一套 API 访问模型对话能力用来做日志分析、配置骨架生成、报错解释。它不替代你的编辑器也不碰你的生产库只是把调试期的“问模型”这件事收敛到一个入口。先拿 Key。打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后在控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。API 基址统一用 https://taotoken.net/api 注意这个地址不加 UTM 参数直接写进配置即可。如果你只是临时验证模型能不能通用模型对话页最快https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。长期做编码和 Agent 调试的话Coding Plan 更合适https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite Claude Code 相关配置参考 https://taotoken.net/claudecode?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。注意Key 只放在本地环境变量或本地配置文件里不要提交到 git也不要写进会被打包进固件的资源文件。3. 可复制配置骨架config.toml 与 settings.json这一节给你两套骨架。config.toml用于本地调试工具链读取 TaoToken 通道settings.json用于把 RK 多屏参数和验证动作固化下来方便团队复用。3.1 config.toml 骨架# ~/.taotoken/config.toml # TaoToken 统一 Key/API 通道配置仅本地调试使用 [api] base_url https://taotoken.net/api api_key ${TAOTOKEN_API_KEY} # 从环境变量读取勿硬编码 timeout_ms 60000 [model] default claude-sonnet # 按控制台可用模型调整 max_tokens 4096 temperature 0.2 # 排障场景低温度更稳 [debug] # 多屏鼠标调试上下文供模型对话时附带 project rk11-multidisplay-mouse tags [RK11, displayId, HDMI, CursorInputMapper]环境变量这样设export TAOTOKEN_API_KEY你的Key3.2 settings.json 骨架{ rk_multidisplay: { mouse_presentation_prop: sys.mouse.presentation, mouse_presentation_value: 1, hdmi_plugged_prop: hdmi.plugged, primary_display_id: 0, layout: primary_left_secondary_right, edge_offset_px: 10 }, verify: { switch_hdmi_then_check: true, expect_cursor_side: { enter_secondary: left, enter_primary: right }, target_display_prop: debug.mouse.target_display }, taotoken: { base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY } }edge_offset_px对应代码里setPosition(minX10, ...)和setPosition(maxX-10, ...)的偏移量你可以按实际 DPI 调。primary_display_id固定为 0因为 RK 默认主屏 id 是 0副屏切换后递增。3.3 核心改动CursorInputMapper 定向切换默认逻辑是“碰边就切”改成“按左右边缘定向切”。关键片段如下路径frameworks/native/services/inputflinger/reader/mapper/CursorInputMapper.cppchar mMousePresentation[PROPERTY_VALUE_MAX] {0}; property_get(sys.mouse.presentation, mMousePresentation, 0); if (strcmp(mMousePresentation, 1) 0) { char mHdmiPlugged[PROPERTY_VALUE_MAX] {0}; property_get(hdmi.plugged, mHdmiPlugged, 0); if (strcmp(mHdmiPlugged, 1) 0) { displayId mDisplayId; } else { // HDMI 拔掉强制回主屏 0避免鼠标失效 displayId 0; } float minX, minY, maxX, maxY; if (mPointerController-getBounds(minX, minY, maxX, maxY)) { // 主屏右边缘 - 切副屏光标落在副屏左侧 if (displayId 0 xCursorPosition maxX) { displayId getPolicy()-notifyDisplayIdChanged(); mDisplayId displayId; if (strcmp(mHdmiPlugged, 1) 0) { mPointerController-setPosition(minX 10, yCursorPosition); } } // 副屏左边缘 - 切主屏光标落在主屏右侧 if (displayId ! 0 xCursorPosition minX) { displayId getPolicy()-notifyDisplayIdChanged(); mDisplayId displayId; mPointerController-setPosition(maxX - 10, yCursorPosition); } } } else { displayId mPointerController-getDisplayId(); }这里有两个坑要提前说。第一xCursorPosition maxX是浮点相等判断实际工程里建议改成xCursorPosition maxX - 1.0f否则边缘像素可能差一点触发不了。第二notifyDisplayIdChanged()返回的是下一个 display id但你要确认 policy 层确实按左右顺序返回而不是按接入顺序。3.4 阻止光标居中PointerController 改动默认setDisplayViewport在 display 变化时会把光标重置到中心mLocked.pointerX (minX maxX) * 0.5f; mLocked.pointerY (minY maxY) * 0.5f;路径frameworks/base/libs/input/PointerController.cpp。如果你已经在CursorInputMapper里用setPosition指定了落点这里的居中会覆盖掉你的设置。处理方式有两种一是在setDisplayViewport里加条件当sys.mouse.presentation1且是左右布局时跳过居中二是调整调用顺序确保setPosition在 viewport 更新之后执行。我倾向第一种改动更集中。char mMousePresentation[PROPERTY_VALUE_MAX] {0}; property_get(sys.mouse.presentation, mMousePresentation, 0); bool keepEdge (strcmp(mMousePresentation, 1) 0); if (!keepEdge (oldViewport.displayId ! viewport.displayId || oldDisplayWidth ! newDisplayWidth || oldDisplayHeight ! newDisplayHeight)) { // 原居中逻辑 }3.5 HDMI 状态写入WiredAccessoryManager.java里把 HDMI 插入状态写进属性路径frameworks/base/services/core/java/com/android/server/WiredAccessoryManager.javaif (status.contains(HDMI)) { SystemProperties.set(hdmi.plugged, status.contains(HDMI1) ? 1 : 0); }这个属性是后面验证动作的锚点必须确保它在插拔时实时更新。如果你们的方案里 HDMI 状态走的是别的节点把属性名统一成hdmi.plugged即可settings.json里也同步改。4. 验证请求切换 HDMI 后确认鼠标进入目标 displayId改完代码、编好镜像刷进去接下来是验证。验证的核心动作就一句话切换 HDMI 屏后确认鼠标进入的目标displayId生效且落点在正确一侧。4.1 用 TaoToken 模型对话核对日志先把关键属性读出来adb shell getprop sys.mouse.presentation adb shell getprop hdmi.plugged adb shell dumpsys input | grep -i displayId把这三段输出贴到模型对话里让它帮你判断displayId是否和预期一致。模型对话入口https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。如果你走 API可以这样请求curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet, messages: [ {role: user, content: sys.mouse.presentation1, hdmi.plugged1, 主屏id0, 副屏id1。鼠标从主屏右边缘移出后 dumpsys 显示 displayId1落点 x10。这符合主左副右布局吗} ] }返回里如果模型指出落点应该在副屏左侧x 接近 minX说明你的setPosition(minX10, ...)生效了。4.2 手动验证步骤第一步主屏在左、副屏在右接好确认hdmi.plugged1。第二步把鼠标移到主屏最右侧观察是否切到副屏且光标出现在副屏左侧而不是中间。第三步从副屏最左侧移回观察是否切回主屏右侧。第四步热拔 HDMI确认hdmi.plugged0且鼠标仍能在主屏正常移动displayId回到 0。# 实时观察属性变化 adb shell watch -n 1 getprop hdmi.plugged; getprop sys.mouse.presentation4.3 成功结果长什么样成功时你会看到displayId在主屏时是 0切到副屏后变成 1光标 x 坐标在副屏上接近minX左侧在主屏上接近maxX右侧拔掉 HDMI 后displayId立刻回 0鼠标不卡死。如果这三点都满足说明鼠标进入方式修改生效了。5. 本篇常见错排查5.1 鼠标切过去还是居中大概率是PointerController::setDisplayViewport的居中逻辑覆盖了你的setPosition。按 3.4 节加keepEdge判断或者确认setPosition调用时机在 viewport 更新之后。用adb logcat | grep PointerController看 viewport 更新和 setPosition 的先后顺序。5.2 边缘触发不了切换xCursorPosition maxX浮点相等太严格。改成xCursorPosition maxX - 1.0fminX同理用 minX 1.0f。另外确认getBounds返回的 maxX 是当前屏的右边界不是整个虚拟桌面的边界。5.3 HDMI 拔掉后鼠标失效说明displayId没回落到 0。检查hdmi.plugged属性是否在拔掉时真的变成 0以及CursorInputMapper里strcmp(mHdmiPlugged, 1) 0的分支是否走到了displayId 0。如果属性没更新回到WiredAccessoryManager确认 HDMI 状态解析。5.4 notifyDisplayIdChanged 返回不对如果 policy 层按接入顺序而不是左右顺序返回 display id主左副右布局下会切错。你需要在 policy 层按物理位置排序或者维护一个 display id 到左右位置的映射。用adb shell dumpsys display看当前 display 列表和 id。5.5 TaoToken 请求 401Key 没读到或者环境变量名写错。确认echo $TAOTOKEN_API_KEY有值config.toml里用的是${TAOTOKEN_API_KEY}而不是硬编码。API 基址是 https://taotoken.net/api 不要多加路径。接入细节看文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。6. 把调试通道固定下来多屏鼠标这类问题改一次代码只是开始后面还有不同分辨率、不同 HDMI 时序、不同 DPI 的组合要验。我的做法是把settings.json里的verify段当成回归清单每次改完CursorInputMapper就跑一遍切 HDMI、看displayId、看落点、拔 HDMI、看回落。这套动作固定下来之后回归成本会低很多。如果你后面要长期做 RK 多屏相关的编码和 Agent 调试Coding Plan 比单次对话更省事https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。Key 管理和接入文档分别在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 和 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。先把 3.3 节的定向切换和 3.4 节的防居中改完再用第 4 节的验证动作确认displayId生效基本就能把 RK 11.0 多屏鼠标进入方式这件事收口。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑