Crash in GtkTreeView (win64 gtk2.12)



Hi
For our application, we are managing some GtkTreeView(s). Our application works on several plateforms, including win32 and win64. For win32 we are using GTK 2.4 and for win64 we are using GTK2.12
We are encontering a pb that occurs on 64 bits only.
Below, is a sample file that simulate what is done in our application.
The crash scenario is
- Populate the tree
- Sort with "TYPE" column
- click on "Rebuild"

The crash does not always occur but it crashes approximatively once every 3 attempts.

The crash does not occur if we link with GTK 2.16, however for internal reason, we have to use GTK2.12

Does anyone know if a specific patch was introduced between GTK2.12 and GTK2.16? Or at least can anyone give us a hint (files, or functions to diff between version, ....)

Any help wil be appreciated because we are really stuck!

Thanks

PS:
This is the code:
------------------------------------------

#include <gtk/gtk.h>

#include <stdlib.h>

#include <string.h>

typedef struct _TreeItem TreeItem;

GtkTreeModel *model;

GtkTreeSelection *selection;

GtkTreeViewColumn *id_column;

static GtkTreeModel *create_and_fill_model(void);

void *create_view_model(GtkTreeView *view,GtkTreeModel *model);

struct _TreeItem

{

const gchar *name;

const gchar *id;

const gchar *type;

const gchar *subtype;

const gchar *entry;

TreeItem *children;

};

enum

{

Name=0,

ID,

Type,

SubType,

Color,

Pixbuf,

N_COLUMNS

};

static GdkColor color;

static TreeItem mats[]=

{

{"Shell","1","MAT","P_SHELL","",NULL},

{"Solid","2","MAT","P_SOLID","",NULL},

{NULL}

};

static TreeItem props[]=

{

{"P_SHELL","4","PROP","shell","",NULL},

{"P_SOLID","21","PROP","solid","",NULL},

{NULL}

};

static TreeItem comps[]=

{

{"PART_1","1","PART","SH3N","",NULL},

{"PART_2","12","PART","SHELL","",NULL},

{"PART_3","11","PART","SH3N","",NULL},

{"PART_4","9","PART","SHELL","",NULL},

{NULL}

};

static TreeItem rwalls[]=

{

{"RWALL_1","1","RWALL","PARAL","",NULL},

{"RWALL_2","5","RWALL","CYL","",NULL},

{"RWALL_3","9","RWALL","PARAL","",NULL},

{"RWALL_4","4","RWALL","CYL","",NULL},

{NULL}

};

static TreeItem toplevel[]=

{

{"PART","","","","",comps},

{"RWALL","","","","",rwalls},

{"MAT","","","","",mats},

{"PROPS","","","","",props},

{NULL}

};

static TreeItem modelexample[]=

{

{"Model","","","","",toplevel},

{NULL}

};

gint name_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)

{/* sorting names*/

char *first =NULL;

char *sec = NULL;

GtkTreeIter parent;

gtk_tree_model_get(model, a,Name, &first, -1);

gtk_tree_model_get(model, b,Name, &sec, -1);

if (gtk_tree_model_iter_has_child(model, a) || gtk_tree_model_iter_has_child(model, b))

return 0;

if( first == NULL || sec == NULL )

{

if( first==NULL && sec==NULL)

{

return 0;

}

return (first == NULL) ? -1 : 1;

}

return g_utf8_collate(first,sec);

}

gint id_compare_func (GtkTreeModel *model,

GtkTreeIter *a,

GtkTreeIter *b,

gpointer user_data)

{

char *first, *sec = NULL;

GtkTreeIter parent;

gtk_tree_model_get(model, a,ID, &first, -1);

gtk_tree_model_get(model, b,ID, &sec, -1);

/* no sort for root folder */

if (!gtk_tree_model_iter_parent(GTK_TREE_MODEL(model), &parent, a))

return 0;

int first_t, sec_t;

first_t = atoi(first);

sec_t = atoi(sec);

if (GTK_SORT_ASCENDING == gtk_tree_view_column_get_sort_order (id_column))

{

if (first_t < sec_t)

return -1;

else

return 1;

} else

{

if (first_t > sec_t)

return 1;

else

return -1;

}

return 0;

}

void dialog_popup(GtkWidget *window,GdkEvent *event,gpointer data)

{

GtkWidget *dialog;

GtkWidget *box;

GtkWidget *label;

dialog=gtk_dialog_new_with_buttons("Validate",GTK_WINDOW(window),GTK_DIALOG_MODAL,"Yes",GTK_RESPONSE_ACCEPT,"No",GTK_RESPONSE_CANCEL,NULL);

box=gtk_hbox_new(FALSE,5);

gtk_container_set_border_width(GTK_CONTAINER(box),20);

gtk_container_add(GTK_CONTAINER(GTK_DIALOG (dialog)-> vbox),box);

gtk_widget_show(box);

label=gtk_label_new("Are you sure to close?");

gtk_box_pack_start(GTK_BOX(box),label,TRUE,TRUE,0);

gtk_widget_show(label);

gint result=gtk_dialog_run(GTK_DIALOG(dialog));

switch (result)

{

case GTK_RESPONSE_ACCEPT:

gtk_widget_destroy(window);

default:

gtk_widget_hide(dialog);

}

}

void on_edit(GtkCellRendererText *cell,const gchar *path_string,const gchar *new_text,gpointer data)

{

GtkTreeModel *model = (GtkTreeModel *)data;

GtkTreePath *path = gtk_tree_path_new_from_string (path_string);

GtkTreeIter iter;

gboolean check;

gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));

gtk_tree_model_get_iter (model, &iter, path);

check=gtk_tree_model_iter_has_child(model,&iter);

if(check == FALSE)

{

gchar *old_text;

gtk_tree_model_get (model, &iter, column, &old_text, -1);

g_free(old_text);

gtk_tree_store_set (GTK_TREE_STORE(model), &iter, column,new_text, -1);

}

gtk_tree_path_free(path);

}

void on_clicked(GtkCellRenderer *cell,const gchar *path_string,guint x, guint y,gpointer data)

{

GtkWidget *color_dialog;

GtkColorSelection *colorselection;

gint response_for_color;

color_dialog=gtk_color_selection_dialog_new("Select");

colorselection=GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel);

gtk_color_selection_set_previous_color (colorselection, &color);

gtk_color_selection_set_current_color (colorselection, &color);

gtk_color_selection_set_has_palette (colorselection, TRUE);

response_for_color = gtk_dialog_run (GTK_DIALOG (color_dialog));

if (response_for_color == GTK_RESPONSE_OK)

{

gtk_color_selection_get_current_color (colorselection,&color);

g_object_set(GTK_CELL_RENDERER(cell),"cell-background-gdk",&color,NULL);

}

gtk_widget_destroy (color_dialog);

}

void show_tree_items(GtkWidget *widget,gpointer data)

{

GtkTreeView *view=(GtkTreeView *)data;

gtk_tree_view_expand_all(view);

}

void collapse_tree_items(GtkWidget *widget,gpointer data)

{

GtkTreeView *view=(GtkTreeView *)data;

gtk_tree_view_collapse_all(view);

}

void show_reverse(GtkWidget *widget,gpointer data)

{

GtkTreeView *view=(GtkTreeView *)data;

gtk_tree_view_expand_all(view);

GtkTreePath *path=gtk_tree_path_new_from_indices(0,0,-1);

gtk_tree_view_collapse_row(view,path);

}

void rebuild_treeStore(GtkWidget *widget,gpointer data)

{

GtkTreeView *view=(GtkTreeView *)data;

GtkTreeModel *treestore = gtk_tree_view_get_model(view);

gtk_tree_store_clear(GTK_TREE_STORE(treestore));

gtk_tree_view_set_model(view,NULL);

treestore = NULL;

if(treestore != NULL)

{

printf("TreeModel not NULL\n");

}

treestore = create_and_fill_model();

gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(GTK_TREE_STORE(treestore)),Type,GtkTreeIterCompareFunc(name_compare_func),NULL,NULL);

gtk_tree_view_set_model(view,treestore);

//redo the build to test

treestore = gtk_tree_view_get_model(view);

gtk_tree_store_clear(GTK_TREE_STORE(treestore));

gtk_tree_view_set_model(view,NULL);

treestore = NULL;

if(treestore != NULL)

{

printf("TreeModel not NULL\n");

}

treestore = create_and_fill_model();

gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(GTK_TREE_STORE(treestore)),Type,GtkTreeIterCompareFunc(name_compare_func),NULL,NULL);

gtk_tree_view_set_model(view,treestore);

gtk_tree_view_expand_all(view);



}

static GtkTreeModel *create_and_fill_model(void)

{ GtkTreeStore *store;

GtkTreeIter iter;

GdkPixbuf *icon1;

GError *error = NULL;

TreeItem *model=modelexample;

icon1 = gdk_pixbuf_new_from_file("C:\\home.xpm", &error);

store=gtk_tree_store_new(N_COLUMNS,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,GDK_TYPE_PIXBUF);

while(model->name)

{

TreeItem *model_properties=model->children;

gtk_tree_store_append(store,&iter,NULL);

gtk_tree_store_set(store,&iter,Name,model->name,ID,"",Type,"",SubType,"",-1);

while(model_properties->name)

{

TreeItem *props=model_properties->children;

GtkTreeIter child;

gtk_tree_store_append(store,&child,&iter);

gtk_tree_store_set(store,&child,Name,model_properties->name,ID,"",Type,"",SubType,"",-1);

while(props->name)

{

GtkTreeIter child_final;

gtk_tree_store_append(store,&child_final,&child);

gtk_tree_store_set(store,&child_final,Name,props->name,ID,props->id,Type,props->type,SubType,props->subtype,-1);

props++;

}

model_properties++;

}

model++;

}

return GTK_TREE_MODEL (store);

}

void *create_view_model(GtkTreeView *view,GtkTreeModel *model)

{

gint col_offset;

GtkCellRenderer *renderer;

GtkTreeViewColumn *column;

renderer=gtk_cell_renderer_text_new();

g_object_set(renderer,"editable",TRUE,NULL);

//g_signal_connect(renderer,"edited",G_CALLBACK(on_edit),model);

g_object_set_data(G_OBJECT(renderer),"column",GINT_TO_POINTER(Name));

col_offset=gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),-1,"Name",renderer,"text",Name,NULL);

column=gtk_tree_view_get_column(GTK_TREE_VIEW(view),col_offset - 1);

gtk_tree_view_column_set_sort_column_id(column,Name);

gtk_tree_view_column_set_sort_indicator(column,TRUE);

gtk_tree_view_column_set_resizable(column,TRUE);

gtk_tree_view_column_set_reorderable(column,TRUE);

gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 10);

gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(GTK_TREE_STORE(model)),Name,GtkTreeIterCompareFunc(name_compare_func),NULL,NULL);

renderer=gtk_cell_renderer_text_new();

g_object_set(renderer,"editable",TRUE,NULL);

//g_signal_connect(renderer,"edited",G_CALLBACK(on_edit),model);

g_object_set_data(G_OBJECT(renderer),"column",GINT_TO_POINTER(ID));

col_offset=gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),-1,"ID",renderer,"text",ID,NULL);

id_column=gtk_tree_view_get_column(GTK_TREE_VIEW(view),col_offset - 1);

gtk_tree_view_column_set_sort_column_id(id_column,ID);

gtk_tree_view_column_set_sort_indicator(id_column,TRUE);

gtk_tree_view_column_set_resizable(id_column,TRUE);

gtk_tree_view_column_set_reorderable(id_column,TRUE);

gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(id_column),GTK_TREE_VIEW_COLUMN_FIXED);

gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (id_column),50);

gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(GTK_TREE_STORE(model)),ID,GtkTreeIterCompareFunc(id_compare_func),NULL,NULL);

renderer=gtk_cell_renderer_text_new();

g_object_set(renderer,"editable",TRUE,NULL);

//g_signal_connect(renderer,"edited",G_CALLBACK(on_edit),model);

g_object_set_data(G_OBJECT(renderer),"column",GINT_TO_POINTER(Type));

col_offset=gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),-1,"Type",renderer,"text",Type,NULL);

column=gtk_tree_view_get_column(GTK_TREE_VIEW(view),col_offset - 1);

gtk_tree_view_column_set_sort_column_id(column,Type);

gtk_tree_view_column_set_sort_indicator(column,TRUE);

gtk_tree_view_column_set_resizable(column,TRUE);

gtk_tree_view_column_set_reorderable(column,TRUE);

gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column),GTK_TREE_VIEW_COLUMN_FIXED);

gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column),60);

gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(GTK_TREE_STORE(model)),Type,GtkTreeIterCompareFunc(name_compare_func),NULL,NULL);

renderer=gtk_cell_renderer_text_new();

g_object_set(renderer,"editable",TRUE,NULL);

//g_signal_connect(renderer,"edited",G_CALLBACK(on_edit),model);

g_object_set_data(G_OBJECT(renderer),"column",GINT_TO_POINTER(SubType));

col_offset=gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),-1,"SubType",renderer,"text",SubType,NULL);

column=gtk_tree_view_get_column(GTK_TREE_VIEW(view),col_offset - 1);

gtk_tree_view_column_set_sort_column_id(column,SubType);

gtk_tree_view_column_set_sort_indicator(column,TRUE);

gtk_tree_view_column_set_resizable(column,TRUE);

gtk_tree_view_column_set_reorderable(column,TRUE);

gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column),GTK_TREE_VIEW_COLUMN_FIXED);

gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 50);

return 0;

}

static gint select_view(GtkWidget *widget,GdkEvent *event,gpointer data)

{

if (event->button.button == 3) {

GdkEventButton *bevent = (GdkEventButton *) event;

gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL,bevent->button, bevent->time);

return TRUE;

}

return FALSE;

}

void make_bold(GtkWidget *widget,GdkEvent *event,gpointer data)

{

GtkTreeIter iter;

gtk_tree_selection_get_selected(selection,&model,&iter);

}

GtkWidget *create_menu(GtkTreeView *view)

{

GtkWidget *select_menu,*item;

select_menu=gtk_menu_new();

item=gtk_menu_item_new_with_label("Make Bold");

gtk_menu_shell_append(GTK_MENU_SHELL(select_menu),item);

g_signal_connect_swapped(G_OBJECT(item),"activate",G_CALLBACK(make_bold),NULL);

gtk_widget_show(item);

g_signal_connect_swapped(G_OBJECT(view),"button-press-event",G_CALLBACK(select_view),select_menu);

return select_menu;

}

int main(int argc,char *argv[])

{ GtkWidget *window;

GtkWidget *vbox,*hbox;

GtkWidget *toolbar;

GtkWidget *first;

GtkWidget *icon1,*icon2,*icon3;

GtkWidget *view;

GtkWidget *menu;

color.red= 0;

color.blue= 65535;

color.green= 0;

gtk_init(&argc,&argv);

window=gtk_window_new(GTK_WINDOW_TOPLEVEL);

g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(dialog_popup),NULL);

gtk_window_set_default_size(GTK_WINDOW(window),600,350);

vbox=gtk_vbox_new(FALSE,0);

gtk_container_add(GTK_CONTAINER(window),vbox);

hbox=gtk_hbox_new(FALSE,0);

gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);

model=create_and_fill_model();

view=gtk_tree_view_new_with_model(model);

gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(view),TRUE);

selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(view));

gtk_tree_selection_set_mode(selection,GTK_SELECTION_EXTENDED);

menu=create_menu(GTK_TREE_VIEW(view));

create_view_model(GTK_TREE_VIEW(view),model);

gtk_container_add(GTK_CONTAINER(vbox),view);

icon1=gtk_image_new_from_stock(GTK_STOCK_APPLY,GTK_ICON_SIZE_SMALL_TOOLBAR);

icon2=gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE,GTK_ICON_SIZE_SMALL_TOOLBAR);

icon3=gtk_image_new_from_stock(GTK_STOCK_REDO,GTK_ICON_SIZE_SMALL_TOOLBAR);

GtkWidget *icon4 = gtk_image_new_from_stock(GTK_STOCK_REFRESH,GTK_ICON_SIZE_SMALL_TOOLBAR);

toolbar=gtk_toolbar_new();

gtk_box_pack_start(GTK_BOX(hbox),toolbar,FALSE,FALSE,0);

gtk_widget_show(toolbar);

gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),"Show","Show the contents","show",icon1,GTK_SIGNAL_FUNC(show_tree_items),view);

gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),"No Show","Hide the contents","hide",icon2,GTK_SIGNAL_FUNC(collapse_tree_items),view);

gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),"Reverse","Show the reverse","reverse",icon3,GTK_SIGNAL_FUNC(show_reverse),view);

gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),"Rebuild","Destroy & Rebuild Tree Store","rebuild",icon4,GTK_SIGNAL_FUNC(rebuild_treeStore),view);

gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),GTK_TOOLBAR_BOTH_HORIZ);

gtk_window_set_title(GTK_WINDOW(window),"Tree");

gtk_widget_show_all(window);

gtk_main();

}





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]