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

Commit

Permalink
Merge 2e6d48d into ceeb0b1
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth authored Jan 14, 2022
2 parents ceeb0b1 + 2e6d48d commit 3f464ec
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/GLib/GLib.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ cfunction_(@nospecialize(f), r, a::Tuple) = cfunction_(f, r, Tuple{a...})
end
end

const gtk_eventloop_f = Ref{Function}()

# local function, handles Symbol and makes UTF8-strings easier
const AbstractStringLike = Union{AbstractString, Symbol}
bytestring(s) = String(s)
Expand Down
1 change: 1 addition & 0 deletions src/GLib/signals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ end
@deprecate g_timeout_add(interval, cb, user_data) g_timeout_add(() -> cb(user_data), interval)

function g_idle_add(cb::Function)
gtk_eventloop_f[](true)
callback = @cfunction(_g_callback, Cint, (Ref{Function},))
ref, deref = gc_ref_closure(cb)
return ccall((:g_idle_add_full , libglib),Cint,
Expand Down
45 changes: 41 additions & 4 deletions src/Gtk.jl
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,50 @@ function __init__()
C_NULL, C_NULL, "Julia Gtk Bindings", C_NULL, C_NULL, error_check)
end

# if g_main_depth > 0, a glib main-loop is already running,
# so we don't need to start a new one
if ccall((:g_main_depth, GLib.libglib), Cint, ()) == 0
global gtk_main_task = schedule(Task(gtk_main))
# if g_main_depth > 0, a glib main-loop is already running.
# unfortunately this call does not reliably reflect the state after the
# loop has been stopped or restarted, so only use it once at the start
gtk_main_running[] = ccall((:g_main_depth, GLib.libglib), Cint, ()) > 0

# Given GLib provides `g_idle_add` to specify what happens during idle, this allows
# that call to also start the eventloop
GLib.gtk_eventloop_f[] = enable_eventloop

auto_idle[] = get(ENV, "GTK_AUTO_IDLE", "true") == "true"

# by default, defer starting the event loop until either `show`, `showall`, or `g_idle_add` is called
enable_eventloop(!auto_idle[])
end

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

"""
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
end
end
end

"""
Gtk.is_eventloop_running()::Bool
Check whether Gtk's event loop is running.
"""
is_eventloop_running() = gtk_main_running[]

const ser_version = Serialization.ser_version
let cachedir = joinpath(splitdir(@__FILE__)[1], "..", "gen")
fastgtkcache = joinpath(cachedir, "gtk$(libgtk_version.major)_julia_ser$(ser_version)")
Expand Down
27 changes: 25 additions & 2 deletions src/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,31 @@ screen_size(w::GtkWindowLeaf) = screen_size(Gtk.GAccessor.screen(w))
### Functions and methods common to all GtkWidget objects
visible(w::GtkWidget) = Bool(ccall((:gtk_widget_get_visible, libgtk), Cint, (Ptr{GObject},), w))
visible(w::GtkWidget, state::Bool) = @sigatom ccall((:gtk_widget_set_visible, libgtk), Nothing, (Ptr{GObject}, Cint), w, state)
show(w::GtkWidget) = (@sigatom ccall((:gtk_widget_show, libgtk), Nothing, (Ptr{GObject},), w); w)
showall(w::GtkWidget) = (@sigatom ccall((:gtk_widget_show_all, libgtk), Nothing, (Ptr{GObject},), w); w)

const shown_widgets = WeakKeyDict()
function handle_auto_idle(w::GtkWidget)
if auto_idle[]
signal_connect(w, :realize) do w
enable_eventloop(true)
shown_widgets[w] = nothing
signal_connect(w, :destroy) do w
delete!(shown_widgets, w)
isempty(shown_widgets) && enable_eventloop(false)
end
end
end
end
function show(w::GtkWidget)
handle_auto_idle(w)
@sigatom ccall((:gtk_widget_show, libgtk), Nothing, (Ptr{GObject},), w)
w
end
function showall(w::GtkWidget)
handle_auto_idle(w)
@sigatom ccall((:gtk_widget_show_all, libgtk), Nothing, (Ptr{GObject},), w)
w
end

hide(w::GtkWidget) = (@sigatom ccall((:gtk_widget_hide , libgtk),Cvoid,(Ptr{GObject},),w); w)
grab_focus(w::GtkWidget) = (@sigatom ccall((:gtk_widget_grab_focus , libgtk), Cvoid, (Ptr{GObject},), w); w)

Expand Down
4 changes: 2 additions & 2 deletions src/windows.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ end

resize!(win::GtkWindow, w::Integer, h::Integer) = ccall((:gtk_window_resize, libgtk), Nothing, (Ptr{GObject}, Int32, Int32), win, w, h)

present(win::GtkWindow) = ccall((:gtk_window_present, libgtk), Nothing, (Ptr{GObject},), win)
present(win::GtkWindow) = (handle_auto_idle(win); ccall((:gtk_window_present, libgtk), Nothing, (Ptr{GObject},), win))

fullscreen(win::GtkWindow) = ccall((:gtk_window_fullscreen, libgtk), Nothing, (Ptr{GObject},), win)
fullscreen(win::GtkWindow) = (handle_auto_idle(win); ccall((:gtk_window_fullscreen, libgtk), Nothing, (Ptr{GObject},), win))
unfullscreen(win::GtkWindow) = ccall((:gtk_window_unfullscreen, libgtk), Nothing, (Ptr{GObject},), win)

maximize(win::GtkWindow) = ccall((:gtk_window_maximize, libgtk), Nothing, (Ptr{GObject},), win)
Expand Down

0 comments on commit 3f464ec

Please sign in to comment.