1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-20 14:20:06 +02:00

Avoid Win startup crash...

... Because of different ordering of file-scope static initializations, visiting
TrackInfo.cpp before wxApp is initialized.  (This didn't happen on Mac.)

This requires other changes to PrefsListener so that safe unbinding is
guaranteed by destructors, even if the PrefsListener is destroyed after the
global wxApp object.
This commit is contained in:
Paul Licameli 2019-06-27 08:46:55 -04:00
parent 9b65840e4e
commit 56a05cc646
3 changed files with 75 additions and 50 deletions

View File

@ -71,29 +71,45 @@ int gMenusDirty = 0;
wxDEFINE_EVENT(EVT_PREFS_UPDATE, wxCommandEvent);
PrefsListener::PrefsListener()
struct PrefsListener::Impl : wxEvtHandler
{
Impl( PrefsListener &owner );
~Impl();
void OnEvent(wxCommandEvent&);
PrefsListener &mOwner;
};
PrefsListener::Impl::Impl( PrefsListener &owner )
: mOwner{ owner }
{
wxTheApp->Bind(EVT_PREFS_UPDATE, &PrefsListener::Impl::OnEvent, this);
}
PrefsListener::Impl::~Impl()
{
}
PrefsListener::PrefsListener()
: mpImpl{ std::make_unique<Impl>( *this ) }
{
wxTheApp->Bind(EVT_PREFS_UPDATE, &PrefsListener::OnEvent, this);
}
PrefsListener::~PrefsListener()
{
// Explicit unbinding is needed because this is not a wxEvtHandler
wxTheApp->Unbind(EVT_PREFS_UPDATE, &PrefsListener::OnEvent, this);
}
void PrefsListener::UpdateSelectedPrefs( int )
{
}
void PrefsListener::OnEvent( wxCommandEvent &evt )
void PrefsListener::Impl::OnEvent( wxCommandEvent &evt )
{
evt.Skip();
auto id = evt.GetId();
if (id <= 0)
UpdatePrefs();
mOwner.UpdatePrefs();
else
UpdateSelectedPrefs( id );
mOwner.UpdateSelectedPrefs( id );
}
#if 0

View File

@ -33,6 +33,7 @@
#include "../include/audacity/ComponentInterface.h"
#include <memory>
#include <wx/fileconf.h> // to inherit wxFileConfig
#include <wx/event.h> // to declare custom event types
@ -182,7 +183,8 @@ protected:
virtual void UpdateSelectedPrefs( int id );
private:
void OnEvent(wxCommandEvent&);
struct Impl;
std::unique_ptr<Impl> mpImpl;
};
#endif

View File

@ -43,10 +43,56 @@ Paul Licameli split from TrackPanel.cpp
#include "ViewInfo.h"
#include "tracks/ui/TrackView.h"
static wxString gSoloPref;
// Subscribe to preference changes to update static variables
struct Settings : PrefsListener {
wxString gSoloPref;
wxFont gFont;
Settings()
{
UpdatePrefs();
}
void UpdatePrefs() override
{
gPrefs->Read(wxT("/GUI/Solo"), &gSoloPref, wxT("Simple"));
// Calculation of best font size depends on language, so it should be redone in case
// the language preference changed.
int fontSize = 10;
gFont.Create(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
int allowableWidth =
// PRL: was it correct to include the margin?
( kTrackInfoWidth + kLeftMargin )
- 2; // 2 to allow for left/right borders
int textWidth;
std::unique_ptr<wxGraphicsContext> pContext(
wxGraphicsContext::Create()
);
pContext->SetFont( gFont, *wxBLACK );
do {
gFont.SetPointSize(fontSize);
double dWidth;
pContext->GetTextExtent(
_("Stereo, 999999Hz"), &dWidth, nullptr );
textWidth = (wxCoord)( dWidth + 0.5 );
fontSize--;
} while (textWidth >= allowableWidth);
}
};
static Settings &settings()
{
static Settings theSettings;
return theSettings;
}
bool TrackInfo::HasSoloButton()
{
return gSoloPref!=wxT("None");
return settings().gSoloPref != wxT("None");
}
#define RANGE(array) (array), (array) + sizeof(array)/sizeof(*(array))
@ -398,12 +444,6 @@ void TrackInfo::MinimizeSyncLockDrawFunction
}
}
namespace {
wxFont gFont;
}
void TrackInfo::GetCloseBoxHorizontalBounds( const wxRect & rect, wxRect &dest )
{
dest.x = rect.x;
@ -508,7 +548,7 @@ void TrackInfo::GetSyncLockIconRect(const wxRect & rect, wxRect &dest)
/// \todo Probably should move to 'Utils.cpp'.
void TrackInfo::SetTrackInfoFont(wxDC * dc)
{
dc->SetFont(gFont);
dc->SetFont(settings().gFont);
}
//#define USE_BEVELS
@ -521,36 +561,3 @@ unsigned TrackInfo::DefaultTrackHeight( const TCPLines &topLines )
totalTCPLines( commonTrackTCPBottomLines, false ) + 1;
return (unsigned) std::max( needed, (int) TrackView::DefaultHeight );
}
// Subscribe to preference changes to update static variables
static struct MyPrefsListener : PrefsListener {
void UpdatePrefs() override
{
gPrefs->Read(wxT("/GUI/Solo"), &gSoloPref, wxT("Simple"));
// Calculation of best font size depends on language, so it should be redone in case
// the language preference changed.
int fontSize = 10;
gFont.Create(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
int allowableWidth =
// PRL: was it correct to include the margin?
( kTrackInfoWidth + kLeftMargin )
- 2; // 2 to allow for left/right borders
int textWidth;
std::unique_ptr<wxGraphicsContext> pContext(
wxGraphicsContext::Create()
);
pContext->SetFont( gFont, *wxBLACK );
do {
gFont.SetPointSize(fontSize);
double dWidth;
pContext->GetTextExtent(
_("Stereo, 999999Hz"), &dWidth, nullptr );
textWidth = (wxCoord)( dWidth + 0.5 );
fontSize--;
} while (textWidth >= allowableWidth);
}
} sPrefsListener;