diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2006-04-27 21:40:47 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2006-04-27 21:40:47 +0000 |
| commit | ad0fc9ca23717b46639d2f28a83437300499870d (patch) | |
| tree | 80502551cd9ec6701c76c5942a8bd6466376f945 /src/Fl.cxx | |
| parent | cbbec03b5e44e8855dbcf424150be5e144044fb2 (diff) | |
STR #1162: Fl_Menu_Button::popup was trying to access a previously deleted widget (itself). The delayed deleting mechanism in 'Fl::delete_widget' did not work in this case because the main loop is called before the callback returns. The fix implements a type of automatic pointer that will be cleared to NULL should the widget get deleted. This may not be a 'nice' solution, but it does fix the problem reliably. We could actually use this for all widget pointers and remove the delayed delete mechanism alltogether
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@5037 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl.cxx')
| -rw-r--r-- | src/Fl.cxx | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx index c9dcd0a6c..72ea71414 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1207,6 +1207,53 @@ Fl::do_widget_deletion() { num_dwidgets = 0; } +static Fl_Widget ***widget_watch = 0; +static int num_widget_watch = 0; +static int max_widget_watch = 0; + +void Fl::watch_widget_pointer(Fl_Widget *&w) +{ + Fl_Widget **wp = &w; + int i; + for (i=0; i<num_widget_watch; ++i) { + if (widget_watch[i]==wp) return; + } + for (i=0; i<num_widget_watch; ++i) { + if (widget_watch[i]==0L) { + widget_watch[i] = wp; + return; + } + } + if (num_widget_watch==max_widget_watch) { + max_widget_watch += 8; + widget_watch = (Fl_Widget***)realloc(widget_watch, sizeof(Fl_Widget**)*max_widget_watch); + } + widget_watch[num_widget_watch++] = wp; +} + +void Fl::release_widget_pointer(Fl_Widget *&w) +{ + Fl_Widget **wp = &w; + int i; + for (i=0; i<num_widget_watch; ++i) { + if (widget_watch[i]==wp) { + widget_watch[i] = 0L; + return; + } + } +} + +void Fl::clear_widget_pointer(Fl_Widget const *w) +{ + if (w==0L) return; + int i; + for (i=0; i<num_widget_watch; ++i) { + if (widget_watch[i] && *widget_watch[i]==w) { + *widget_watch[i] = 0L; + } + } +} + // // End of "$Id$". |
