I have this code snippet , my desired str_ptr is not shown correctly , why ?
[...]
data* dip=g_new(data,RECENTS_COUNT+1);
gulong hid[RECENTS_COUNT+1];
gchar *str_ptr=NULL;
for(i=0; i<RECENTS_COUNT && recents_ptr[i] ; i++)
{
//str_ptr=g_strdup_printf ("si is %d\n",i); // TODO this works
// TODO this does not work:
str_ptr=g_strdup_printf("%s\n",gtk_recent_info_get_uri(recents_ptr[i]));
(dip+i)->str=str_ptr;
(dip+i)->window=mainwindow;
hid[i]=g_signal_connect_data
(G_OBJECT(recents_ptr[i]),
"activate"
,G_CALLBACK(show_message_caller),
(dip+i),
(GClosureNotify)g_free,
0);
assert(hid[i]>0);
[...]
void show_message ( data* mes_par)
{
GtkWidget* dialog;
gchar * message=mes_par->str;
GtkWidget* parent=GTK_WIDGET(mes_par->window);
dialog = gtk_message_dialog_new (GTK_WINDOW(parent),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
"Message: %s",
message);
// Destroy the dialog when the user responds to it (e.g. clicks a button)
g_signal_connect_swapped (dialog, "response",
G_CALLBACK (gtk_widget_destroy),
dialog);
gtk_widget_show_all (dialog);
return;
}
void show_message_caller(GtkWidget* choice,gpointer mes_par)
{
UNUSED(choice);
data *udp=mes_par;
show_message(udp);
return;
}
There isn’t enough context here, but you are treating recents_ptr[i] as both a GtkRecentInfo * (passing it to gtk_recent_info_get_uri()), and as an object with an activate signal. One of those must be wrong.
Also, the memory management with g_signal_connect_data() is incorrect. Your data was allocated as a block, so it can’t be freed individually, and you would leak the string from g_strdup_printf().
That should be rec_labels[i], not GTK_WIDGET(recents_ptr[i]). I would expect the GTK_WIDGET() cast to complain about that. Also, you could just create the menu items, add them to the menu, and connect the signals all in the same loop. That way, you wouldn’t need to keep the array of menu items at all.
You can’t free the memory right away because it needs to be valid when the callback fires. You can g_new0() a struct in each iteration of the loop and pass it to g_signal_connect_data() along with a free function that frees the contents and then the struct itself.
The root problem is that you are storing the return value of gtk_menu_item_new_with_label in rf_widget and recents_ptr[i], both of which are GtkRecentInfo *, not GtkWidget *. Your compiler should have warned about this (Maybe you need -Wall ?). Your original menu-building code works because the GTK_WIDGET() cast hides the incorrect type that is actually pointing to the correct object. However, you can’t use gtk_recent_info_get_uri() with recents_ptr[i], because that isn’t really the GtkRecentInfo, which you haven’t saved at all. This is why you get gibberish with the calls to gtk_recent_info_get_uri() when you build a second set of menu items (rec_labels) and when you populate the data structs.
Bigger picture: you can probably just use gtk_recent_chooser_menu_new() instead of most of this. If you want to build your own widgets, then use gtk_recent_manager_get_default() instead; there’s no reason to create a GtkRecentChooserMenu around it if you’re not going to use the menu.