You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu下如何用C++、GDK/XKB获取活跃键盘的名称?

获取活跃键盘布局名称(C++/GDK/XKB实现)

方法一:基于GDK的上层实现

GDK(GTK的底层图形库)提供了封装好的接口,适合基于GTK/GDK的应用程序直接调用,无需直接操作X11底层。

代码示例

#include <gdk/gdk.h>
#include <string>

std::string get_active_keyboard_layout() {
    // 获取默认显示设备
    GdkDisplay* display = gdk_display_get_default();
    if (!display) return "";

    // 获取当前键盘映射
    GdkKeymap* keymap = gdk_keymap_get_for_display(display);
    if (!keymap) return "";

    // 获取当前活跃布局的索引
    gint current_layout_idx = gdk_keymap_get_current_layout(keymap);
    // 获取所有布局的名称列表
    const gchar** layout_names = gdk_keymap_get_layout_names(keymap);

    // 校验索引有效性并返回名称
    if (layout_names && current_layout_idx >= 0 && layout_names[current_layout_idx]) {
        return std::string(layout_names[current_layout_idx]);
    }

    return "";
}

// 若需要友好的显示名称(如"German"而非"de"),可使用以下扩展函数
std::string get_active_keyboard_layout_description() {
    GdkDisplay* display = gdk_display_get_default();
    if (!display) return "";

    GdkKeymap* keymap = gdk_keymap_get_for_display(display);
    if (!keymap) return "";

    gint current_layout_idx = gdk_keymap_get_current_layout(keymap);
    const gchar** layout_descs = gdk_keymap_get_layout_descriptions(keymap);

    if (layout_descs && current_layout_idx >= 0 && layout_descs[current_layout_idx]) {
        return std::string(layout_descs[current_layout_idx]);
    }

    return "";
}

编译说明

编译时需要链接GTK/GDK库,命令如下:

g++ -o keyboard_layout keyboard_layout.cpp `pkg-config --cflags --libs gtk+-3.0`

方法二:基于XKB的底层实现

如果你的程序不依赖GTK/GDK,可直接使用XKB的X11底层API,直接与X服务器交互获取布局信息。

代码示例

#include <X11/XKBlib.h>
#include <string>

std::string get_active_xkb_layout() {
    // 打开X显示连接
    Display* dpy = XOpenDisplay(nullptr);
    if (!dpy) return "";

    // 获取当前XKB状态(包含活跃布局组)
    XkbStateRec state;
    XkbGetState(dpy, XkbUseCoreKbd, &state);

    // 获取XKB键盘描述符
    XkbDescPtr xkb_desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
    if (!xkb_desc) {
        XCloseDisplay(dpy);
        return "";
    }

    std::string layout_name;
    // 校验组索引有效性并读取布局名称
    if (state.group < xkb_desc->num_groups && xkb_desc->names->groups[state.group]) {
        layout_name = xkb_desc->names->groups[state.group];
    }

    // 释放资源
    XkbFreeKeyboard(xkb_desc, XkbAllComponentsMask, True);
    XCloseDisplay(dpy);

    return layout_name;
}

编译说明

编译时需要链接X11和XKB库:

g++ -o xkb_layout xkb_layout.cpp -lX11 -lXkbfile

注意事项

  • GDK方法需要确保程序已初始化GDK环境(可通过gdk_init(&argc, &argv)完成),否则无法获取显示设备。
  • XKB方法仅适用于Xorg环境,Wayland下可能需要使用Wayland对应的输入框架接口(如libinput)。
  • 返回的布局名称通常为ISO语言代码(如de代表德语、fr代表法语),部分场景下可能包含后缀(如de(nodeadkeys)),可根据需求对字符串进行裁剪处理。

内容的提问来源于stack exchange,提问作者user3443063

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 16:20:28