From f62d1998bebedb54a5d08b98ea699c337395d005 Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Wed, 12 Jul 2017 09:11:23 +0000 Subject: [PATCH] Fix for STR#3387 "Bug of timer implementation on macosx". git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@12310 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_cocoa.mm | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index ff40ce391..5a047d3da 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -506,7 +506,7 @@ struct MacTimeout { static MacTimeout* mac_timers; static int mac_timer_alloc; static int mac_timer_used; -static MacTimeout* current_timer; // the timer that triggered its callback function, or NULL +static MacTimeout* current_timer; // the timer that triggered its callback function static void realloc_timers() { @@ -518,6 +518,10 @@ static void realloc_timers() MacTimeout* new_timers = new MacTimeout[mac_timer_alloc]; memset(new_timers, 0, sizeof(MacTimeout)*mac_timer_alloc); memcpy(new_timers, mac_timers, sizeof(MacTimeout) * mac_timer_used); + if (current_timer) { + MacTimeout* newCurrent = new_timers + (current_timer - mac_timers); + current_timer = newCurrent; + } MacTimeout* delete_me = mac_timers; mac_timers = new_timers; delete [] delete_me; @@ -531,14 +535,14 @@ static void delete_timer(MacTimeout& t) kCFRunLoopDefaultMode); CFRelease(t.timer); memset(&t, 0, sizeof(MacTimeout)); - if (&t == current_timer) current_timer = NULL; } } static void do_timer(CFRunLoopTimerRef timer, void* data) { fl_lock_function(); - current_timer = (MacTimeout*)data; + fl_intptr_t timerId = (fl_intptr_t)data; + current_timer = &mac_timers[timerId]; current_timer->pending = 0; (current_timer->callback)(current_timer->data); if (current_timer && current_timer->pending == 0) @@ -563,7 +567,7 @@ void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) } } // no existing timer to use. Create a new one: - int timer_id = -1; + fl_intptr_t timer_id = -1; // find an empty slot in the timer array for (int i = 0; i < mac_timer_used; ++i) { if ( !mac_timers[i].timer ) { @@ -581,7 +585,7 @@ void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) } // now install a brand new timer MacTimeout& t = mac_timers[timer_id]; - CFRunLoopTimerContext context = {0, &t, NULL,NULL,NULL}; + CFRunLoopTimerContext context = {0, (void*)timer_id, NULL,NULL,NULL}; CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + time, 1E30, @@ -604,18 +608,14 @@ void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data) { - if (current_timer) { - // k = how many times 'time' seconds after the last scheduled timeout until the future - double k = ceil( (CFAbsoluteTimeGetCurrent() - current_timer->next_timeout) / time); - if (k < 1) k = 1; - current_timer->next_timeout += k * time; - CFRunLoopTimerSetNextFireDate(current_timer->timer, current_timer->next_timeout ); - current_timer->callback = cb; - current_timer->data = data; - current_timer->pending = 1; - return; - } - add_timeout(time, cb, data); + // k = how many times 'time' seconds after the last scheduled timeout until the future + double k = ceil( (CFAbsoluteTimeGetCurrent() - current_timer->next_timeout) / time); + if (k < 1) k = 1; + current_timer->next_timeout += k * time; + CFRunLoopTimerSetNextFireDate(current_timer->timer, current_timer->next_timeout ); + current_timer->callback = cb; + current_timer->data = data; + current_timer->pending = 1; } int Fl::has_timeout(Fl_Timeout_Handler cb, void* data)