From 0161825261b75440c4de12514e89177d17c87beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 19 Oct 2009 20:40:15 +0000 Subject: [PATCH] Fixed an annoying problem with the scroll bar repeat feature. If you clicked a button or within the bar background within the timeout for the repeat-thread, the thread would exit and there would be no repeating. I think there is still a race condition somewhere since I managed to see it stall once again, probably because it locks the looper twice in the loop... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33666 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/ScrollBar.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/kits/interface/ScrollBar.cpp b/src/kits/interface/ScrollBar.cpp index b1e2fd52eb..84334a55b9 100644 --- a/src/kits/interface/ScrollBar.cpp +++ b/src/kits/interface/ScrollBar.cpp @@ -58,6 +58,8 @@ typedef enum { #define NOARROW -1 +static const bigtime_t kRepeatDelay = 300000; + // Because the R5 version kept a lot of data on server-side, we need to kludge // our way into binary compatibility class BScrollBar::Private { @@ -68,6 +70,7 @@ public: fEnabled(true), fRepeaterThread(-1), fExitRepeater(false), + fRepeaterDelay(0), fThumbFrame(0.0, 0.0, -1.0, -1.0), fDoRepeat(false), fClickOffset(0.0, 0.0), @@ -114,6 +117,7 @@ public: thread_id fRepeaterThread; volatile bool fExitRepeater; + bigtime_t fRepeaterDelay; BRect fThumbFrame; volatile bool fDoRepeat; @@ -144,8 +148,13 @@ BScrollBar::Private::button_repeater_thread(void *data) int32 BScrollBar::Private::ButtonRepeaterThread() { - // wait a bit before auto scrolling starts - snooze(500000); + // Wait a bit before auto scrolling starts. As long as the user releases + // and presses the button again while the repeat delay has not yet + // triggered, the value is pushed into the future, so we need to loop such + // that repeating starts at exactly the correct delay after the last + // button press. + while (fRepeaterDelay > system_time() && !fExitRepeater) + snooze_until(fRepeaterDelay, B_SYSTEM_TIMEBASE); // repeat loop while (!fExitRepeater) { @@ -713,12 +722,17 @@ BScrollBar::MouseDown(BPoint where) // launch the repeat thread if (fPrivateData->fRepeaterThread == -1) { fPrivateData->fExitRepeater = false; + fPrivateData->fRepeaterDelay = system_time() + kRepeatDelay; fPrivateData->fThumbInc = scrollValue; fPrivateData->fDoRepeat = true; fPrivateData->fRepeaterThread = spawn_thread(fPrivateData->button_repeater_thread, "scroll repeater", B_NORMAL_PRIORITY, fPrivateData); resume_thread(fPrivateData->fRepeaterThread); + } else { + fPrivateData->fExitRepeater = false; + fPrivateData->fRepeaterDelay = system_time() + kRepeatDelay; + fPrivateData->fDoRepeat = true; } } }