Bug 247594 - QProgressBar progress is out of sync with textual representation
Summary: QProgressBar progress is out of sync with textual representation
Status: RESOLVED FIXED
Alias: None
Product: Oxygen
Classification: Plasma
Component: style (show other bugs)
Version: unspecified
Platform: Unlisted Binaries Linux
: NOR normal
Target Milestone: ---
Assignee: Hugo Pereira Da Costa
URL:
Keywords:
: 247478 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-08-13 01:33 UTC by Tobias Koenig
Modified: 2010-08-13 23:54 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Koenig 2010-08-13 01:33:19 UTC
Version:           unspecified (using KDE 4.5.0) 
OS:                Linux

Sometimes (unfortunately not 100% reproducable) the progress bar in KMail's progress notification widget in the status bar (which is a plain QProgressBar) shows for example the status text '49%' but the blue progress indicator has covered only 10% or less of the widget. I suppose this is yet another Oxygen style bug, because I can't reproduce it with Plastique style.

Reproducible: Sometimes

Steps to Reproduce:
Open KMail and start the mail check, click on the up-arrow in the status bar and watch the progress bars

Actual Results:  
Textual representation doesn't match the painted progress bar

Expected Results:  
Textual representation should match the painted progress bar
Comment 1 Christoph Feck 2010-08-13 02:08:54 UTC
*** Bug 247478 has been marked as a duplicate of this bug. ***
Comment 2 Elias Probst 2010-08-13 03:04:38 UTC
As I wrote in bug#247478 which was marked as DUP of this one, the progressbar does also moves backwards when being shown with a value of 100% and a coverage of 10%.

This means: the progressbar shows from the beginning the numeric value of 100% and the coverage of the bar itself is around 10%.
Then as the process progresses, the 10% coverage shrinks down towards 0% while the numeric value also goes towards 0% starting from 100%.
Comment 3 Hugo Pereira Da Costa 2010-08-13 03:37:50 UTC
Hello,
I think this is due to the progressbar "smooth" animation (which adds intermediate steps between two consecutive values of the progress, for a smoother look).
Could you try disable it in oxygen-settings 'animations' tab (typed from konsole and krunner) ? 
I'll double check how things behave when there are collisions between the animation being in progress and a new value is set.
Comment 4 Hugo Pereira Da Costa 2010-08-13 03:40:48 UTC
as for the "yet another oxygen style bug", these kind of statements are pretty useless and serves nothing except maybe de-motivating maintainers. 

As far as I know nobody gets paid for working on kde (at least I don't) so the amount of bugs is nothing but the competition between the amount of time available to spend on the code and the amount of features one tries to fit in ...

Feel free to use another style or go fixing directly, its open source.
Comment 5 Christoph Feck 2010-08-13 12:07:08 UTC
Hugo, don't let this de-motivate you. Just compare the number of Oxygen "bugs", and those of KMail ;)

And yes, KDEPIM developers get paid. At least some of them.

To get back on topic, the animation code in Oxygen should not use setValue() on the QProgressBar at any point in time. I haven't checked deeply how it works, but an application always expects to read the value that it has set.
Comment 6 Hugo Pereira Da Costa 2010-08-13 15:49:33 UTC
@Christoph
it does not call QProgressBar::setValue().
It leaves the internal value of the progressbar unchanged, stores it (in a different object) as either a 'start' or 'end' value for animation, trigger updates at regular time interval, and while animating, the 'painting part' uses the modified (animated) value (somewhere between start and stop), instead of the one returned by the progressbar. 
On the application side, its therefore 100% transparent. 
Makes sense ? 
Anyway: I think I just fixed it (though I messed-up with my commit message (again)) so it does not show up here.
I'll copy the svn log message manually and close.
Comment 7 Hugo Pereira Da Costa 2010-08-13 15:51:03 UTC
r1163198 | hpereiradacosta | 2010-08-13 09:43:07 -0400 (Fri, 13 Aug 2010) | 6 lines

When progressbar value changes while animation is running (from previous value),
stop animation and jump directly to new value. This prevents the scrollbar to always stay 
'behind' the set value, and increases responsiveness when progressbar changes too quickly.

BUG 247594

--------------------------------------
backport to kde4.5 branch: 

Backport r1163198

When progressbar value changes while animation is running (from previous value),
stop animation and jump directly to new value. This prevents the scrollbar to always stay 
'behind' the set value, and increases responsiveness when progressbar changes too quickly.

CCBUG 247594

---------------------------------------
closing as resolved
Comment 8 Christoph Feck 2010-08-13 16:08:22 UTC
> it does not call QProgressBar::setValue()

oxygenprogressbarengine.cpp, line 100 (in trunk)
Comment 9 Christoph Feck 2010-08-13 16:11:58 UTC
And why doesn't it simply restart the animation? Check what I did on Smaragd (r1159992).
Comment 10 Hugo Pereira Da Costa 2010-08-13 16:39:52 UTC
> oxygenprogressbarengine.cpp, line 100 (in trunk)

Oh, but that's different (:))
This part is to handle 'busy' progressbars, (when min and max are set to 0, and you get a cursor that oscillates from left to right without indicating a value). I think this code is actually copied from other styles. 

The part I was discussing is when you have 'meaningfull value', meaning: jumping for e.g. 0 to 50% 

As for the other comment: 
start and stop the animation was what was done before. 
The problem is that even if you do so, when you update to a new value quickly enough, you will always have the progressbar stay 'behind' its set value, no matter what (basically if the application set progress at a pace that is faster than the true transition). I think that's what happens here.

In the commit above, when values are changed too rapidily for the animation to catch up, the animation is disabled and the progressbar is updated immediatly. I think it should fix it.
Comment 11 Christoph Feck 2010-08-13 17:26:58 UTC
You also are "behind" for the initial animation, so I don't see the need to abruptly jump to a new position later. You could restart the animation with a shorter duration if you feel you "lag behind" too much. If you want to be really smart, you would use some differential math to predict the speed ;)

Well, I haven't seen it in action, neither the old (buggy one), nor the new one, so maybe I am talking nonsense and it looks good now.
Comment 12 Hugo Pereira Da Costa 2010-08-13 19:40:02 UTC
> Well, I haven't seen it in action, neither the old (buggy one), nor the new
> one, so maybe I am talking nonsense and it looks good now.

No, not nonsense. Actually, the previous implementation (to the extend I understand my own code), was 
simply updating the new end value whenever a new value comes. This way the animation was supposed to 'accelerate' (or descelerate depending on whether the new value would be with respect to the old new value), towards the new one. But apparently this was already not 'snappy' enough (for this bug report). 

At least the commit fixes it for sure.
I'll see if I can do smarter things, (we do such things in other animations), and will commit if I found something (the current bug is not that clear to me either, but I believe it actually depends on how fast your GPU is, and how many frames are piped into the animation).
Comment 13 Christoph Feck 2010-08-13 20:00:15 UTC
Oh, just setting a new end() value does not restart the animation. You need to call stop(), then set parameters, then start().
Comment 14 Hugo Pereira Da Costa 2010-08-13 23:54:00 UTC
--- Comment #13 from Christoph Feck <christoph maxiom de>  2010-08-13 20:00:15 ---
Oh, just setting a new end() value does not restart the animation. You need to
call stop(), then set parameters, then start().

But that was the point: keep the same animation running (and therefore not reset the timer), and just change the end value. So that you go on from the current value (between say A and B, and goes to Bprime instead of B) 

To summarize you're supposed go from A to B in say 200 msec. But at t=150ms Bprime is set, (while you are at Aprime (somewhere between A and B). Then you'd take the remaining 50msec to go from Aprim to Bprim

anyway ...