Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In simple gtk key press event example, GDK_SHIFT_MASK seems to be ignored

Tags:

c

gtk2

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.

like image 361
nomadicME Avatar asked Apr 13 '12 03:04

nomadicME


2 Answers

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)
  {
....
like image 154
ergosys Avatar answered Sep 19 '22 11:09

ergosys


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

like image 32
Enris Nogare Avatar answered Sep 22 '22 11:09

Enris Nogare