The hidden wxFrame is shown automatically and can not be hidden after restoring from minimize (Issue #23997)

44 views
Skip to first unread message

EDI Systems

unread,
Oct 25, 2023, 5:32:31 AM10/25/23
to wx-...@googlegroups.com, Subscribed

Description

See https://github.com/wxWidgets/Phoenix/issues/1606 for detailed problem description and reproduction.
I can confirm that this is a bug in the wxWidgets core, not in the wxPython binding, as I'm using C++.

Platform and version information

  • wxWidgets version you use: 3.2.1
  • wxWidgets port you use: wxMSW
  • OS and its version: Windows 10 22H2


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23997@github.com>

VZ

unread,
Oct 25, 2023, 11:41:59 AM10/25/23
to wx-...@googlegroups.com, Subscribed

It's not clear if this is specific to wxFRAME_FLOAT_ON_PARENT or not. Translating Python code to C++ shouldn't be difficult, and would be the first step towards debugging this, but I just don't have time to do it now, sorry. Any help with this would, of course, be welcome.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23997/1779562159@github.com>

PB

unread,
Oct 25, 2023, 1:53:16 PM10/25/23
to wx-...@googlegroups.com, Subscribed

FWIW, here is the patch to the minimal sample and how to reproduce the issue there.

iff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index 5f32257c6b..d068a9b7fe 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
@@ -53,6 +53,23 @@ public:
     virtual bool OnInit() override;
 };
 
+class SubFrame: public wxFrame
+{
+public:
+    SubFrame(wxWindow* parent)
+        : wxFrame (parent, wxID_ANY, "SubFrame", wxDefaultPosition, wxSize(300, 300),
+                   wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxMINIMIZE_BOX | wxFRAME_NO_TASKBAR
+#if 1
+                   | wxFRAME_FLOAT_ON_PARENT
+#endif
+        )
+    {
+        Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent&){ wxLogDebug("Hiding SubFrame"); Hide(); });
+        Show();
+    }
+};
+
+
 // Define a new frame type: this is going to be our main frame
 class MyFrame : public wxFrame
 {
@@ -175,6 +192,8 @@ MyFrame::MyFrame(const wxString& title)
     CreateStatusBar(2);
     SetStatusText("Welcome to wxWidgets!");
 #endif // wxUSE_STATUSBAR
+
+    new SubFrame(this);
 }
 
 
  1. Run the patched sample.
  2. Minimize the main frame to the taskbar.
  3. Restore the main frame from the taskbar.
  4. Click the X caption button (close window) on SubFrame to hide it.
  5. Minimize the main frame to the taskbar.
  6. Restore the main frame from the taskbar.
  7. Observe that SubFrame becomes visible and clicking X (i.e., calling its Hide()) no longer hides it.

I did not attempt to look into the issue but it seems that presence of wxFRAME_FLOAT_ON_PARENT does make a difference.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23997/1779774296@github.com>

VZ

unread,
Oct 29, 2023, 1:18:40 PM10/29/23
to wx-...@googlegroups.com, Subscribed

Thanks, I can reproduce this. Using wxFRAME_TOOL_WINDOW (in addition or instead of the other style) could be a workaround, I think.

The real bug is due to the fact that Windows decides to restore the child ("owned") frames on its own when restoring the parent ("owner"), it's not wx code which does it, as it already has checks in place for this case, see https://github.com/wxWidgets/wxWidgets/blob/8fc73d45ce22d69d1173a4ac9e7cf16562edbb89/src/msw/frame.cpp#L705-L708

So to really fix this we need to ignore the call to show the window when it's being shown by Windows just because its owner was restored. This should be doable but is not trivial.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23997/1784173650@github.com>

EDI Systems

unread,
Nov 6, 2023, 1:47:36 AM11/6/23
to wx-...@googlegroups.com, Subscribed

Thanks, I can reproduce this. Using wxFRAME_TOOL_WINDOW (in addition or instead of the other style) could be a workaround, I think.

The real bug is due to the fact that Windows decides to restore the child ("owned") frames on its own when restoring the parent ("owner"), it's not wx code which does it, as it already has checks in place for this case, see

https://github.com/wxWidgets/wxWidgets/blob/8fc73d45ce22d69d1173a4ac9e7cf16562edbb89/src/msw/frame.cpp#L705-L708

So to really fix this we need to ignore the call to show the window when it's being shown by Windows just because its owner was restored. This should be doable but is not trivial.

Yes, wx already checks this case. I've looked through the source and did not catch anything weird.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23997/1794180061@github.com>

rudolfwalter

unread,
Mar 24, 2026, 9:46:38 AMMar 24
to wx-...@googlegroups.com, Subscribed
rudolfwalter left a comment (wxWidgets/wxWidgets#23997)

I also encountered this bug.

My limited investigation seems to indicate that wxWidgets doesn't take into account the various types of WM_SHOWWINDOW message, particularly the SW_PARENTOPENING type.

The follow patch fixes the symptoms for me:

diff --git a/src/msw/window.cpp b/src/msw/window.cpp
index 0522e6e7d9..6c0d4b07f9 100644
--- a/src/msw/window.cpp
+++ b/src/msw/window.cpp
@@ -3166,7 +3166,11 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result,
             break;

         case WM_SHOWWINDOW:
-            processed = HandleShow(wParam != 0, (int)lParam);
+            if (!m_isShown && lParam == SW_PARENTOPENING) {
+                processed = true;
+            } else {
+                processed = HandleShow(wParam != 0, (int)lParam);
+            }
             break;

         case WM_MOUSEMOVE:

...but note that I have not thought about or tested whether this is a good idea in general or if it breaks anything else, nor did I consider if the related SW_PARENTCLOSING should be handled too in any way.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23997/4118447693@github.com>

VZ

unread,
Mar 24, 2026, 11:00:33 AMMar 24
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#23997)

Thanks, I completely forgot about SW_PARENTOPENING but this indeed looks like the right thing to do, except that I'd probably do it at wxNonOwnedWindow level. We probably don't need to handle SW_PARENTCLOSING because we hide the children ourselves anyhow (maybe we could avoid doing this, but I'd rather not change the existing code without a good reason).

I'll try to make a PR soon, thanks again for the idea.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23997/4118991900@github.com>

VZ

unread,
Apr 15, 2026, 10:22:02 PM (8 days ago) Apr 15
to wx-...@googlegroups.com, Subscribed

Closed #23997 as completed via 922c5cc.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issue/23997/issue_event/24550847248@github.com>

Reply all
Reply to author
Forward
0 new messages