diff --git a/clientgui/BOINCBaseFrame.cpp b/clientgui/BOINCBaseFrame.cpp index eb2e7bda90..07b7a1e14b 100644 --- a/clientgui/BOINCBaseFrame.cpp +++ b/clientgui/BOINCBaseFrame.cpp @@ -310,7 +310,15 @@ void CBOINCBaseFrame::OnClose(wxCloseEvent& event) { if (!event.CanVeto() || IsIconized()) { wxGetApp().FrameClosed(); +#ifdef __WXMAC__ + // Needed to properly write wxConfig data on logout / shutdown + wxGetApp().OnExit(); + event.Skip(); + // Prevent wxCocoa from issuing events to closed frames + wxGetApp().ExitMainLoop(); +#else Destroy(); +#endif } else { #ifdef __WXGTK__ // Apparently aborting a close event just causes the main window to be displayed @@ -365,12 +373,6 @@ void CBOINCBaseFrame::OnExit(wxCommandEvent& WXUNUSED(event)) { // Save state before exiting SaveState(); - // Under wxWidgets 2.8.0, the task bar icons must be deleted for app to exit its main loop -#ifdef __WXMAC__ - wxGetApp().DeleteMacDockIcon(); -#endif - wxGetApp().DeleteTaskBarIcon(); - CDlgEventLog* eventLog = wxGetApp().GetEventLog(); if (eventLog) { eventLog->Destroy(); diff --git a/clientgui/BOINCGUIApp.cpp b/clientgui/BOINCGUIApp.cpp index b7c9d0300c..6d02395a8b 100644 --- a/clientgui/BOINCGUIApp.cpp +++ b/clientgui/BOINCGUIApp.cpp @@ -84,7 +84,7 @@ OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt SysBeep(4); return userCanceledErr; } - + anErr = AEGetAttributePtr(appleEvt, keyAddressAttr, typeProcessSerialNumber, &senderType, &SenderPSN, sizeof(SenderPSN), &actualSize); @@ -500,9 +500,30 @@ void CBOINCGUIApp::OnEndSession(wxCloseEvent& ) { int CBOINCGUIApp::OnExit() { +#ifdef __WXMAC__ +// Needed to properly handle logout / shutdown +// See comment in CBOINCBaseFrame::OnClose() +static bool alreadyExited = false; + if (alreadyExited) return 0; + alreadyExited = true; +#endif + // Shutdown the System Idle Detection code IdleTrackerDetach(); +// Under wxWidgets 2.8.0, the task bar icons +// must be deleted for app to exit its main loop +#ifdef __WXMAC__ + if (m_pMacDockIcon) { + delete m_pMacDockIcon; + } + m_pMacDockIcon = NULL; +#endif + if (m_pTaskBarIcon) { + delete m_pTaskBarIcon; + } + m_pTaskBarIcon = NULL; + if (m_pDocument) { m_pDocument->OnExit(); delete m_pDocument; @@ -1310,23 +1331,6 @@ bool CBOINCGUIApp::IsModalDialogDisplayed() { return false; } -void CBOINCGUIApp::DeleteTaskBarIcon() { - if (m_pTaskBarIcon) { - delete m_pTaskBarIcon; - } - m_pTaskBarIcon = NULL; -} - -#ifdef __WXMAC__ -void CBOINCGUIApp::DeleteMacDockIcon() { - if (m_pMacDockIcon) { - delete m_pMacDockIcon; - } - m_pMacDockIcon = NULL; -} -#endif - - // Prevent recursive entry of CMainDocument::RequestRPC() int CBOINCGUIApp::FilterEvent(wxEvent &event) { int theEventType; diff --git a/clientgui/BOINCGUIApp.h b/clientgui/BOINCGUIApp.h index 282c15f59b..b72a83ee7d 100644 --- a/clientgui/BOINCGUIApp.h +++ b/clientgui/BOINCGUIApp.h @@ -49,7 +49,6 @@ class CBOINCGUIApp : public wxApp { DECLARE_DYNAMIC_CLASS(CBOINCGUIApp) protected: - int OnExit(); #if (defined(__WXMSW__) && !wxCHECK_VERSION(2, 9, 4)) void OnEndSession(wxCloseEvent& event); #endif @@ -117,6 +116,7 @@ protected: public: + int OnExit(); bool OnInit(); void SaveState(); @@ -133,7 +133,6 @@ public: int GetClientRPCPortArg() { return m_iRPCPortArg; } CDlgEventLog* GetEventLog() { return m_pEventLog; } CTaskBarIcon* GetTaskBarIcon() { return m_pTaskBarIcon; } - void DeleteTaskBarIcon(); bool IsMgrMultipleInstance() { return m_bMultipleInstancesOK; } @@ -143,7 +142,6 @@ public: bool CallOnInit() { return OnInit(); } CTaskBarIcon* GetMacDockIcon() { return m_pMacDockIcon; } - void DeleteMacDockIcon(); int ShouldShutdownCoreClient() { return true; } #else int ShouldShutdownCoreClient() { return m_iShutdownCoreClient; }