summaryrefslogtreecommitdiff
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
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.
-rw-r--r--FL/Fl.H46
-rw-r--r--FL/forms.H2
-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
8 files changed, 114 insertions, 28 deletions
diff --git a/FL/Fl.H b/FL/Fl.H
index 578971348..245d9a562 100644
--- a/FL/Fl.H
+++ b/FL/Fl.H
@@ -99,10 +99,17 @@ typedef void (*Fl_Timeout_Handler)(void *data);
/** Signature of some wakeup callback functions passed as parameters */
typedef void (*Fl_Awake_Handler)(void *data);
-/** Signature of add_idle callback functions passed as parameters */
+/** Signature of add_idle callback function passed as parameter.
+ This signature allows an idle callback to use one parameter as an
+ arbitrary `data` value.
+*/
typedef void (*Fl_Idle_Handler)(void *data);
-/** Signature of set_idle callback functions passed as parameters */
+/** Signature of add_idle callback function passed as parameter.
+ This signature allows an idle callback without parameters.
+ When the callback is called it is called with an additional
+ parameter (set to nullptr) which is not used by the callback.
+*/
typedef void (*Fl_Old_Idle_Handler)();
/** Signature of add_fd functions passed as parameters */
@@ -312,6 +319,8 @@ public:
*/
static void option(Fl_Option opt, bool val);
+private:
+
/**
The currently executing idle callback function: DO NOT USE THIS DIRECTLY!
@@ -319,7 +328,22 @@ public:
idle callback functions to be called.
\see add_idle(), remove_idle()
*/
- static void (*idle)();
+ static void (*idle_)();
+
+public:
+ /**
+ Returns whether at least one idle callback is currently set.
+
+ \c true means that at least one callback is currently queued, but
+ not necessarily active. While a callback is being executed, it is
+ also counted as "set" unless (i.e. before) it removes itself from
+ the idle callback queue (ring).
+
+ \return whether an idle callback is currently set
+ \retval true At least one idle callback is currently set.
+ \retval false No idle callback is currently set.
+ */
+ static bool idle() { return (idle_ != nullptr); }
#ifndef FL_DOXYGEN
private:
@@ -491,9 +515,10 @@ public:
static long ticks_since(Fl_Timestamp& then);
static long ticks_between(Fl_Timestamp& back, Fl_Timestamp& further_back);
- // private
+private:
static void run_idle();
static void run_checks();
+public:
static void add_fd(int fd, int when, Fl_FD_Handler cb, void* = 0); // platform dependent
static void add_fd(int fd, Fl_FD_Handler cb, void* = 0); // platform dependent
/** Removes a file descriptor handler. */
@@ -504,6 +529,7 @@ public:
static void add_idle(Fl_Idle_Handler cb, void* data = 0);
static int has_idle(Fl_Idle_Handler cb, void* data = 0);
static void remove_idle(Fl_Idle_Handler cb, void* data = 0);
+ static void add_idle(Fl_Old_Idle_Handler cb);
/** If true then flush() will do something. */
static int damage() {return damage_;}
static void redraw();
@@ -1292,12 +1318,18 @@ public:
static int event_button5() {return e_state & FL_BUTTON5;}
/** @} */
+private:
/**
- Sets an idle callback.
+ Sets an idle callback (internal use only).
+
+ This method is now private and is used to store the idle callback.
+ The old, public set_idle() method was deprecated since 1.3.x and
+ is no longer available in FLTK 1.5.
- \deprecated This method is obsolete - use the add_idle() method instead.
+ See documentation: use Fl::add_idle() instead.
*/
- static void set_idle(Fl_Old_Idle_Handler cb) {idle = cb;}
+ static void set_idle_(Fl_Old_Idle_Handler cb) {idle_ = cb;}
+public:
/** See grab(Fl_Window*) */
static void grab(Fl_Window& win) {grab(&win);}
/** Releases the current grabbed window, equals grab(0).
diff --git a/FL/forms.H b/FL/forms.H
index 9523b4da5..076c54d6f 100644
--- a/FL/forms.H
+++ b/FL/forms.H
@@ -170,7 +170,7 @@ inline void fl_add_timeout(long msec, void (*cb)(void*), void* v) {
inline void fl_remove_timeout(int) {}
// type of callback is different!
-inline void fl_set_idle_callback(void (*cb)()) {Fl::set_idle(cb);}
+inline void fl_set_idle_callback(void (*cb)()) {Fl::add_idle(cb);}
FL_EXPORT Fl_Widget* fl_do_forms(void);
FL_EXPORT Fl_Widget* fl_check_forms();
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();