fix wxTipWindow construction sequencing (PR #26071)

54 views
Skip to first unread message

Bill Su

unread,
Jan 4, 2026, 1:53:19 PMJan 4
to wx-...@googlegroups.com, Subscribed

You can view, comment on, or merge this pull request online at:

  https://github.com/wxWidgets/wxWidgets/pull/26071

Commit Summary

  • 2e51fe3 wxTipWindow: avoid race condition by using two-phase construction
  • f005074 wxTipWindow: safe one-phase construction

File Changes

(6 files)

Patch Links:


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/pull/26071@github.com>

Bill Su

unread,
Jan 4, 2026, 1:57:15 PMJan 4
to wx-...@googlegroups.com, Push

@wsu-cb pushed 1 commit.

  • dd743a0 wxTipWindow: safe one-phase construction


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26071/before/f005074fecf360d067fa11557028933324025d2b/after/dd743a035e54fca0f385ce9f5cb23fbf3f3b9d80@github.com>

Bill Su

unread,
Jan 4, 2026, 4:58:25 PMJan 4
to wx-...@googlegroups.com, Push

@wsu-cb pushed 1 commit.

  • 94a4164 wxTipWindow: safe one-phase construction


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26071/before/4a152fd13e0b637395bf83338152f2a3f07c60da/after/94a416499fb095f0b0da67e4d26802bffadf8266@github.com>

VZ

unread,
Jan 5, 2026, 3:14:15 PMJan 5
to wx-...@googlegroups.com, Subscribed

@vadz commented on this pull request.

Thanks, this looks nice, but I think that adding IsOk() or operator!=(nullptr_t) is needed to make using this even more natural.

Also, if the use of unique_ptr for Ref::p is really required, please add a comment explaining why as I just don't see it (and please rename p to something with m_ prefix in any case).

TIA!


In interface/wx/tipwin.h:

> @@ -25,7 +25,77 @@ class wxTipWindow : public wxWindow
 {
 public:
     /**
-        Constructor. The tip is shown immediately after the window is constructed.
+        The (weak) reference of class wxTipWindow
+
+        wxTipWindow may close itself, so provide a smart pointer
+        that acts as a weak reference to wxTipWindow.
+
+        This is a move-only type.
+
+        Note that this is not a wxWeakRef<> because this is set
+        to @NULL when wxTipWindow is closed, which may be
+        "long" before wxTipWindow is destroyed, and wxWeakRef<>
+        is set to @NULL on object destruction.
+    */

Please add

⬇️ Suggested change
-    */
+        
+        @since 3.3.2
+    */

here and for the new functions below.


In samples/dialogs/dialogs.cpp:

>                            );
     }
 }
 
 void MyFrame::OnUpdateShowTipUI(wxUpdateUIEvent& event)
 {
-    event.Check(m_tipWindow != nullptr);
+    event.Check(bool(m_tipWindow));

I think this shows that we need IsOk() member function in Ref.

Or, maybe, implement operator!=() for it?


In src/html/helpctrl.cpp:

> @@ -314,11 +314,11 @@ bool wxHtmlHelpController::DisplayTextPopup(const wxString& text, const wxPoint&
         s_tipWindow->SetTipWindowPtr(nullptr);
         s_tipWindow->Close();
     }
-    s_tipWindow = nullptr;
+    s_tipWindow.Reset();

In theory we could also keep this working and avoid this change by providing overloaded operator=(std::nullptr_t). Not sure if it's really much better than Reset().


In include/wx/tipwin.h:

> +    // Note that this is not a wxWeakRef<> because this is set
+    // to nullptr when wxTipWindow is closed, which may be
+    // "long" before wxTipWindow is destroyed, bug wxWeakRef<>
+    // is set to nullptr on object destruction
+    class Ref
+    {
+    public:
+        Ref() { *p = nullptr; }
+
+        void Reset() { *p = nullptr; }
+
+        explicit operator bool() const { return *p; }
+        wxTipWindow* operator->() const { wxASSERT(*p);  return *p; }
+
+    private:
+        std::unique_ptr<wxTipWindow*> p { new wxTipWindow* };

Sorry, I may be missing something obvious but why do we need to use std::unique_ptr here when it looks like we could just have wxTipWindow* m_ptr; and replace *p above with m_ptr?


In include/wx/tipwin.h:

> +    //
+    // Note that this is a move-only type.
+    //
+    // Note that this is not a wxWeakRef<> because this is set
+    // to nullptr when wxTipWindow is closed, which may be
+    // "long" before wxTipWindow is destroyed, bug wxWeakRef<>
+    // is set to nullptr on object destruction
+    class Ref
+    {
+    public:
+        Ref() { *p = nullptr; }
+
+        void Reset() { *p = nullptr; }
+
+        explicit operator bool() const { return *p; }
+        wxTipWindow* operator->() const { wxASSERT(*p);  return *p; }

This wxASSERT() is pretty useless, it's going to crash in any case and it doesn't add anything helpful in debug builds (asserting or crashing at this line is about the same).


In include/wx/tipwin.h:

> @@ -26,15 +26,56 @@ class WXDLLIMPEXP_FWD_CORE wxTipWindowView;
 class WXDLLIMPEXP_CORE wxTipWindow : public wxPopupTransientWindow
 {
 public:
-    // the mandatory ctor parameters are: the parent window and the text to
+    // wxTipWindow may close itself, so provide a smart pointer
+    // that acts as a weak reference to wxTipWindow.
+    //
+    // Note that this is a move-only type.

Can it actually be moved? I think you need to provide move ctor/assignment operator (but they can be = default).


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/pull/26071/review/3628248939@github.com>

Bill Su

unread,
Jan 5, 2026, 9:41:30 PMJan 5
to wx-...@googlegroups.com, Subscribed

@wsu-cb commented on this pull request.


In samples/dialogs/dialogs.cpp:

> @@ -2858,21 +2854,20 @@ void MyFrame::OnShowTip(wxCommandEvent& WXUNUSED(event))
     }
     else
     {
-        m_tipWindow = new wxTipWindow
+        m_tipWindow = wxTipWindow::New

This line proves that wxTipWindow::Ref is moveable.


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/pull/26071/review/3629114955@github.com>

Bill Su

unread,
Jan 5, 2026, 9:45:38 PMJan 5
to wx-...@googlegroups.com, Subscribed

@wsu-cb commented on this pull request.


In include/wx/tipwin.h:

> @@ -26,15 +26,56 @@ class WXDLLIMPEXP_FWD_CORE wxTipWindowView;
 class WXDLLIMPEXP_CORE wxTipWindow : public wxPopupTransientWindow
 {
 public:
-    // the mandatory ctor parameters are: the parent window and the text to
+    // wxTipWindow may close itself, so provide a smart pointer
+    // that acts as a weak reference to wxTipWindow.
+    //
+    // Note that this is a move-only type.

See https://github.com/wxWidgets/wxWidgets/pull/26071/files#r2663388851. (The std::unique_ptr<> provides move ctor/assignment, and any class ctor or assignment automatically uses its members ctor or assignment unless they are blocked somehow. See https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rc-zero).


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/pull/26071/review/3629129131@github.com>

Bill Su

unread,
Jan 5, 2026, 10:54:20 PMJan 5
to wx-...@googlegroups.com, Push

@wsu-cb pushed 1 commit.

  • fcec3ce wxTipWindow: implement code review requests


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26071/before/94a416499fb095f0b0da67e4d26802bffadf8266/after/fcec3ce3a0a8c7004ae4100edb62489f6a188b18@github.com>

Bill Su

unread,
Jan 5, 2026, 10:55:58 PMJan 5
to wx-...@googlegroups.com, Subscribed

@wsu-cb commented on this pull request.


In interface/wx/tipwin.h:

> @@ -25,7 +25,77 @@ class wxTipWindow : public wxWindow
 {
 public:
     /**
-        Constructor. The tip is shown immediately after the window is constructed.
+        The (weak) reference of class wxTipWindow
+
+        wxTipWindow may close itself, so provide a smart pointer
+        that acts as a weak reference to wxTipWindow.
+
+        This is a move-only type.
+
+        Note that this is not a wxWeakRef<> because this is set
+        to @NULL when wxTipWindow is closed, which may be
+        "long" before wxTipWindow is destroyed, and wxWeakRef<>
+        is set to @NULL on object destruction.
+    */

done


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/pull/26071/review/3629253198@github.com>

Bill Su

unread,
Jan 5, 2026, 10:57:18 PMJan 5
to wx-...@googlegroups.com, Subscribed

@wsu-cb commented on this pull request.


In samples/dialogs/dialogs.cpp:

>                            );
     }
 }
 
 void MyFrame::OnUpdateShowTipUI(wxUpdateUIEvent& event)
 {
-    event.Check(m_tipWindow != nullptr);
+    event.Check(bool(m_tipWindow));

implemented operator!=(nullptr_t)


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/pull/26071/review/3629257220@github.com>

Bill Su

unread,
Jan 5, 2026, 10:57:38 PMJan 5
to wx-...@googlegroups.com, Subscribed

@wsu-cb commented on this pull request.


In src/html/helpctrl.cpp:

> @@ -314,11 +314,11 @@ bool wxHtmlHelpController::DisplayTextPopup(const wxString& text, const wxPoint&
         s_tipWindow->SetTipWindowPtr(nullptr);
         s_tipWindow->Close();
     }
-    s_tipWindow = nullptr;
+    s_tipWindow.Reset();

implemented operator=(nullptr_t)


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/pull/26071/review/3629258113@github.com>

Bill Su

unread,
Jan 5, 2026, 10:58:59 PMJan 5
to wx-...@googlegroups.com, Subscribed

@wsu-cb commented on this pull request.


In include/wx/tipwin.h:

> +    //
+    // Note that this is a move-only type.
+    //
+    // Note that this is not a wxWeakRef<> because this is set
+    // to nullptr when wxTipWindow is closed, which may be
+    // "long" before wxTipWindow is destroyed, bug wxWeakRef<>
+    // is set to nullptr on object destruction
+    class Ref
+    {
+    public:
+        Ref() { *p = nullptr; }
+
+        void Reset() { *p = nullptr; }
+
+        explicit operator bool() const { return *p; }
+        wxTipWindow* operator->() const { wxASSERT(*p);  return *p; }

wxASSERT() removed


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/pull/26071/review/3629261266@github.com>

Bill Su

unread,
Jan 5, 2026, 11:00:22 PMJan 5
to wx-...@googlegroups.com, Subscribed

@wsu-cb commented on this pull request.


In include/wx/tipwin.h:

> +    // Note that this is not a wxWeakRef<> because this is set
+    // to nullptr when wxTipWindow is closed, which may be
+    // "long" before wxTipWindow is destroyed, bug wxWeakRef<>
+    // is set to nullptr on object destruction
+    class Ref
+    {
+    public:
+        Ref() { *p = nullptr; }
+
+        void Reset() { *p = nullptr; }
+
+        explicit operator bool() const { return *p; }
+        wxTipWindow* operator->() const { wxASSERT(*p);  return *p; }
+
+    private:
+        std::unique_ptr<wxTipWindow*> p { new wxTipWindow* };

done


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/pull/26071/review/3629262925@github.com>

Bill Su

unread,
Jan 5, 2026, 11:32:52 PMJan 5
to wx-...@googlegroups.com, Push

@wsu-cb pushed 1 commit.

  • aae8aed wxTipWindow: implement code review requests


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26071/before/fcec3ce3a0a8c7004ae4100edb62489f6a188b18/after/aae8aed2c55825f505cc82f39ac5c9720ad5b44c@github.com>

VZ

unread,
Jan 6, 2026, 1:10:08 PMJan 6
to wx-...@googlegroups.com, Subscribed

@vadz commented on this pull request.


In include/wx/tipwin.h:

> @@ -26,15 +26,56 @@ class WXDLLIMPEXP_FWD_CORE wxTipWindowView;
 class WXDLLIMPEXP_CORE wxTipWindow : public wxPopupTransientWindow
 {
 public:
-    // the mandatory ctor parameters are: the parent window and the text to
+    // wxTipWindow may close itself, so provide a smart pointer
+    // that acts as a weak reference to wxTipWindow.
+    //
+    // Note that this is a move-only type.

Yes, you're right, sorry for overlooking this.

I know that this class is hardly performance-critical, but it still makes me cringe a little that we use an extra heap allocation just to move this movable. It looks like using a raw pointer and deleting special copy member functions and implementing move ones shouldn't be that difficult and would avoid it...


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/pull/26071/review/3631933932@github.com>

Bill Su

unread,
Jan 7, 2026, 12:09:24 AMJan 7
to wx-...@googlegroups.com, Push

@wsu-cb pushed 1 commit.

  • b19cd01 wxTipWindow: avoid unnecessary heap use


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26071/before/aae8aed2c55825f505cc82f39ac5c9720ad5b44c/after/b19cd019f249db2074d174878d992a9997f1df0d@github.com>

VZ

unread,
Jan 7, 2026, 9:14:46 AMJan 7
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26071)

Great, thanks! Will merge soon.


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/pull/26071/c3719080829@github.com>

VZ

unread,
Jan 8, 2026, 5:05:01 PMJan 8
to wx-...@googlegroups.com, Subscribed

Closed #26071 via 96eca64.


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/pull/26071/issue_event/21933885945@github.com>

Reply all
Reply to author
Forward
0 new messages