Re: CList segfault



Hello again,

On 25 Feb 2001 12:41:03 -0500 Owen Taylor <otaylor redhat com> wrote:
> 
> Daniel Elstner <daniel elstner gmx net> writes:
> 
> > I have some problems with GtkCList in extended selection mode,
> > reproduceable with the following steps:
> > 
> > 1. The user selects some rows _including_ the last one.
> > 2. The program will call gtk_clist_remove() for each selected row.
> > 3. The user changes the selection via mouse clicks before
> >    all rows are removed.
>
> Well, if you provide a test case, somebody could take a look.

Here's a little test program which triggers the segfault.

Thanks for your help,
Daniel
/*
 * GtkCList test program
 * by <daniel elstner gmx net>
 *
 * This little program demonstrates a bug in the GtkCList widget.
 * The button `Start removing' triggers a sequence of timeout signals
 * with 0.1 seconds interval.
 * Try the following:
 *
 * 1. fill the clist by pressing `Fill list'
 * 2. select some rows
 * 3. press `Start removing'
 * 4. while the removing is in progress, change the selection via mouse click
 *
 * If the last row is selected when the selection changes, you will get
 * a segmentation fault in resync_selection().
 */

#include <gtk/gtk.h>
#include <stdio.h>

GtkWidget *clist;
int idx;

gint delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{
    return FALSE;
}

void destroy (GtkWidget *widget, gpointer data)
{
    gtk_main_quit();
}

gint timeout_callback (gpointer data)
{
    if (idx < 0) return FALSE;

    g_print ("removing row %d\n", idx);
    gtk_clist_remove (GTK_CLIST(clist), idx);

    --idx;
    return TRUE;
}

void fill_clist (GtkWidget *widget, gpointer data)
{
    gchar buf1[64];
    gchar buf2[64];
    gchar *row[] = { buf1, buf2 };
    int i;

    g_print ("fill_clist\n");

    for (i=0; i<16; ++i) {
	sprintf (buf1, "Foo item %d", i);
	sprintf (buf2, "Bar item %d", i);
	gtk_clist_append (GTK_CLIST(clist), row);
    }
}

void start_removing (GtkWidget *widget, gpointer data)
{
    g_print ("start_removing\n");
    idx = 15;
    gtk_timeout_add (100, &timeout_callback, NULL);
}

int main (int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *hbox;
    GtkWidget *button_fill;
    GtkWidget *button_remove;
    gchar *titles[] = { "Foo", "Bar" };

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_usize (GTK_WIDGET(window), 300, 350);

    gtk_signal_connect (GTK_OBJECT(window), "delete_event",
			GTK_SIGNAL_FUNC (delete_event), NULL);
    gtk_signal_connect (GTK_OBJECT(window), "destroy",
			GTK_SIGNAL_FUNC (destroy), NULL);

    vbox = gtk_vbox_new (FALSE, 5);
    gtk_container_set_border_width (GTK_CONTAINER(vbox), 5);
    gtk_container_add (GTK_CONTAINER(window), vbox);

    clist = gtk_clist_new_with_titles (2, titles);
    gtk_clist_set_selection_mode (GTK_CLIST(clist), GTK_SELECTION_EXTENDED);
    gtk_clist_set_column_width (GTK_CLIST(clist), 0, 100);
    gtk_clist_set_column_width (GTK_CLIST(clist), 1, 100);
    gtk_box_pack_start (GTK_BOX(vbox), clist, TRUE, TRUE, 0);

    hbox = gtk_hbox_new (TRUE, 10);
    gtk_box_pack_start (GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

    button_fill = gtk_button_new_with_label ("Fill list");
    gtk_box_pack_start (GTK_BOX(hbox), button_fill, TRUE, TRUE, 0);
    gtk_signal_connect (GTK_OBJECT(button_fill), "clicked",
			GTK_SIGNAL_FUNC(fill_clist), NULL);

    button_remove = gtk_button_new_with_label ("Start removing");
    gtk_box_pack_start (GTK_BOX(hbox), button_remove, TRUE, TRUE, 0);
    gtk_signal_connect (GTK_OBJECT(button_remove), "clicked",
			GTK_SIGNAL_FUNC(start_removing), NULL);

    gtk_widget_show (button_fill);
    gtk_widget_show (button_remove);
    gtk_widget_show (hbox);
    gtk_widget_show (clist);
    gtk_widget_show (vbox);
    gtk_widget_show (window);

    gtk_main();
    return 0;
}


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