GNOME Bugzilla – Bug 120187
Difficult to quickly select multiple entries
Last modified: 2011-02-04 16:12:02 UTC
If you try to quickly select a set of entries in a GtkTreeView you usually have one entry out of two which will not be selected. You can see this bug more easily if you increase the double-click delay. What happens is that if you click quickly, one GDK_2BUTTON_PRESS event will be genered above the row where occured the second GDK_BUTTON_PRESS. GtkTreeView will process this event normally so this row selected thanks to the second GDK_BUTTON_PRESS will immediately be deselected. There is a test to see if a double-click happened on the same row but right now it used only for the row_activated event. Notice that the same problem happens with the GDK_3BUTTON_PRESS which must always be ignored.
Created attachment 19319 [details] [review] This patche solves the problem.
That may sound a bit perfectionnist but thinking again about this problem, I thought that we should not just ignore the triple click case since one user can click on a row and then quickly double-click on another. With the current code it will ignored since we would get a double-click on different row (ignored) and then a triple click (currently ignored). this triple click should be interpreted as a double click for the activation signal. I made the modification, will post the patch as soon as it's ready. Now GkTreeView will work perfectly ! ;)
Created attachment 19348 [details] [review] Better patch
Created attachment 19362 [details] [review] updated patch
- Got rid of the return statement, which is obviously wrong - Got rid of the tabs in the indentation (I know the prev revision also had tabs there, but I am just making use of the situation to get rid of them :) - Other small tweaks Also, before I commit/approve, I want to know why you have moved the codeblock in question upwards?
Well you're both right and wrong. You're wrong, because the return statement was there to fix the bug that prevent to quickly select multiple entries. I was not very clear in my explanations, here is what currently happens: The user clicks on a row: -> GDK_BUTTON_EVENT -> the first row is selected. The user clicks on a second row -> GDK_BUTTON_EVENT -> the second row is selected. But if the user clicked too fast -> GDK_2BUTTON_EVENT -> the second row is deselected. Because the selection/deselection code is called even if the double click didn't occur on the same row. With that behaviour you can't quickly select multiple entries. But you're also right, because in fact we do not need to check if double click happened on the same row for the selection ! We should never select/deselect on a double-click or triple-click as the select job was done during the GDK_BUTTON_EVENT preceding a GDK_2BUTTON_EVENT or GDK_3BUTTON_EVENT. So basically we can move back the row_double_click test codeblock at the end (but keeping the test for GDK_3BUTTON_EVENT) but we must also addd an if statement to select or deselect only if it's a GDK_BUTTON_EVENT.
Discussed things with yann on IRC and updated patch accordingly. This makes things work a lot better. So I would like to get it in 2.2.3. Jrb, could you look at this too when you manage to untangle yourself from the wires? ;)
Created attachment 19390 [details] [review] updated patch (Aug 20)
It's not directly related to this bug but since it concerns this part of the code, I just wonder if we should change a bit the behaviour of the right click, a lot of applications are using it for popup. and, right now: - If you have a bunch of entries selected - and you right click on one of them -> it deselect but the one clicked (and popup the menu) What you would expect is that the popup menu appears without deselecting any entries, this is the normal behaviour in Nautilus or Evolution. This can be easily done replacing the if statement if (event->type == GDK_BUTTON_PRESS) by if (event->type == GDK_BUTTON_PRESS && (event->button != 3 || !gtk_tree_selection_path_is_selected (gtk_tree_view_get_selection (tree_view), path))) (since we are in gtk_tree_view I suppose there's a better way to know if a path/node is selected) Anyway I am not sure it's a good idea since it's popup specific. What do you think ?
I would rather change the code so, that it only handles selections when the first button is being pressed. So the line would read: if (event->type = GDK_BUTTON_PRESS && event->button == 1)
Oh sounds simplier... but most apps I've seen select on right-click (so you can select and have the popup concerning the item in one click, I think it's convenient, but I think what is mostly important is that all apps have the same behaviour). Well it's up to you to decide.
Euhm, changed the first part of the conditional to event->type == instead of = :). Committed to gtk-2-2 and HEAD.
Reverted the event->button == 1 check post 2.2.3, as it broke right click menus in multiple programs (for example in nautilus). We can't make this change until 3.0. 2.2.4 will be released with this fix soon.