The notion of an event in the Prolog+Tcl/Tk system is overloaded. We have already come across the following kinds of events:
bind
command
tcl_event/3
,
tk_next_event(2,3)
, and prolog_event
functions
It is further about to be overloaded with the notion of Tcl/Tk events. It is possible to create event handlers in Tcl/Tk for reacting to other kinds of events. We will not cover them here but describe them so that the library functions are understandable and in case the user needs these features in an advanced application.
There are the following kinds of Tcl/Tk events:
The problem is that in advanced Tcl/Tk applications it is possible to create event handlers for each of these kinds of event, but they are not normally serviced while in Prolog code. This can result in unresponsive behavior in the application; for example, if window events are not serviced regularly then if the user tries to resize a Tk window, it will not resize in a timely fashion.
The solution to this is to introduce a Prolog predicate that
passes control to Tk for a while so that it can process its events,
tk_do_one_event/[0,1]
. If an application is unresponsive because
it is spending a lot of time in Prolog and is not servicing Tk events
often enough, then critical sections of the Prolog code can be sprinkled
with calls to tk_do_one_event/[0,1]
to alleviate the problem.
tk_do_one_event/[0,1]
has the following forms:
tk_do_one_event tk_do_one_event(+ListOrBitMask)
which passes control to Tk to handle a single event before passing control back to Prolog. The type of events handled is passed through the ListOrBitMask variable. As indicated, this is either a list of atoms that are event types, or a bit mask as specified in the Tcl/Tk documentation. (The bit mask should be avoided for portability between Tcl/Tk versions.)
The ListOrBitMask list can contain the following atoms:
tk_dont_wait
tk_x_events
tk_window_events
tk_file_events
tk_timer_events
tk_idle_events
Tk_DoWhenIdle
events
tk_all_events
Calling tk_do_one_event/0
is equivalent to a call to
tk_do_one_event/1
with all flags set.
A call to either of these predicates succeeds only if an event of
the appropriate type happens in the Tcl/Tk interpreter. If there are no
such events, then tk_do_one_event/1
will fail if the
tk_dont_wait
wait flag is present, as will
tk_do_one_event/0
, which has that flag set implicitly.
If the tk_dont_wait
flag is not set, then a call to
tk_do_one_event/1
will block until an appropriate Tk event
happens (in which case it will succeed).
It is straight forward to define a predicate that handles all Tk events and then returns:
tk_do_all_events :- tk_do_one_event, !, tk_do_all_events. tk_do_all_events.
The predicate tk_next_event/[2,3]
is similar to
tk_do_one_event/[0,1]
except that it processes Tk events until at
least one Prolog event happens. (We came across this predicate
before when discussing Prolog event queue predicates. This shows
the overloading of the notion event where we have a predicate that
handles both Tcl/Tk events and Prolog queue events.)
It has the following forms:
tk_next_event(+TclInterpreter, -Event) tk_next_event(+ListOrBitMask, +TclInterpreter, -Event)
The Prolog event is returned in the variable Event and is the
first term on the Prolog event queue associated with the
interpreter TclInterpreter. (Prolog events are initiated on the
Tcl side through the new Tcl command prolog_event
, covered
earlier; see prolog_event).