Some testing here reveals it happens on mouseDown, but not on mouseEnter or mouseUp. In both the latter two cases, the window closes, end of story. Xojo 2023 r1.1 under macOS Catalina.
Hey guys, thanks for the interest, I’m going to bow out now. It was only a quirk that I found this as I don’t usually call the Close from the rectangle anyway.
You’ve given me something to tinker with tho, I’ll have a look at canvases as another way to do this. I’ll leave the technical riddle of this issue to you guys
Barry
I have a similar issue with 2021r2.1 if I call App.Quit while a window opened via MouseDown on a GroupBox is still open. I can close the window without error but quitting the app with that window open crashes every time. My workaround is to close the window, if open, in App.CancelClose.
Finding bugs comes from “oh, that looks odd”.
Both a bug and a quirk
The bug is this (and could/should be reported, just in case):
The crash / stack trace very much looks like this.
Certainly something that Xojo could fix.
I agree that MouseDown
is the wrong place for actions (and it would even “magically fix” this bug if you’d close the Window in MouseUp
)… because:
And to finish why I agree that it’s both bug (see above) and a quirk:
Over the years I came across quite some issues when trying to do things like this in (Mouse) Events. Another one is showing a Modal Dialog out of these places. Sometimes it’s a macOS-issue, others Windows-issues.
In short: One shouldn’t do “blocking” or “destroying” things in these (Mouse / Key) Events.
Especially when Events come in pairs, such as MouseDown
→ MouseUp
.
Again: Actions in MouseUp
. MouseDown
is just to return true
if you intend to handle the MouseUp
Event in your code.
Just try to think that these two events belong together. It doesn’t make sense to “remove” the Window/Control when it is expected that the second Event will/should happen later.
And for those rare and “to be avoided” cases the “ugly workaround” would be to schedule your action a tiny bit later (in a different RunLoop) e.g. by using a Timer
:
Function MouseDown(x As Integer, y As Integer) Handles MouseDown as Boolean
Timer.CallLater(1, AddressOf Self.Close)
Return True
End Function
Sub MouseUp(x As Integer, y As Integer) Handles MouseUp
' Empty
End Sub