2013-04-25 34 views
1

我想抓住用户键在GUI窗口上按下Ctrl + d以退出。我的代码如下所示:GDK信号,按键和关键蒙版

static gboolean 
callback(GtkWidget *widget, 
     GdkEventKey *event, 
     gpointer data) 
{ 
    if(event->state == GDK_CONTROL_MASK && event->keyval == 'd') 
     gtk_main_quit(); 

    return FASLE; 
} 

这适用于我的笔记本电脑(Ubuntu 11.04,gcc 4.5.2,libgtk 2.24.4)。但是当我在一个较新的系统(Ubuntu 12.10,gcc 4.7.2,libgtk 2.24.13)上做同样的事情时,它不起作用。

我的if语句之前加入g_print("%u\n", event->state);,它表明,当我按下Ctrl,所述event->state是20而不是4或1 < < 2的文件中。如果我将GDK_CONTROL_MASK更改为20,则它适用于较新的系统,但不适用于旧系统。有人请告诉我为什么会发生这种情况,以及如何解决这个问题。

回答

4

event->statebitmap,这意味着值20并不意味着“20而不是4”,而是“同时4和16”。根据标题,值16(1 << 4)对应于修改器MOD2,该修改器可能对应于便携式计算机上存在的钥匙fn

一个简单的解决方法是使用&操作检查控制而忽略了其他修饰符:

if (event->state & GDK_CONTROL_MASK && event->keyval == 'd') 

,这将在两个系统上运行。

+0

MOD2是许多系统上的数字锁。所以掩盖这一点是有道理的。但只检查是否设置了CONTROL意味着它也会将Ctrl + Alt + D,Ctrl + Shift + D等视为Ctrl + D,这也不理想。 – Mikel 2017-10-02 21:51:12

0

发生这种情况是因为state还包含修饰符,如Caps Lock和Num Lock。

该解决方案记录在https://developer.gnome.org/gtk3/stable/checklist-modifiers.html

使用gtk_accelerator_get_default_mod_mask()来获取,也加速键(控制,Alt键,Shift键,超,超,和元)的修饰符的位图,然后按位和事件状态,例如:

GdkModifierType accel_mask = gtk_accelerator_get_default_mod_mask(); 

if (event->state & accel_mask == GDK_CONTROL_MASK && event->keyval == 'd') 
    ...