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
相关产品推荐
相关产品推荐

