首页 > 解决方案 > 在 Linux 上 GTK+3 的 GtkDrawingArea 中拦截 X11 KeyPress 事件

问题描述

GTK+ 版本:3.18.9

我用以下代码创建了一个绘图区域(GtkWidget)

content = gtk_drawing_area_new();
gtk_widget_set_can_focus(content, TRUE);
gtk_widget_add_events(content, GDK_ALL_EVENTS_MASK);
g_signal_connect(content, "draw", G_CALLBACK(&drawCallback), ctx);
gtk_widget_realize(content);

// Add a filter for interception
gdk_window_add_filter(content, gtk_widget_get_window(content),
  OnXEvent, NULL);

问题是当我点击wideget时,我得到了如下的XEvents序列:

LeaveNotify
FocusIn
EnterNotify
ButtonPress
FocusOut    // Lost focus!
ButtonRelease

FocusOut上方表示我们在单击后立即失去焦点。这意味着我们无法接收任何键盘事件,因为它们仅在焦点内可用。

这是GTK的限制吗?如果没有,是否有任何工具/方法可以找出哪个小部件/寡妇触发了 FocusOut?

参考:

gdk_window_add_filter

标签: gtkx11gtk3

解决方案


从 GTK+ 版本 3.18.9 开始,它使用一个额外的 X 窗口作为顶层窗口,并且任何键盘事件都由该窗口捕获。因此需要添加一个过滤器作为全局过滤器,即

gdk_window_add_filter(NULL, OnXEvent, NULL)

请注意,该 API在 GTK+ 4.x的此提交中被删除。


推荐阅读