GNOME Bugzilla – Bug 327243
GtkFileChooserButton emits two "selection-changed" signal during initialization
Last modified: 2013-09-23 20:56:37 UTC
Here's some (simplified version of) code from the panel: ... image = panel_profile_get_background_image (dialog->toplevel); if (!image || !image[0]) gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (dialog->image_chooser)); else gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog->image_chooser), image); if (image) g_free (image); g_signal_connect_swapped (dialog->image_chooser, "selection-changed", G_CALLBACK (panel_properties_dialog_image_changed), dialog); ... gtk_widget_show (dialog->properties_dialog); When the dialog is shown and if the image is not null, two "selection-changed" signals are sent: + when the first one is sent, we can see that nothing is selected (gtk_file_chooser_get_filename() returns NULL) + when the second is sent, we have the original path that we provided with gtk_file_chooser_set_filename() We shouldn't see those signals because we connected to the "selection-changed" signal after we set the selected file. But it seems there's a timeout somewhere making this possible.
Looking quickly at gtkfilechoosedefault.c, I'm making a rough guess: the selection-changed signal should not be emitted unless we're in LOAD_FINISHED state. (disclaimer: I don't know the code, so this might be totally wrong)
cc myself, affected by the bug
Kris, this looks like it is due to your async changes.
I think the first selection-changed is from the tree view realizing (since selection-changed is emitted everytime the file chooser dialog receives GtkTreeSelection::changed); the second one should be from actually selecting the file, this is postponed until the folder finished loading. [Note that this bug did not appear because of the async changes since it was already there with 2.8.x and filed before we merged the async code.]
Does this still happen in 2.10 or trunk? Is this the same bug where someone wants to use "selection-changed" on GtkFileChooserButton instead of "file-set"?
yes
*** Bug 347541 has been marked as a duplicate of this bug. ***
Would a "selection-changed" be fired also for programatic 'set_filename' calls? In Banshee bug 443027, we've been doing: 1. button = new GtkFileChooserButton *and immediately following* 2. button.SetFilename("/full/path/to/folder") which resulted in *4* selection-changed events. Also it should be noted that most of the times (inconsistently) button.GetFilename resulted in "/full/path/to". That is, we never switched to the desired /full/path/to/folder. The racy behavior we've seen here makes me wonder if it's also an artifact of the async code.
Yes, this does still happen with GTK+ 2.10.13. And it breaks the preferences dialog in GIMP 2.3.
Created attachment 95235 [details] test case GtkFileChooserButton is broken. - Run the attached test. - Click on the button. - Navigate to a directory containing two dozen files or so (it's harder to reproduce if the directory only contains a few files). - Select a file and click on Open: the selected file is reflected in the button. So far so good. - Click on the button again: another file (I'll name it file1) is selected, seemingly randomly. That's already not quite ok, but the worst comes next. - Select a file and then click on Cancel. A selection-changed event is emitted and the button now displays file1. Calling gtk_file_chooser_get_filename() will also return file1. I also remember seeing a flood of selection-changed events when pressing Cancel after performing certain actions, but I don't remember how to reproduce that. Anyway, you get the point. This widget is unusable. I'm using 2.10.11, btw.
*** Bug 408210 has been marked as a duplicate of this bug. ***
Given lots of people seem to being burnt by this, how evil would it be to backport 'file-set' to GTK 2.10.15 or whatever? [We'll push to GTK 2.12 as soon as we can, but I've got to wait for it to get out into the wilds at least a little bit first] AfC
(In reply to comment #10) > - Click on the button again: another file (I'll name it file1) is selected, > seemingly randomly. That's already not quite ok, but the worst comes next. > - Select a file and then click on Cancel. A selection-changed event is emitted > and the button now displays file1. Calling gtk_file_chooser_get_filename() will > also return file1. What happens here is that the iter conversion in select_func() goes wrong. If the ITERS_PERSIST flag in GtkFileSystemModel is turned off, the problem disappears. I don't know yet which component is faulty yet...
The problem is in the GtkFileSystemModel that reverses the list of nodes after they have been added (and row-inserted was emitted) that breaks the promise that iterators are persistent. Applying this patch makes things work correctly: Index: gtkfilesystemmodel.c =================================================================== --- gtkfilesystemmodel.c (revision 18575) +++ gtkfilesystemmodel.c (working copy) @@ -664,7 +664,9 @@ got_root_folder_cb (GtkFileSystemHandle } g_slist_free (roots); +#if 0 model->roots = (FileModelNode *) g_slist_reverse ((GSList *)model->roots); +#endif out: g_object_unref (model); I'll be putting together a proper patch after dinner.
(Oh, and for the record: this bug is different than the original bug this report is about. I haven't seen floods of selection-changed signals; only two on change of model. It has been like this since *before* the async code was merged. As with GtkTreeSelection's changed signal, I would say it's really just a hit that the selection could have changed).
I see the following approaches to fix the problem: * Use append instead of prepend, drop reverse. Gives us a performance problem with long lists... * Emit a rows-reordered signal after list reversal. * Drop the list reversal; since the order in which the file system model holds the items doesn't matter anyway -- the file system model is always put a in a GtkTreeModelSort which sorts the list. The last option seems like the best solution to me, I will attach a patch that removes the list reversals.
Created attachment 96585 [details] [review] proposed patch
If the order doesn't matter anyway, then your patch is probably the best way to go, but I guess another option would be to use GQueue instead of GSList ?
Kris, sounds fine to me.
Committed the patch in comment 17 in r18891. The bug in comment 10 is now fixed, will leave the bug open for the original issue...
Is this related to Bug 355623?
(In reply to comment #20) > Committed the patch in comment 17 in r18891. The bug in comment 10 is now > fixed, will leave the bug open for the original issue... While that bug is indeed fixed, other oddities remain: - Compile and run test2.c. - Click on the button. - Select a file. - Click on Open: as expected, the file appears in the button. - Click on the button. - Select another file (file2). - Click on Cancel: spurious file-set and selection-changed events are emitted. This is visually noticeable as file2 appears for a split-second in the button. Also note that if you happen to click on Cancel from a different folder than the one that was in effect when the dialog was opened, you get several selection-changed events, not just one.
Created attachment 111538 [details] test 2
*** This bug has been marked as a duplicate of bug 691040 ***