Destroying window before releasing mouse capture: this will result in a crash later

119 views
Skip to first unread message

Andreas Falkenhahn

unread,
Aug 17, 2020, 10:02:46 AM8/17/20
to wx-u...@googlegroups.com
I'm getting this message and it makes sense because it appears when I'm trying to exit my app at a time when the mouse has been captured using CaptureMouse(). However, I'm wondering why wxWidgets doesn't simply release the mouse capture itself instead of nagging about it?

FWIW, I've tried to do it manually by adding the following to the destructor of the wxWindow that has called CaptureMouse():

if(HasCapture()) ReleaseCapture();

But this doesn't solve the problem either because now I get the error "window that captured the mouse didn't process wxEVT_MOUSE_CAPTURE_LOST". This is very strange because I do process wxEVT_MOUSE_CAPTURE_LOST. It looks like this:

void wxMyClass::OnMouseCaptureLost(wxMouseCaptureLostEvent &event)
{
event.Skip();
}

I'm pretty confused now. How can I fix this?

--
Best regards,
Andreas Falkenhahn mailto:and...@falkenhahn.com

Vadim Zeitlin

unread,
Aug 17, 2020, 10:27:38 AM8/17/20
to wx-u...@googlegroups.com
On Mon, 17 Aug 2020 16:03:08 +0200 Andreas Falkenhahn wrote:

AF> I'm getting this message and it makes sense because it appears when I'm
AF> trying to exit my app at a time when the mouse has been captured using
AF> CaptureMouse(). However, I'm wondering why wxWidgets doesn't simply
AF> release the mouse capture itself instead of nagging about it?

Because in 99% of cases you need to do something else than just releasing
the capture when it's lost, i.e. update some internal flags telling that
the mouse is being dragged or something like this.

AF> FWIW, I've tried to do it manually by adding the following to the
AF> destructor of the wxWindow that has called CaptureMouse():
AF>
AF> if(HasCapture()) ReleaseCapture();
AF>
AF> But this doesn't solve the problem either because now I get the error
AF> "window that captured the mouse didn't process
AF> wxEVT_MOUSE_CAPTURE_LOST". This is very strange because I do process
AF> wxEVT_MOUSE_CAPTURE_LOST. It looks like this:
AF>
AF> void wxMyClass::OnMouseCaptureLost(wxMouseCaptureLostEvent &event)
AF> {
AF> event.Skip();
AF> }
AF>
AF> I'm pretty confused now. How can I fix this?

And you do this "something else" in wxEVT_MOUSE_CAPTURE_LOST handler, so
it's quite surprising that your handler is empty. But it can be empty, of
course, if you really have nothing to do.

Of course, you must not call Skip() in it if you want to indicate that
you've handled the event -- calling Skip() means exactly the converse.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Andreas Falkenhahn

unread,
Aug 17, 2020, 10:35:51 AM8/17/20
to Vadim Zeitlin
On 17.08.2020 at 16:27 Vadim Zeitlin wrote:

> On Mon, 17 Aug 2020 16:03:08 +0200 Andreas Falkenhahn wrote:

AF>> I'm getting this message and it makes sense because it appears when I'm
AF>> trying to exit my app at a time when the mouse has been captured using
AF>> CaptureMouse(). However, I'm wondering why wxWidgets doesn't simply
AF>> release the mouse capture itself instead of nagging about it?

> Because in 99% of cases you need to do something else than just releasing
> the capture when it's lost, i.e. update some internal flags telling that
> the mouse is being dragged or something like this.

Yes, but I don't need this. I'm just calling CaptureMouse() to get mouse
move events for the whole screen while a button is down instead of just
for my wxWindow's area.

> Of course, you must not call Skip() in it if you want to indicate that
> you've handled the event -- calling Skip() means exactly the converse.

Thanks, that's it. Removing Skip() fixes the issue.

Eric Jensen

unread,
Aug 17, 2020, 11:58:02 AM8/17/20
to Vadim Zeitlin
Hello Vadim,

Monday, August 17, 2020, 4:27:34 PM, you wrote:

VZ> Of course, you must not call Skip() in it if you want to indicate that
VZ> you've handled the event -- calling Skip() means exactly the converse.

I know from the wx forum that many wx beginner have problems with
this. How about adding a synonym ContinueProcessing() or similar?

Eric



--

Vadim Zeitlin

unread,
Aug 17, 2020, 5:44:14 PM8/17/20
to wx-u...@googlegroups.com
On Mon, 17 Aug 2020 17:58:17 +0200 Eric Jensen wrote:

EJ> Monday, August 17, 2020, 4:27:34 PM, you wrote:
EJ>
EJ> VZ> Of course, you must not call Skip() in it if you want to indicate that
EJ> VZ> you've handled the event -- calling Skip() means exactly the converse.
EJ>
EJ> I know from the wx forum that many wx beginner have problems with
EJ> this. How about adding a synonym ContinueProcessing() or similar?

Hello Eric,

I agree that Skip() is confusing, but I'm really not sure that adding
another synonym for it can help the matters.

In fact, even leaving this, and compatibility considerations aside, I
still don't know what the ideal API would look like. There are several
conflicting goals for it:

1. It should do the right thing by default, i.e. some events should be
skipped by default (notorious example: focus), while other shouldn't
be (command events).

2. It should be possible to let the default handling to take place while
still keeping the user-defined handlers, e.g. ideally we'd have
CallNextHandler() and CallDefaultHandler().

3. Because of (1), we should also have SkipNextHandler() and also
SkipDefaultHandler().

4. But it should also be simple and 1+2+3 is anything but.

So I just honestly have no idea what's the best way to do it. I'd like to
compare how do the other toolkits (including HTML DOM) handle this, all I
know so far is that GTK way is not great neither, but probably is still
better than ours (in GTK you need to stop propagating the signal because it
is propagated by default).

Stefan Csomor

unread,
Aug 19, 2020, 3:36:50 AM8/19/20
to wx-u...@googlegroups.com
Hi

Am 17.08.20, 23:44 schrieb "Vadim Zeitlin" <wx-u...@googlegroups.com im Auftrag von va...@wxwidgets.org>:
I also think that we should do something here, perhaps just some naming or aptly named parameter values together with an overload might already help, if we don't come to a more elaborate solution.

A few comparisons

In my 4th GL, Omnis

I have a command "Quit event handler" that has two options "Discard Event" and "Pass to Next Handler"

In Cocoa

There is the notion of a responder on an object, it is a subclass of NSResponder. That's your handler. A responder can have a nextResponder, this forms the responder chain. You have to override the eventMethods you are interested in, eg mouseDown:, if you are handling this and you want to pass it on, you must call [super mouseDown], that way potential superclass handlers first get their chance, before the NSResponder itself can forward the call to the nextResponder, if it is a event that gets forwarded that way at all. Only in special cases you should forgo all the superclass handlers can call [self nextResponder] mouseDown yourself.

In contrast to these so called Event Messages there are also Action Messages, comparable to our commands, ie the method that gets called when a button gets clicked or a menu item selected are a little bit more complicated,

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW2

JavaScript

anyone more fluent please correct me - an Event Handler (which is also called Event Listener, making the situation of multiple 'handlers' more obvious to me) for an event that usually gets propagated does have to call stopPropagation on the vent to stop further processing in 'user handlers'. And there's the concept of 'default' ie built-in handlers, if you don't want that one to jump in after the user handlers you have to call preventDefault on the event

Thanks,

Stefan


QuentinC

unread,
Aug 21, 2020, 2:35:47 AM8/21/20
to wx-u...@googlegroups.com
Hello,

@VZ
> I'd like to compare how do the other toolkits (including HTML DOM)
handle this


In HTML5/DOM/ you have three methods: preventDefault, stopPropagation
and stopImmediatePropagation.
I don't find it super clear what exactly the difference is between the
three. You can have a look at stackoverflow, there are a lot of
questions about what to call or not to call when.

Speaking about doing the right thing by default, HTML5 also have its
total stupidities. Notable example, drag and drop. If I recall
correctly, the first thing you have to do is to preventDefault in order
to allow the drag and the drop to take place, otherwise it is blocked by
default and nothing happens. Also a lot of questions why the cursor
doesn't change shape to show the drag&drop taking place and the like.

Additionnally to those three methods, you ahve the old way to handle
this by returning true or false. It's worse: you never know which does
which.

So I'm not sure that HTML5 is really better.

The same problem of return true or false exists in win32 and it's
unclear too.

The advantage of return value is that you have to decide something, and
write it explicitely.
Perhaps it would be interesting to return an enum instead of a bool ?
something like CALL_DEFAULT / PROPAGATE / DONE.
Unfortunately this would totally break WX compatibility.

Vadim Zeitlin

unread,
Aug 21, 2020, 6:18:29 AM8/21/20
to wx-u...@googlegroups.com
Thanks to your replies, I'm replying to both of them to avoid bifurcating
the thread:

On Wed, 19 Aug 2020 07:36:45 +0000 Stefan Csomor wrote:

SC> I also think that we should do something here, perhaps just some naming
SC> or aptly named parameter values together with an overload might already
SC> help, if we don't come to a more elaborate solution.
SC>
SC> A few comparisons
SC>
SC> In my 4th GL, Omnis
SC>
SC> I have a command "Quit event handler" that has two options "Discard
SC> Event" and "Pass to Next Handler"

But what is the default behaviour? Or do you have to use one of those 2
commands?

SC> In Cocoa
SC>
SC> There is the notion of a responder on an object, it is a subclass of
SC> NSResponder. That's your handler. A responder can have a nextResponder,
SC> this forms the responder chain. You have to override the eventMethods
SC> you are interested in, eg mouseDown:, if you are handling this and you
SC> want to pass it on, you must call [super mouseDown],

This is close to what C++ does (except for ctors and dtors) and has the
advantage that you can call the default handler before, or in the middle,
of your own handling code, instead of only after it. However it has an
important drawback too: I don't think it's universally implementable. E.g.
HTML5 API, discussed below, doesn't seem to provide anything like this.
As another random example, looking at Android UI events documentation
(https://developer.android.com/guide/topics/ui/ui-events), this doesn't
seem possible there neither. So I don't think we can guarantee such API on
all platforms.

Besides, in my own experience with wx PushEventHandler(), which is rather
next-responder-like, using it often results in unclear and fragile code and
Bind() is much simpler and less error-prone, so I wouldn't really regret
not having anything like this in an event handling API.

SC> In contrast to these so called Event Messages there are also Action
SC> Messages, comparable to our commands

This is another thing I was wondering about: does it really make sense to
distinguish between command events and all the rest? Our experience seems
to show that people expect all events to bubble up

SC> JavaScript
SC>
SC> anyone more fluent please correct me - an Event Handler (which is also
SC> called Event Listener, making the situation of multiple 'handlers' more
SC> obvious to me)

Yes, I agree that from the terminological point of view "listener" is
better than "handler", which is more final. OTOH it makes sense to talk
about the "default handler", but not so much about "default listener". So
even this is not obvious :-(

SC> for an event that usually gets propagated does have to call
SC> stopPropagation on the vent to stop further processing in 'user
SC> handlers'. And there's the concept of 'default' ie built-in handlers,
SC> if you don't want that one to jump in after the user handlers you have
SC> to call preventDefault on the event

One thing to notice is that stopPropagation() "skips" the other handlers
defined in the program, but still allows the default handling to take
place. I think this is useful, but it's not supported by wx currently.

On Fri, 21 Aug 2020 08:35:31 +0200 QuentinC wrote:

Q> In HTML5/DOM/ you have three methods: preventDefault, stopPropagation
Q> and stopImmediatePropagation.
Q> I don't find it super clear what exactly the difference is between the
Q> three.

I think MDN explains it rather clearly. It's interesting that calling
preventDefault() doesn't actually prevent default processing for some
events, as this is something I thought about implementing for some wx
events (e.g. focus ones) too, as you (almost?) always want the default
processing to take place for them. This "almost?" part has prevented me
from doing it, because I couldn't conclusively prove, even to myself, that
there were no cases in which this could be useful. But if we're discussing
backwards-incompatible changes anyhow, this is something I'd definitely
consider doing.

Q> The advantage of return value is that you have to decide something, and
Q> write it explicitely.
Q> Perhaps it would be interesting to return an enum instead of a bool ?
Q> something like CALL_DEFAULT / PROPAGATE / DONE.

One problem with this is that you need to have an extra statement in all
your event handlers. It might not sound like a lot, but if you have many
simple handlers, this gets unnecessarily verbose and it seems like there
ought to be a reasonable default. OTOH having a mandatory "return" is, of
course, more explicit.

Q> Unfortunately this would totally break WX compatibility.

All this discussion is about some new/parallel event system, replacing the
current one. I don't think we can really do anything about the existing API
without subtly (i.e. horribly) breaking tons of existing code.
Reply all
Reply to author
Forward
0 new messages