Search code examples
pythoncross-platformwxpythonwxwidgets

wx.ListBox.HitTest not working on Mac


The following code sample works under linux (ubuntu) and Windows XP, but not under OSX.

import wx
class frame(wx.Frame):
    def __init__(self,p=None):
        wx.Frame.__init__(self,p)
        self.box = wx.ListBox(self)
        self.box.AppendItems( ["Zero","One","Two","Three","Four","Five","Six"])
        self.box.Bind(wx.EVT_MOUSE_EVENTS,self.onMouse)
    def onMouse(self,evt):
        pos = evt.GetPosition()
        print self.box.HitTest(pos)
        evt.Skip()
class guiApp(wx.App):
    def __init__(self,redirect=False):
        wx.App.__init__(self,redirect)
    def OnInit(self):
        f = frame()
        f.Show()
        self.SetTopWindow(f)
        return True
if __name__=="__main__":
    app = guiApp()
    app.MainLoop()

On Linux and Windows, the correct items are identified when moused over. On OSX hittest always returns -1 (wx.NOT_FOUND)

I'm running 32-bit wxPython, 2.8.12.1 (mac-unicode) which uses the Carbon API in 32bit python 2.7.2.

I can't find this listed as a known bug in wxWidgets and I'm hesitant to submit as it seems this should work. The listbox control is deeply integrated into out GUI and I really don't want to swap it out for ListCtrl or something similar as we have all other functionality working now. Does anyone know a workaround?


Solution

  • There is no work around if the listbox is scrolling. The scroll is handled be the underlying Carbon library and scroll position is not accurately reported back through wx.

    I found the bug in the wxWidgets source code and opened a ticket on the wxWidgets trac, http://trac.wxwidgets.org/ticket/13699, with a patch.

    The root of the bug is a call to the Mac's underlying DataBrowser with an incorrect rowId argument. wxWidgets was passing row position offsets, assuming this would be the rowId's (and maybe at some point apple used these internally when true Id's weren't specified.) Adding a call to another function translates a row's position (offset) into it's real id. With a patched version of wxWidgets the above script works as expected.