V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bczhc
V2EX  ›  Android

MIUI 13 如何关闭系统的 compose key

  •  
  •   bczhc · 4 天前 · 727 次点击

    在我的小米平板 5 ( MIUI 13.0.9 )上,当外接键盘时,Alt 键会被系统作为 compose key ,如按下“alt+s”时会输出“ß”,按下“alt+u u”时会上屏“ü”。使用 Gboard 和“CodeBoard”测试过了,都是如此,可以判断是系统行为,不是输入法的。

    感觉小米总喜欢瞎搞些这种东西。手头四五个安卓设备里就它有问题,不过手机 HyperOS 也是正常的。我并不需要这个功能,设置里也没找到哪个能关。这直接导致了开发 IME 时无法处理任何 Alt 组合键( onKeyDown 里完全接收不到按下 Alt 时的字母事件)。

    3 条回复    2025-11-06 21:30:33 +08:00
    kuanat
        1
    kuanat  
       3 天前
    Android 系统在语言和输入法相关设置里有个物理键盘的设定,可以点进去看看是否有切换键盘布局的选项,如果有的话切换到不使用 AltGr/Compose 的布局。印象 aosp 中有过,但我不是很确定。

    这个问题说起来比较复杂。Android 系统的输入栈在内核部分和 Linux 是没有区别的,但之后就完全不一样了。因为是针对移动平台设计的,关于键盘布局的设定是和输入法、语言强绑定的。从底层修改这个按键和功能的映射是可行的,可以参考一下 https://github.com/keymapperorg/KeyMapper 这个应用。

    简单说 Android 输入栈有两层,最底层和 Linux 处理输入设备一样,在内核态完成 scan code 到名义按键的映射,比如 scan code 1 代表 esc 按键。上面一层是按键和具体功能的映射,比如 A 按键的效果是 a 字符,有 shift 修饰的时候产生 A 字符。

    如果你的系统可以获得 root 的话,可以看一下 /system/usr/keylayout/ 和 /system/usr/keychars/ 两个路径的文件。前者包含不同设备的 .kl 定义,代表 scan code 到名义按键的映射,后者包含 .kcm 定义,即名义按键到实际功能的映射,也就是一般所说的布局。可以检查一下是否正常。

    如果你可以用 onKeyDown 获得 COMPOSE 事件的话,可以在编写的代码里强行当作 alt 来处理。
    bczhc
        2
    bczhc  
    OP
       2 天前
    @kuanat 感谢回复。又测试了手上的 MIUI 13 和 HyperOS ,发现两者对此有不同行为。我做了一些测试。

    当按下 Alt 时 onKeyDown 中可以接收到 Alt 事件(如果长按了还会有一连串),但对于 HyperOS ,当按下后续字母时,会有那个字母按键的事件,但对于 MIUI 13 ,则是表现为那串 Alt 事件戛然而止,无后续的字母按键。

    另外,才发现 HyperOS 其实同样是处理 compose key 的,以 Alt+S 为例,当系统接收到 Alt+S 时就会上屏`ß`,但尽管如此,不影响 IME 中获取到 Alt 后续的 S 事件,且只有在 IME 不拦截( onKeyDown 返回`false`)时才会上屏`ß`。反之,HyperOS 中无论 IME 是否拦截,则都会上屏`ß`。拦截无效,显然可以合理怀疑这是 MIUI 13 的 bug 。

    在 MIUI 13 中是能找到“实体键盘布局”一选项,但当我选到了其他的布局时,compose key 倒没了(比如按 Alt+S 不会上屏`ß`了),但 IME 中仍然接收不到 Alt 修饰的按键。

    那两个文件不需要 root 也可以由 adb 拉取,我看了下内容,左 ALT 的处理正常,如下:

    ```console
    ~/keyboard/miui13/keylayout ❯ rg -i 'KEY 56' 17:55:17
    qwerty.kl
    97:key 56 ALT_LEFT

    Vendor_046d_Product_c532.kl
    81:key 56 ALT_RIGHT

    Vendor_22b8_Product_093d.kl
    73:key 56 ALT_LEFT

    Vendor_05ac_Product_0239.kl
    78:key 56 ALT_LEFT

    Vendor_18d1_Product_5018.kl
    78:key 56 ALT_LEFT

    Generic.kl
    78:key 56 ALT_LEFT
    ```

    对于“S”键的处理则都有在被 Alt 修饰时上屏`ß`(`\u00df`):

    ```console
    ~/keyboard/miui13/keychars ❯ rg -i 'KEY S ' --after-context=5 17:57:07
    qwerty2.kcm
    183:key S {
    184- label: 'S'
    185- number: '7'
    186- base: 's'
    187- shift, capslock: 'S'
    188- alt: '\u00df'

    qwerty.kcm
    186:key S {
    187- label: 'S'
    188- number: '7'
    189- base: 's'
    190- shift, capslock: 'S'
    191- alt: '4'

    Generic.kcm
    140:key S {
    141- label: 'S'
    142- base: 's'
    143- shift, capslock: 'S'
    144- alt: '\u00df'
    145-}

    Vendor_18d1_Product_5018.kcm
    140:key S {
    141- label: 'S'
    142- base: 's'
    143- shift, capslock: 'S'
    144- alt: '\u00df'
    145-}

    Virtual.kcm
    137:key S {
    138- label: 'S'
    139- base: 's'
    140- shift, capslock: 'S'
    141- alt: '\u00df'
    142-}
    ```

    MIUI 13 和 HyperOS 对于这些定义大差不差。没看出有什么大的不妥。顺便说下,MIUI 13 对于 Ctrl 在 IME 中也是获取不到后续按键的。似乎是 MIUI 13 直接一整个把至少这俩修饰键的处理全放在系统中拦截了(哪怕 Alt+某个 key 是完全没有 compose 行为的),就导致了 IME 看不到一点。
    kuanat
        3
    kuanat  
       1 天前
    @bczhc #2

    看你这个回复基本上就是系统的 bug 了。小米的软件 bug 多到离谱,而且大多数时候管杀不管埋……

    关键是从这个表现来看,在进入到 InputMethodService 之前就被拦截了,连拯救一下的机会都没有。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2684 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 13:24 · PVG 21:24 · LAX 05:24 · JFK 08:24
    ♥ Do have faith in what you're doing.