Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Add a yield for windows (fix #610). Fix window not finishing close on…
Browse files Browse the repository at this point in the history
… MacOS (#611)

* add a yield for windows (fix #610)

* make static

* add fix for MacOS windows not reliably closing too

* fix thread safety in auto idle handler
  • Loading branch information
IanButterworth authored Jan 16, 2022
1 parent d377ac6 commit c23b075
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
29 changes: 19 additions & 10 deletions src/Gtk.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,22 +145,31 @@ end

const auto_idle = Ref{Bool}(true) # control default via ENV["GTK_AUTO_IDLE"]
const gtk_main_running = Ref{Bool}(false)

const quit_task = Ref{Task}()
const enable_eventloop_lock = Base.ReentrantLock()
"""
Gtk.enable_eventloop(b::Bool = true)
Set whether Gtk's event loop is running.
"""
function enable_eventloop(b::Bool = true)
if b
if !is_eventloop_running()
global gtk_main_task = schedule(Task(gtk_main))
gtk_main_running[] = true
end
else
if is_eventloop_running()
gtk_quit()
gtk_main_running[] = 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
if !is_eventloop_running()
global gtk_main_task = schedule(Task(gtk_main))
gtk_main_running[] = true
end
else
if is_eventloop_running()
# @async and short sleep is needer on MacOS at least, otherwise
# the window doesn't always finish closing before the eventloop stops.
quit_task[] = @async begin
sleep(0.2)
gtk_quit()
gtk_main_running[] = false
end
end
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion src/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ function handle_auto_idle(w::GtkWidget)
signal_connect(w, :realize) do w
enable_eventloop(true)
shown_widgets[w] = nothing
signal_connect(w, :destroy) do w
signal_connect(w, :destroy, #= after =# true) do w
delete!(shown_widgets, w)
isempty(shown_widgets) && enable_eventloop(false)
end
end
@static Sys.iswindows() && yield() # issue #610
end
end
function show(w::GtkWidget)
Expand Down

0 comments on commit c23b075

Please sign in to comment.