GNOME Bugzilla – Bug 318676
gtkfilechooserdefault should not use gtk_dialog_run
Last modified: 2017-08-15 14:43:01 UTC
In the new gedit we want to make toplevels very indipendent (hiding the fact that it's the same app running) and thus we try to avoid gtk_dialog_run, and we explicitely set the window group when displaying a modal dialog so that the dialog it's modal only to it's parent and doesn't block the whole app. However gtkfilechooserdefault.c pops up confirmation dialogs using gtk_dialog_run() and this introduces weird behaviors. In particular, if the "location" dialog is displayed, all the other file choosers of the app are blocked. In the case you have two or more file choosers displaying the "overwrite confirmation" dialog, you can not interact with them on an individual manner. The root of the problem is that in some cases we end running two or more gtk_dialog_run at the same time and this clearly does not work. Note that gtkfilechooserdefault.c is the only place where gtk_dialog_run is called inside gtk. I guess we should not do that.
Sounds easy to fix? This is a request for guidance :).
Paolo ? -- This message is brought to you by your beloved Bugs cleaning team.
Hey Paolo, Could you give some guidance on this bug, it seems Diego is just waiting for you to fix the problem :)
well, you have to look for places where gtk_dialog_run is used in gtk and replace them with a real modal dialog + connect to response etc
Actually: gtk/gtkfilechooserdefault.c: gtk_dialog_run (GTK_DIALOG (dialog)); gtk/gtkfilechooserdefault.c: response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk/gtkprintoperation-unix.c: response = gtk_dialog_run (GTK_DIALOG (pd)); gtk/gtkprintoperation-unix.c: response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk/gtkprintunixdialog.c: response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk/gtkrecentchooserdefault.c: gtk_dialog_run (GTK_DIALOG (dialog)); gtk/gtk.symbols:gtk_dialog_run gtk/gtkwidget.c: * response = gtk_dialog_run (GTK_DIALOG (dialog)); So the correct thing would be to create the dialog but use _show() instead so it doesn't block anything? That?
yes, use show and connect to the response signal. Note that those dialogs should *still* be modal, they just should not use gtk_dialog_run since it causes a recursive main loop that van block also unrelated windows
I'd like to see a small, self-contained example of this. Could you please cook a little program (say, gtk+/tests/testfilechoosermodality.c) that creates two toplevel windows in different window groups, and then pops up file choosers for each of them? [gtk_dialog_run() should definitely be made usable by different window groups --- maybe there is just a bug in there?]
from irc federico asks: "pbor_: I know we have had this conversation before, but I have a turkey's memory... can you post to the bugs some details of why gtk_dialog_run() doesn't work for multiple windows (even window groups)?" Since I have memory which is worse of federico's I do not recall all details either, but I am pretty sure we discussed this with mclasen etc. If I recall correctly, gtk_dialog_run starts another gtk main loop, which means all events are processed by this main loop until it exits. When a gtk_dialog_run is running all other windows are blocked, no matter which window group are in. Window groups only matters when creating a modal dialog *without* using an inner main loop, since in that case you can specify that the dialog is modal only to a specific window group.
Other issue that I've been reported to happen is that while there is a dialog active that's been shown with gtk_dialog_run(), a user code call to gtk_main_quit(), intended to quit the application main loop, will result in only the dialog's main loop being quit, as it's the innermost. That sounds to me like a good reason for library code to avoid using gtk_dialog_run(). (note: haven't reproduced this, I'm only describing a problem I've been reported)
Created attachment 143803 [details] Test case using gtk_dialog_run() This is a test case I wrote some time ago to explain how gtk_dialog_run() works It opens three toplevel windows in different window groups, each one with a button that pops up a GtkDialog using gtk_dialog_run() Open dialog 1, then open dialog 2, then try to close dialog 1. You'll see that it won't disappear until you close dialog 2.
Created attachment 143804 [details] Test case without gtk_dialog_run() And this is the same test case, but without gtk_dialog_run(). This one works fine.
(In reply to comment #9) > Other issue that I've been reported to happen is that while there is > a dialog active that's been shown with gtk_dialog_run(), a user code > call to gtk_main_quit(), intended to quit the application main loop, > will result in only the dialog's main loop being quit, as it's the > innermost. That sounds to me like a good reason for library code to > avoid using gtk_dialog_run(). That's not what happens. gtk_main_quit() quits the application's main loop, but the app will keep running until you close the dialog. You can check it out using my first test case if you add this call right before gtk_main(): gdk_threads_add_timeout_seconds (5, (GSourceFunc) gtk_main_quit, NULL);
marking as a time travelling duplicate of this one, which proposes to deprecate gtk_dialog_run() and nested main loops overall: *** This bug has been marked as a duplicate of bug 659007 ***