CaptureMouse in ScrolledWindow generates spurious events

57 views
Skip to first unread message

Phil Mayes

unread,
Jun 13, 2009, 3:35:39 PM6/13/09
to wxPython-users
If I capture the mouse in a scrolled window then drag outside the
window, I get a stream of mouse events with incorrect coordinates,
even when the mouse is not moving. Sample code attached and below.
Any clues, anyone?

Thanks in advance, Phil

import wx

PARENT = wx.ScrolledWindow
#PARENT = wx.Panel # uncomment this to "fix" problem
class DragWindow(PARENT):
def __init__(self, parent):
PARENT.__init__(self, parent, size=(300,200))
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_MOTION, self.OnMotion)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
self.SetBackgroundColour("YELLOW")

def OnMotion(self, evt):
if self.HasCapture():
print 'drag at',evt.GetPosition()

def OnLeftDown(self, evt):
self.CaptureMouse()

def OnLeftUp(self, evt):
if self.HasCapture():
self.ReleaseMouse()

class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'CLICK AND DRAG FROM YELLOW
TO GREEN')
sizer = wx.BoxSizer(wx.HORIZONTAL)

wnd = wx.Panel(self, size=(100,-1))
sizer.Add(wnd)
wnd = DragWindow(self)
sizer.Add(wnd, 1, wx.EXPAND|wx.ALL, 0)

self.SetSizer(sizer)
self.SetBackgroundColour("GREEN")
self.Fit()

if __name__=="__main__":
print wx.version()
app = wx.App(0)
win = TestFrame()
win.Show(True)
app.MainLoop()

Robin Dunn

unread,
Jun 15, 2009, 1:51:11 PM6/15/09
to wxPytho...@googlegroups.com
Phil Mayes wrote:
> If I capture the mouse in a scrolled window then drag outside the
> window, I get a stream of mouse events with incorrect coordinates,
> even when the mouse is not moving. Sample code attached and below.
> Any clues, anyone?

This is intentional. The extra events are sent to help facilitate
situations where you want to scroll the window while dragging. For
example, if you want to drag an item in a tree to another location in
the tree that is not visible yet.

--
Robin Dunn
Software Craftsman
http://wxPython.org

Phil Mayes

unread,
Jun 15, 2009, 4:01:01 PM6/15/09
to wxPython-users
I can't see the benefit here. I am receiving a flood of MouseEvents
with two types of coordinates, one relative to the captured window,
and one relative to the parent; furthermore, I get events fired even
when the mouse is stationary:

drag at (-20, 20) < mouse...
drag at (-21, 20) < ...is moving and
drag at (-21, 19) < ...supplying window-relative events
drag at (83, 49) < [parent-relative events interleaved]
drag at (-21, 18) <...still moving
drag at (83, 48)
drag at (-22, 18)
drag at (82, 48) < mouse is stopped
drag at (82, 48) < ...and gets stream
drag at (82, 48) < ...of parent-relative events

I understand the utility of CaptureMouse firing events to allow
scrolling, but this escapes me. I've looked in scrlwing.cpp and
see where wxAutoScrollTimer::Notify finds the top-most parent:
while ( parentTop->GetParent() )
parentTop = parentTop->GetParent();

I would comment out those lines and also add a check that mouse
has moved since the last call. But my experience of the cpp
source is zero, so maybe I'm not seeing the big picture...

Phil

Robin Dunn

unread,
Jun 15, 2009, 7:37:20 PM6/15/09
to wxPytho...@googlegroups.com
Phil Mayes wrote:
> On Jun 15, 10:51 am, Robin Dunn <ro...@alldunn.com> wrote:
>> Phil Mayes wrote:
>>> If I capture the mouse in a scrolled window then drag outside the
>>> window, I get a stream of mouse events with incorrect coordinates,
>>> even when the mouse is not moving. Sample code attached and below.
>>> Any clues, anyone?
>> This is intentional. The extra events are sent to help facilitate
>> situations where you want to scroll the window while dragging. For
>> example, if you want to drag an item in a tree to another location in
>> the tree that is not visible yet.
>
> I can't see the benefit here. I am receiving a flood of MouseEvents
> with two types of coordinates, one relative to the captured window,
> and one relative to the parent;

This is the only problem here. See below.

> furthermore, I get events fired even
> when the mouse is stationary:

This is the way it is supposed to work. Doing it this way means that
you don't need to jiggle the mouse to make the drop target scroll some more.


> I understand the utility of CaptureMouse firing events to allow
> scrolling, but this escapes me. I've looked in scrlwing.cpp and
> see where wxAutoScrollTimer::Notify finds the top-most parent:
> while ( parentTop->GetParent() )
> parentTop = parentTop->GetParent();
>
> I would comment out those lines and also add a check that mouse
> has moved since the last call.

The problem that code is trying to solve (incorrectly IMO) is that the
mouse position used for the generated motion event is relative to the
screen, so it is trying to convert it to be relative to the window.
However it appears to be doing it incorrectly, simply adjusting by the
TLW's position. I thing that it instead should be using
m_win->ScreenToClient and not bother using the TLW parent at all...
Please create a trac ticket about this and we'll see what other wx-devs
think.

Phil Mayes

unread,
Jun 15, 2009, 8:25:18 PM6/15/09
to wxPython-users
On Jun 15, 4:37 pm, Robin Dunn <ro...@alldunn.com> wrote:
> This is the only problem here.  See below.
>
> > furthermore, I get events fired even
> > when the mouse is stationary:
>
> This is the way it is supposed to work.  Doing it this way means that
> you don't need to jiggle the mouse to make the drop target scroll some more.

Good point, though the checks in HandleOnMouseLeave to ignore exits
in non-scrollable directions don't seem to be honored.

> The problem that code is trying to solve (incorrectly IMO) is that the
> mouse position used for the generated motion event is relative to the
> screen, so it is trying to convert it to be relative to the window.
> However it appears to be doing it incorrectly, simply adjusting by the
> TLW's position.  I thing that it instead should be using
> m_win->ScreenToClient and not bother using the TLW parent at all...
> Please create a trac ticket about this and we'll see what other wx-devs
> think.

Ticket #10897 submitted.
Reply all
Reply to author
Forward
0 new messages