CaptureMouse in ScrolledWindow generates spurious events

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()

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

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

···

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.

Phil Mayes 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.

···

On Jun 15, 10:51 am, Robin Dunn <ro...@alldunn.com> wrote:

--
Robin Dunn
Software Craftsman

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.

···

On Jun 15, 4:37 pm, Robin Dunn <ro...@alldunn.com> wrote: