implement wxEventLoop::DispatchTimeout() for wxGTK (thanks Paul) and rewrote it to not use wxEventLoopImpl which it doesn't need

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57581 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-12-27 11:01:39 +00:00
parent e5794f50e7
commit 564c7fc412
5 changed files with 91 additions and 38 deletions

View File

@@ -2352,6 +2352,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_LOWLEVEL_HDR = \
wx/gtk/dcmemory.h \ wx/gtk/dcmemory.h \
wx/gtk/dcscreen.h \ wx/gtk/dcscreen.h \
wx/gtk/dnd.h \ wx/gtk/dnd.h \
wx/gtk/evtloop.h \
wx/gtk/font.h \ wx/gtk/font.h \
wx/gtk/minifram.h \ wx/gtk/minifram.h \
wx/gtk/pen.h \ wx/gtk/pen.h \

View File

@@ -1027,6 +1027,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/gtk/dcmemory.h wx/gtk/dcmemory.h
wx/gtk/dcscreen.h wx/gtk/dcscreen.h
wx/gtk/dnd.h wx/gtk/dnd.h
wx/gtk/evtloop.h
wx/gtk/font.h wx/gtk/font.h
wx/gtk/minifram.h wx/gtk/minifram.h
wx/gtk/pen.h wx/gtk/pen.h

View File

@@ -126,6 +126,8 @@ protected:
#include "wx/osx/evtloop.h" #include "wx/osx/evtloop.h"
#elif defined(__WXDFB__) #elif defined(__WXDFB__)
#include "wx/dfb/evtloop.h" #include "wx/dfb/evtloop.h"
#elif defined(__WXGTK20__)
#include "wx/gtk/evtloop.h"
#else // other platform #else // other platform
#include "wx/stopwatch.h" // for wxMilliClock_t #include "wx/stopwatch.h" // for wxMilliClock_t

37
include/wx/gtk/evtloop.h Normal file
View File

@@ -0,0 +1,37 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/gtk/evtloop.h
// Purpose: wxGTK event loop implementation
// Author: Vadim Zeitlin
// Created: 2008-12-27
// RCS-ID: $Id$
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_GTK_EVTLOOP_H_
#define _WX_GTK_EVTLOOP_H_
// ----------------------------------------------------------------------------
// wxGUIEventLoop for wxGTK
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxGUIEventLoop : public wxEventLoopBase
{
public:
wxGUIEventLoop();
virtual int Run();
virtual void Exit(int rc = 0);
virtual bool Pending() const;
virtual bool Dispatch();
virtual int DispatchTimeout(unsigned long timeout);
virtual void WakeUp();
protected:
// the exit code of this event loop
int m_exitcode;
DECLARE_NO_COPY_CLASS(wxGUIEventLoop)
};
#endif // _WX_GTK_EVTLOOP_H_

View File

@@ -25,7 +25,6 @@
#endif #endif
#include "wx/evtloop.h" #include "wx/evtloop.h"
#include "wx/ptr_scpd.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/app.h" #include "wx/app.h"
@@ -33,79 +32,65 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
// ----------------------------------------------------------------------------
// wxEventLoopImpl
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxEventLoopImpl
{
public:
// ctor
wxEventLoopImpl() { SetExitCode(0); }
// set/get the exit code
void SetExitCode(int exitcode) { m_exitcode = exitcode; }
int GetExitCode() const { return m_exitcode; }
private:
// the exit code of the event loop
int m_exitcode;
};
// ============================================================================ // ============================================================================
// wxEventLoop implementation // wxEventLoop implementation
// ============================================================================ // ============================================================================
wxDEFINE_TIED_SCOPED_PTR_TYPE(wxEventLoopImpl)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxEventLoop running and exiting // wxEventLoop running and exiting
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxGUIEventLoop::~wxGUIEventLoop() wxGUIEventLoop::wxGUIEventLoop()
{ {
wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") ); m_exitcode = 0;
} }
int wxGUIEventLoop::Run() int wxGUIEventLoop::Run()
{ {
// event loops are not recursive, you need to create another loop! // event loops are not recursive, you need to create another loop!
wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") ); wxCHECK_MSG( !IsRunning(), -1, "can't reenter a message loop" );
wxEventLoopActivator activate(this); wxEventLoopActivator activate(this);
wxEventLoopImplTiedPtr impl(&m_impl, new wxEventLoopImpl);
gtk_main(); gtk_main();
OnExit(); OnExit();
return m_impl->GetExitCode(); return m_exitcode;
} }
void wxGUIEventLoop::Exit(int rc) void wxGUIEventLoop::Exit(int rc)
{ {
wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") ); wxCHECK_RET( IsRunning(), "can't call Exit() if not running" );
m_impl->SetExitCode(rc); m_exitcode = rc;
gtk_main_quit(); gtk_main_quit();
} }
void wxGUIEventLoop::WakeUp()
{
// TODO: idle events handling should really be done by wxEventLoop itself
// but for now it's completely in gtk/app.cpp so just call there when
// we have wxTheApp and hope that it doesn't matter that we do
// nothing when we don't...
if ( wxTheApp )
wxTheApp->WakeUpIdle();
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxEventLoop message processing dispatching // wxEventLoop message processing dispatching
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool wxGUIEventLoop::Pending() const bool wxGUIEventLoop::Pending() const
{ {
bool pending; if ( wxTheApp )
wxApp* app = wxTheApp; {
if (app != NULL) // this avoids false positives from our idle source
// app->EventsPending() avoids false positives from our idle source return wxTheApp->EventsPending();
pending = app->EventsPending(); }
else
pending = gtk_events_pending() != 0; return gtk_events_pending() != 0;
return pending;
} }
bool wxGUIEventLoop::Dispatch() bool wxGUIEventLoop::Dispatch()
@@ -115,3 +100,30 @@ bool wxGUIEventLoop::Dispatch()
// gtk_main_iteration() returns TRUE only if gtk_main_quit() was called // gtk_main_iteration() returns TRUE only if gtk_main_quit() was called
return !gtk_main_iteration(); return !gtk_main_iteration();
} }
extern "C" {
static gboolean wx_event_loop_timeout(void* data)
{
bool* expired = static_cast<bool*>(data);
*expired = true;
// return FALSE to remove this timeout
return FALSE;
}
}
int wxGUIEventLoop::DispatchTimeout(unsigned long timeout)
{
bool expired = false;
const unsigned id = g_timeout_add(timeout, wx_event_loop_timeout, &expired);
bool quit = gtk_main_iteration() != 0;
if ( expired )
return -1;
g_source_remove(id);
return !quit;
}