cgtksignals

When are GTK signals emitted


Given a signal connected from the user to a callback function, the gtk_main thread sleeps until the signal is emitted. I searched for details on how or when it is emitted, but couldn't find any info that I don't know.

More specifically is it emitted asynchronously so that I can invoke the signal in the middle of some function or it waits for the particular function to return first? Emitting the "switch-page" signal (for example with gtk_notebook_remove_page()) from within GThread may have odd effect as the events happen in the main thread and I cannot guarantee that gtk_notebook_remove_page() is executed in the main context as if g_main_context_invoke() is used? But what if I manually emit the signal with g_signal_emit() inside the thread (if the signal is emitable on that way)?


Solution

  • First of all, gtk mainloop is not thread safe. It's UB to call any gtk functions from threads other than mainloop.

    Detailed description can be found here, but in short: mainloop doesn't sleep or wait for signals. It's always iterating and if it sees, that user pressed a button, it emits a signal.

    Personally I use functions of this kind, which are g_timeout_add'ed:

    static gboolean
    redrawer (gpointer data)
    {
       MyObj *self = data;
    
       if (g_atomic_int_get (&self->priv->request_redraw)
         gtk_widget_queue_draw (GTK_WIDGET (self));
    
      return G_SOURCE_CONTINUE;
    }
    

    Edit: a bit later I found out, that g_idle_add is thread-safe so this function could be rewritten without explicit checking of request_redraw flag:

    static void
    callback_which_initiates_redraw (gpointer data)
    {
       MyObj *self = data;
       g_idle_add (gtk_widget_queue_draw, self);
    }
    

    More specifically is it emitted asynchronously so that I can invoke the signal in the middle of some function or it waits for the particular function to return first?

    It waits. While you are in main loop, nothing is asyncronous.

    Emitting the "switch-page" signal (for example with gtk_notebook_remove_page()) from within GThread may have odd effect as the events happen in the main thread and I cannot guarantee that gtk_notebook_remove_page() is executed in the main context as if g_main_context_invoke() is used? But what if I manually emit the signal with g_signal_emit() inside the thread (if the signal is emitable on that way)?

    I don't quite understand these 2 questions, but again: calling gtk functions not from mainloop is UB.