Problem running the GTK main loop in a separate thread (different from the main one).



Hi, I've been using GTK for a pretty long time but I've never used threads with it and I'm not able to properly run the GTK main loop in a separate thread.
More to the point if I create a window, for example, in a thread other than the GTK one, it becomes unresponsive. Other GTK calls (that don't create widgets) seem to work fine, however.
I've attached a sample program to show what I mean, the flag "create_in_gt" sets whether to create the widgets in the GTK thread or in the main one.

Is this normal behaviour, am I not supposed to do this, or is it a bug?

(NOTE: The first time I've sent this message it was detected as spam so I'll include the file instead of attaching it)

threadtest1.cpp:
#include <gtk/gtk.h>

const int create_in_gt = FALSE; // Whether to create the widgets in the GTK thread.
GtkWidget *win, *but;

// Creates a window with a button in it.
// This function will be called in the GTK thread if "create_in_gt" is TRUE
// or in the main thread otherwise.
int create_widgets(void*) {
    win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    but = gtk_button_new_with_label("My Button");

    gtk_container_add(GTK_CONTAINER(win),but);
    gtk_widget_show_all(win);
    return FALSE;
}

// The GTK thread function
void* gtkthread(void *) {
    gdk_threads_enter(); // GTK calls to follow - locking.

    // Inits gtk in this thread (I have tried initing it in both threads, the
    // result is the same.)
    gtk_init(NULL,NULL);

    // Creates the widgets if neccesary and then enters the main loop.
    if( create_in_gt ) create_widgets(NULL);
    gtk_main();

    gdk_threads_leave(); // GTK calls end here - unlocking
}

int main(int argc, char *argv[]) {
    g_thread_init(NULL); // Init threads in main thread.
    gdk_threads_init();

    // Creates the GTK thread.
    GThread *gt = g_thread_create(gtkthread, NULL, TRUE,NULL);

    // Waits 1 second, creates widgets if neccesary then, waits 2 more seconds.
    g_usleep( 1000000 );
    if( !create_in_gt )
        g_idle_add(create_widgets,NULL);
    g_usleep( 2000000 );

    gdk_threads_enter(); // Quits GTK safely.
    gtk_main_quit();
    gdk_threads_leave();

    g_thread_join(gt); // Waits for GTK to quit.

    return 0;
}

--
Cristi Cobzarenco


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