]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk1/evtloop.cpp
Don't use images in wxToolBar with wxTB_NOICONS in wxOSX.
[wxWidgets.git] / src / gtk1 / evtloop.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk1/evtloop.cpp
3// Purpose: implements wxEventLoop for GTK+
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 10.07.01
7// RCS-ID: $Id$
8// Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#include "wx/evtloop.h"
28
29#ifndef WX_PRECOMP
30 #include "wx/app.h"
31 #include "wx/log.h"
32#endif // WX_PRECOMP
33
34#include <gtk/gtk.h>
35
36// ----------------------------------------------------------------------------
37// wxEventLoopImpl
38// ----------------------------------------------------------------------------
39
40class WXDLLEXPORT wxEventLoopImpl
41{
42public:
43 // ctor
44 wxEventLoopImpl() { SetExitCode(0); }
45
46 // set/get the exit code
47 void SetExitCode(int exitcode) { m_exitcode = exitcode; }
48 int GetExitCode() const { return m_exitcode; }
49
50private:
51 // the exit code of the event loop
52 int m_exitcode;
53};
54
55// ============================================================================
56// wxGUIEventLoop implementation
57// ============================================================================
58
59// ----------------------------------------------------------------------------
60// wxGUIEventLoop running and exiting
61// ----------------------------------------------------------------------------
62
63wxGUIEventLoop::~wxGUIEventLoop()
64{
65 wxASSERT_MSG( !m_impl, wxT("should have been deleted in Run()") );
66}
67
68int wxGUIEventLoop::DoRun()
69{
70 m_impl = new wxEventLoopImpl;
71
72 guint loopLevel = gtk_main_level();
73
74 // This is placed inside of a loop to take into account nested
75 // event loops. For example, inside this event loop, we may recieve
76 // Exit() for a different event loop (which we are currently inside of)
77 // That Exit() will cause this gtk_main() to exit so we need to re-enter it.
78 while ( !m_shouldExit )
79 {
80 gtk_main();
81 }
82
83 // Force the enclosing event loop to also exit to see if it is done
84 // in case that event loop ended inside of this one. If it is not time
85 // yet for that event loop to exit, it will be executed again due to
86 // the while() loop on m_shouldExit().
87 //
88 // This is unnecessary if we are the top level loop, i.e. loop of level 0.
89 if ( loopLevel )
90 {
91 gtk_main_quit();
92 }
93
94 OnExit();
95
96 int exitcode = m_impl->GetExitCode();
97 wxDELETE(m_impl);
98
99 return exitcode;
100}
101
102void wxGUIEventLoop::ScheduleExit(int rc)
103{
104 wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not started") );
105
106 m_impl->SetExitCode(rc);
107
108 m_shouldExit = true;
109
110 gtk_main_quit();
111}
112
113// ----------------------------------------------------------------------------
114// wxEventLoop message processing dispatching
115// ----------------------------------------------------------------------------
116
117bool wxGUIEventLoop::Pending() const
118{
119 if (wxTheApp)
120 {
121 // We need to remove idle callbacks or gtk_events_pending will
122 // never return false.
123 wxTheApp->RemoveIdleTag();
124 }
125
126 return gtk_events_pending();
127}
128
129bool wxGUIEventLoop::Dispatch()
130{
131 wxCHECK_MSG( IsRunning(), false, wxT("can't call Dispatch() if not running") );
132
133 gtk_main_iteration();
134
135 return true;
136}
137
138//-----------------------------------------------------------------------------
139// wxYield
140//-----------------------------------------------------------------------------
141
142bool wxGUIEventLoop::YieldFor(long eventsToProcess)
143{
144#if wxUSE_THREADS
145 if ( !wxThread::IsMain() )
146 {
147 // can't call gtk_main_iteration() from other threads like this
148 return true;
149 }
150#endif // wxUSE_THREADS
151
152 m_isInsideYield = true;
153 m_eventsToProcessInsideYield = eventsToProcess;
154
155 // We need to remove idle callbacks or the loop will
156 // never finish.
157 wxTheApp->RemoveIdleTag();
158
159#if wxUSE_LOG
160 // disable log flushing from here because a call to wxYield() shouldn't
161 // normally result in message boxes popping up &c
162 wxLog::Suspend();
163#endif
164
165 // TODO: implement event filtering using the eventsToProcess mask
166 while (gtk_events_pending())
167 gtk_main_iteration();
168
169 // It's necessary to call ProcessIdle() to update the frames sizes which
170 // might have been changed (it also will update other things set from
171 // OnUpdateUI() which is a nice (and desired) side effect). But we
172 // call ProcessIdle() only once since this is not meant for longish
173 // background jobs (controlled by wxIdleEvent::RequestMore() and the
174 // return value of Processidle().
175 ProcessIdle();
176
177#if wxUSE_LOG
178 // let the logs be flashed again
179 wxLog::Resume();
180#endif
181
182 m_isInsideYield = false;
183
184 return true;
185}