From 74ea434841c8dfa735ea78db24d2cb232d3cc955 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Tue, 28 Jul 2026 15:54:27 -0700 Subject: [PATCH] Add a function to perform internal processing of wxSysColourChangedEvent This avoids the chronic problem of wxSysColourChangedEvent handlers inadvertently failing to call Skip() and thus blocking important internal processing, including propagating to child windows. --- include/wx/msw/frame.h | 7 +++---- include/wx/msw/window.h | 4 +--- include/wx/osx/frame.h | 4 +++- include/wx/window.h | 3 ++- src/common/prntbase.cpp | 4 +--- src/common/wincmn.cpp | 11 ++++++----- src/generic/calctrlg.cpp | 4 +--- src/generic/statusbr.cpp | 3 +-- src/gtk/settings.cpp | 4 +--- src/gtk/toplevel.cpp | 4 +--- src/msw/frame.cpp | 13 ++----------- src/msw/window.cpp | 23 ++++++++--------------- src/osx/carbon/frame.cpp | 12 +++--------- src/osx/carbon/mdi.cpp | 4 +--- src/osx/cocoa/nonownedwnd.mm | 8 ++------ 15 files changed, 36 insertions(+), 72 deletions(-) diff --git a/include/wx/msw/frame.h b/include/wx/msw/frame.h index f10cec64e7..ebcba5204b 100644 --- a/include/wx/msw/frame.h +++ b/include/wx/msw/frame.h @@ -16,6 +16,7 @@ class WXDLLIMPEXP_FWD_CORE wxTaskBarButton; class WXDLLIMPEXP_CORE wxFrame : public wxFrameBase { + typedef wxFrameBase BaseType; public: // construction wxFrame() { Init(); } @@ -47,9 +48,6 @@ public: // implementation only from now on // ------------------------------- - // event handlers - void OnSysColourChanged(wxSysColourChangedEvent& event); - // Toolbar #if wxUSE_TOOLBAR virtual wxToolBar* CreateToolBar(long style = -1, @@ -88,6 +86,8 @@ public: // override the base class function to handle iconized/maximized frames virtual void SendSizeEvent(int flags = 0) override; + virtual void SendSysColourChangedEvents() override; + virtual wxPoint GetClientAreaOrigin() const override; // override base class version to add menu bar accel processing @@ -186,7 +186,6 @@ private: wxTaskBarButton* m_taskBarButton; #endif - wxDECLARE_EVENT_TABLE(); wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxFrame); }; diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 771de072c1..2b362bcf16 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -544,8 +544,7 @@ public: wxShowEffect effect, unsigned timeout); - // Responds to colour changes: passes event on to children. - void OnSysColourChanged(wxSysColourChangedEvent& event); + virtual void SendSysColourChangedEvents() override; // initialize various fields of wxMouseEvent (common part of MSWOnMouseXXX) void InitMouseEvent(wxMouseEvent& event, int x, int y, WXUINT flags); @@ -837,7 +836,6 @@ protected: private: wxDECLARE_DYNAMIC_CLASS(wxWindowMSW); wxDECLARE_NO_COPY_CLASS(wxWindowMSW); - wxDECLARE_EVENT_TABLE(); }; // window creation helper class: before creating a new HWND, instantiate an diff --git a/include/wx/osx/frame.h b/include/wx/osx/frame.h index 323ec1fa38..49c9ba518a 100644 --- a/include/wx/osx/frame.h +++ b/include/wx/osx/frame.h @@ -18,6 +18,7 @@ class WXDLLIMPEXP_FWD_CORE wxMacToolTip ; class WXDLLIMPEXP_CORE wxFrame: public wxFrameBase { + typedef wxFrameBase BaseType; public: // construction wxFrame() = default; @@ -53,7 +54,6 @@ public: // event handlers void OnActivate(wxActivateEvent& event); - void OnSysColourChanged(wxSysColourChangedEvent& event); // Toolbar #if wxUSE_TOOLBAR @@ -79,6 +79,8 @@ public: // internal response to size events virtual void MacOnInternalSize() override { PositionBars(); } + virtual void SendSysColourChangedEvents() override; + protected: #if wxUSE_TOOLBAR virtual void PositionToolBar() override; diff --git a/include/wx/window.h b/include/wx/window.h index 389d2010d4..cbe0eb490b 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -1612,7 +1612,6 @@ public: static inline const wxWindow* AsWindow(const wxWindowBase* win); // event handlers - void OnSysColourChanged( wxSysColourChangedEvent& event ); void OnInitDialog( wxInitDialogEvent &event ); void OnMiddleClick( wxMouseEvent& event ); #if wxUSE_HELP @@ -1627,6 +1626,8 @@ public: // Returns true if more idle time is requested. virtual bool SendIdleEvents(wxIdleEvent& event); + virtual void SendSysColourChangedEvents(); + // Send wxContextMenuEvent and return true if it was processed. // // Note that the event may end up being sent to a different window, if this diff --git a/src/common/prntbase.cpp b/src/common/prntbase.cpp index 0eab198a63..008102f13e 100644 --- a/src/common/prntbase.cpp +++ b/src/common/prntbase.cpp @@ -1005,7 +1005,6 @@ void wxPreviewCanvas::OnDPIChanged(wxDPIChangedEvent& event) event.Skip(); } -// Responds to colour changes, and passes event on to children. void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event) { #ifdef __WXMAC__ @@ -1020,8 +1019,7 @@ void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event) SetBackgroundColour(wxSystemSettings::GetColour(colourIndex)); Refresh(); - // Propagate the event to the non-top-level children - wxWindow::OnSysColourChanged(event); + event.Skip(); } void wxPreviewCanvas::OnChar(wxKeyEvent &event) diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 534efa7420..ae652227d7 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -113,7 +113,6 @@ wxIMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler); // ---------------------------------------------------------------------------- wxBEGIN_EVENT_TABLE(wxWindowBase, wxEvtHandler) - EVT_SYS_COLOUR_CHANGED(wxWindowBase::OnSysColourChanged) EVT_INIT_DIALOG(wxWindowBase::OnInitDialog) EVT_MIDDLE_DOWN(wxWindowBase::OnMiddleClick) @@ -3019,8 +3018,12 @@ wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) const // ---------------------------------------------------------------------------- // propagate the colour change event to the subwindows -void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) +void wxWindowBase::SendSysColourChangedEvents() { + wxSysColourChangedEvent event; + event.SetEventObject(this); + HandleWindowEvent(event); + wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); while ( node ) { @@ -3028,9 +3031,7 @@ void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) wxWindow *win = node->GetData(); if ( !win->IsTopLevel() ) { - wxSysColourChangedEvent event2; - event2.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(event2); + win->SendSysColourChangedEvents(); } node = node->GetNext(); diff --git a/src/generic/calctrlg.cpp b/src/generic/calctrlg.cpp index 2d5e591af8..d61bc3b2ab 100644 --- a/src/generic/calctrlg.cpp +++ b/src/generic/calctrlg.cpp @@ -1612,14 +1612,12 @@ void wxGenericCalendarCtrl::OnYearTextChange(wxCommandEvent& event) HandleYearChange(event); } -// Responds to colour changes, and passes event on to children. void wxGenericCalendarCtrl::OnSysColourChanged(wxSysColourChangedEvent& event) { // reinit colours InitColours(); - // Propagate the event to the children - wxControl::OnSysColourChanged(event); + event.Skip(); // Redraw control area SetBackgroundColour(m_colBackground); diff --git a/src/generic/statusbr.cpp b/src/generic/statusbr.cpp index 18ef03c023..3e970c4198 100644 --- a/src/generic/statusbr.cpp +++ b/src/generic/statusbr.cpp @@ -460,8 +460,7 @@ void wxStatusBarGeneric::OnSysColourChanged(wxSysColourChangedEvent& event) { InitColours(); - // Propagate the event to the non-top-level children - wxWindow::OnSysColourChanged(event); + event.Skip(); } #ifdef __WXGTK__ diff --git a/src/gtk/settings.cpp b/src/gtk/settings.cpp index 7dc4e01f56..52fa64a63d 100644 --- a/src/gtk/settings.cpp +++ b/src/gtk/settings.cpp @@ -328,9 +328,7 @@ void DoUpdateColorScheme(wxGTKImpl::ColorScheme colorScheme) for (auto* win: wxTopLevelWindows) { - wxSysColourChangedEvent event; - event.SetEventObject(win); - win->HandleWindowEvent(event); + win->SendSysColourChangedEvents(); } } diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index 7b7c6be401..e6e26dec52 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -564,9 +564,7 @@ gtk_frame_window_state_callback( GtkWidget* WXUNUSED(widget), extern "C" { static void notify_gtk_theme_name(GObject*, GParamSpec*, wxTopLevelWindowGTK* win) { - wxSysColourChangedEvent event; - event.SetEventObject(win); - win->HandleWindowEvent(event); + win->SendSysColourChangedEvents(); } } diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 3a44017557..99358c3027 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -66,14 +66,6 @@ extern wxMenu *wxCurrentPopupMenu; #endif // wxUSE_MENUS || wxUSE_MENUS_NATIVE -// ---------------------------------------------------------------------------- -// event tables -// ---------------------------------------------------------------------------- - -wxBEGIN_EVENT_TABLE(wxFrame, wxFrameBase) - EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged) -wxEND_EVENT_TABLE() - // ============================================================================ // implementation // ============================================================================ @@ -470,7 +462,7 @@ wxTaskBarButton* wxFrame::MSWGetTaskBarButton() } #endif // wxUSE_TASKBARBUTTON -void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event) +void wxFrame::SendSysColourChangedEvents() { #if wxUSE_MENUS && wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__) if ( wxMenuBar* const menuBar = GetMenuBar() ) @@ -479,8 +471,7 @@ void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event) } #endif // wxUSE_MENUS && wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__) - // Let children react to this event too. - event.Skip(); + BaseType::SendSysColourChangedEvents(); } // Pass true to show full screen, false to restore. diff --git a/src/msw/window.cpp b/src/msw/window.cpp index ff18696bb8..79da62420b 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -299,20 +299,12 @@ static bool wxIsTouchEventMSW() return (::GetMessageExtraInfo() & SIGNATURE_MASK) == MI_WP_SIGNATURE; } -// --------------------------------------------------------------------------- -// event tables -// --------------------------------------------------------------------------- - // in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu() // method #ifdef __WXUNIVERSAL__ wxIMPLEMENT_ABSTRACT_CLASS(wxWindowMSW, wxWindowBase); #endif // __WXUNIVERSAL__ -wxBEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase) - EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged) -wxEND_EVENT_TABLE() - // =========================================================================== // implementation // =========================================================================== @@ -4829,7 +4821,6 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id), { return item->MSWOnDraw(itemStruct); } - #endif // wxUSE_CONTROLS return false; @@ -5090,10 +5081,7 @@ bool wxWindowMSW::HandleSysColorChange() // that information. wxMSWDarkMode::NotifySysColorChange(); - wxSysColourChangedEvent event; - event.SetEventObject(this); - - (void)HandleWindowEvent(event); + SendSysColourChangedEvents(); if ( IsTopLevel() ) Refresh(); @@ -5271,8 +5259,7 @@ bool wxWindowMSW::HandleQueryNewPalette() return HandleWindowEvent(event) && event.GetPaletteRealized(); } -// Responds to colour changes: passes event on to children. -void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) +void wxWindowMSW::SendSysColourChangedEvents() { // the top level window also reset the standard colour map as it might have // changed (there is no need to do it for the non top level windows as we @@ -5290,6 +5277,10 @@ void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) MSWSetDarkOrLightMode(SetMode::Change); } + wxSysColourChangedEvent event; + event.SetEventObject(this); + ProcessWindowEvent(event); + wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); while ( node ) { @@ -5306,6 +5297,8 @@ void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) node = node->GetNext(); } + + // Base class functionality is duplicated here, so don't chain up } extern wxCOLORMAP *wxGetStdColourMap() diff --git a/src/osx/carbon/frame.cpp b/src/osx/carbon/frame.cpp index c50f34f43e..ce1b4ec0b7 100644 --- a/src/osx/carbon/frame.cpp +++ b/src/osx/carbon/frame.cpp @@ -43,7 +43,6 @@ int GetMacStatusbarHeight() wxBEGIN_EVENT_TABLE(wxFrame, wxFrameBase) EVT_ACTIVATE(wxFrame::OnActivate) - EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged) wxEND_EVENT_TABLE() // ---------------------------------------------------------------------------- @@ -179,23 +178,18 @@ void wxFrame::PositionStatusBar() } #endif // wxUSE_STATUSBAR -// Responds to colour changes, and passes event on to children. -void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event) +void wxFrame::SendSysColourChangedEvents() { Refresh(); #if wxUSE_STATUSBAR if ( m_frameStatusBar ) { - wxSysColourChangedEvent event2; - - event2.SetEventObject( m_frameStatusBar ); - m_frameStatusBar->GetEventHandler()->ProcessEvent(event2); + m_frameStatusBar->SendSysColourChangedEvents(); } #endif // wxUSE_STATUSBAR - // Propagate the event to the non-top-level children - wxWindow::OnSysColourChanged(event); + BaseType::SendSysColourChangedEvents(); } // Default activation behaviour - set the focus for the first child diff --git a/src/osx/carbon/mdi.cpp b/src/osx/carbon/mdi.cpp index bbd9d6983e..799d074306 100644 --- a/src/osx/carbon/mdi.cpp +++ b/src/osx/carbon/mdi.cpp @@ -238,13 +238,11 @@ void wxMDIParentFrame::OnActivate(wxActivateEvent& event) event.Skip(); } -// Responds to colour changes, and passes event on to children. void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event) { // TODO - // Propagate the event to the non-top-level children - wxFrame::OnSysColourChanged(event); + event.Skip(); } bool wxMDIParentFrame::ShouldBeVisible() const diff --git a/src/osx/cocoa/nonownedwnd.mm b/src/osx/cocoa/nonownedwnd.mm index bf79a5d72e..e79f52a306 100644 --- a/src/osx/cocoa/nonownedwnd.mm +++ b/src/osx/cocoa/nonownedwnd.mm @@ -702,9 +702,7 @@ static void SendFullScreenWindowEvent(NSNotification* notification, bool fullscr objectForKey:@"NSBackingPropertyOldColorSpaceKey"]; if (![newColorSpace isEqual:oldColorSpace]) { - wxSysColourChangedEvent event; - event.SetEventObject(wxpeer); - wxpeer->HandleWindowEvent(event); + wxpeer->SendSysColourChangedEvents(); } } } @@ -731,9 +729,7 @@ static void SendFullScreenWindowEvent(NSNotification* notification, bool fullscr wxNonOwnedWindow* wxpeer = windowimpl ? windowimpl->GetWXPeer() : nullptr; if (wxpeer) { - wxSysColourChangedEvent event; - event.SetEventObject(wxpeer); - wxpeer->HandleWindowEvent(event); + wxpeer->SendSysColourChangedEvents(); } } }