CEF Linux中,SendKeyEvent发送Ctrl+A时,会产生空的DOM key和 code

前端开发 2026-07-10

我在Linux上使用 CEF(OSR/无窗口),并配合一个 SDL2输入桥接

我想通过 CefBrowserHost::SendKeyEvent 将本地的 Ctrl+A快捷键 发送给聚焦中的编辑器(这不是一个基于JavaScript的选中文本变通方法,后者确实可用)。


当前做法

我按这个顺序发送4 个事件:

  1. Ctrl按下
  2. A按下
  3. A松开
  4. Ctrl松开
void App::SendCtrlA() {
    if (!client_ || !client_->GetBrowser() || !client_->GetBrowser()->GetHost())
        return;

    CefRefPtr<CefBrowserHost> host = client_->GetBrowser()->GetHost();
    CefKeyEvent ev;
    memset(&ev, 0, sizeof(ev));

    ev.type = KEYEVENT_RAWKEYDOWN;
    ev.windows_key_code = 17;
    ev.native_key_code = 17;
    ev.modifiers = EVENTFLAG_CONTROL_DOWN;
    ev.focus_on_editable_field = true;
    host->SendKeyEvent(ev);

    memset(&ev, 0, sizeof(ev));
    ev.type = KEYEVENT_RAWKEYDOWN;
    ev.windows_key_code = 65;
    ev.native_key_code = 65;
    ev.modifiers = EVENTFLAG_CONTROL_DOWN;
    ev.character = 1;
    ev.unmodified_character = 'a';
    ev.focus_on_editable_field = true;
    host->SendKeyEvent(ev);

    memset(&ev, 0, sizeof(ev));
    ev.type = KEYEVENT_KEYUP;
    ev.windows_key_code = 65;
    ev.native_key_code = 65;
    ev.modifiers = EVENTFLAG_CONTROL_DOWN;
    ev.focus_on_editable_field = true;
    host->SendKeyEvent(ev);

    memset(&ev, 0, sizeof(ev));
    ev.type = KEYEVENT_KEYUP;
    ev.windows_key_code = 17;
    ev.native_key_code = 17;
    ev.focus_on_editable_field = true;
    host->SendKeyEvent(ev);
}

我也会记录发送的内容,这些事件肯定已经传递给 SendKeyEvent()


页面中的JS日志

document.addEventListener('keydown', function(e){
  console.log(
    '[GSNDBG] kd'
    + ' key=' + JSON.stringify(e.key)
    + ' code=' + JSON.stringify(e.code)
    + ' ctrl=' + e.ctrlKey
    + ' shift=' + e.shiftKey
    + ' alt=' + e.altKey
    + ' meta=' + e.metaKey
    + ' keyCode=' + e.keyCode
    + ' which=' + e.which
    + ' target=' + (e.target && e.target.tagName)
  );
}, true);

观察到的结果

[GSNDBG] kd key="\u0000" code="" ctrl=false shift=false alt=false meta=false keyCode=0 which=0 target=DIV

问题

  • 事件 到达页面
  • 但DOM KeyboardEvent 实际上是 空的
  • ctrlKey
  • Ctrl+A 不会触发全选

疑问

  1. 在Linux上,对于像Ctrl+A这样的快捷键,正确填充 CefKeyEvent 的方式是什么?
  2. 具体来说,native_key_codeevent.type 应该是什么?
  3. 是否存在将SDL2的按键数据转换为有效的CEF/Chromium快捷键事件的标准或推荐做法?

解决方案

通过无窗口模式解决问题,这一模式是由CEF模块本身授权的。
在那种情况下,我可以使用原生的SDL输入方法。
JavaScript选项只是临时的变通方法。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章