Migration Details Checklist

Implement GtkWidget::popup_menu
Use GdkEventExpose.region
Test for modifier keys correctly
Use named icons

This chapter includes a checklist of smaller things you need to do to ensure that your programs are good citizens in the GTK+ world. By paying attention to the points in the checklist, you ensure that many automatic features of GTK+ will work correctly in your program.

Implement GtkWidget::popup_menu

Why.  By handling this signal, you let widgets have context-sensitive menus that can be invoked with the standard key bindings.

The “popup-menu” signal instructs the widget for which it is emitted to create a context-sensitive popup menu. By default, the key binding mechanism is set to emit this signal when the Shift+F10 or Menu keys are pressed while a widget has the focus. If a widget in your application shows a popup menu when you press a mouse button, you can make it work as well through the normal key binding mechanism in the following fahion:

  1. Write a function to create and show a popup menu. This function needs to know the button number and the event's time to pass them to gtk_menu_popup(). You can implement such a function like this:

    static void
    do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
    {
      GtkWidget *menu;
      int button, event_time;
    
      menu = gtk_menu_new ();
      g_signal_connect (menu, "deactivate",
                        G_CALLBACK (gtk_widget_destroy), NULL);
    
      /* ... add menu items ... */
    
      if (event)
        {
          button = event->button;
          event_time = event->time;
        }
      else
        {
          button = 0;
          event_time = gtk_get_current_event_time ();
        }
    
      gtk_menu_attach_to_widget (GTK_MENU (menu), my_widget, NULL);
      gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
                      button, event_time);
    }
            
  2. In your “button-press-event” handler, call this function when you need to pop up a menu:

    static gboolean
    my_widget_button_press_event_handler (GtkWidget *widget, GdkEventButton *event)
    {
      /* Ignore double-clicks and triple-clicks */
      if (gdk_event_triggers_context_menu ((GdkEvent *) event) &&
          event->type == GDK_BUTTON_PRESS)
        {
          do_popup_menu (widget, event);
          return TRUE;
        }
    
      return FALSE;
    }
            
  3. Implement a handler for the “popup-menu” signal:

    static gboolean
    my_widget_popup_menu_handler (GtkWidget *widget)
    {
      do_popup_menu (widget, NULL);
      return TRUE;
    }
            

If you do not pass a positioning function to gtk_menu_popup(), it will show the menu at the mouse position by default. This is what you usually want when the menu is shown as a result of pressing a mouse button. However, if you press the Shift+F10 or Menu keys while the widget is focused, the mouse cursor may not be near the widget at all. In the example above, you may want to provide your own menu-positioning function in the case where the event is NULL. This function should compute the desired position for a menu when it is invoked through the keyboard. For example, GtkEntry aligns the top edge of its popup menu with the bottom edge of the entry.

For the standard key bindings to work, your widget must be able to take the keyboard focus. In general, widgets should be fully usable through the keyboard and not just the mouse. The very first step of this is to ensure that your widget can receive focus, using gtk_widget_set_can_focus().