@@ -159,50 +159,62 @@ function __init__()
159159 C_NULL , C_NULL , " Julia Gtk Bindings" , C_NULL , C_NULL , error_check)
160160 end
161161
162- # if g_main_depth > 0, a glib main-loop is already running.
163- # unfortunately this call does not reliably reflect the state after the
164- # loop has been stopped or restarted, so only use it once at the start
165- gtk_main_running[] = ccall ((:g_main_depth , GLib. libglib), Cint, ()) > 0
166-
167- # Given GLib provides `g_idle_add` to specify what happens during idle, this allows
168- # that call to also start the eventloop
169- GLib. gtk_eventloop_f[] = enable_eventloop
170-
171162 auto_idle[] = get (ENV , " GTK_AUTO_IDLE" , " true" ) == " true"
172-
173- # by default, defer starting the event loop until either `show`, `showall`, or `g_idle_add` is called
174- enable_eventloop (! auto_idle[])
163+ # by default, defer starting the event loop until widgets are "realized"
164+ if auto_idle[]
165+ # Start-stopping the event loop once makes the auto-stop process
166+ # more stable. Reason unknown
167+ enable_eventloop (true )
168+ enable_eventloop (false )
169+ else
170+ enable_eventloop (true )
171+ end
175172end
176173
177174const auto_idle = Ref {Bool} (true ) # control default via ENV["GTK_AUTO_IDLE"]
178- const gtk_main_running = Ref {Bool} (false )
179- const quit_task = Ref {Task} ()
180175const enable_eventloop_lock = Base. ReentrantLock ()
176+ const eventloop_instructed_to_stop = Ref {Bool} (false )
177+
181178"""
182179 Gtk.enable_eventloop(b::Bool = true)
183180
184181Set whether Gtk's event loop is running.
185182"""
186- function enable_eventloop (b:: Bool = true ; wait_stopped :: Bool = false )
183+ function enable_eventloop (b:: Bool = true ; wait = true )
187184 lock (enable_eventloop_lock) do # handle widgets that are being shown/destroyed from different threads
188- isassigned (quit_task) && wait (quit_task[]) # prevents starting while the async is still stopping
189185 if b
190186 if ! is_eventloop_running ()
187+ eventloop_instructed_to_stop[] = false
191188 global gtk_main_task = schedule (Task (gtk_main))
192- gtk_main_running[] = true
189+ if ! is_eventloop_running () && wait
190+ t = Timer (5 ) # TODO : replace with Base.timedwait when 1.3 is dropped
191+ while isopen (t) && ! is_eventloop_running ()
192+ sleep (0.1 )
193+ end
194+ isopen (t) || @debug " enable_eventloop: timed-out waiting for eventloop to start"
195+ end
193196 end
194197 else
195198 if is_eventloop_running ()
196- # @async and short sleep is needer on MacOS at least, otherwise
197- # the window doesn't always finish closing before the eventloop stops.
198- quit_task[] = @async begin
199- sleep (0.2 )
200- gtk_quit ()
201- gtk_main_running[] = false
199+ recursive_quit_main ()
200+ eventloop_instructed_to_stop[] = true
201+ if is_eventloop_running () && wait
202+ t = Timer (5 ) # TODO : replace with Base.timedwait when 1.3 is dropped
203+ while isopen (t) && is_eventloop_running ()
204+ sleep (0.1 )
205+ end
206+ isopen (t) || @debug " enable_eventloop: timed-out waiting for eventloop to stop"
202207 end
203- wait_stopped && wait (quit_task[])
204208 end
205209 end
210+ return is_eventloop_running ()
211+ end
212+ end
213+
214+ function recursive_quit_main ()
215+ gtk_main_quit ()
216+ if GLib. main_depth () > 1
217+ @idle_add recursive_quit_main ()
206218 end
207219end
208220
@@ -214,8 +226,8 @@ pausing. Respects whether Gtk.jl is configured to allow auto-stopping of the
214226eventloop, unless `force = true`.
215227"""
216228function pause_eventloop (f; force = false )
217- was_running = is_eventloop_running ()
218- (force || auto_idle[]) && enable_eventloop (false , wait_stopped = true )
229+ was_running = eventloop_instructed_to_stop[] ? false : is_eventloop_running ()
230+ (force || auto_idle[]) && enable_eventloop (false )
219231 try
220232 f ()
221233 finally
228240
229241Check whether Gtk's event loop is running.
230242"""
231- is_eventloop_running () = gtk_main_running[]
243+ is_eventloop_running () = GLib. main_depth () > 0
244+
232245
233246const ser_version = Serialization. ser_version
234247let cachedir = joinpath (splitdir (@__FILE__ )[1 ], " .." , " gen" )
0 commit comments