X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2fd35de1c3d757f2b9eabdf8d828e363eb754db9..538a2cfaf2be9f864e58c9a9fe232966af6bf2a0:/src/common/appcmn.cpp diff --git a/src/common/appcmn.cpp b/src/common/appcmn.cpp index f70be7b5ad..9a3ead6a33 100644 --- a/src/common/appcmn.cpp +++ b/src/common/appcmn.cpp @@ -40,16 +40,7 @@ #include "wx/msgout.h" #include "wx/thread.h" #include "wx/vidmode.h" - -#ifdef __WXDEBUG__ - #if wxUSE_STACKWALKER - #include "wx/stackwalk.h" - #endif // wxUSE_STACKWALKER -#endif // __WXDEBUG__ - -#if defined(__WXMSW__) - #include "wx/msw/private.h" // includes windows.h for LOGFONT -#endif +#include "wx/evtloop.h" #if wxUSE_FONTMAP #include "wx/fontmap.h" @@ -59,8 +50,6 @@ #include "wx/build.h" WX_CHECK_BUILD_OPTIONS("wxCore") -WXDLLIMPEXP_DATA_CORE(wxList) wxPendingDelete; - // ============================================================================ // wxAppBase implementation // ============================================================================ @@ -78,9 +67,6 @@ wxAppBase::wxAppBase() m_isActive = true; - m_isInsideYield = false; - m_eventsToProcessInsideYield = wxEVT_CATEGORY_ALL; - // We don't want to exit the app if the user code shows a dialog from its // OnInit() -- but this is what would happen if we set m_exitOnFrameDelete // to Yes initially as this dialog would be the last top level window. @@ -105,6 +91,10 @@ bool wxAppBase::Initialize(int& argcOrig, wxChar **argvOrig) wxBitmap::InitStandardHandlers(); + // for compatibility call the old initialization function too + if ( !OnInitGui() ) + return false; + return true; } @@ -138,8 +128,7 @@ void wxAppBase::CleanUp() wxDeleteStockLists(); - delete wxTheColourDatabase; - wxTheColourDatabase = NULL; + wxDELETE(wxTheColourDatabase); wxAppConsole::CleanUp(); } @@ -207,10 +196,10 @@ void wxAppBase::OnInitCmdLine(wxCmdLineParser& parser) }, #endif // __WXUNIVERSAL__ -#if defined(__WXMGL__) - // VS: this is not specific to wxMGL, all fullscreen (framebuffer) ports +#if defined(__WXDFB__) + // VS: this is not specific to wxDFB, all fullscreen (framebuffer) ports // should provide this option. That's why it is in common/appcmn.cpp - // and not mgl/app.cpp + // and not dfb/app.cpp { wxCMD_LINE_OPTION, NULL, @@ -219,7 +208,7 @@ void wxAppBase::OnInitCmdLine(wxCmdLineParser& parser) wxCMD_LINE_VAL_STRING, 0x0 }, -#endif // __WXMGL__ +#endif // __WXDFB__ // terminator wxCMD_LINE_DESC_END @@ -247,12 +236,12 @@ bool wxAppBase::OnCmdLineParsed(wxCmdLineParser& parser) } #endif // __WXUNIVERSAL__ -#if defined(__WXMGL__) +#if defined(__WXDFB__) wxString modeDesc; if ( parser.Found(OPTION_MODE, &modeDesc) ) { unsigned w, h, bpp; - if ( wxSscanf(modeDesc.c_str(), _T("%ux%u-%u"), &w, &h, &bpp) != 3 ) + if ( wxSscanf(modeDesc.c_str(), wxT("%ux%u-%u"), &w, &h, &bpp) != 3 ) { wxLogError(_("Invalid display mode specification '%s'."), modeDesc.c_str()); return false; @@ -261,7 +250,7 @@ bool wxAppBase::OnCmdLineParsed(wxCmdLineParser& parser) if ( !SetDisplayMode(wxVideoMode(w, h, bpp)) ) return false; } -#endif // __WXMGL__ +#endif // __WXDFB__ return wxAppConsole::OnCmdLineParsed(parser); } @@ -326,23 +315,22 @@ void wxAppBase::SetActive(bool active, wxWindow * WXUNUSED(lastFocus)) (void)ProcessEvent(event); } -bool wxAppBase::IsEventAllowedInsideYield(wxEventCategory cat) const -{ - return (m_eventsToProcessInsideYield & cat) != 0; -} - bool wxAppBase::SafeYield(wxWindow *win, bool onlyIfNeeded) { wxWindowDisabler wd(win); - return Yield(onlyIfNeeded); + wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); + + return loop && loop->Yield(onlyIfNeeded); } bool wxAppBase::SafeYieldFor(wxWindow *win, long eventsToProcess) { wxWindowDisabler wd(win); - return YieldFor(eventsToProcess); + wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); + + return loop && loop->YieldFor(eventsToProcess); } @@ -350,87 +338,30 @@ bool wxAppBase::SafeYieldFor(wxWindow *win, long eventsToProcess) // idle handling // ---------------------------------------------------------------------------- -void wxAppBase::DeletePendingObjects() -{ - wxList::compatibility_iterator node = wxPendingDelete.GetFirst(); - while (node) - { - wxObject *obj = node->GetData(); - - // remove it from the list first so that if we get back here somehow - // during the object deletion (e.g. wxYield called from its dtor) we - // wouldn't try to delete it the second time - if ( wxPendingDelete.Member(obj) ) - wxPendingDelete.Erase(node); - - delete obj; - - // Deleting one object may have deleted other pending - // objects, so start from beginning of list again. - node = wxPendingDelete.GetFirst(); - } -} - // Returns true if more time is needed. bool wxAppBase::ProcessIdle() { - // call the base class version first, it will process the pending events - // (which should be done before the idle events generation) and send the - // idle event to wxTheApp itself + // call the base class version first to send the idle event to wxTheApp + // itself bool needMore = wxAppConsoleBase::ProcessIdle(); wxIdleEvent event; wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); while (node) { wxWindow* win = node->GetData(); - if (SendIdleEvents(win, event)) + + // Don't send idle events to the windows that are about to be destroyed + // anyhow, this is wasteful and unexpected. + if ( !wxPendingDelete.Member(win) && win->SendIdleEvents(event) ) needMore = true; node = node->GetNext(); } - // 'Garbage' collection of windows deleted with Close(). - DeletePendingObjects(); - -#if wxUSE_LOG - // flush the logged messages if any - wxLog::FlushActive(); -#endif - wxUpdateUIEvent::ResetUpdateTime(); return needMore; } -// Send idle event to window and all subwindows -bool wxAppBase::SendIdleEvents(wxWindow* win, wxIdleEvent& event) -{ - bool needMore = false; - - win->OnInternalIdle(); - - // should we send idle event to this window? - if ( wxIdleEvent::GetMode() == wxIDLE_PROCESS_ALL || - win->HasExtraStyle(wxWS_EX_PROCESS_IDLE) ) - { - event.SetEventObject(win); - win->HandleWindowEvent(event); - - if (event.MoreRequested()) - needMore = true; - } - wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst(); - while ( node ) - { - wxWindow *child = node->GetData(); - if (SendIdleEvents(child, event)) - needMore = true; - - node = node->GetNext(); - } - - return needMore; -} - // ---------------------------------------------------------------------------- // wxGUIAppTraitsBase // ---------------------------------------------------------------------------- @@ -440,7 +371,11 @@ bool wxAppBase::SendIdleEvents(wxWindow* win, wxIdleEvent& event) wxLog *wxGUIAppTraitsBase::CreateLogTarget() { #if wxUSE_LOGGUI +#ifndef __WXOSX_IPHONE__ return new wxLogGui; +#else + return new wxLogStderr; +#endif #else // we must have something! return new wxLogStderr; @@ -486,10 +421,9 @@ wxRendererNative *wxGUIAppTraitsBase::CreateRenderer() return NULL; } -#ifdef __WXDEBUG__ - bool wxGUIAppTraitsBase::ShowAssertDialog(const wxString& msg) { +#if wxDEBUG_LEVEL // under MSW we prefer to use the base class version using ::MessageBox() // even if wxMessageBox() is available because it has less chances to // double fault our app than our wxMessageBox() @@ -498,48 +432,48 @@ bool wxGUIAppTraitsBase::ShowAssertDialog(const wxString& msg) // // and finally we can't use wxMessageBox() if it wasn't compiled in, of // course -#if defined(__WXMSW__) || defined(__WXDFB__) || !wxUSE_MSGDLG - return wxAppTraitsBase::ShowAssertDialog(msg); -#else // wxUSE_MSGDLG - wxString msgDlg = msg; +#if !defined(__WXMSW__) && !defined(__WXDFB__) && wxUSE_MSGDLG + + // we can't (safely) show the GUI dialog from another thread, only do it + // for the asserts in the main thread + if ( wxIsMainThread() ) + { + wxString msgDlg = msg; #if wxUSE_STACKWALKER - // on Unix stack frame generation may take some time, depending on the - // size of the executable mainly... warn the user that we are working - wxFprintf(stderr, wxT("[Debug] Generating a stack trace... please wait")); - fflush(stderr); - - const wxString stackTrace = GetAssertStackTrace(); - if ( !stackTrace.empty() ) - msgDlg << _T("\n\nCall stack:\n") << stackTrace; + const wxString stackTrace = GetAssertStackTrace(); + if ( !stackTrace.empty() ) + msgDlg << wxT("\n\nCall stack:\n") << stackTrace; #endif // wxUSE_STACKWALKER - // this message is intentionally not translated -- it is for - // developpers only - msgDlg += wxT("\nDo you want to stop the program?\n") - wxT("You can also choose [Cancel] to suppress ") - wxT("further warnings."); + // this message is intentionally not translated -- it is for + // developpers only + msgDlg += wxT("\nDo you want to stop the program?\n") + wxT("You can also choose [Cancel] to suppress ") + wxT("further warnings."); - switch ( wxMessageBox(msgDlg, wxT("wxWidgets Debug Alert"), - wxYES_NO | wxCANCEL | wxICON_STOP ) ) - { - case wxYES: - wxTrap(); - break; + switch ( wxMessageBox(msgDlg, wxT("wxWidgets Debug Alert"), + wxYES_NO | wxCANCEL | wxICON_STOP ) ) + { + case wxYES: + wxTrap(); + break; - case wxCANCEL: - // no more asserts - return true; + case wxCANCEL: + // no more asserts + return true; - //case wxNO: nothing to do + //case wxNO: nothing to do + } + + return false; } +#endif // wxUSE_MSGDLG +#endif // wxDEBUG_LEVEL - return false; -#endif // !wxUSE_MSGDLG/wxUSE_MSGDLG + return wxAppTraitsBase::ShowAssertDialog(msg); } -#endif // __WXDEBUG__ - bool wxGUIAppTraitsBase::HasStderr() { // we consider that under Unix stderr always goes somewhere, even if the @@ -551,14 +485,3 @@ bool wxGUIAppTraitsBase::HasStderr() #endif } -void wxGUIAppTraitsBase::ScheduleForDestroy(wxObject *object) -{ - if ( !wxPendingDelete.Member(object) ) - wxPendingDelete.Append(object); -} - -void wxGUIAppTraitsBase::RemoveFromPendingDelete(wxObject *object) -{ - wxPendingDelete.DeleteObject(object); -} -