19

Could someone please compile and execute the small sample code I provided below? Please let me know if the shift key modifier works properly for you. This example is suppose to demonstrate the key press functionality in gtk. It works fine for simple key presses and even works with the control key modifier, but it does not work with the shift key modifier.

/*
 * 
 * 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; 
}

The output I am getting:

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

I get nothing when I press shift + s or shift + m, so it seems that I am not quite getting how the GDK_SHIFT_MASK should be used even though I have read the documentation and I have seen plenty of other examples where it appears to be used exactly the same way.

nomadicME
  • 1,389
  • 5
  • 15
  • 35

2 Answers2

26

The value of event->keyval when shift+s is pressed is GDK_S, not GDK_s. In other words, GDK has already interpreted the keyboard for you, giving you the symbol 'S', not 's'. The shift mask is still set, though. You can see this by adding a case for 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)
  {
....
ergosys
  • 47,835
  • 5
  • 49
  • 70
10

Just a heads up for people Using Gtk3 and using this code as base. The Macros changed and GDK_s is now GDK_KEY_s. Compiling this code as it is will not work. The full list of updated Keyvals is here: https://git.gnome.org/browse/gtk+/plain/gdk/gdkkeysyms.h

Enris Nogare
  • 129
  • 1
  • 7
  • This is not an answer and should be a comment on the post to which it responds. I hoped folk didn't just use code from SO posts wholesale as basis for their own... and those who did would quickly figure out the problem by reading errors and documentation... but I might be too optimistic there. So, this might well be useful. But it still isn't an answer. – underscore_d Sep 18 '16 at 07:35