GNOME Bugzilla – Bug 321560
File chooser filter behaves weird
Last modified: 2011-02-04 16:20:07 UTC
Version details: 2.8.7 1. Run "testfilechooser" 2. Filter the file list with "PNG and JPEG" pattern 3. Change the directory with a button of the button row above the file list. 4. Look at the filter combo box label (becomes blank). This is Windows, but I don't think it matters.
There is a change between 2.8.6 and 2.8.7 (maybe the one in http://bugzilla.gnome.org/show_bug.cgi?id=318444) that reveals or introduces a crasher bug in GtkFileChooser. I don't know if it is related to the above report, but I am getting random crashes on Windows and I can reproduce them in Linux with "testfilechooser". I think there are two distinct bugs: First this one, when dialog is opened (this existed in 2.8.6 as well): ==15675== Conditional jump or move depends on uninitialised value(s) ==15675== at 0x46944525: XInitImage (in /usr/X11R6/lib/libX11.so.6.2) ==15675== by 0x4D16E485: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D16FDCD: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D16298A: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D1662B1: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D1669C8: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D16EC6C: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D162B02: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D15AFB9: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D15B288: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D15B566: (within /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D154E2F: cairo_fill_preserve (in /usr/lib/libcairo.so.2.2.3) ==15675== by 0x4D154E5F: cairo_fill (in /usr/lib/libcairo.so.2.2.3) ==15675== by 0x1B9F44C5: gtk_cell_renderer_pixbuf_render (gtkcellrendererpixbuf.c:713) ==15675== by 0x1B9F2843: gtk_cell_renderer_render (gtkcellrenderer.c:592) ==15675== by 0x1BB7EC44: gtk_tree_view_column_cell_process_action (gtktreeviewcolumn.c:2791) ==15675== by 0x1BB7F410: _gtk_tree_view_column_cell_render (gtktreeviewcolumn.c:3122) ==15675== by 0x1BB6E3BA: gtk_tree_view_expose (gtktreeview.c:3800) ==15675== by 0x1BAA7CA4: _gtk_marshal_BOOLEAN__BOXED (gtkmarshalers.c:83) ==15675== by 0x41BB8FD7: (within /usr/lib/libgobject-2.0.so.0.800.4) ==15675== by 0x41BB967A: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.800.4) ==15675== by 0x41BC8EA1: (within /usr/lib/libgobject-2.0.so.0.800.4) ==15675== by 0x41BC9E34: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.800.4) ==15675== by 0x41BCA42D: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.800.4) ==15675== by 0x1BB8BE07: gtk_widget_event_internal (gtkwidget.c:3735) ==15675== by 0x1BAA6880: gtk_main_do_event (gtkmain.c:1364) ==15675== by 0x1B94527F: gdk_window_process_updates_internal (gdkwindow.c:2215) ==15675== by 0x1B94537B: gdk_window_process_all_updates (gdkwindow.c:2268) ==15675== by 0x1BA1FE92: gtk_container_idle_sizer (gtkcontainer.c:1117) ==15675== by 0x41B51960: (within /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B4F420: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B52686: (within /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B52BD7: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x1BAA58C8: gtk_main (gtkmain.c:985) ==15675== by 0x804D937: main (testfilechooser.c:665) ==15675== The second one: Still in save mode, navigate to a long path (like, on my system, /usr/share/Xprint/xserver/POSIX/print/ddx-config/raster/). Reduce also the width of the dialog and start clicking randomly on the buttons of the GtkPathBar above the filelist. Eventually you will get a crash like this: ==15675== Invalid read of size 4 ==15675== at 0x1BACBE0D: gtk_path_bar_scroll_down (gtkpathbar.c:684) ==15675== by 0x1BACBFAC: gtk_path_bar_scroll_timeout (gtkpathbar.c:740) ==15675== by 0x41B511D3: (within /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B4F420: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B52686: (within /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B52BD7: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x1BAA58C8: gtk_main (gtkmain.c:985) ==15675== by 0x804D937: main (testfilechooser.c:665) ==15675== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==15675== ==15675== Process terminating with default action of signal 11 (SIGSEGV) ==15675== Access not within mapped region at address 0x0 ==15675== at 0x1BACBE0D: gtk_path_bar_scroll_down (gtkpathbar.c:684) ==15675== by 0x1BACBFAC: gtk_path_bar_scroll_timeout (gtkpathbar.c:740) ==15675== by 0x41B511D3: (within /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B4F420: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B52686: (within /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x41B52BD7: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.800.4) ==15675== by 0x1BAA58C8: gtk_main (gtkmain.c:985) ==15675== by 0x804D937: main (testfilechooser.c:665) ==15675==
It happens that down_button is NULL in: 684 space_needed = BUTTON_DATA (down_button->data)->button->allocation.width + path_bar->spacing;
Regarding first trace: There's exactly one XInitImage call in cairo right now, in cairo-xlib-surface.c:_draw_image_surface. The uninitialised value is image->depth and is used in a conditional in X11/ImUtil.c:387 (x.org as of today). There are other problems, e.g. in cairo_show_glyphs as previously mentioned by http://bugs.gnome.org/show_bug.cgi?id=320946 I'm retracing through cairo and will report there if appropriate.
Regarding the crasher: Found a way to consistently crash it: Reduce the size of the GtkFileChooser window (no matter what mode it is in) until the GtkPathBar has only one directory button (it may be easier to copy the executable in a directory with a long name). Click the 'up' button and then the 'down' button -> *crash*. Initializing both 'down_button' and 'up_button' with 'path_bar->button_list' instead of NULL removes the crash, although that's only a workaround. I still think that the original report (file list filtering is disabled by changing the directory using the GtkPathBar) is somehow related to this problem.
Having found an easy way to trigger it, I can confirm that both the crash and the filtering bug were introduced between 2.8.6 and 2.8.7.
Backing out this patch: http://cvs.gnome.org/viewcvs/gtk%2B/gtk/gtkpathbar.c?r1=1.42.2.1&r2=1.42.2.2 removes the crasher.
I agree that the functionality introduced by solving: http://bugzilla.gnome.org/show_bug.cgi?id=314486 is useful, but I think the present introduces the possibility that 'down_button' and 'up_button' in gtk_path_bar_scroll_down() will remain NULL after the for-loops that try to set them. Checking their value immediately after each for-loop and returning from the function in case any of them are NULL seems to work well. Please also cast the first argument of the gtk_button_set_focus_on_click() functions to GtkButton.
Thanks for investigating
Backing out: http://cvs.gnome.org/viewcvs/gtk%2B/gtk/gtkfilechooserdefault.c?r1=1.282.2.8&r2=1.282.2.9 solves my other (filter disabled) problem. It may be a symptom of another bug lurking, empty file list returned by the current filter being misinterpreted.
Re comment #8: Thank _you_ for GTK+ :-) http://bugs.gnome.org/show_bug.cgi?id=321810 is a duplicate of this bug, albeit with a more appropriate title. The change that provoked the crasher probably also has the side-effect described in: http://bugs.gnome.org/show_bug.cgi?id=321811
The filter issue is still present 2005-11-18 Matthias Clasen <mclasen@redhat.com> Fix crashes in connection with pathbar scrolling (#321560, Bogdan Nicula) * gtk/gtkpathbar.c (gtk_path_bar_update_slider_buttons): Stop scrolling when desensitising slider buttons. (gtk_path_bar_scroll_timeout, gtk_path_bar_slider_button_press): And use it here. * gtk/gtkpathbar.h (struct _GtkPathBar): Add a separate scrolling_down flag.
Pathbar works fine now, thank you for the fix.
Federico points out that the fix for the filter issue is described in http://bugzilla.gnome.org/show_bug.cgi?id=318444#c2
What I mentioned there is to use pending_select_paths_add() instad of gtk_file_chooser_default_path(). If *that* doesn't fix the bug, then that is the right code path to get fixed, anyway. Rationale: pending_select_paths_add() means "once you have finished loading the current folder, select these paths and only disturb the rest of the UI as little as possible".
Ok, mostly shooting in the dark: GTK+ 2.8.7, gtkfilechooserdefault.c: gtk_file_chooser_default_select_path() calls anyway pending_select_paths_add(). Instead of the four lines added to path_bar_clicked(): ( + if (child_path != NULL) + { + gtk_file_chooser_default_select_path (impl, child_path, NULL); + browse_files_center_selected_row (impl); + } ) probably it was better to add: if (child_path != NULL) pending_select_paths_add (impl, child_path); as the first lines, before if (!change_folder_and_display_error (impl, file_path, ...)) But the problem is deeper, because paths selected like that eventually get passed to show_and_select_paths() and, if they are hidden and/or filtered, the filter is unset and/or "show-hidden" is turned TRUE. This changes the UI behind the user's back and he will suddenly sees a different set of files than he used to see a couple of clicks ago... From a user point of view, I particularly find offensive the unsetting of the filter. Even if you create a workaround for this particular case, I think something similar is bound to show up in the future.
Created attachment 55062 [details] [review] Workaround
Created attachment 55081 [details] [review] Alternative workaround I think the file filtering code should be made aware of differences between files and folders.
Thanks for the suggestions, Bogdan - I committed a patch based on yours. This is fixed in the gtk-2-8 and HEAD branches now. 2005-11-28 Federico Mena Quintero <federico@ximian.com> Fix bug #321560, based on a patch by Bogdan Nicula (bogdanni@hotmail.com): * gtk/gtkfilechooserdefault.c (up_folder_handler): Don't add the current_folder to the pending select paths here; the path bar will give it to us now. (path_bar_clicked): Add the child_path to the pending select paths here. (show_and_select_paths): Don't filter out folders. (show_and_select_paths): Don't take separate arguments for only_one_path and multiple paths. * tests/autotestfilechooser.c (test_folder_switch_and_filters): New test about preserving the filters when we change folders.
Everything works fine now. Thank you, Federico.
*** Bug 328973 has been marked as a duplicate of this bug. ***