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
This commit is contained in:
Stephan Aßmus
2009-10-19 20:40:15 +00:00
parent e19e3efd0d
commit 0161825261
+16 -2
View File
@@ -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;
}
}
}