After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 165246 - gtk_tree_view_set_cursor does not always do the scroll right
gtk_tree_view_set_cursor does not always do the scroll right
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkTreeView
2.6.x
Other Linux
: Normal critical
: ---
Assigned To: gtktreeview-bugs
gtktreeview-bugs
Depends on:
Blocks:
 
 
Reported: 2005-01-25 22:57 UTC by Jorn Baayen
Modified: 2011-02-04 16:18 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Testcase (11.48 KB, application/x-gzip)
2005-01-25 23:41 UTC, Jorn Baayen
  Details
Another testcase (2.34 KB, text/plain)
2005-02-07 09:46 UTC, Nickolay V. Shmyrev
  Details
Patch to CVS (1.45 KB, patch)
2005-02-10 18:14 UTC, Nickolay V. Shmyrev
none Details | Review

Description Jorn Baayen 2005-01-25 22:57:59 UTC
Calling gtk_tree_view_set_cursor to select the first row of a treeview just
after its contents have been modified, does not always end up in the selected
row being actually visible. Doing the _set_cursor after the treeview contents
have been modified in an idle works around the problem. My impression is that
gtk_tree_view_scroll_to_cell does not always get the right coordinates, perhaps
because the rows are not yet validated? I don't know much about treeview
internals, just guessing ..

I have spent the past few hours trying to come up with a standalone testcase for
this, however I cannot get it reproduced. It is however 100% reproducible using
the Muine (muine CVS module) music player.. just load some music into it, press
'play album', and type some things, press backspace, type some more.. at some
point it will come up. Only reproducable using CVS, I believe the latest release
still has the workarounds in place.

My eternal gratitude goes out to whoever fixes this, it is a really annoying bug.
Comment 1 Jorn Baayen 2005-01-25 23:41:59 UTC
Created attachment 36528 [details]
Testcase

Managed to come up with a test case after all. Not very small, but it is now at
least consistently reproducable:

press 'f' in the entry, and a second later 'backspace'. The first row should be
selected, but it is not.
Comment 2 Jorn Baayen 2005-01-26 17:40:17 UTC
Using latest gtk-2-6 CVS, Muine even crashes here. The testcase doesn't,
however. What follows is a trace from the crash:

Program received signal SIGSEGV, Segmentation fault.

Thread NaN (LWP 23340)

  • #0 gtk_tree_view_adjustment_changed
    at gtktreeview.c line 9149
  • #1 _gtk_marshal_VOID__VOID
    at gtkmarshalers.c line 1081
  • #2 IA__g_closure_invoke
    at gclosure.c line 437
  • #3 signal_emit_unlocked_R
    at gsignal.c line 2485
  • #4 IA__g_signal_emit_valist
    at gsignal.c line 2244
  • #5 IA__g_signal_emit
    at gsignal.c line 2288
  • #6 IA__gtk_adjustment_value_changed
    at gtkadjustment.c line 392
  • #7 IA__gtk_adjustment_set_value
    at gtkadjustment.c line 375
  • #8 gtk_tree_view_top_row_to_dy
    at gtktreeview.c line 5315
  • #9 do_validate_rows
    at gtktreeview.c line 5125
  • #10 validate_rows
    at gtktreeview.c line 5139
  • #11 gtk_tree_view_size_request
    at gtktreeview.c line 1770
  • #12 _gtk_marshal_VOID__BOXED
    at gtkmarshalers.c line 1269
  • #13 g_type_class_meta_marshal
    at gclosure.c line 514
  • #14 IA__g_closure_invoke
    at gclosure.c line 437
  • #15 signal_emit_unlocked_R
    at gsignal.c line 2415
  • #16 IA__g_signal_emit_valist
    at gsignal.c line 2244
  • #17 IA__g_signal_emit_by_name
    at gsignal.c line 2312
  • #18 do_size_request
    at gtksizegroup.c line 496
  • #19 _gtk_size_group_compute_requisition
    at gtksizegroup.c line 683
  • #20 IA__gtk_widget_size_request
    at gtkwidget.c line 2607
  • #21 gtk_scrolled_window_size_request
    at gtkscrolledwindow.c line 948
  • #22 _gtk_marshal_VOID__BOXED
    at gtkmarshalers.c line 1269
  • #23 g_type_class_meta_marshal
    at gclosure.c line 514
  • #24 IA__g_closure_invoke
    at gclosure.c line 437
  • #25 signal_emit_unlocked_R
    at gsignal.c line 2415
  • #26 IA__g_signal_emit_valist
    at gsignal.c line 2244
  • #27 IA__g_signal_emit_by_name
  • #28 do_size_request
    at gtksizegroup.c line 496
  • #29 _gtk_size_group_compute_requisition
    at gtksizegroup.c line 683
  • #30 IA__gtk_widget_size_request
    at gtkwidget.c line 2607
  • #31 gtk_vbox_size_request
    at gtkvbox.c line 122
  • #32 _gtk_marshal_VOID__BOXED
    at gtkmarshalers.c line 1269
  • #33 g_type_class_meta_marshal
    at gclosure.c line 514
  • #34 IA__g_closure_invoke
    at gclosure.c line 437
  • #35 signal_emit_unlocked_R
    at gsignal.c line 2415
  • #36 IA__g_signal_emit_valist
  • #37 IA__g_signal_emit_by_name
    at gsignal.c line 2312
  • #38 do_size_request
    at gtksizegroup.c line 496
  • #39 _gtk_size_group_compute_requisition
    at gtksizegroup.c line 683
  • #40 IA__gtk_widget_size_request
    at gtkwidget.c line 2607
  • #41 gtk_vbox_size_request
    at gtkvbox.c line 122
  • #42 _gtk_marshal_VOID__BOXED
    at gtkmarshalers.c line 1269
  • #43 g_type_class_meta_marshal
    at gclosure.c line 514
  • #44 IA__g_closure_invoke
    at gclosure.c line 437
  • #45 signal_emit_unlocked_R
    at gsignal.c line 2415
  • #46 IA__g_signal_emit_valist
  • #47 IA__g_signal_emit_by_name
    at gsignal.c line 2312
  • #48 do_size_request
    at gtksizegroup.c line 496
  • #49 _gtk_size_group_compute_requisition
    at gtksizegroup.c line 683
  • #50 IA__gtk_widget_size_request
    at gtkwidget.c line 2607
  • #51 gtk_window_size_request
    at gtkwindow.c line 4198
  • #52 _gtk_marshal_VOID__BOXED
    at gtkmarshalers.c line 1269
  • #53 g_type_class_meta_marshal
    at gclosure.c line 514
  • #54 IA__g_closure_invoke
    at gclosure.c line 437
  • #55 signal_emit_unlocked_R
  • #56 IA__g_signal_emit_valist
    at gsignal.c line 2244
  • #57 IA__g_signal_emit_by_name
    at gsignal.c line 2312
  • #58 do_size_request
    at gtksizegroup.c line 496
  • #59 _gtk_size_group_compute_requisition
    at gtksizegroup.c line 683
  • #60 IA__gtk_widget_size_request
    at gtkwidget.c line 2607
  • #61 gtk_window_compute_configure_request
    at gtkwindow.c line 5027
  • #62 gtk_window_check_resize
    at gtkwindow.c line 5230
  • #63 _gtk_marshal_VOID__VOID
    at gtkmarshalers.c line 1081
  • #64 g_type_class_meta_marshal
    at gclosure.c line 514
  • #65 IA__g_closure_invoke
    at gclosure.c line 437
  • #66 signal_emit_unlocked_R
    at gsignal.c line 2523
  • #67 IA__g_signal_emit_valist
    at gsignal.c line 2244
  • #68 IA__g_signal_emit
    at gsignal.c line 2288
  • #69 IA__gtk_container_check_resize
    at gtkcontainer.c line 1190
  • #70 gtk_container_idle_sizer
    at gtkcontainer.c line 1114
  • #71 g_idle_dispatch
    at gmain.c line 3821
  • #72 IA__g_main_context_dispatch
    at gmain.c line 1947
  • #73 g_main_context_iterate
    at gmain.c line 2578
  • #74 IA__g_main_loop_run
    at gmain.c line 2782
  • #75 IA__gtk_main
    at gtkmain.c line 963

Comment 3 Nickolay V. Shmyrev 2005-02-07 09:46:15 UTC
Created attachment 37093 [details]
Another testcase

I've just meet similar problems. Here is my testcase.

What is going there:

1. Tree view is realized if it's added to visible container but is still not
shown.

2. After addition of rows presize_handler shedule
gtk_tree_view_size_request_columns and it updates header height of tree view

3. scroll to cell function using wrong header height calculates visible area of
tree view with height less then zero - {0, 0, 1, -27}

4. After that it's scrolls incorrectly.

Now we should somehow fix it :)
Comment 4 Daniele 2005-02-07 12:04:40 UTC
Same problem here (CVS version): http://glsof.sourceforge.net
'Search' shows a "two rows scrolldown". You can see it on 'single or double
list' choice.

Problem is for 'gtk_tree_view_scroll_to_cell' too.
Comment 5 Nickolay V. Shmyrev 2005-02-10 18:14:58 UTC
Created attachment 37309 [details] [review]
Patch to CVS

Definitely it's two different problems. One is that scroll tries to find cell
on widget that is really hidded and not allocated properly. Second is about
race condition with scrolling to scroll_row and scrolling to top_row. But this
small patch fixes both.
Comment 6 Jorn Baayen 2005-02-14 10:33:14 UTC
Rock!

I can confirm that this patch fixes both of the problems.
Comment 7 Jorn Baayen 2005-02-14 11:41:58 UTC
Actually, it doesn't fix the crash- the crash just occurs less frequently now.
Comment 8 Nickolay V. Shmyrev 2005-02-14 23:08:59 UTC
Well, probably there remain some problems, but it needs some debugging. Two
questions:

1. Is it reproduced with release of gtk like 2.6.1?

2. Could you provide additional information, at least values of parametrs of
gdk_window_move?

This it too complicated bug - three problem at one report :)
Comment 9 Jorn Baayen 2005-02-15 12:46:18 UTC
1. Actually, yes- all gtk 2.6 releases.

2. The crash happens in gdk_window_move (the same trace is still valid),
parameters are (0, 0) which is right. Running a GDK_IS_WINDOW assert on
tree_view->priv->bin_window right before the gdk_window_move doesn't complain.

I'd be happy to provide any more needed info.
Comment 10 Nickolay V. Shmyrev 2005-02-15 14:43:35 UTC
It's interesing but it's not reproduced on some machines but is reproduced on
others. The most strange that I see it only on Redhat 9 with standard XFree86. 

What is your XFree version?
Comment 11 Jorn Baayen 2005-02-15 16:27:16 UTC
This is FC3, xorg 6.8.1-12.FC3.21
Comment 12 Jorn Baayen 2005-02-16 13:57:17 UTC
Doing some debugging, this is pretty strange:

The crash happens while calling gdk_window_move, but:
- All the parameters passed to the function seem correct, or at least
  don't cause a crash when accessing them separately right before the call.
- gdk_window_move itself is not actually entered

Smells like some kind of memory corruption?
Comment 13 Jorn Baayen 2005-02-16 15:27:44 UTC
More information:

The gtk_adjustment_changed () where it crashes is not actually the one caused by
scroll_to_point (), instead it is caused by the gtk_adjustment_set_value () in
validate_visible_area (), which in turn is called by bin_expose ().

It is odd that it wants to scroll, as the row is perfectly visible.

Just before the call to _scroll_to_cell (), the relevant row is changed, and
thus invalidated. Perhaps there is another race here?
Comment 14 Nickolay V. Shmyrev 2005-02-17 17:31:24 UTC
I think that it's normal situation that adjustment changes several times.
Anyhow, it should not crash whatever race condition is there.

Unfortunately, I still can't reproduce crash with my version of muine 0.8.2 and
gtk 2.6.1. Probably, another testcase is possible?
Comment 15 Jorn Baayen 2005-02-17 17:59:42 UTC
The way I can reproduce it, using Gtk+ CVS, 2.6 branch, with your patch and
Muine CVS, is by queueing up a few albums and songs and pressing "next" a couple
of times.
Comment 16 Jorn Baayen 2005-02-18 20:56:44 UTC
Another consistent way to reproduce it here is by trying to scroll any of the
treeviews using the arrow keys.
Comment 17 Jorn Baayen 2005-02-18 23:42:26 UTC
Further digging reveals that the bug only occurs when both
a) Using Gtk#
and
b) Gtk+ is compiled with -march=pentium4

So I guess this is not really a Gtk issue. In this case, Nickolay's patch fixes
all relevant issues.
Comment 18 Matthias Clasen 2005-06-14 17:20:41 UTC
Moving to 2.8, as Kris thinks his patch is risky
Comment 19 Kristian Rietveld 2005-06-14 23:44:21 UTC
Jorn's problem has been fixed with the fix in #163214. The problem Nickolay's
testcase describes is caused by this piece of code in gtk_tree_view_scroll_to_cell:

  if (cell_rect.y + cell_rect.height > vis_rect.y + vis_rect.height)
    dest_y = cell_rect.y + cell_rect.height - vis_rect.height;

with the problem being that this code does not work correctly when the treeview
has not been allocated yet. (vis_rect.height does not have a usable value at
this time). A fix which might be correct is probably not doing this correction
when vis_rect.height does not have a usable value. But this still gives us the
problem on how to decide whether vis_rect.height is usable or not.

I need to sleep about this before I can make a final decision.
Comment 20 Nickolay V. Shmyrev 2005-06-15 07:32:07 UTC
Thanks for review, Kris - this part of patch should do exactly what you need -
checks if vis_rect.height has usable value. 

+#include "gtkprivate.h"
 
 #define GTK_TREE_VIEW_PRIORITY_VALIDATE (GDK_PRIORITY_REDRAW + 5)
 #define GTK_TREE_VIEW_PRIORITY_SCROLL_SYNC (GTK_TREE_VIEW_PRIORITY_VALIDATE + 2)
@@ -10195,12 +10196,20 @@ gtk_tree_view_scroll_to_cell (GtkTreeVie
    * scrolling code, we short-circuit validate_visible_area's immplementation as
    * it is much slower than just going to the point.
    */
-  if (! GTK_WIDGET_REALIZED (tree_view) ||
+    if (!GTK_WIDGET_VISIBLE (tree_view) || GTK_WIDGET_ALLOC_NEEDED (tree_view) ||
       GTK_RBNODE_FLAG_SET (tree_view->priv->tree->root,
GTK_RBNODE_DESCENDANTS_INVALID))
Comment 21 Kristian Rietveld 2005-06-17 14:12:48 UTC
Okay, I gave it some more thought. It's indeed better to have the scrolling
handled via validate_visible_area() if the treeview is not visible or needs
reallocation. Committed your patch to HEAD (together with another fix, which
makes your testcase fully work). Thanks!