cpopupgtkpopupmenu

C: How do I make context menus in gtk


How would I make a popup menu (I am using C and GTK+) using GTK. I tried using gtk_event_box and put my scrolled window, then the tree view widget in it. It did not work. I used the source code found here under the popup menu section.

Anything that works will do.


Solution

  • NOTE: This is for GTK3 only.

    When making a popup menu, the code that handles the popup needs to know when there is a click on the target entry. This is done through a signal handler, and when you are setting up the target widget.

    g_signal_connect_swapped(widget, “button-press-event”, G_CALLBACK(on_widget_clicked), data_to_pass_along);
    

    In on_widget_clicked you see whether or not the button press was a right click.

    void on_widget_clicked (gpointer data, GdkEvent *event)
    {
        struct widgets_placeholder widgets = data;
        const int RIGHT_CLICK = 3;
        GdkEventButton *bevent = (GdkEventButton *) event;
        if (bevent->button == RIGHT_CLICK)
        {
            if(widgets->popup == NULL)
                widgets->popup = create_popup_menu();
    
            gtk_menu_popup_at_pointer(GTK_MENU(popup), event);
        }
    }
    

    Gdk (GIMP Drawing Kit, part of GTK+ (GIMP ToolKit)) represents a right-click as 3; therefore it is declared that way. Because GTK+ generated error messages if event->button is compared to a number, in this case to 3, the GdkEvent passed along to the function is casted into a GdkEventButton variable, which is them compared to 3: if (bevent->button == RIGHT_CLICK) GdkEvent is designed for generic events, hence it is not possible to compare its button element (structure element) to an integer. GdkEventButton is specifically for buttons, and their events, and it has the capability to have its button element (structure element) compared to 3. And then popup is tested to see if it was already made, this speeds thing up. And now the magic code: gtk_menu_popup_at_pointer(GTK_MENU(popup), event); Notice here that the GdkEvent was passed, not GdkEventButton. This is due to the way this function was designed: it is not a mistake.

    I hope this will help people out with popup menus.