added wxApp::Yield()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12095 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2001-10-19 18:29:32 +00:00
parent 85ee61ac2e
commit 8461e4c253
19 changed files with 2116 additions and 2100 deletions

View File

@ -603,3 +603,29 @@ This function currently only has effect under GTK.
\docparam{flag}{If TRUE, the app will use the best visual.}
\membersection{wxApp::Yield}{wxappyield}
\func{bool}{Yield}{\param{bool}{ onlyIfNeeded = FALSE}}
Yields control to pending messages in the windowing system. This can be useful, for example, when a
time-consuming process writes to a text window. Without an occasional
yield, the text window will not be updated properly, and on systems with
cooperative multitasking, such as Windows 3.1 other processes will not respond.
Caution should be exercised, however, since yielding may allow the
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 \helpref{::wxSafeYield}{wxsafeyield} for a better
function.
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 a
message box dialog may be undesirable. If you do wish to flush the log
messages immediately (otherwise it will be done during the next idle loop
iteration), call \helpref{wxLog::FlushActive}{wxlogflushactive}.
Calling Yield() recursively is normally an error and an assert failure is
raised in debug build if such situation is detected. However if the the
{\it onlyIfNeeded} parameter is {\tt TRUE}, the method will just silently
return {\tt FALSE} instead.

View File

@ -2143,22 +2143,10 @@ See also \helpref{wxGetResource}{wxgetresource}, \helpref{wxConfigBase}{wxconfig
\func{bool}{wxYield}{\void}
Yields control to pending messages in the windowing system. This can be useful, for example, when a
time-consuming process writes to a text window. Without an occasional
yield, the text window will not be updated properly, and on systems with
cooperative multitasking, such as Windows 3.1 other processes will not respond.
Calls \helpref{wxApp::Yield}{wxappyield}.
Caution should be exercised, however, since yielding may allow the
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 \helpref{::wxSafeYield}{wxsafeyield} for a better
function.
Note that wxYield will not flush the message logs. This is intentional as
calling wxYield is usually done to quickly update the screen and popping up a
message box dialog may be undesirable. If you do wish to flush the log
messages immediately (otherwise it will be done during the next idle loop
iteration), call \helpref{wxLog::FlushActive}{wxlogflushactive}.
This function is kept only for backwards compatibility, please use the
wxApp method instead in any new code.
\wxheading{Include files}

View File

@ -65,9 +65,6 @@ public:
// the virtual functions which may/must be overridden in the derived class
// -----------------------------------------------------------------------
#ifdef __DARWIN__
virtual ~wxAppBase() { }
#endif
// called during the program initialization, returning FALSE from here
// prevents the program from continuing - it's a good place to create
@ -135,6 +132,17 @@ public:
// process the first event in the event queue (blocks until an event
// apperas if there are none currently)
virtual void Dispatch() = 0;
// process all currently pending events right now
//
// it is an error to call Yield() recursively unless the value of
// onlyIfNeeded is TRUE
//
// WARNING: this function is dangerous as it can lead to unexpected
// reentrancies (i.e. when called from an event handler it
// may result in calling the same event handler again), use
// with _extreme_ care or, better, don't use at all!
virtual bool Yield(bool onlyIfNeeded = FALSE) = 0;
#endif // wxUSE_GUI
// application info: name, description, vendor
@ -285,6 +293,11 @@ public:
static wxAppInitializerFunction GetInitializerFunction()
{ return m_appInitFn; }
// needed to avoid link errors
#ifdef __DARWIN__
virtual ~wxAppBase() { }
#endif
// process all events in the wxPendingEvents list
virtual void ProcessPendingEvents();

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: app.h
// Name: wx/gtk/app.h
// Purpose:
// Author: Robert Roebling
// Id: $Id$
@ -46,6 +46,7 @@ public:
virtual bool Initialized();
virtual bool Pending();
virtual void Dispatch();
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: app.h
// Name: wx/gtk/app.h
// Purpose:
// Author: Robert Roebling
// Id: $Id$
@ -46,6 +46,7 @@ public:
virtual bool Initialized();
virtual bool Pending();
virtual void Dispatch();
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const;

View File

@ -51,6 +51,7 @@ class WXDLLEXPORT wxApp: public wxAppBase
virtual bool Initialized();
virtual bool Pending() ;
virtual void Dispatch() ;
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const;
virtual void SetPrintMode(int mode) { m_printMode = mode; }

View File

@ -53,6 +53,7 @@ public:
virtual bool Initialized();
virtual bool Pending();
virtual void Dispatch();
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual bool OnInitGui();

View File

@ -41,6 +41,7 @@ public:
virtual bool Initialized();
virtual bool Pending();
virtual void Dispatch();
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const;

View File

@ -76,6 +76,7 @@ public:
virtual bool Initialized(void);
virtual bool Pending(void) ;
virtual void Dispatch(void);
virtual bool Yield(bool onlyIfNeeded = FALSE);
virtual wxIcon GetStdIcon(int which) const;

View File

@ -20,7 +20,6 @@
#pragma interface "utils.h"
#endif
#include "wx/setup.h"
#include "wx/object.h"
#include "wx/list.h"
#include "wx/filefn.h"

View File

@ -76,13 +76,6 @@ void WXDLLEXPORT wxExit()
abort();
}
// Yield to other apps/messages
bool WXDLLEXPORT wxYield()
{
// do nothing
return TRUE;
}
// Yield to other apps/messages
void WXDLLEXPORT wxWakeUpIdle()
{

View File

@ -36,6 +36,7 @@
#include "wx/log.h"
#if wxUSE_GUI
#include "wx/app.h"
#include "wx/window.h"
#include "wx/frame.h"
#include "wx/menu.h"
@ -1312,4 +1313,25 @@ long wxExecute(const wxString& command,
return wxDoExecuteWithCapture(command, output, &error);
}
// ----------------------------------------------------------------------------
// wxApp::Yield() wrappers for backwards compatibility
// ----------------------------------------------------------------------------
bool wxYield()
{
#if wxUSE_GUI
return wxTheApp && wxTheApp->Yield();
#else
return FALSE;
#endif
}
bool wxYieldIfNeeded()
{
#if wxUSE_GUI
return wxTheApp && wxTheApp->Yield(TRUE);
#else
return FALSE;
#endif
}

View File

@ -83,10 +83,21 @@ void wxExit()
// wxYield
//-----------------------------------------------------------------------------
static bool gs_inYield = FALSE;
bool wxYield()
bool wxApp::Yield(bool onlyIfNeeded)
{
// MT-FIXME
static bool s_inYield = FALSE;
if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return FALSE;
}
#if wxUSE_THREADS
if ( !wxThread::IsMain() )
{
@ -95,19 +106,14 @@ bool wxYield()
}
#endif // wxUSE_THREADS
#ifdef __WXDEBUG__
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
gs_inYield = TRUE;
s_inYield = TRUE;
if (!g_isIdle)
{
// We need to remove idle callbacks or the loop will
// never finish.
gtk_idle_remove( wxTheApp->m_idleTag );
wxTheApp->m_idleTag = 0;
gtk_idle_remove( m_idleTag );
m_idleTag = 0;
g_isIdle = TRUE;
}
@ -121,29 +127,18 @@ bool wxYield()
/* 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 (wxTheApp->ProcessIdle()) { }
while ( ProcessIdle() )
{
}
// let the logs be flashed again
wxLog::Resume();
gs_inYield = FALSE;
s_inYield = FALSE;
return TRUE;
}
//-----------------------------------------------------------------------------
// wxYieldIfNeeded
// Like wxYield, but fails silently if the yield is recursive.
//-----------------------------------------------------------------------------
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
//-----------------------------------------------------------------------------
// wxWakeUpIdle
//-----------------------------------------------------------------------------

View File

@ -83,10 +83,21 @@ void wxExit()
// wxYield
//-----------------------------------------------------------------------------
static bool gs_inYield = FALSE;
bool wxYield()
bool wxApp::Yield(bool onlyIfNeeded)
{
// MT-FIXME
static bool s_inYield = FALSE;
if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return FALSE;
}
#if wxUSE_THREADS
if ( !wxThread::IsMain() )
{
@ -95,19 +106,14 @@ bool wxYield()
}
#endif // wxUSE_THREADS
#ifdef __WXDEBUG__
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
gs_inYield = TRUE;
s_inYield = TRUE;
if (!g_isIdle)
{
// We need to remove idle callbacks or the loop will
// never finish.
gtk_idle_remove( wxTheApp->m_idleTag );
wxTheApp->m_idleTag = 0;
gtk_idle_remove( m_idleTag );
m_idleTag = 0;
g_isIdle = TRUE;
}
@ -121,29 +127,18 @@ bool wxYield()
/* 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 (wxTheApp->ProcessIdle()) { }
while ( ProcessIdle() )
{
}
// let the logs be flashed again
wxLog::Resume();
gs_inYield = FALSE;
s_inYield = FALSE;
return TRUE;
}
//-----------------------------------------------------------------------------
// wxYieldIfNeeded
// Like wxYield, but fails silently if the yield is recursive.
//-----------------------------------------------------------------------------
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
//-----------------------------------------------------------------------------
// wxWakeUpIdle
//-----------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -360,43 +360,43 @@ void wxApp::ProcessXEvent(WXEvent* _event)
widget, XtParent(widget));
#endif // DEBUG
if (CheckForAccelerator(_event))
{
if (CheckForAccelerator(_event))
{
// Do nothing! We intercepted and processed the event as an
// accelerator.
return;
}
}
#if 1
// It seemed before that this hack was redundant and
// key down events were being generated by wxCanvasInputEvent.
// But no longer - why ???
//
else if (CheckForKeyDown(_event))
{
else if (CheckForKeyDown(_event))
{
// We intercepted and processed the key down event
return;
}
}
#endif
else
{
else
{
XtDispatchEvent(event);
return;
}
return;
}
}
else if (event->type == KeyRelease)
{
// TODO: work out why we still need this ! -michael
//
if (CheckForKeyUp(_event))
{
// We intercepted and processed the key up event
return;
}
else
{
XtDispatchEvent(event);
return;
}
{
// We intercepted and processed the key up event
return;
}
else
{
XtDispatchEvent(event);
return;
}
}
else if (event->type == PropertyNotify)
{
@ -677,20 +677,20 @@ bool wxApp::CheckForKeyDown(WXEvent* event)
if (xEvent->xany.type == KeyPress)
{
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
xEvent->xany.window);
wxWindow* win = NULL;
xEvent->xany.window);
wxWindow* win = NULL;
// Find the first wxWindow that corresponds to this event window
while (widget && !(win = wxGetWindowFromTable(widget)))
// Find the first wxWindow that corresponds to this event window
while (widget && !(win = wxGetWindowFromTable(widget)))
widget = XtParent(widget);
if (!widget || !win)
if (!widget || !win)
return FALSE;
wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
return win->ProcessEvent( keyEvent );
return win->ProcessEvent( keyEvent );
}
return FALSE;
@ -702,20 +702,20 @@ bool wxApp::CheckForKeyUp(WXEvent* event)
if (xEvent->xany.type == KeyRelease)
{
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
xEvent->xany.window);
wxWindow* win = NULL;
xEvent->xany.window);
wxWindow* win = NULL;
// Find the first wxWindow that corresponds to this event window
while (widget && !(win = wxGetWindowFromTable(widget)))
widget = XtParent(widget);
// Find the first wxWindow that corresponds to this event window
while (widget && !(win = wxGetWindowFromTable(widget)))
widget = XtParent(widget);
if (!widget || !win)
return FALSE;
if (!widget || !win)
return FALSE;
wxKeyEvent keyEvent(wxEVT_KEY_UP);
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
wxKeyEvent keyEvent(wxEVT_KEY_UP);
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
return win->ProcessEvent( keyEvent );
return win->ProcessEvent( keyEvent );
}
return FALSE;
@ -737,40 +737,30 @@ void wxExit()
// Yield to other processes
static bool gs_inYield = FALSE;
bool wxYield()
bool wxApp::Yield(bool onlyIfNeeded)
{
#ifdef __WXDEBUG__
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
gs_inYield = TRUE;
bool s_inYield = FALSE;
if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return FALSE;
}
s_inYield = TRUE;
while (wxTheApp && wxTheApp->Pending())
wxTheApp->Dispatch();
// VZ: is it the same as this (taken from old wxExecute)?
#if 0
XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
#endif
gs_inYield = FALSE;
s_inYield = FALSE;
return TRUE;
}
// Yield to incoming messages; but fail silently if recursion is detected.
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
// TODO use XmGetPixmap (?) to get the really standard icons!
#include "wx/generic/info.xpm"

View File

@ -1435,20 +1435,26 @@ void wxExit()
// Yield to incoming messages
static bool gs_inYield = FALSE;
bool wxYield()
bool wxApp::Yield(bool onlyIfNeeded)
{
// MT-FIXME
static bool s_inYield = FALSE;
// disable log flushing from here because a call to wxYield() shouldn't
// normally result in message boxes popping up &c
wxLog::Suspend();
#ifdef __WXDEBUG__
if (gs_inYield)
wxFAIL_MSG( wxT("wxYield called recursively" ) );
#endif
if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
gs_inYield = TRUE;
return FALSE;
}
s_inYield = TRUE;
// we don't want to process WM_QUIT from here - it should be processed in
// the main event loop in order to stop it
@ -1464,27 +1470,17 @@ bool wxYield()
break;
}
// If they are pending events, we must process them.
if (wxTheApp)
wxTheApp->ProcessPendingEvents();
// if there are pending events, we must process them.
ProcessPendingEvents();
// let the logs be flashed again
wxLog::Resume();
gs_inYield = FALSE;
s_inYield = FALSE;
return TRUE;
}
// Yield to incoming messages; but fail silently if recursion is detected.
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
bool wxHandleFatalExceptions(bool doit)
{
#if wxUSE_ON_FATAL_EXCEPTION
@ -1493,9 +1489,9 @@ bool wxHandleFatalExceptions(bool doit)
return TRUE;
#else
wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to sue this function"));
(void)doit;
wxFAIL_MSG(_T("set wxUSE_ON_FATAL_EXCEPTION to 1 to use this function"));
(void)doit;
return FALSE;
#endif
}

View File

@ -1117,13 +1117,23 @@ void wxExit()
wxApp::CleanUp();
} // end of wxExit
static bool gs_inYield = FALSE;
//
// Yield to incoming messages
//
bool wxYield()
bool wxApp::Yield(bool onlyIfNeeded)
{
static bool s_inYield = FALSE;
if ( s_inYield )
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( _T("wxYield() called recursively") );
}
return FALSE;
}
HAB vHab = 0;
QMSG vMsg;
@ -1133,7 +1143,7 @@ bool wxYield()
//
wxLog::Suspend();
gs_inYield = TRUE;
s_inYield = TRUE;
//
// We want to go back to the main message loop
@ -1157,19 +1167,10 @@ bool wxYield()
// Let the logs be flashed again
//
wxLog::Resume();
gs_inYield = FALSE;
s_inYield = FALSE;
return TRUE;
} // end of wxYield
// Yield to incoming messages; but fail silently if recursion is detected.
bool wxYieldIfNeeded()
{
if (gs_inYield)
return FALSE;
return wxYield();
}
wxIcon wxApp::GetStdIcon(
int nWhich
) const