How to avoid "Julia is not responding" when using a file dialog

I have a GLMakie based GUI app and want to load a file using a native file dialog. This is my code:

using GLMakie, NativeFileDialog

fig = Figure(size=(200, 200), backgroundcolor=RGBf(0.7, 0.8, 1))
btn_RUN  = Button(fig, label = " Open file... ")
on(btn_RUN.clicks) do c;
    println("opening file dialog...")
    filename      = pick_file(pwd())
    println(filename)
end
fig

While it works, I get the message “Julia is not responding…” if I keep the dialog open for more than 5 or 10 seconds.

How can I avoid that?

My idea would be to run the dialog in a separate thread, but how can that be achieved?

I am one step further:

using KiteViewers.GLMakie, NativeFileDialog

fig = Figure(size=(200, 200), backgroundcolor=RGBf(0.7, 0.8, 1))
btn_RUN  = Button(fig, label = " Open file... ")
on(btn_RUN.clicks) do c;
    println("opening file dialog...")
    Threads.@spawn begin
        filename      = pick_file("")
        println(filename)
    end
end
fig

But how can I read the filename in the main thread in a thread-safe manner?

This seams to work:

using KiteViewers.GLMakie, NativeFileDialog

fig = Figure(size=(200, 200), backgroundcolor=RGBf(0.7, 0.8, 1))
btn_RUN  = Button(fig, label = " Open file... ")
lk = ReentrantLock()
filename = ""
on(btn_RUN.clicks) do c;
    println("opening file dialog...")
    Threads.@spawn begin
        global filename
        lock(lk) do
            filename      = pick_file("")
        end
    end
end
@async begin
    while true
        global filename
        lock(lk) do
            if filename != ""
                println(filename)
                filename = ""
            end
        end
        sleep(0.1)
    end
end
fig

Does fetching the spawned task make Julia unresponsive? If not

filename = fetch(Threads.@spawn pick_file(""))

should accomplish the same.

Well, this does NOT work, it still blocks the main thread:

using GLMakie, NativeFileDialog

fig = Figure(size=(200, 200), backgroundcolor=RGBf(0.7, 0.8, 1))
btn_RUN  = Button(fig, label = " Open file... ")
on(btn_RUN.clicks) do c;
    println("opening file dialog...")
    filename = fetch(Threads.@spawn pick_file(""))
    println(filename)
end
fig
1 Like

OK, this seams to work and is easier than the first solution:

using GLMakie, NativeFileDialog

fig = Figure(size=(200, 200), backgroundcolor=RGBf(0.7, 0.8, 1))
btn_OPEN  = Button(fig, label = " Open file... ")
on(btn_OPEN.clicks) do c;
    @async begin 
        filename = fetch(Threads.@spawn pick_file(""))
        println(filename)
    end
end
fig
3 Likes