Adds the FL_AUTO_DELETE_EVENT to suppress auto delete.

Language wrappers can have major issues with FLTK auto deleting
all children of a group if a group is deleted. This event gives individual
widget the opportunity to override auto delete.
This commit is contained in:
Matthias Melcher 2024-07-21 13:19:00 +02:00
parent b740c48ee8
commit 8cffbd6941
3 changed files with 26 additions and 4 deletions

View File

@ -407,7 +407,14 @@ enum Fl_Event { // events
/** A zoom event (ctrl/+/-/0/ or cmd/+/-/0/) was processed. /** A zoom event (ctrl/+/-/0/ or cmd/+/-/0/) was processed.
Use Fl::add_handler() to be notified of this event. Use Fl::add_handler() to be notified of this event.
*/ */
FL_ZOOM_EVENT = 27 FL_ZOOM_EVENT = 27,
/** This event is sent if the parent widget is deleted and the parent is about
to delete this widget as well. Returning the default value 0 will give the
parent permission to call the destructor of this widget. Returning 1 will
preserve this widget, but still remove it from the widget hierarchy.
\see Fl_Group::clear()
*/
FL_AUTO_DELETE_EVENT = 28
// DEV NOTE: Keep this list in sync with FL/names.h // DEV NOTE: Keep this list in sync with FL/names.h
}; };

View File

@ -73,9 +73,10 @@ const char * const fl_eventnames[] =
"FL_FULLSCREEN", "FL_FULLSCREEN",
"FL_ZOOM_GESTURE", "FL_ZOOM_GESTURE",
"FL_ZOOM_EVENT", "FL_ZOOM_EVENT",
"FL_EVENT_28", // not yet defined, just in case it /will/ be defined ... "FL_AUTO_DELETE_EVENT",
"FL_EVENT_29", // not yet defined, just in case it /will/ be defined ... "FL_EVENT_29", // not yet defined, just in case it /will/ be defined ...
"FL_EVENT_30" // not yet defined, just in case it /will/ be defined ... "FL_EVENT_30", // not yet defined, just in case it /will/ be defined ...
"FL_EVENT_31" // not yet defined, just in case it /will/ be defined ...
}; };
/** /**

View File

@ -375,6 +375,19 @@ Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l)
\internal If the Fl_Group widget contains the Fl::focus() or the \internal If the Fl_Group widget contains the Fl::focus() or the
Fl::pushed() widget these are set to sensible values (other widgets Fl::pushed() widget these are set to sensible values (other widgets
or the Fl_Group widget itself). or the Fl_Group widget itself).
\note FLTK's auto-delete feature efficiently manages widget hierarchies in
C++ applications by automatically cleaning up. However, this feature can
cause issues when FLTK is used with reference-counting languages like Python,
where automatic deletion might interfere with reference counting. To address
this, auto-delete can be disabled for individual widgets. When
\ref Fl_Group::clear() is called, it sends an \ref FL_AUTO_DELETE event to
each widget. If a widget returns 1 in response to this event, it will not
be deleted. In a Python wrapper, this behavior would typically involve
decrementing the widget's reference count instead of deleting it.
\see Fl_Group::remove(int), Fl_Group::delete_child(int),
Fl_Group::~Fl_Group()
*/ */
void Fl_Group::clear() { void Fl_Group::clear() {
savedfocus_ = 0; savedfocus_ = 0;
@ -417,7 +430,8 @@ void Fl_Group::clear() {
} else { // slow removal } else { // slow removal
remove(idx); remove(idx);
} }
delete w; // delete the child if (w->handle(FL_AUTO_DELETE_EVENT)==0)
delete w; // delete the child
} else { // should never happen } else { // should never happen
remove(idx); // remove it anyway remove(idx); // remove it anyway
} }