I am trying to create a button which uses GtkAccelLabel
and at the time where the user press CTRL + Q
both callbacks ( first_clbk
and second_clbk
) should be called.
The program works fine, but the msg
created with g_strdup
does not get destroyed.
This happens because the function free_data
never gets called.
Here is a demo program:
#include <gtk/gtk.h>
static void free_data ( gchar *data, G_GNUC_UNUSED GClosure *clo )
{
g_print ( "The data memory was cleared\n" );
g_free ( data );
}
static void first_clbk ( const gchar *const msg )
{
g_print ( "%s\n", msg );
}
static void second_clbk ( gchar *msg )
{
g_print ( "\t%s\n", msg );
}
int main ( void )
{
GtkWidget *window;
GtkWidget *accelLabel;
GtkAccelGroup *accel_group;
GtkWidget *button;
/// ***
gtk_init ( NULL, NULL );
/// *** Create a new Window
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
gtk_window_set_default_size ( GTK_WINDOW ( window ), 400, 200 );
g_signal_connect ( window, "delete-event", gtk_main_quit, NULL );
g_signal_connect ( window, "destroy", gtk_main_quit, NULL );
/// ***
accel_group = gtk_accel_group_new ();
gtk_window_add_accel_group ( GTK_WINDOW ( window ), accel_group );
/// ***
button = gtk_button_new( );
g_object_set ( button, "margin", 100, NULL );
gtk_container_add ( GTK_CONTAINER ( window ), button );
g_signal_connect_swapped ( button, "clicked", G_CALLBACK ( first_clbk ), ( gpointer ) "You clicked the button" );
/// ***
accelLabel = gtk_accel_label_new ( "Quit" );
gtk_container_add ( GTK_CONTAINER ( button ), accelLabel );
gtk_accel_label_set_accel ( GTK_ACCEL_LABEL ( accelLabel ), GDK_KEY_q, GDK_CONTROL_MASK );
gtk_accel_label_set_accel_widget ( GTK_ACCEL_LABEL ( accelLabel ), button );
/// *** Create the msg with g_strdup
gchar *msg;
msg = g_strdup ( "You pressed CTRL + Q" );
/// *** create the closure callback
GClosure *closure_clbk;
closure_clbk = g_cclosure_new_swap ( G_CALLBACK ( second_clbk ), msg, ( GClosureNotify ) free_data );
/// *** connect the callback with the accel_group
gtk_accel_group_connect ( accel_group, GDK_KEY_q, GDK_CONTROL_MASK, 0, closure_clbk );
/// *** Set the accel closure
gtk_accel_label_set_accel_closure ( GTK_ACCEL_LABEL ( accelLabel ), closure_clbk );
/// *** add the accelerator
gtk_widget_add_accelerator ( button, "activate", accel_group, GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE );
/// ***
gtk_widget_show_all ( window );
gtk_main ();
}
Why free_data
never gets called?