use a common m_isInsideYield flag instead of static booleans in all ports; add a IsYielding() test which can help to fix unwanted re-entrancies
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57637 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
67badd5753
commit
d181e877b0
@ -454,6 +454,10 @@ public:
|
||||
// with _extreme_ care or, better, don't use at all!
|
||||
virtual bool Yield(bool onlyIfNeeded = false) = 0;
|
||||
|
||||
// returns true if the main thread is inside a Yield() call
|
||||
bool IsYielding() const
|
||||
{ return m_isInsideYield; }
|
||||
|
||||
// this virtual function is called in the GUI mode when the application
|
||||
// becomes idle and normally just sends wxIdleEvent to all interested
|
||||
// parties
|
||||
@ -576,6 +580,7 @@ protected:
|
||||
// does any of our windows have focus?
|
||||
bool m_isActive;
|
||||
|
||||
bool m_isInsideYield;
|
||||
|
||||
DECLARE_NO_COPY_CLASS(wxAppBase)
|
||||
};
|
||||
|
@ -176,6 +176,11 @@ public:
|
||||
*/
|
||||
static bool IsMainLoopRunning();
|
||||
|
||||
/**
|
||||
Returns @true if called from inside Yield().
|
||||
*/
|
||||
bool IsYielding() const;
|
||||
|
||||
/**
|
||||
Process all pending events; it is necessary to call this function to
|
||||
process posted events.
|
||||
@ -466,6 +471,7 @@ public:
|
||||
user to perform actions which are not compatible with the current task.
|
||||
Disabling menu items or whole menus during processing can avoid unwanted
|
||||
reentrance of code: see ::wxSafeYield for a better function.
|
||||
You can avoid unwanted reentrancies also using IsYielding().
|
||||
|
||||
Note that Yield() will not flush the message logs. This is intentional as
|
||||
calling Yield() is usually done to quickly update the screen and popping up
|
||||
|
@ -297,16 +297,13 @@ void wxApp::Exit()
|
||||
// Yield to other processes
|
||||
bool wxApp::Yield(bool onlyIfNeeded)
|
||||
{
|
||||
// MT-FIXME
|
||||
static bool s_inYield = false;
|
||||
|
||||
#if wxUSE_LOG
|
||||
// disable log flushing from here because a call to wxYield() shouldn't
|
||||
// normally result in message boxes popping up &c
|
||||
wxLog::Suspend();
|
||||
#endif // wxUSE_LOG
|
||||
|
||||
if (s_inYield)
|
||||
if (m_isInsideYield)
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -316,7 +313,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
return false;
|
||||
}
|
||||
|
||||
s_inYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
// Run the event loop until it is out of events
|
||||
while(1)
|
||||
@ -358,7 +355,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
wxLog::Resume();
|
||||
#endif // wxUSE_LOG
|
||||
|
||||
s_inYield = false;
|
||||
m_isInsideYield = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -78,6 +78,8 @@ wxAppBase::wxAppBase()
|
||||
|
||||
m_isActive = true;
|
||||
|
||||
m_isInsideYield = false;
|
||||
|
||||
// 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.
|
||||
|
@ -171,9 +171,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
return true; // can't process events from other threads
|
||||
#endif // wxUSE_THREADS
|
||||
|
||||
static bool s_inYield = false;
|
||||
|
||||
if ( s_inYield )
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -183,7 +181,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
return false;
|
||||
}
|
||||
|
||||
s_inYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
#if wxUSE_LOG
|
||||
wxLog::Suspend();
|
||||
@ -203,7 +201,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
wxLog::Resume();
|
||||
#endif // wxUSE_LOG
|
||||
|
||||
s_inYield = false;
|
||||
m_isInsideYield = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -54,14 +54,9 @@ static GtkWidget *gs_RootWindow = (GtkWidget*) NULL;
|
||||
// wxYield
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// not static because used by textctrl.cpp
|
||||
//
|
||||
// MT-FIXME
|
||||
bool wxIsInsideYield = false;
|
||||
|
||||
bool wxApp::Yield(bool onlyIfNeeded)
|
||||
{
|
||||
if ( wxIsInsideYield )
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -79,7 +74,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
}
|
||||
#endif // wxUSE_THREADS
|
||||
|
||||
wxIsInsideYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
#if wxUSE_LOG
|
||||
// disable log flushing from here because a call to wxYield() shouldn't
|
||||
@ -103,7 +98,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
wxLog::Resume();
|
||||
#endif
|
||||
|
||||
wxIsInsideYield = false;
|
||||
m_isInsideYield = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -103,14 +103,9 @@ static wxMutex gs_idleTagsMutex;
|
||||
// wxYield
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// not static because used by textctrl.cpp
|
||||
//
|
||||
// MT-FIXME
|
||||
bool wxIsInsideYield = false;
|
||||
|
||||
bool wxApp::Yield(bool onlyIfNeeded)
|
||||
{
|
||||
if ( wxIsInsideYield )
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -128,7 +123,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
}
|
||||
#endif // wxUSE_THREADS
|
||||
|
||||
wxIsInsideYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
// We need to remove idle callbacks or the loop will
|
||||
// never finish.
|
||||
@ -156,7 +151,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
wxLog::Resume();
|
||||
#endif
|
||||
|
||||
wxIsInsideYield = false;
|
||||
m_isInsideYield = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -175,8 +175,6 @@ gtk_scrollbar_changed_callback( GtkWidget *WXUNUSED(widget), wxTextCtrl *win )
|
||||
// which implicitly calls wxYield()) so we override GtkText::draw() and simply
|
||||
// don't do anything if we're inside wxYield()
|
||||
|
||||
extern bool wxIsInsideYield;
|
||||
|
||||
extern "C" {
|
||||
typedef void (*GtkDrawCallback)(GtkWidget *widget, GdkRectangle *rect);
|
||||
}
|
||||
@ -186,7 +184,7 @@ static GtkDrawCallback gs_gtk_text_draw = NULL;
|
||||
extern "C" {
|
||||
static void wxgtk_text_draw( GtkWidget *widget, GdkRectangle *rect)
|
||||
{
|
||||
if ( !wxIsInsideYield )
|
||||
if ( !wxTheApp->IsYielding() )
|
||||
{
|
||||
wxCHECK_RET( gs_gtk_text_draw != wxgtk_text_draw,
|
||||
_T("infinite recursion in wxgtk_text_draw aborted") );
|
||||
|
@ -48,11 +48,9 @@ void wxApp::Exit()
|
||||
// wxYield
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static bool gs_inYield = false;
|
||||
|
||||
bool wxApp::Yield(bool onlyIfNeeded)
|
||||
{
|
||||
if ( gs_inYield )
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -70,7 +68,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
}
|
||||
#endif // wxUSE_THREADS
|
||||
|
||||
gs_inYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
wxLog::Suspend();
|
||||
|
||||
@ -88,7 +86,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
|
||||
wxLog::Resume();
|
||||
|
||||
gs_inYield = false;
|
||||
m_isInsideYield = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -472,9 +472,7 @@ void wxApp::SetTopLevelRealizedWidget(WXDisplay* display, WXWidget widget)
|
||||
|
||||
bool wxApp::Yield(bool onlyIfNeeded)
|
||||
{
|
||||
static bool s_inYield = false;
|
||||
|
||||
if ( s_inYield )
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -484,13 +482,13 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
return false;
|
||||
}
|
||||
|
||||
s_inYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
wxEventLoopGuarantor dummyLoopIfNeeded;
|
||||
while (wxTheApp && wxTheApp->Pending())
|
||||
wxTheApp->Dispatch();
|
||||
|
||||
s_inYield = false;
|
||||
m_isInsideYield = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1015,10 +1015,7 @@ int wxApp::GetShell32Version()
|
||||
|
||||
bool wxApp::Yield(bool onlyIfNeeded)
|
||||
{
|
||||
// MT-FIXME
|
||||
static bool s_inYield = false;
|
||||
|
||||
if ( s_inYield )
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -1029,8 +1026,8 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
}
|
||||
|
||||
// set the flag and don't forget to reset it before returning
|
||||
s_inYield = true;
|
||||
wxON_BLOCK_EXIT_SET(s_inYield, false);
|
||||
m_isInsideYield = true;
|
||||
wxON_BLOCK_EXIT_SET(m_isInsideYield, false);
|
||||
|
||||
|
||||
#if wxUSE_LOG
|
||||
|
@ -509,9 +509,7 @@ void wxApp::OnQueryEndSession( wxCloseEvent& rEvent )
|
||||
//
|
||||
bool wxApp::Yield(bool onlyIfNeeded)
|
||||
{
|
||||
static bool s_inYield = false;
|
||||
|
||||
if ( s_inYield )
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -530,7 +528,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
//
|
||||
wxLog::Suspend();
|
||||
|
||||
s_inYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
//
|
||||
// We want to go back to the main message loop
|
||||
@ -545,6 +543,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
if (!wxTheApp->Dispatch())
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// If they are pending events, we must process them.
|
||||
//
|
||||
@ -552,11 +551,13 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
wxTheApp->ProcessPendingEvents();
|
||||
|
||||
HandleSockets();
|
||||
|
||||
//
|
||||
// Let the logs be flashed again
|
||||
//
|
||||
wxLog::Resume();
|
||||
s_inYield = false;
|
||||
m_isInsideYield = false;
|
||||
|
||||
return true;
|
||||
} // end of wxYield
|
||||
|
||||
|
@ -184,7 +184,7 @@ short wxApp::MacHandleAEGURL(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
|
||||
if (err != noErr)
|
||||
return err;
|
||||
|
||||
url[actualSize] = '\0'; // Terminate the C string
|
||||
url[actualSize] = '\0'; // Terminate the C string
|
||||
|
||||
ProcessSerialNumber PSN ;
|
||||
PSN.highLongOfPSN = 0 ;
|
||||
@ -357,9 +357,9 @@ void wxApp::MacReopenApp()
|
||||
// make sure we don't show 'virtual toplevel windows' like wxTaskBarIconWindow
|
||||
if ( firstHidden == NULL && ( wxDynamicCast( win, wxFrame ) || wxDynamicCast( win, wxDialog ) ) )
|
||||
firstHidden = win ;
|
||||
}
|
||||
}
|
||||
else if ( win->IsIconized() )
|
||||
{
|
||||
{
|
||||
if ( firstIconized == NULL )
|
||||
firstIconized = win ;
|
||||
}
|
||||
@ -499,7 +499,7 @@ wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item )
|
||||
|
||||
// is it part of the application or the Help menu, then look for the id directly
|
||||
if ( ( GetMenuHandle( kwxMacAppleMenuId ) != NULL && command.menu.menuRef == GetMenuHandle( kwxMacAppleMenuId ) ) ||
|
||||
( helpMenuHandle != NULL && command.menu.menuRef == helpMenuHandle ) ||
|
||||
( helpMenuHandle != NULL && command.menu.menuRef == helpMenuHandle ) ||
|
||||
wxMenuBar::MacGetWindowMenuHMenu() != NULL && command.menu.menuRef == wxMenuBar::MacGetWindowMenuHMenu() )
|
||||
{
|
||||
wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
|
||||
@ -576,7 +576,7 @@ wxMacAppMenuEventHandler( EventHandlerCallRef WXUNUSED(handler),
|
||||
case kEventMenuTargetItem:
|
||||
{
|
||||
HICommand command ;
|
||||
|
||||
|
||||
command.menu.menuRef = menuRef;
|
||||
command.menu.menuItemIndex = cEvent.GetParameter<MenuItemIndex>(kEventParamMenuItemIndex,typeMenuItemIndex) ;
|
||||
command.commandID = cEvent.GetParameter<MenuCommand>(kEventParamMenuCommand,typeMenuCommand) ;
|
||||
@ -900,7 +900,7 @@ bool wxApp::DoInitGui()
|
||||
|
||||
if ( !wxMacInitCocoa() )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1130,9 +1130,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
}
|
||||
#endif // wxUSE_THREADS
|
||||
|
||||
static bool s_inYield = false;
|
||||
|
||||
if (s_inYield)
|
||||
if (m_isInsideYield)
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -1142,7 +1140,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
return false;
|
||||
}
|
||||
|
||||
s_inYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
#if wxUSE_LOG
|
||||
// disable log flushing from here because a call to wxYield() shouldn't
|
||||
@ -1158,16 +1156,16 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
while ( loop->Pending() )
|
||||
loop->Dispatch();
|
||||
}
|
||||
|
||||
|
||||
// it's necessary to call ProcessIdle() to update the frames sizes which
|
||||
// might have been changed (it also will update other things set from
|
||||
// OnUpdateUI() which is a nice (and desired) side effect)
|
||||
while ( ProcessIdle() ) {}
|
||||
|
||||
|
||||
#if wxUSE_LOG
|
||||
wxLog::Resume();
|
||||
#endif // wxUSE_LOG
|
||||
s_inYield = false;
|
||||
m_isInsideYield = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1558,34 +1556,34 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess
|
||||
{
|
||||
keyval = (keyval - '0') + WXK_NUMPAD0;
|
||||
}
|
||||
else if (keycode >= 65 && keycode <= 81)
|
||||
else if (keycode >= 65 && keycode <= 81)
|
||||
{
|
||||
switch (keycode)
|
||||
{
|
||||
case 76 :
|
||||
keyval = WXK_NUMPAD_ENTER;
|
||||
break;
|
||||
|
||||
|
||||
case 81:
|
||||
keyval = WXK_NUMPAD_EQUAL;
|
||||
break;
|
||||
|
||||
|
||||
case 67:
|
||||
keyval = WXK_NUMPAD_MULTIPLY;
|
||||
break;
|
||||
|
||||
|
||||
case 75:
|
||||
keyval = WXK_NUMPAD_DIVIDE;
|
||||
break;
|
||||
|
||||
|
||||
case 78:
|
||||
keyval = WXK_NUMPAD_SUBTRACT;
|
||||
break;
|
||||
|
||||
|
||||
case 69:
|
||||
keyval = WXK_NUMPAD_ADD;
|
||||
break;
|
||||
|
||||
|
||||
case 65:
|
||||
keyval = WXK_NUMPAD_DECIMAL;
|
||||
break;
|
||||
@ -1594,7 +1592,7 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
event.m_shiftDown = modifiers & shiftKey;
|
||||
event.m_controlDown = modifiers & controlKey;
|
||||
event.m_altDown = modifiers & optionKey;
|
||||
@ -1621,7 +1619,7 @@ void wxApp::MacHideApp()
|
||||
HICommand command;
|
||||
memset( &command, 0 , sizeof(command) );
|
||||
command.commandID = kHICommandHide ;
|
||||
event.SetParameter<HICommand>(kEventParamDirectObject, command );
|
||||
event.SetParameter<HICommand>(kEventParamDirectObject, command );
|
||||
SendEventToApplication( event );
|
||||
#endif
|
||||
}
|
||||
|
@ -777,9 +777,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
int i;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
static bool s_inYield = false;
|
||||
|
||||
if ( s_inYield )
|
||||
if ( m_isInsideYield )
|
||||
{
|
||||
if ( !onlyIfNeeded )
|
||||
{
|
||||
@ -789,11 +787,12 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
return false;
|
||||
}
|
||||
|
||||
s_inYield = true;
|
||||
m_isInsideYield = true;
|
||||
|
||||
// Make sure we have an event loop object,
|
||||
// or Pending/Dispatch will fail
|
||||
wxEventLoopGuarantor dummyLoopIfNeeded;
|
||||
wxEventLoopGuarantor dummyLoopIfNeeded;
|
||||
|
||||
// Call dispatch at least once so that sockets
|
||||
// can be tested
|
||||
wxTheApp->Dispatch();
|
||||
@ -806,7 +805,7 @@ bool wxApp::Yield(bool onlyIfNeeded)
|
||||
#endif
|
||||
ProcessIdle();
|
||||
|
||||
s_inYield = false;
|
||||
m_isInsideYield = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user