2

I'm making an application using GTK4 in C language. I'm trying to connect some actions with menu items but such items are inactive, i.e., they are not clickable while they appear. I don't know a way to solve this problem so any help are appreciated.

A part of code is below.

#include <gtk/gtk.h>

int main(int argc, char **argv)
{
    int status;
    
    application = gtk_application_new("gtk.example", G_APPLICATION_FLAGS_NONE);
    g_signal_connect_swapped(application, "active" G_CALL_BACK(create_window), application);

    status = g_application_run(G_APPLICATION(application),argc,argv);
    g_object_unref(application);
    return status;
}

void create_window(GtkApplication *application)
{
    GMenu *menubar;
    GMenu *menu;
    GMenuItem *item;

    window = gtk_application_window_new(application);
    gtk_window_set_application(GTK_WINDOW(window),application);
    
    const GActionEntry entries[] =
    {
        {"close", quit}
    };
    g_action_map_add_action_entries(G_ACTION_MAP(application), entries, G_N_ELEMENTS(entries),NULL);

    menubar = g_menu_new();
    menu = g_menu_new();
    item = g_menu_item_new("Close", "app.close");
    g_menu_append_item(menu,item);
    g_object_unref(item);
    
    g_menu_append_submenu(menubar, "File", G_MENU_MODEL(menu));
    g_object_unref(menu);

    gtk_application_set_menubar(application, G_MENU_MODEL(menubar));
    gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(window),TRUE);
    gtk_window_present(GTK_WINDOW(window));        
}

static void quit(GSimpleAction *action, GVariant *parameter, gpointer data)
{
    g_print("You choose close action\n");
}

The result I got is below. Close is not clickable.

enter image description here

Michi
  • 5,175
  • 7
  • 33
  • 58
user
  • 153
  • 5

1 Answers1

3

There are so many problems with your code, that I have no Idea where I should start with.

Anyway, the main problem (but not the only one) it is here:

const GActionEntry entries[] =
{
    {"close", quit}
};

It should be like this:

const GActionEntry entries[] =
{
    {"close", quit, NULL, NULL, NULL, { 0, 0, 0 } }
};

Here is a working program:

#include <gtk/gtk.h>

void create_window ( GtkApplication *application );
static void quit   ( GSimpleAction *action, GVariant *parameter, gpointer data );

int main ( int argc, char **argv )
{
    GtkApplication *application;
    int status;

    /// ***
    application = gtk_application_new ( "gtk.example", G_APPLICATION_FLAGS_NONE );
    g_signal_connect_swapped ( application, "activate", G_CALLBACK ( create_window ), application );

    /// ***
    status = g_application_run ( G_APPLICATION ( application ), argc, argv );
    g_object_unref ( application );
    
    return status;
}

void create_window ( GtkApplication *application )
{
    GtkWidget *window;
    GMenu *menubar;
    GMenu *menu;
    GMenuItem *item;

    /// ***
    window = gtk_application_window_new ( application );
    gtk_window_set_application ( GTK_WINDOW ( window ), application );

    /// ***
    const GActionEntry entries[] =
    {
        {"close", quit, NULL, NULL, NULL, { 0, 0, 0 } }
    };
    
    /// **
    g_action_map_add_action_entries ( G_ACTION_MAP ( application ), entries, G_N_ELEMENTS ( entries ), NULL );

    /// ***
    menubar = g_menu_new();
    menu    = g_menu_new();
    item    = g_menu_item_new ( "Close", "app.close" );
    
    /// ***
    g_menu_append_item ( menu, item );
    g_object_unref ( item );

    /// ***
    g_menu_append_submenu ( menubar, "File", G_MENU_MODEL ( menu ) );
    g_object_unref ( menu );

    /// ***
    gtk_application_set_menubar ( application, G_MENU_MODEL ( menubar ) );
    gtk_application_window_set_show_menubar ( GTK_APPLICATION_WINDOW ( window ), TRUE );
    
    /// ***
    gtk_window_present ( GTK_WINDOW ( window ) );
}

static void quit ( GSimpleAction *action, G_GNUC_UNUSED GVariant *parameter, G_GNUC_UNUSED gpointer data )
{
    g_print ( "You choose `%s` action\n", g_action_get_name ( G_ACTION( action ) ) );
}

I am strongly suggesting you to check these Videos.

By the way, there is not active Signal, you need activate instead.

Michi
  • 5,175
  • 7
  • 33
  • 58
  • OK, my question is how to display the accelarator key combination? For example in your code for Close it would be like CTRL + Q – Joel May 31 '22 at 02:21
  • 1
    For anyone wondering, the `{ 0, 0, 0 }` as the final component of a `GActionEntry` is for its private `padding` field. It just avoids warnings when using strict compiler settings. See: https://stackoverflow.com/a/27539131/9959012 – 6equj5 Aug 03 '22 at 02:23