diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2025-05-13 21:04:56 +0200 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2025-05-13 21:08:51 +0200 |
| commit | 9b1379e6888abc7cc051a6c82d8b27ce454ceb5a (patch) | |
| tree | e3256c9936097166efac395a2411eba4e8da5f34 /src | |
| parent | 4d0c1a2a289556eacc63fd407fb77d8190be0b1f (diff) | |
Remove deprecated function Fl::set_idle()
This turned out to be more complicated than just to delete a function
because it was used internally, and the callback signatures were a bit
flaky. I also added a lot of documentation to clarify matters.
FL/Fl.H: document idle callback signatures, make some internal
functions of class Fl private, add public Fl::idle() accessor (read-
only), add Fl::add_idle(Fl_Old_Idle_Handler cb) to enable using
old-style idle callbacks w/o 'data' argument.
FL/forms.H: replace Fl::set_idle() with Fl::add_idle().
src/Fl.cxx: rename private Fl::idle_ with trailing underscore.
src/Fl_System_Driver.cxx: use new public accessor Fl::idle() to access
Fl::idle_ which is now private.
src/Fl_add_idle.cxx: improve documentation, clarify idle callback
matching, add example code in docs, rename methods, add overloaded
Fl::add_idle(Fl_Old_Idle_Handler cb).
src/Fl_win32.cxx: use public Fl::idle() rather than private member.
src/drivers/Unix/Fl_Unix_System_Driver.cxx: same as above.
src/Fl_cocoa.mm: same as above.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl.cxx | 6 | ||||
| -rw-r--r-- | src/Fl_System_Driver.cxx | 9 | ||||
| -rw-r--r-- | src/Fl_add_idle.cxx | 73 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 2 | ||||
| -rw-r--r-- | src/Fl_win32.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/Unix/Fl_Unix_System_Driver.cxx | 2 |
6 files changed, 74 insertions, 20 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx index bae7f1328..b1c38caf6 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -580,7 +580,7 @@ void fl_trigger_clipboard_notify(int source) { //////////////////////////////////////////////////////////////// // idle/wait/run/check/ready: -void (*Fl::idle)(); // see Fl::add_idle.cxx for the add/remove functions +void (*Fl::idle_)(); // see Fl::add_idle.cxx for the add/remove functions /* Private, undocumented method to run idle callbacks. @@ -611,9 +611,9 @@ void (*Fl::idle)(); // see Fl::add_idle.cxx for the add/remove functions */ void Fl::run_idle() { static char in_idle; - if (Fl::idle && !in_idle) { + if (Fl::idle_ && !in_idle) { in_idle = 1; - Fl::idle(); + Fl::idle_(); // call the idle callback stored in Fl::idle_ == Fl::idle() in_idle = 0; } } diff --git a/src/Fl_System_Driver.cxx b/src/Fl_System_Driver.cxx index 7cac84faf..5a01d6534 100644 --- a/src/Fl_System_Driver.cxx +++ b/src/Fl_System_Driver.cxx @@ -1,7 +1,7 @@ // // A base class for platform specific system calls. // -// Copyright 1998-2022 by Bill Spitzak and others. +// Copyright 1998-2025 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -360,9 +360,10 @@ double Fl_System_Driver::wait(double time_to_wait) { Fl::run_checks(); Fl::run_idle(); - // the idle function may turn off idle, we can then wait, - // or it leaves Fl::idle active and we set time_to_wait to 0 - if (Fl::idle) { + // The idle function may turn off idle() if *all* idle callbacks + // are removed from the callback queue (ring), we can then wait. + // Or it leaves Fl::idle() active and we set time_to_wait to 0. + if (Fl::idle()) { time_to_wait = 0.0; } else { // limit time by next timer interval diff --git a/src/Fl_add_idle.cxx b/src/Fl_add_idle.cxx index 1f1673f36..50e34780a 100644 --- a/src/Fl_add_idle.cxx +++ b/src/Fl_add_idle.cxx @@ -1,7 +1,7 @@ // // Idle routine support for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2022 by Bill Spitzak and others. +// Copyright 1998-2025 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -15,7 +15,8 @@ // // Allows you to manage an arbitrary set of idle() callbacks. -// Replaces the older set_idle() call (which is used to implement this) +// Replaces the older set_idle() call which has been renamed to set_idle_(), +// is now private in class Fl::, and is used to implement this. #include <FL/Fl.H> @@ -25,8 +26,8 @@ struct idle_cb { idle_cb *next; }; -// the callbacks are stored linked in a ring. last points at the one -// just called, first at the next to call. last->next == first. +// The callbacks are stored linked in a ring. `last` points at the one +// just called, `first` at the next to call. last->next == first. static idle_cb* first; static idle_cb* last; @@ -37,7 +38,7 @@ static idle_cb* freelist; // - adds it as the last entry and // - calls the idle callback. // The idle callback may remove itself from the list of idle callbacks -// by calling Fl::remove_idle() +// by calling Fl::remove_idle(). static void call_idle() { idle_cb* p = first; @@ -49,11 +50,15 @@ static void call_idle() { Adds a callback function that is called every time by Fl::wait() and also makes it act as though the timeout is zero (this makes Fl::wait() return immediately, so if it is in a loop it is called repeatedly, and thus the - idle function is called repeatedly). The idle function can be used to get + idle function is called repeatedly). The idle function can be used to get background processing done. - You can have multiple idle callbacks. To remove an idle callback use - Fl::remove_idle(). + You can have multiple idle callbacks. If this is the case, then all idle + callbacks are called in turn. Each idle callback should return after it + has done \b some work to let the next idle callback or the FLTK event loop + continue processing. + + To remove an idle callback use Fl::remove_idle(). Fl::wait() and Fl::check() call idle callbacks, but Fl::ready() does not. @@ -61,6 +66,8 @@ static void call_idle() { Fl::check(), and Fl::ready(). FLTK will not recursively call the idle callback. + + \param[in] cb your idle callback */ void Fl::add_idle(Fl_Idle_Handler cb, void* data) { idle_cb* p = freelist; @@ -75,12 +82,26 @@ void Fl::add_idle(Fl_Idle_Handler cb, void* data) { } else { first = last = p; p->next = p; - set_idle(call_idle); + set_idle_(call_idle); } } +void Fl::add_idle(Fl_Old_Idle_Handler cb) { + Fl::add_idle((Fl_Idle_Handler)cb, nullptr); +} + /** Returns true if the specified idle callback is currently installed. + + An idle callback matches the request only if \p data matches the \p data + argument when the callback was installed. There is no "wildcard" search. + + \param[in] cb idle callback in question + \param[in] data optional data. Default: zero / nullptr. + + \returns Whether the given callback \p cb is queued with \p data. + \retval 1 The callback is currently in the callback queue. + \retval 0 The callback is not queued, or \p data doesn't match. */ int Fl::has_idle(Fl_Idle_Handler cb, void* data) { idle_cb* p = first; @@ -93,6 +114,38 @@ int Fl::has_idle(Fl_Idle_Handler cb, void* data) { /** Removes the specified idle callback, if it is installed. + + The given idle callback is only removed if \p data matches the + value used when the idle callback was installed. If the idle + callback wants to remove itself, the value provided by the \p data + variable can (and should) be used. + + Example for a "one-shot" idle callback, i.e. one that removes itself + when it is called for the first time. + \code + #include <FL/Fl.H> + #include <FL/Fl_Double_Window.H> + #include <FL/Fl_Button.H> + void idle1(void *data) { + printf("idle1 called with data %4d\n", fl_int(data)); + fflush(stdout); + // ... do something ... + Fl::remove_idle(idle1, data); + } + void quit_cb(Fl_Widget *w, void *v) { + w->window()->hide(); + } + int main(int argc, char **argv) { + auto window = new Fl_Double_Window(200, 100); + auto button = new Fl_Button(20, 20, 160, 60, "Quit"); + button->callback(quit_cb); + window->end(); + window->show(argc, argv); + Fl::add_idle(idle1, (void *)1234); + return Fl::run(); + } + \endcode + */ void Fl::remove_idle(Fl_Idle_Handler cb, void* data) { idle_cb* p = first; @@ -105,7 +158,7 @@ void Fl::remove_idle(Fl_Idle_Handler cb, void* data) { } if (l == p) { // only one first = last = 0; - set_idle(0); + set_idle_(0); } else { last = l; first = l->next = p->next; diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 2b8ebd7aa..19aa86791 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -865,7 +865,7 @@ double Fl_Darwin_System_Driver::wait(double time_to_wait) Fl::flush(); if (fl_mac_os_version < 101100) NSEnableScreenUpdates(); // deprecated 10.11 #pragma clang diagnostic pop - if (Fl::idle) // 'idle' may have been set within flush() + if (Fl::idle()) // 'idle' may have been set within flush() time_to_wait = 0.0; int retval = do_queued_events(time_to_wait); diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index d7681c96d..84cb6649d 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -396,7 +396,7 @@ double Fl_WinAPI_System_Driver::wait(double time_to_wait) { } } - if (Fl::idle || Fl::damage()) + if (Fl::idle() || Fl::damage()) time_to_wait = 0.0; // if there are no more windows and this timer is set diff --git a/src/drivers/Unix/Fl_Unix_System_Driver.cxx b/src/drivers/Unix/Fl_Unix_System_Driver.cxx index f1d846842..2b15882a1 100644 --- a/src/drivers/Unix/Fl_Unix_System_Driver.cxx +++ b/src/drivers/Unix/Fl_Unix_System_Driver.cxx @@ -803,7 +803,7 @@ double Fl_Unix_System_Driver::wait(double time_to_wait) } else { // do flush first so that user sees the display: Fl::flush(); - if (Fl::idle) // 'idle' may have been set within flush() + if (Fl::idle()) // 'idle_' may have been set within flush() time_to_wait = 0.0; else { Fl_Timeout::elapse_timeouts(); |
