GNOME Bugzilla – Bug 577098
GtkTreeView (lists, Nautilus) is very slow with Assistive Technologies enabled (at-spi)
Last modified: 2013-01-02 16:21:33 UTC
Please describe the problem: In general, there appears to be bad interaction between GtkTreeView and gail/atk/at-spi functions. This is noticeable in nautilus but apparently it affects other programs too. Similar description for Rhythmbox, bug #419383 Crashes are in bug #572406, and #512743. However in the present case nautilus, and rhythmbox don't crash, they just take a long time to load. So it probably is a different issue. Bug #575873 gives technical details on the problem, but I can't tell if it is in fact describing the issue we see with nautilus and rhythmbox. Bug #571596, describes a similar problem, but affecting TreeStore in PyGtk, which probably relates to GtkTreeView. Finally bug #302296 and bug #163583 indicate that more work needs to be done in gailtreeview.c Ubuntu Launchpad bug #159042 also discusses this problem. The logs there seem to point the cause of the problem to some functions in gail. Steps to reproduce: 1. Make sure Assistive Technologies is enabled: System > Preferences > Assistive Technologies 2. Log out and login 3. Open 'nautilus' in browser mode, and use 'List View' as default to display contents of directories 4. Open any folder with several files or subfolders, for instance '/usr/bin' or '/usr/lib' Actual results: Nautilus uses 100% of CPU time and it becomes unresponsive for several seconds. The time it takes to respond depends on the number of files being displayed. It could take from 30 seconds to 5 minutes or more. Expected results: Nautilus should display the directory in 1 or 2 seconds, just like when Assistive Technologies is not enabled. Does this happen every time? Yes. Other information: Can somebody please explain the cause of this general slowness when loading treeviews, and if there is a master bug report that we can reference?
Just for reference. Here are some related Gnome bugs: bug #163583 gailtreeview.c bug #302296 gailtreeview.c bug #419383 Rhythmbox bug #512743 application crash, libgail bug #554171 gailtreeview.c, Rhythmbox bug #571596 TreeStore in PyGTK bug #572406 application crash bug #575873 technical details, gail bug #587020 (duplicate, and other reports) The Ubuntu Launchpad bug https://bugs.launchpad.net/atk/+bug/159042
For GRAMPS, here is the downstream ticket: http://www.gramps-project.org/bugs/view.php?id=3069 GRAMMPS always becomes very slow, sometimes crashes
If any ATK developers are reading these bug submissions, I'd like to know if the following is possible: Check if ATK is enabled on startup of my application. I could then show a Dialog to the user with info: "ATK is enabled. This app does not work when ATK is enabled, please disable it before continuing."
(In reply to comment #3) > If any ATK developers are reading these bug submissions, I'd like to know if > the following is possible: > > Check if ATK is enabled on startup of my application. > > I could then show a Dialog to the user with info: "ATK is enabled. This app > does not work when ATK is enabled, please disable it before continuing." Accessibility is a core value of GNOME and purposely working around it or making applications inaccessible violates this value. The right thing to do is fix the application or the infrastructure.
Willie, I agree with the theory, but we are in the real world where if people don't like my app, they'll use another. From our point of we, we make a GTK application (genealogy, so used by many older people, some need ATK ) and see bugs coming in from GNOME users complaining the app is too slow or crashes (KDE, windows, mac have no problem as ATK is always not enabled). We made a special wiki page for this: http://www.gramps-project.org/wiki/index.php?title=Known_issues, but let's be serious, how many of the users trying out the application submit a bug, or read a wiki? They only see that deleting a person takes 30 seconds, adding a person 10, and move on. The dialog I mentioned would be a warning dialog, not an error dialog blocking the application. It is the least we can do to help our users having a user experience as the developers intended it. As a python developer, I do not have the skills to fix ATK. The launchpad ubuntu bug in nautilius is open from 2007. Looking here: http://bugzilla.gnome.org/browse.cgi?product=atk it is impossible to determine for me if this core value part of GNOME is actively supported. Two developers from sun.com I see, with more assigned bugs than a normal human can handle.
(In reply to comment #5) > I agree with the theory, but we are in the real world where if people don't > like my app, they'll use another. The real world has people with disabilities in it and I'll venture they are also interested in genealogy. I hear your frustration, however, so lets try see if there are things that can be done in the Gramps code to understand and alleviate the problem. > As a python developer... According to http://www.pygtk.org/pygtk2tutorial/sec-TreeModelInterface.html#sec-LargeDataStores "If adding a large number of rows disconnect the TreeModel from its TreeView (using the set_model() method with the model parameter set to None) to avoid TreeView updates for each row entered." From http://www.gramps-project.org/bugs/view.php?id=3069, I see that "Detaching the model before calling build_columns() and reattaching thereafter alleviates the problem". So, I'm curious if we're talking about different problems? > Looking here: http://bugzilla.gnome.org/browse.cgi?product=atk it isimpossible > to determine for me if this core value part of GNOME is actively supported. Two > developers from sun.com I see, with more assigned bugs than a normal human can > handle. Programmers are not normal humans. ;-) But yes, there is work to do. Regardless of what has been incorrectly stated in the Gramps bugtracking system, ATK is being supported and it is supported pretty well. Other than searching for open bugs (I see Gramps has 804 bugs at the 'assigned' level or above, for example), there are other kinds of searches one can perform, such as bugs that have been closed as well as activity in the git repository. Before engaging in a separate and potentially unconstructive discussion, however, let's try to work constructively to see if there are solutions we can come up with for the specific problem you are experiencing.
> Before > engaging in a separate and potentially unconstructive discussion, however, > let's try to work constructively to see if there are solutions we can come up > with for the specific problem you are experiencing. Discussions of the calls ATK causes in the treemodel are on the mailing list: http://www.nabble.com/People-Model-speedup-td24188200.html So without setting model to None, this is in the tens of thousands of calls to things like iter_has_child (http://www.pygtk.org/docs/pygtk/class-gtktreemodel.html#method-gtktreemodel--iter-has-child) Adding setting model to None, rebuilding view, rebuilding model, then connecting model back to view, reduces this to some 3002 calls. In other words the entire model, what is what is the code wants to avoid by leaving the model attached. The link you give is for TreeStore and ListStore, not the GenericTreeModel GRAMPS uses due to TreeStore being too slow. Not using ATK, even if model remains attached (and in the view the columns removed, and new ones attached), leads to one call, the row that is changed. Although the GRAMPS code is somewhat strange (the people who wrote it are no longer around to ask), one call is what you would expect. GRAMPS uses a GenericTreeModel, so the view should only react and query the model when the explicit signals are called like row_changed (http://www.pygtk.org/docs/pygtk/class-gtktreemodel.html#method-gtktreemodel--row-changed ). ATK causes extra calls Now, I agree that we must certainly change the GRAMPS code, and rewriting the views is on the TODO for version 3.2 (spring 2010). Perhaps the rebuilding of columns is something that messes up ATK? The model should remain attached though, too avoid many calls, and hopefully ATK can cope with that. Well, enough about GRAMPS, the bug here is started due to Nautilius, so I would expect the problems are not really GRAMPS related. The important thing for me is: Documentation on TreeModel/View should be such that it is clear how ATK interacts with a view and signals from the treemodel. What calls will ATK do extra to the model so that applications that put much effort in customizing performance of the treeview can take this into account. For GRAMPS we need to be able to show a treeview with 10000+ entries and add entries on a constant basis without performance loss. Previous developers have done research and noted that only GenericTreeModel with keeping in memory only the sortkey and hitting database when a line is shown for the rest of the data, can provide that. I think to be able for 3.2 to improve this code, but it will not be much different from the present code
(In reply to comment #7) > The important thing for me is: > Documentation on TreeModel/View should be such that it is clear how ATK > interacts with a view and signals from the treemodel. What calls will ATK do > extra to the model so that applications that put much effort in customizing > performance of the treeview can take this into account. > This is a good point. It should be helpful for many applications which use treeview. I will take this work.
I did some performance analysis through D-Trace. The case is to open /usr/bin in Nautilus in list mode. There are more than 2000 files in the directory. It takes more than 2 mins to show the directory. Here is the output of my script, shows the execute time which gail_tree_view_* functions take. times gail_tree_view_size_allocate_gtk 12 gail_tree_view_get_n_columns 2188 gail_tree_view_get_n_children 8752 gail_tree_view_ref_child 8752 gail_tree_view_get_type 54753 sum in ns gail_tree_view_get_n_columns 50067161 gail_tree_view_get_type 421709745 gail_tree_view_size_allocate_gtk 2427303245 gail_tree_view_get_n_children 16151530946 gail_tree_view_ref_child 121506068367 avg in ns gail_tree_view_get_type 7702 gail_tree_view_get_n_columns 22882 gail_tree_view_get_n_children 1845467 gail_tree_view_ref_child 13883234 gail_tree_view_size_allocate_gtk 202275270 From the output, gail_tree_view_ref_child is the champion(takes 121 seconds). The function is called by atk-bridge because atk-bridge want to emit the "children-changed::add" signal with the added child. So I modified the code in atk-bridge, to only emit "children-changed::add" with the child's index number if it is in a tree (as I tested, Orca can still read the children). And I got the second output, the total time is less than 20 seconds, much better than the original one: times gail_tree_view_changed_gtk 1 gail_tree_view_size_allocate_gtk 37 gail_tree_view_get_n_columns 2188 gail_tree_view_get_type 2423 sum in ns gail_tree_view_changed_gtk 374209 gail_tree_view_size_allocate_gtk 2906596 gail_tree_view_get_type 17957877 gail_tree_view_get_n_columns 28667793 avg in ns gail_tree_view_get_type 7411 gail_tree_view_get_n_columns 13102 gail_tree_view_size_allocate_gtk 78556 gail_tree_view_changed_gtk 374209 The champion (gail_tree_view_get_n_columns) only takes 0.0287 seconds. So obviously only monitor gail_tree_view* is not enough now. I tried to monitor all functions in gail this time, here is a piece of the output (the number is a little long becaue D-Trace takes some time): sum in ns gail_container_remove_gtk 6336336 gail_label_real_notify_gtk 6436256 gail_toplevel_show_event_watcher 7612316 gail_focus_watcher 10248290 gail_widget_notify_gtk 14734194 gail_tree_view_get_type 26738036 gail_tree_view_get_n_columns 42531378 gail_widget_size_allocate_gtk 51395269 gail_util_get_root 141433675 traverse_cells 878151584 iterate_thru_children 44012265771 get_row_from_tree_path 44084278176 model_row_inserted 49255042999 Actually model_row_inserted calls get_row_from_tree_path, and get_row_from_tree_path calls iterate_thru_children. So if we want to improve more, iterate_thru_children should be called as less times as possible. I am going to continue the work next week. Note all work I do is in CORBA version of at-spi. D-Bus version of at-spi gets a similar result which gail_tree_view_ref_child takes the most time for similar reason.
Li, where are things w.r.t. this bug? Thanks!
For at-spi, we can modify atk-bridge to not ref the child when "children-changed:add" signal emits. But I think it may be difficult for the D-Bus version, since the list of children well be sent.
Okay.... But given that we really need to do *something* to address this issue.... Any ideas?
*** Bug 587020 has been marked as a duplicate of this bug. ***
*** Bug 575696 has been marked as a duplicate of this bug. ***
*** Bug 575873 has been marked as a duplicate of this bug. ***
*** Bug 571596 has been marked as a duplicate of this bug. ***
[Mass-reassigning open atk bug reports for better trackability as requested in https://bugzilla.gnome.org/show_bug.cgi?id=653179 . PLEASE NOTE: If you have watched the previous assignee of this bug report as a workaround for actually getting notified of changes in atk bugs, you yourself will now have to add atk-maint@gnome.bugs to your watchlist at the bottom of https://bugzilla.gnome.org/userprefs.cgi?tab=email to keep watching atk bug reports in GNOME Bugzilla. Sorry for the noise: Feel free to filter for this comment in order to mass-delete the triggered bugmail.]
This bug was created several years ago (and btw, IMHO with the wrong product). Since then, a lot of changes were made on ATK, at-spi and (more important) on the accessibility support on gtk. Specifically on the accessibility support for the GtkTreeView. Thanks to all those changes, the performance on all the stack and tree view has improved a lot. So summing all those, I think that we can close this bug as OBSOLETE.