2013-04-25 33 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') 
    ...