summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2025-05-13 21:04:56 +0200
committerAlbrecht Schlosser <albrechts.fltk@online.de>2025-05-13 21:08:51 +0200
commit9b1379e6888abc7cc051a6c82d8b27ce454ceb5a (patch)
treee3256c9936097166efac395a2411eba4e8da5f34 /src
parent4d0c1a2a289556eacc63fd407fb77d8190be0b1f (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.cxx6
-rw-r--r--src/Fl_System_Driver.cxx9
-rw-r--r--src/Fl_add_idle.cxx73
-rw-r--r--src/Fl_cocoa.mm2
-rw-r--r--src/Fl_win32.cxx2
-rw-r--r--src/drivers/Unix/Fl_Unix_System_Driver.cxx2
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();