macOS, dual monitors, and the disappearing Dialog

Disappear.py (2.8 KB)

I’ve attached a little sample that shows a very strange issue I’m struggling with. I’m using python 3.7.8 and wxPython 4.1.1 on macOS Catalina and python 3.7.9 and wxPython 4.1.1 on WIndows 10.

If I create a sub-frame on macOS and drag that sub-frame to my other monitor, it loses its background color.

If I create a sub-dialog on macOS and drag that sub-dialog to my other monitor, it disappears. Poof! If I then create another sub-dialog, the first sub-dialog will pop up on the first monitor in the position it should have on the second monitor.

I do not experience this difficulty on Windows.

Anyone have any ideas for me? (I mean, other than “Don’t do that!”)

Thanks,
David

It looks like there is an event for that.

class PopupFrame(wx.Frame):
    def __init__(self, parent, title):
        ...
        self.Bind(wx.EVT_SYS_COLOUR_CHANGED, self.OnSysColourChanged)

    def OnSysColourChanged(self, evt):
        self.SetBackgroundColour(wx.CYAN)

I’m not seeing this problem, but i’m still on macOS 10.14 on this machine.

Thanks for the wx.EVT_SYS_COLOUR_CHANGED event tip.

I can confirm that neither problem occurs on macOS 10.14 Mojave.

Handling wx.EVT_SYS_COLOUR_CHANGED does the trick on macOS 10.15 Catalina. The sub-Dialog behavior is definitely different on Mojave and Catalina with the same wxPython version, 4.1.1, although I have different Python 3.7 versions on the two partitions.

David

Well, this is fun.

On Catalina, the wx.EVT_SYS_COLOUR_CHANGED method doesn’t need to DO anything. If you bind the method and give it nothing but “pass”, the color change does not occur. Remove the event binding and the color will change when you move the Frame to the new monitor.

Something like that is to be expected: If one handles a
callback, and then let the callback do nothing, it will
not do anything.

Karsten

Karsten, what is unexpected is that program behavior is different if I don’t bind the method vs. if I do bind the method even if the method is empty. Robin’s original suggestion was to use the method to explicitly reset the color. But simply binding the method is sufficient even if the method does nothing. In fact, the empty method DOES do something, in that it prevents the color of the dialog from changing.

Disappear.py (3.5 KB)

Two more tidbits.

  1. The sub-dialog reports itself as shown even when you can’t see it.

  2. The position of the sub-dialog is influenced by the position of the parent. If you move the parent, the sub-dialog will move in parallel. This is true even if the sub-dialog has disappeared. You can use this to move a disappeared subdialog back onto the original monitor, where it will become invisible again. And if you move the parent onto the second monitor, the sub-dialog will move in parallel and will remain visible. In contrast, a sub-frame will maintain its own position when you move the parent.

And all of this is true only on macOS Catalina, not macOS Mojave or Windows.

I can certainly see how that is surprising, but it shouldn’t
really be:

Simply binding the event already “does” something, namely
overriding the default action (here, a color change).

Doing anything in the handler would either be redundant
(re-setting the color) or would be doing something
additionally.

But, yeah, it can be perceived to be bewildering.

I wonder whether it makes a difference if the do-nothing
handler includes and “.Skip()” or not.

Karsten

It should cause the default handler to be called after the current handler returns, so it would just restore the (unwanted) default behavior.

I’m curious, has anybody been able to reproduce the issue I
describe on macOS Catalina (10.15)?

  I know Robin tried and was unable to reproduce it on Mojave

(10.14), and I can’t produce it on Mojave either.

  I need to make sure it's not just something ideosyncratic about

my Mac.

David

I know this issue has dropped off the radar, which surprises me because my dialog boxes FREAKING DISAPPEAR whenever I move them to another monitor, often rendering my program frozen and forcing me to invoke Force Quit. It’s really quite an impossible situation. But for reasons that elude me, nobody else is talking about it.

I have determined that this issue appears to be limited to macOS Catalina, at least as demonstrated in my simple sample program. It does not occur on macOS 10.14 Mojave, nor on macOS 11.0 Big Sur, but it occurs perfectly reliably on macOS 10.15 Catalina. I need to see if it happens with wxPython’s Standard Dialog boxes like the MessageDialog() and FileDialog(), which I’ve unfortunately been too distracted to pursue. (I had a kid in the hospital.)

David