Search code examples
cmultithreadinggtkpolling

How can I call a Gtk API from another thread?


I've written a C program in which I implemented some threads to make polling. When something happens in the thread I have to modify some Widgets created in main function. This program sometimes crashes when a thread tries to do an operation on a Widget, for example simply calling the function gtk_widget_hide, and I discovered that's because I must not call any GTK API from another thread.

How can I do what I've described before avoiding any crashes? Is it possible, considering I need threads?

That's an example of what my code does

static GtkWidget* widget;

void check_user_action(){
    while(!user_does_action){
        g_sleep(1);
    }

    gtk_widget_hide(main_widget);
}

void main(){
    widget = //I skip widget creation
    gtk_widget_show_all(widget);

    g_thread_new("check_user_action", check_user_action, NULL);

    //do something else
}

That's only an example, but assume the only way I have to check_user_action is with polling.


Solution

  • For your snippet you can pass the task to your main thread:

    gboolean my_hide_func(gpointer user_data)
    {
        gtk_widget *widget = (gtk_widget*) user_data;
        gtk_widget_hide(widget);
        return FALSE;
    }
    
    void check_user_action(){
        while(!user_does_action){
            g_sleep(1);
        }
        g_idle_add(my_hide_func, main_widget);
    }
    

    This will enqueue a request to call that function in the queue for the main thread running your GTK application.