diff --git a/src/Gtk.jl b/src/Gtk.jl index ad83b5c6..7bc15dc5 100644 --- a/src/Gtk.jl +++ b/src/Gtk.jl @@ -152,7 +152,7 @@ const enable_eventloop_lock = Base.ReentrantLock() Set whether Gtk's event loop is running. """ -function enable_eventloop(b::Bool = true) +function enable_eventloop(b::Bool = true; wait_stopped::Bool = false) lock(enable_eventloop_lock) do # handle widgets that are being shown/destroyed from different threads isassigned(quit_task) && wait(quit_task[]) # prevents starting while the async is still stopping if b @@ -169,11 +169,29 @@ function enable_eventloop(b::Bool = true) gtk_quit() gtk_main_running[] = false end + wait_stopped && wait(quit_task[]) end end end end +""" + Gtk.pause_eventloop(f; force = false) + +Pauses the eventloop around a function. Restores the state of the eventloop after +pausing. Respects whether Gtk.jl is configured to allow auto-stopping of the +eventloop, unless `force = true`. +""" +function pause_eventloop(f; force = false) + was_running = is_eventloop_running() + (force || auto_idle[]) && enable_eventloop(false, wait_stopped = true) + try + f() + finally + (force || auto_idle[]) && enable_eventloop(was_running) + end +end + """ Gtk.is_eventloop_running()::Bool diff --git a/test/misc.jl b/test/misc.jl index b307ffa5..347fed78 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -38,4 +38,30 @@ destroy(win) @test isa(Gtk.GdkEventKey(), Gtk.GdkEventKey) +@testset "Eventloop control" begin + before = Gtk.auto_idle[] + + Gtk.enable_eventloop(true) + @test Gtk.is_eventloop_running() + + Gtk.auto_idle[] = true + Gtk.pause_eventloop() do + @test !Gtk.is_eventloop_running() + end + @test Gtk.is_eventloop_running() + + Gtk.auto_idle[] = false + Gtk.pause_eventloop() do + @test Gtk.is_eventloop_running() + end + @test Gtk.is_eventloop_running() + + Gtk.pause_eventloop(force = true) do + @test !Gtk.is_eventloop_running() + end + @test Gtk.is_eventloop_running() + + Gtk.auto_idle[] = before +end + end