On 7/6/21 7:22 AM Manolo wrote:
Le lundi 5 juillet 2021 à
22:02:45 UTC+2, Albrecht Schlosser a écrit :
@Manolo: Before you dive too deep into a specific
implementation for Wayland I'd like to share some thoughts
I'm having since some time now to unify the timer handling
on all platforms. I believe that the Linux timer
implementation is superior to the Windows and maybe also the
macOS implementation. The Linux timer implementation works
like this (maybe over-simplified):
I believe this means the timer implementation for the X11
FLTK platform (which covers Linux but also Unix and Darwin).
(1) Every call to Fl::add_timeout() or Fl::repeat_timeout()
adds a timer entry to the internal timer queue. This queue
is sorted by the timer's due time.
(2) There's only one system timer, using the smallest delta
value, i.e. the time of the first timer in the queue.
In my view, there's no system timer at all. FLTK sets the
max length of the next select/poll call to the smallest delta
which has the effect of breaking the event loop at the
desired time. This setup is possible because with X11 (and
with Wayland too)
the event loop is built using a select/poll call that
returns when data arrive on a fd or when the waiting delay
Yes, that's true. What I wanted to say is that FLTK does not
schedule a different (system) timer for each timer entry of the
timer queue as opposed to the Windows implementation (IIRC).
(3) Whenever the timer triggers (or maybe more often) the
event handling decrements the delta time of all timers.
I find this procedure awkward, even though it's correct.
Awkward or not, it's more precise than that of the Windows timers.
My intention is to simplify and unify the timer event handling on
all platforms. We have the documented "delta adjustment" of
Fl::repeat_timeout() which definitely doesn't work well (or not at
all) on Windows which is why timers on Windows tend to drift away.
One reason of inaccuracy is the Windows timer granularity which has
limits (this affects each single timer). The overall timer accuracy
of Fl::repeat_timer() could, however, be improved (less or no
overall timer drift). Let's say: if you n repeated timers then the
average timer interval should be as accurate as possible.
(4) All timers callbacks of expired timers are called.
(5) A new timer with the shortest delay (which is always the
first timer in the queue) is scheduled.
(6) Wait for timer events...
In my view, there're no real timer events: the poll/select
Yep, I agree. As said above...
This is AFAICT done because the standard Unix timers can
be interrupted and need to [be] re-scheduled whenever such
The benefit of this approach is as described in
Fl::repeat_timer() docs: if the call to Fl::repeat_timer()
is done "late" it can be corrected by the delay and the
overall timer sequence of repeated timers is more accurate
than on other platforms.
On the Windows platform we're (AFAICT) using one system
timer per Fl::add/repeat_timer() call. The Windows timer
events are less accurate anyway, but a change as designed
for Unix/Linux could probably contribute to more accuracy of
repeated timer events because the correction of timer delay
as on Unix/Linux could work better (it does not currently on
I know less about the macOS platform, but I know for sure
that the timer handling is different. There are
inconsistencies WRT Unix/Linux/Windows on the user visible
level (which I intend to demonstrate with a test program
anyway) but which are too difficult (and OT now).
The macOS FLTK platform uses a system timer: the event loop
is made by calling a function that does "wait until an event
and Fl::add_timeout creates a system object that makes the
waiting function run the timer cb when the delay has expired.
Is it correct that this is one distinct system timer per timer queue
My idea was to also use a true system timer for the Wayland
platform (but that could be for all Linux). Posix timers do
They trigger either a signal or a thread after a specified
delay. With the thread approach, having the child thread call
allows the main thread to stop waiting and process the
Hmm, is this a necessary change for the Wayland platform, or do you
want to do it because you find the current implementation "awkward"?
Did you consider the possibly new requirements, platform
dependencies, and such? If we extended this to the normal Unix
platform ("all Linux", as you wrote), would this affect
Note: I don't consider the current Unix/Linux implementation awkward
(it has its advantages), and if you want to change it to POSIX
timers we should discuss this here in general. I would rather change
all other implementations to the "manage our own timer event queue"
approach like it is in our current Unix/Linux implementation. But
this is not a contradiction because the timer event scheduling and
the timer event processing can be independent - see my description
That all said: I hope that the Wayland implementation
would be basically like the Unix/Linux timer queue handling so
we can easily unify all platforms.
More about the unification: I'm thinking of a platform
independent timer queue where Fl::add_timeout() and friends
would be platform independent. They would add an Fl_Timeout_XX
object to the timer queue which may contain platform
specific timer data (or not?). Triggering the timeout would
then, as always, be done by the system, the timer queue
handling would still be platform independent, as well as
calling the callbacks etc.. The more I think about it, the
more I believe that only the scheduling of this single timer
event would be a platform dependent (i.e. system driver)
As written above, the X11 approach uses the fd through
which all X11 data arrives and the poll/select call on this fd
timeout events: it reduces the max waiting time of the
poll/select call. Is your idea to change the organization of
the event loop
of other platforms (namely macOS) and have it wait for GUI
events for a time determined by the next scheduled timeout?
I can't answer this question with yes or no.
My basic idea is to unify (and therefore simplify) the timer event
handling on all platforms. I've seen IMHO too much platform specific
code to handle timer events. The more platforms we add, the more
platform specific code we need to maintain.
My goal is to do as much as possible in platform independent code.
This platform independent code would schedule timer events by adding
them to the timer event queue - in my model the Unix/Linux code
would be a valid implementation. This could be done on all current
and future platforms in a platform independent way. There would also
be only one platform independent timer event processing function.
This could be (like) the current Unix/Linux implementation which
decrements the timer delay of all timer events in the queue.
The only platform dependent code should be the scheduling of the
timer event. This could be as it is now on Unix/Linux to reduce the
select/poll timer to the next timer delay or to schedule exactly one
system timer on each platform which would be the delta time to the
next (first) timer event. The only requirement is that the resulting
timer event would call the platform independent
For further clarification: my model would allow to use the fd
approach we're using now as well as POSIX timers and Windows or
macOS timers as long as we're only scheduling one timer for all
systems and we're doing the timer event processing in only one
system independent function. This is basically what I want to
This would allow us to get the same behavior on all current and
future platforms including the optimal "repeated timer delay
correction" with the minimum of platform specific code. A nice side
effect would be that porting to another platform would be
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to email@example.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/81d29927-8a93-c2c0-5dc7-a2fd42c05dd0%40online.de.
[ Direct Link to Message ]