Menu

#2777 listbox returns wrong active element index

obsolete: 8.5.8
open
5
2010-03-16
2010-03-16
No

The result of "pathName index active" when called as a result of a <<ListboxSelect>> event triggered when the listbox is clicked on, always returns the index of the last active element in the listbox, rather than the current active element.

Example code to illustrate the problem:

package require Tk
set lv "element_0 element_1 element_2"
proc lb_report {path} {puts "current selection: [$path curselection]" ; puts "active index: [$path index active]"}
listbox .lb -listvariable lv
bind .lb <<ListboxSelect>> "lb_report %W"
pack .lb

Clicking on the elements in the listbox created echoes the current selection and the active index. They should be the same, but in successive clicks the active index lags the current selection by 1. This becomes a serious problem when the "-multiple" option is used on creation of the listbox, so the current selection and the active index are not necessarily the same, but the active index is needed to identify the users's choice and process the event properly.

Thinking this might be a case of the script being called before all event bindings were processed, I changed the binding using the following command:

bind .lb <<ListboxSelect>> "after idle lb_report %W"

But even after the event queue is empty, the wrong active index is reported in the same way.

As a workaround I used the following binding:

bind .lb <<ListboxSelect>> "after 100 lb_report %W"

This produces the correct active index when the listbox is clicked on. But doing event programming that depends explicitly on timing is a very poor design choice.

The Tk FAQ suggests a workaround of binding to a mouse click event and finding the mouse cursor position to deduce the user's choice, but of course this only works if the mouse is used for selection, rather than key presses, which the default bindings enable.

ActiveTcl 8.5.8 on Ubuntu Intrepid.

Discussion