Action with Boolean State

I am trying to create an action with state for a item with GMenu.

What I have so far works fine:
check_me

#include <gtk/gtk.h>

static void check_clbk ( GSimpleAction *action, G_GNUC_UNUSED GVariant *parameter, G_GNUC_UNUSED gpointer data )
{
    GVariant *action_state;
    action_state = g_action_get_state ( G_ACTION ( action ) );

    if ( g_variant_get_boolean ( action_state ) == FALSE )
    {
        g_print ( "Menu set\n" );
        g_simple_action_set_state ( action, g_variant_new_boolean ( TRUE ) );
    }
    else
    {
        g_print ( "\tMenu unset\n" );
        g_simple_action_set_state ( action, g_variant_new_boolean ( FALSE ) );
    }
}

static void startup ( GtkApplication *application )
{
    GMenu     *menu;
    GMenu     *subMenu;
    GMenuItem *item;

    GSimpleAction *state_action;
    GVariant *state;

    /// ***
    state = g_variant_new ( "b", TRUE );

    /// ***
    state_action = g_simple_action_new_stateful ( "check", NULL, state );
    g_action_map_add_action ( G_ACTION_MAP ( application ), G_ACTION ( state_action ) );

    /// ***
    g_signal_connect_swapped ( state_action, "activate", G_CALLBACK ( check_clbk ),  state_action );

    /// ***
    menu    = g_menu_new ();
    subMenu = g_menu_new();

    /// ***
    item = g_menu_item_new ( "Check me", "app.check" );
    g_menu_append_item ( subMenu, G_MENU_ITEM ( item ) );
    g_object_unref ( item );

    /// ***
    g_menu_append_submenu ( menu, "File",  G_MENU_MODEL ( subMenu ) );

    /// ***
    gtk_application_set_menubar ( application, G_MENU_MODEL ( menu ) );
    g_object_unref ( menu );
}

static void activate ( GtkApplication *app )
{
    GtkWidget *window;
    window = gtk_application_window_new ( app );

    gtk_window_set_application ( GTK_WINDOW ( window ), GTK_APPLICATION ( app ) );
    gtk_window_set_title ( GTK_WINDOW ( window ), "Check" );

    gtk_widget_show_all ( GTK_WIDGET ( window ) );
}

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

    app = gtk_application_new ( "org.gtk.example", G_APPLICATION_FLAGS_NONE );
    g_signal_connect_swapped ( app, "startup", G_CALLBACK ( startup ), app );
    g_signal_connect_swapped ( app, "activate", G_CALLBACK ( activate ), app );
    status = g_application_run ( G_APPLICATION ( app ), argc, argv );
    g_object_unref ( app );
    return status;
}

But it does not work if I replace :

GSimpleAction *state_action;
GVariant *state;

/// ***
state = g_variant_new ( "b", TRUE );

/// ***
state_action = g_simple_action_new_stateful ( "check", NULL, state );
g_action_map_add_action ( G_ACTION_MAP ( application ), G_ACTION ( state_action ) );

/// ***
g_signal_connect_swapped ( state_action, "activate", G_CALLBACK ( check_clbk ),  state_action );

with:

static const GActionEntry actions[] =
{
    { "check", NULL, "b", "true", check_clbk,  { 0, 0, 0 } }
};

g_action_map_add_action_entries ( G_ACTION_MAP ( application ), actions, G_N_ELEMENTS ( actions ), application );

check_me_02

The Item is not activated, what I am missing here?

I’m not a C speaker, but i wonder why you think “true” == True?

It’s GVariant-as-string so “true” is right for state

However if you look at the GtkApplication demo you’ll note you don’t need to provide a parameter type ("b") since parameters and state are different and boolean actions simply flip state when activated

static GActionEntry app_entries[] = {
  { "dark", activate_toggle, NULL, "false", change_theme_state }
};
1 Like

I see now. Thank you for your Time.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.