I have two GTK windows
Normal (main) window that runs animation, draws stuff in callback registered by gtk_widget_add_tick_callback()
.
At some point secondary window is created that runs modal loop:
void show_modal()
{
GtkWindow* gw = gtkwindow(this);
if( parent() )
gtk_window_set_transient_for(gw, gtkwindow( parent() ));
gtk_widget_show(GTK_WIDGET(gw));
gtk_window_set_modal(gw,TRUE);
gtk_window_set_keep_above(gw,TRUE);
this->update_window_state(gool::WINDOW_SHOWN);
while( this->is_valid_window() )
{
if(this->_window_state == WINDOW_HIDDEN) break;
if(this->_window_state == WINDOW_STATE_NA) break;
gtk_main_iteration(); // gtk_main_iteration_do(true);
}
}
Problem: Animation in main window works fine until show_modal()
is invoked. It appears as gtk_main_iteration();
blocks ticks added by gtk_widget_add_tick_callback()
function. As soon as I close secondary window and so while() {gtk_main_iteration();}
loop exits then animations in main window start running again.
Any idea of how to make "animation friendly" modal loops in GTK?
UPDATE: it appears as gtk_main_iteration();
blocks not only ticks but any updates of any windows other than "current" - they are simply frozen. What is the reasoning of such GTK behavior?
UPDATE #2:
gtk_dialog_run();
behaves exactly as gtk_main_iteration();
- locks any updates on any window in process other than active window.
It seems to be by definition: link
gboolean gtk_main_iteration (void);
Runs a single iteration of the mainloop. If no events are waiting to be processed GTK+ will block until the next event is noticed. If you don’t want to block look atgtk_main_iteration_do()
or check if any events are pending withgtk_events_pending()
first.
The explanation suggests to use gtk_main_iteration_do(FALSE)
if you don't want blocking:
gboolean gtk_main_iteration_do (gboolean blocking);
Runs a single iteration of the mainloop. If no events are available either return or block depending on the value ofblocking
:TRUE
if you want GTK+ to block if no events are pending
As for gtk_dialog_run
: it also blocks by design link
gint gtk_dialog_run (GtkDialog *dialog);
Blocks in a recursive main loop until the dialog either emits the “response” signal, or is destroyed.[...]
I read about people solving this using multiple threads: handle the GUI in the main thread and do background work in another one. There's an article about it here that might be useful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With