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