web-dev-qa-db-ja.com

単純なgtkキー押下イベントの例では、GDK_SHIFT_MASKは無視されているようです

誰かが私が以下に提供した小さなサンプルコードをコンパイルして実行してくれませんか? Shiftキーモディファイアが適切に機能するかどうかをお知らせください。この例は、gtkのキー押下機能を示すことを目的としています。単純なキーを押すだけで問題なく機能し、Ctrlキー修飾子でも機能しますが、Shiftキー修飾子では機能しません。

/*
 * 
 * compile command:
 * 
 * gcc keypress3.c -o keypress3  `pkg-config --libs --cflags gtk+-2.0`
 * 
 */

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

gboolean
on_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data);

int main (int argc, char *argv[])
{
  GtkWidget *window;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
  g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (on_key_press), NULL);

  gtk_widget_show_all (window);

  gtk_main ();

  return 0;
}

gboolean
on_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
  switch (event->keyval)
  {
    case GDK_p:
      printf("key pressed: %s\n", "p");
      break;
    case GDK_s:
      if (event->state & GDK_SHIFT_MASK)
      {
        printf("key pressed: %s\n", "shift + s");
      }
      else if (event->state & GDK_CONTROL_MASK)
      {
        printf("key pressed: %s\n", "ctrl + s");
      }
      else
      {
        printf("key pressed: %s\n", "s");
      }
      break;
    case GDK_m:
      if (event->state & GDK_SHIFT_MASK)
      {
        printf("key pressed: %s\n", "shift + m");
      }
      else if (event->state & GDK_CONTROL_MASK)
      {
        printf("key pressed: %s\n", "ctrl + m");
      }
      else
      {
        printf("key pressed: %s\n", "m");
      }
      break;

    default:
      return FALSE; 
  }

  return FALSE; 
}

私が得ている出力:

key pressed: m
key pressed: ctrl + m
key pressed: p
key pressed: ctrl + s
key pressed: s

Shift + sまたはShift + mを押しても何も表示されないため、ドキュメントを読んだり、GDK_SHIFT_MASKが使用されているように見える他の例をたくさん見たりしても、GDK_SHIFT_MASKの使用方法がよくわからないようです。まったく同じ方法です。

13
nomadicME

Shift + sが押されたときのevent->keyvalの値は、GDK_sではなくGDK_Sです。言い換えると、GDKはすでにキーボードを解釈しており、「s」ではなく「S」の記号を付けています。ただし、シフトマスクはまだ設定されています。これは、GDK_Sのケースを追加することで確認できます。

...
case GDK_S:  // add this line
case GDK_s:
  if (event->state & GDK_SHIFT_MASK)
  {
    printf("key pressed: %s\n", "shift + s");
  }
  else if (event->state & GDK_CONTROL_MASK)
  {
....
17
ergosys

Gtk3を使用し、このコードをベースとして使用している人々のために注意してください。マクロが変更され、GDK_s 今です GDK_KEY_s。このコードをそのままコンパイルしても機能しません。更新されたKeyvalsの完全なリストはここにあります: https://git.gnome.org/browse/gtk+/plain/gdk/gdkkeysyms.h

6
Enris Nogare