Closed Bug 33966 Opened 24 years ago Closed 22 years ago

Smooth Scrolling would be nice.

Categories

(Core :: XUL, enhancement, P3)

enhancement

Tracking

()

RESOLVED DUPLICATE of bug 174049
Future

People

(Reporter: frantb, Assigned: neil)

References

Details

(Keywords: polish, Whiteboard: (testing needed))

Attachments

(1 file, 7 obsolete files)

In IE the default behavior is smooth scrolling where alhtough the page scrolls 
10 pixels or so, the page is drawn in 1 or 2 pxl incraments so that the page 
glides up rather than just jumping. I find it much easier to keep my place on a 
page, particularly with lots of text, with this behavior. Netscape/Mozilla 
scrolls in 10 pxl or so incriments but I don't beleave there is a smooth 
scrolling option.
asadotzler@netscape.net (Asa Dotzler) taking ownership of Browser General bugs. 
 New QA Contact is jelwell@singleclick.com (Joseph Elwell).  Sorry for the spam.
Assignee: cbegle → asadotzler
QA Contact: asadotzler → jelwell
Moving to UI: Design Feedback.

Gerv
Assignee: asadotzler → bdonohoe
Component: Browser-General → User Interface: Design Feedback
QA Contact: jelwell → elig
I'm afraid I can't see the difference between the two.  I studied scrolling on a 
number of pages, using a number of different methods of scrolling in Netscape and 
IE on Mac and Windows.  Although the redraw speed is sometimes faster in IE, the 
method of scrolling does not seem to differ.
Status: NEW → RESOLVED
Closed: 24 years ago
Resolution: --- → WORKSFORME
With yesterday's Mozilla I still see IE and Mozilla behaving different in this 
respect. In IE it is an option so be sure it is turned on to see it in IE. Go 
to Tools->Internet Options then under the ``Advanced'' tab, near the bottom of 
the ``Browsing'' section is ``Use Smooth Scrolling''. Check that box and hit OK.

Now, if you are in a web page and scroll with the arrow keys, it will scroll 
about 50 pixels at a time but the motion of the page is animated at 2 or 3 
pixel incriments. Mozilla scrolls fewer pixels per keypress than IE does but it 
does it in jumps.
Ah.  Got it.  Okay, I've reopened the bug as an enhancement to think about down 
the road.
Status: RESOLVED → REOPENED
Component: User Interface: Design Feedback → Browser-General
Resolution: WORKSFORME → ---
Target Milestone: --- → M20
Reassigning to engineering
Assignee: bdonohoe → asadotzler
Status: REOPENED → NEW
QA Contact: elig → jelwell
bdonohoe@netscape.com, where do you think this bug belongs.  What is 
"Reassigning to engineering"?
Sorry, I had been under the impression "Browser-General" was somehow connected to 
general browser engineering.  I stand corrected, though.

Reassigning to XP Toolkit/Widgets since smooth scrolling could apply to scrolling 
in any window...
updating component and owner
Assignee: asadotzler → trudelle
Component: Browser-General → XP Toolkit/Widgets
QA Contact: jelwell → jrgm
would be nice == not doing it in first release.  targetting m30, help wanted
Status: NEW → ASSIGNED
Keywords: helpwanted
Target Milestone: M20 → M30
Mass-moving all M20-M30 XPToolkit bugs to Future
Target Milestone: M30 → Future
If this going to be done, two parameters should be added to allow flexibility:
 1) lines per scroll
 2) scroll rate
I've started trying to get Mozilla to smooth-scroll by altering
nsScrollPortView.cpp. By editing the Scroll(..) routine I've been able to
achieve a smoother scroll by making more (smaller-increment) calls to
scrollWidget->Scroll(...) and mViewManager->UpdateViewAfterScroll(...).

However, this causes a repainting problem. When the user scrolls down, the area
where new content should appear is filled with copies of the bottom-most row of
pixels before the scroll. Once the scroll completes, the expected content
appears. I'm calling UpdateViewAfterScroll each time: any ideas?
Smooth scrolling would be *very* nice. It's especially usefull with mouse wheels
and auto-scrolling. Internet Explorer and MS Office 97 (and probably 2000)
supports auto-scrolling this way.

You *click* the wheel, and a icon appear on the screen. When you move the
pointer over/under the icon, it starts auto-scrolling (faster as you move the
pointer further away from the icon). This also works in Mozilla, but in IE and
Word, the scrolling is ultra-smooth, i.e. it scrolls only one (perhaps two)
pixels at a time, instead of a line at the time.

If you haven't a wheel mouse, you use this feature by selecting the AutoScroll
command in Word (under Tools | Macros).
scott, do you have a patch?  this would be a very useful feature, especially for
LCD-display users.
See also bug 32265, "RFE: jump-scroll should indicate already-seen area".
Neil: Sadly, I was never able to smooth out scrolling without creating m previously-described problem In addition, CPU usage skyrocketed. While a solution may be possible, it was not as simple as I originally hoped.
Smooth scrolling has to be smart enough not to degrade performance. It should 
only work when scrolling at a certain speed, and should use small increments. 

Also: make sure that it happens fast enough as not to interfere with the 
autoscroll i'm implementing.

Keeping each scroll call under 50ms on the slowest computers will probably do 
the trick. Although its not the end of the world if you overrun that a little. 
I believe that my code will just skip a scroll then. I still haven't verified 
this as the code is still being worked on.

See bug 22775 about this. Reply in that bug please.
adding self to cc list
IE also smooth scrolls if you hit page-up and page-down (so smooth scrolling is
working regardless of scroll distance), however, it also uses quite a lot of CPU
time. Smooth scrolling over a longer page, using only page-down key raises CPU
usage up to 60% on my 1 GHz Athlon in IE. Scrolling over the same page with
smooth scrolling disabled raises CPU usage only up to 30%. From this point of
view it's important that smooth scrolling stays an option that you can disable.

And now to the bad news. Even though Mozilla does not use smooth scrolling,
scrolling down the same page with page-down key raises CPU usage to up to 40%,
which already is higher than in case of IE without smooth scrolling.
What's wrong with using the CPU?
What is wrong with using the CPU? Maybe the fact that there aren't unlimited CPU
resources available and that the PC may also need CPU time for other things than
just scrolling down a page?

If IE manages to do the same task, using less CPU time than Mozilla, it means
that either the code of IE is better (more optimized) or that the way how IE
does it is better (more effective). Whatever is true, it means that Mozilla
wastes more CPU resources on doing something that could also be done with using
less CPU resources. And now give me one good argument for using more CPU time on
a process that can be done with less CPU time? Also bear in mind that not
everyone is having a 1 GHz CPU and we are talking about a static page here (no
animated GIFs, no JavaScript animations, no Java applets, no Flash multimedia
nonsense).
While smooth scrolling is certainly appropriate when dragging the scrollbar
thumb, or panning with a hand tool, I'm not convinced that it would be
beneficial for other scrolling that we currently do by line or page. I recall
seeing some usability data (somewhwere) that it can actually decrease reading
speed, due to being more jarring than discrete jumps.  If it gets implemented,
it would be good to do some usability testing rather than just assuming it is an
improvement.
> While smooth scrolling is certainly appropriate
> when dragging the scrollbar thumb, or panning
> with a hand tool, I'm not convinced that it would be
> beneficial for other scrolling that we currently do by line or page.

IE uses smooth scrolling *only* when scrolling by line or page, and not when dragging the scrollbar thumb.
Okay, I guess that's the difference between smooth scrolling and Smooth© Scrolling™
*** Bug 151352 has been marked as a duplicate of this bug. ***
I'm the reporter of bug http://bugzilla.mozilla.org/show_bug.cgi?id=151352 which
is a dup of this bug and would like to comment on it or better on this proposal
for enhancement.

I second the comment http://bugzilla.mozilla.org/show_bug.cgi?id=33966#c14 from
Karl Ove Hufthammer. Concerning the Additional Comment #23 from Peter Trudelle,
 in my opinion the lack of smooth scrolling in mozilla makes it clearly less
comfortable to navigate through and reading lots of text on webpages, compared
to IE6, especially when using a wheel mouse. It happens easier to lose the point
where you are just reading while scrolling forwards. Maybe this depends on the 
 screen resolution used also, mine is rather low, though.
Anyway, I think it would be a definite plus in usability if "smooth scrolling"
gets implemented in mozilla. It wouldn't be just a fancy looking feature which
actually makes no sense and nobody needs. damn, if I only could code and would
have the time left to work on it... 

btw. does the entry "future" at "Target Milestone" mean, that the feature will 
be probably neither in Moz 1.1 nor in 1.2?! This would be not very good news ...
Thanks a lot guys ('n gals)!
Future basically means 'no plans to do this in the current release cycle, may be
considered later'. If anyone wants to take this bug, they are most welcome to it.
Yes, I would like to have smooth scrolling, too.
My eyes are easily getting tired when the text is jumping
and they have to find the text where I was reading before.

I have found a nice workaround on Solaris (2.7) for this. :)
Hold the LEFT button on the main scrollbar, then move left
to inside of the window, then press RIGHT button while
holding the LEFT button. Now release LEFT button, then also the
RIGHT button and click on RIGHT button, so the context-menu
disappears.
Now You can move Your mouse up and down with smooth scrolling.

No kidding! Looks like a game cheat... Hehehehe... But try it!
It's because of the context menu that mozilla doesnt get the
release-button event. And when You have already scrolled
without having to touch ANY buttons, You will not want to
touch the wheel anymore. That I can promise You!
Well, you're abusing bug #48037. :)

And yes, I could use smooth scrolling too...
Any status updates with this?

Adding myself to CC list.
Personally, I would be a lot more likely to switch to Mozilla from IE if this 
RFE was implemented. It really makes the page easier on my eyes as I seem to 
do a lot of scrolling.
*** Bug 159806 has been marked as a duplicate of this bug. ***
Hi all...

I just want to second what Andrew Pattison said.  I would be more likely to 
switch from IE to Mozilla if it had smooth scrolling.  In fact, to go one step 
further, I would probably switch to Linux from Windows 2000 if Mozilla had 
smooth scrolling.

I don't think you guys actually realize what a big issue user-friendliness is.  
In essence it's the very kind of mentality that is keeping Linux from the 
desktop in general (IMHO).  I really think that this should go right to the top 
of the priority list, as should a lot of user-friendly features.

I have downloaded the source and tried hacking away, but I'm not much of a C 
programmer, and also because I'm using Windows, the development environment is 
not exactly easy to get one's head around.  But for the seasoned developers, I 
can't see why this problem could take more than a few hours to fix.

Thanks,

Matt
I have added a vote for this bug also.  I admit it's not a big 'functional'
issue, but it is a big comfort and convenience thing for (apparently) many
users. 

And I too would be much happier if I could smooth scroll down and up the 
pages (horizontally too, of course) as I'm reading them.  

My recollection w.r.t Comment 23 is that smooth scrolling enhances regular text
readability (eliminates discontinuous visual queues).... But I can't recall the
reference, so my opinion is no better than Peter's!

There must be existing usability research that we can find to answer this
question.... I'll look about, and post a reference if I find anything. 
Attached file a js version of smooth scrolling (obsolete) —
there seems to be some confusion about what 'smooth scrolling' is and why it's
useful, so I'm attaching a kludgy demo.  it is far from perfect, but I think it
gives a good indication of how this feature should work.  

open the attachement and press the up arrow and the down arrow and watch how
the content scrolls.

notes:
- for some reason, the event listener does not catch the first keypress, so you
should press some key first (i.e., press 'a', then 'up' and 'down').
- I'm not sure how to detect the end of the document, so things get funny when
you get to the bottom of the page.
- I created this on a laptop, and if 101 keyboards have diff keycodes, this
will probably not work at all.

I don't know that much about DOM event listeners, but I guess it would be
pretty easy to create a bookmarklet out of this code (hint hint).
Attached file more compelling example (obsolete) —
sorry for the spam.  I fine tuned the numbers and the content to make a more
compelling example of this feature.
Attachment #93510 - Attachment is obsolete: true
That JS example looks great! Now if someone could link it to the mouse scroll
wheel and the scrollbar that would be it almost complete!

Oh, and for some reason my mousewheel is dead in mozilla after viewing that
page, so obviously still some work to do.
Attachment #93514 - Attachment mime type: text/html → text/plain
Comment on attachment 93514 [details]
more compelling example

oops, sorry for the spam, trying to edit a text/plain attachment does not seem
to work...
Attachment #93514 - Attachment mime type: text/plain → text/html
Comments from
http://arstechnica.infopop.net/OpenTopic/page?a=tpc&s=50009562&f=174096756&m=7340966825&r=7340966825


"I tried Mozilla back when 1.0 came out. I loved it, except for one thing. It
doesn't scroll smoothly! I don't know if my eyes are trained somehow or what,
but when I scroll in Netscape it takes a split second for my eyes to find the
text that just moved. My friends think I'm nuts, but it is such a problem that I
can't use Mozilla effectively."

"I have the exact opposite problem in IE, where when it tries to smooth the
scrolling, all it does it blur the screen for a split second because my laptop's
pixel refresh is too slow."

Smooth scrolling may have to be a pref.
Don't know if this is of any use but as I have been missing smooth scrolling so
much I helped myself by keeping the left mouse button pressed and moving the
mouse-pointer just a little bit beyond the upper or lower window border causing
smooth scrolling :-) - well and causing the page content to be selected. Anyway,
the smooth scrolling that I get this way looks fine and allows my eyes to follow
the line that I have been (or am) reading.

Build ID: 2002072104 
Version 1.1b
Windows 98
I agree that smooth scrolling should be pref. It uses much more CPU resources to
scroll the same page and on weak systems where Mozilla isn't even running at
full speed anymore, that would be very annoying.

The example attached to this bug is not working very well on my system. It
basically only scrolls much more than when I usually hit the down arrow key, but
not really smooth (it scrolls too fast to be called "smooth"). Page-up and
Page-down aren't smooth at all, they look like always and when I scroll down the
very bottom of the page and try to scroll up again using arrow up key, then the
page hangs a over a second at a certain position, always jumping forth and back
before it finally scrolls upwards again.

But it goes into the right direction, still somewhere between the normal Mozilla
scrolling and the IE smooth-scrolling when enabled (notice: In IE this is also
just a pref, you don't have to use it).
here's a patch that implements this feature.  I'm having trouble switching over
the pref, however, so this is not final.

I have not implemented any special animation algorithm, so I'd appreciate it if
folks with particularly slow or particularly fast machines give this patch a
try.  it's possible that this patch is unusable on very slow machines and
unnoticable on very fast machines.  on my machine, it's just right (of course).


I can provide a linux build with this patch if there is a willing tester
without a tree.  email me.

RE: CPU concerns: this patch does cause slightly more CPU usage, about 10% on
my 1ghz athlon.
I tested this on a Pentium II 200MHz (with an unoptimized build) and it runs
fine.  if anyone has a slower machine, please test this patch.

I still need to get the pref hooked up.
d'oh!  use the consts.
Attachment #93798 - Attachment is obsolete: true
   This may be slightly off topic but since it has to do with scrolling and
since only Mozilla has ever had a problem on my system with the following
utility, I will mention it.  When I use Snag It, the screen capture utility, and
I tell it to autoscroll when capturing any window's image, it simply will not do
it on Mozilla, so I can't capture a full picture of a web page.  It only
captures the currently visible part of the window.  So why would this be only
with Mozilla?
Re: comment 46: Yes, that was off-topic.  Please file another bug on that.
I don't think bug 32265 depends on this.
No longer blocks: 32265
Keywords: patch
this patch fixes page up/down.	someone mentioned to me that I should be using
nsIPrefService rather than nsIPref, so if I have time I'll give that a go.
Attachment #93824 - Attachment is obsolete: true
Attached patch UI for smooth scrolling pref (obsolete) — Splinter Review
I added this pref to the 'appearance' group.  it may belong with
'advanced'/'mouse wheel' renamed to 'advanced'/'scroll behavior', but that
seemed outside the scope of this patch.
Attachment #93514 - Attachment is obsolete: true
Attachment #94047 - Attachment is obsolete: true
->Neil
Assignee: trudelle → neil
Status: ASSIGNED → NEW
*** Bug 162136 has been marked as a duplicate of this bug. ***
Oh my... voting for this one if i haven't already :)))
Think it can work when clicking scrollbar slider-area too?
I built with patch 94055 and 94488 on Linux and the first thing i tested was
clicking scrollbar sliding area... and I thought it didn't work.

As it turns out, that is about the only thing that does NOT work.
The rest - wheelscrolling, key navigation  - is superb!
First time I've seen this effect in a Linux app - great fun.

Speed seems right (P4/1.8)
the slider dingus uses a different scrolling api then the keyboard does, and
that widget is used in other contexts where smooth scrolling might not be
useful, i.e., the mailnews message list.  

it certainly could be done, but I don't use the scrollbar interactively, so I
don't have plans to do it.
Keywords: helpwantedreview
Ouch. I guess this one is in danger of bitrotting then: A "half implemented"
feature risk spawning dozens of duplicates about scrollbar clicking not being
smooth.

In the meanwhile: with patch in attachments wheel/key scrolling on a P4/1.8 is
actually noticably faster than on MSIE, allthough not so fast the effect is
"lost". Would be interesting to hear how it behaves on "low end" systems.
Comment on attachment 94055 [details] [diff] [review]
UI for smooth scrolling pref

just some nit:

... "useSmoothScroll" ];

no need for extra space
other than that r=varga
Attachment #94055 - Flags: review+
Attachment #94055 - Attachment is obsolete: true
Comment on attachment 94488 [details] [diff] [review]
use nsIPrefService, a tad more comments

>+#include "nsCOMPtr.h"
>+#include "nsITimer.h"

it compiles even w/o these two

>+#define SMOOTH_PAGE_INCREMENTS 20 
>+#define SMOOTH_LINE_INCREMENTS 6

I think 6 lines is too much, I checked IE and it scrolls 3 lines.
6 lines is also too much for mouse wheel scrolling.

>+    if ( SmoothScrollIsEnabled() ) {
>+      for (int i=0; i < SMOOTH_LINE_INCREMENTS; i++) {
>+        ScrollTo( (mOffsetX + dx), (mOffsetY + dy), 0);
>+        // timing code goes here?  not needed on my machine
>+      }
>+    } else {
>+      ScrollTo( (mOffsetX + dx), (mOffsetY + dy), 0);
>+    }

- I think IsSmoothScrollEnabled() sounds better
- please remove extra spaces - ScrollTo( (mOffserX ...
- |int i=0| should be PRInt32 i = 0
- you don't need braces - (mOffsetX + dx) ...

>+    if ( SmoothScrollIsEnabled() ) {
>+      // set up the number of iterations, distance per iteration, etc 
>+      int numOfIncrements = SMOOTH_PAGE_INCREMENTS;
>+      nscoord dyIncrement = dy/numOfIncrements;
>+      nscoord nextY = mOffsetY+dyIncrement;
>+  
>+      // do the iteration
>+      for (int i=0; i<numOfIncrements; i++) {
>+        ScrollTo( mOffsetX, nextY, 0);
>+        nextY = mOffsetY+dyIncrement; // nextY += dyIncrement; won't work because of rounding
>+        // timing code goes here?  not needed on my machine
>+      }
>+    } else { // smooth scroll pref is not set, scroll in one big leap
>+      ScrollTo(mOffsetX, mOffsetY + dy, 0);
>+    }

- you don't need another local variable numOfIncrements
- extra spaces ...

>+PRBool 
>+nsScrollPortView::SmoothScrollIsEnabled() 
>+{ 
>+
>+    nsresult rv;
>+    nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
>+    NS_ENSURE_SUCCESS(rv, rv);
>+    nsCOMPtr<nsIPrefBranch> prefBranch;
>+    rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch));
>+    NS_ENSURE_SUCCESS(rv, rv);
>+
>+    PRBool doSmoothScroll;
>+    rv = prefBranch->GetBoolPref("general.smoothScroll", &doSmoothScroll);
>+    NS_ENSURE_SUCCESS(rv, rv);
>+
>+    return doSmoothScroll;
>+
> }

I wonder if it would be better to cache pref branch.
hmm, I'm not an expert here

>Index: view/src/nsScrollPortView.h
>+#include "nsCOMPtr.h"

again, no need for this
Using a for loop for scrolling will lead to wildly different scrolling speeds 
depending on the processor (imagine running it from processors PII 450 to P4 3.0 
GHz).

A better solution would be to use a fine granularity timer (say a few 
millisecs).

Something like:

handleEvents() {
....
case SMOOTH_SCROLLING_EVENT:
    // scroll first minor increment here
    StartScrollTimer( ScrollTimerHandler )  // other increments in a timer
    break

case NON_SMOOTH_SCROLLING_EVENT:
    // stop smooth scrolling before doing blocky scrolling or if scrolling
    //   changes direction
    StopScrollTimerIfStarted()    
    DoRegularScroll();
    break
...
}

struct ScrollerState {
   PRInt32 incrementNumber;   // number of increments that have taken place
};

// this timer callback is called each time the ScrollTimer is triggered
void ScrollTimerHandler( ScrollerState* state ){
      nscoord dyIncrement = dy / SMOOTH_PAGE_INCREMENTS;
      nscoord nextY;

      if ( state->numberOfIncrements >= SMOOTH_PAGE_INCREMENTS ) {
          stopTimer()       // done scrolling, so stop
      }
      else {
          state->numberOfIncrements++;     // update count

          nextY = mOffsetY + dyIncrement;
          ScrollTo( mOffsetX, nextY, 0);   // scroll a bit
      }
}


This is just approximate code. Using a scroll timer is essential, but the rest 
is completely changeable.

> I think 6 lines is too much, I checked IE and it scrolls 3 lines.
> 6 lines is also too much for mouse wheel scrolling.

yup, it's 3 (as system default). it should also depend on the internal moz prefs...
prefs -> advanced -> mouse wheel.

in windows you can change the system default (3) from:
control panel -> mouse -> wheel tab -> (wheel) .. settings
Re: Comment #60 (using a timer): indeed, using a precision timer is a must. But 
in addition to using the timer for setting the scroll speed, I think the actual 
scrolling performance should be measured, and if the result is too slow, smooth 
scrolling should be disabled. This will greatly help people with slow PCs 
browsing 'heavy' pages.
I don't think that a timer is appropriate at all.  

slow machines scroll slowly because it takes longer to draw the viewport. 
adding a timer could potentially try to scroll faster than the viewport could
redraw itself, queueing the callbacks.  this would cause *slower* scrolling.

adding a timer to fast machines that can redraw the viewport instantaniously
would introduge jagged animation.

I've tested this patch on a very slow machine (PII 200/64mb) and the scrolling
is not noticably slower than a reasonably fast machine (1GHz Athlon/1gb), and I
don't think we need to address slower machines.

I think that if this patch is ineffective on extremely fast machines, more
smaller increments should be used, not a timer.
Re: #63 (timers):

Properly-implemented timers do not cause queues or performance loss. The 
algorithm is simple:

 startTimer();
 redraw();
 waitFor(amountOfTime);

if amountOfTime has not yet passed since startTimer() was called, then the 
waitFor() function does just that -- waits. If that much time (or more) had 
already passed, we proceed immediately. This simple approach works flawlessly 
on any machine -- if the machine is slow, we introduce no extra delays, and if 
it is fast, we get exact timing.

Using smaller increments would mean torture to people with slower machines. And 
no test on a slower machine is really meaningful unless it uses extremely heavy 
pages (including animated GIFs, a few Flash ads, and an SVG or two thrown in 
for good measure).

Regarding my own suggestion of automatically disabling smooth scrolling if the 
machine is too slow, this can easily be done using the above-presented scheme. 
The change is that waitFor() returns the number of milliseconds actually 
waited; if the requested time had already passed when waitFor() is invoked, it 
would return a negative number. Thus, the code would look like this:

 actualWait = 0;
 loop:
   startTimer();
   redraw();
   actualWait += waitFor(amountOfTime);

if actualWait falls below a preset (negative) threshold (i.e., the computer 
doesn't keep up with the required timing), we immediately jump to the last step 
of the loop (that is, to the final position).

Note: the startTimer()/waitFor() pair can be implemented using temporary 
variables, i.e., startTime() returns a value (the real-time clock's value at 
start time) and waitFor() accepts this value as an additional parameter.
Tal, do you have a patch?
No; I wish I was sufficiently familiar with the code to create one. But I 
suppose that, following the guidelines I've provided, creating such a patch 
should not be too difficult to someone more, um, initiated than myself.
Tal, I don't know of any way to know when the screen has been redrawn.  there is
no event that I know of that says, "the screen is redrawn and the monitor is
displaying the correct bitmap".  it depends on many factors including video card
speed, monitor refresh rate, and system bus speed.  I really don't think this
can be easily done in a cross platform manner.  have you tried the attached
patch?  it works fine for everyone who has tried it on various hardware.
The idea of smooth scrolling is to make the text scroll the most possible 
increments possible between start and stop. Let's say you want to scroll "x" 
lines smoothly in "t" amount of milliseconds. Firstly, you have to determine 
an amount of times you are willing to redraw the whole browser window in a 
specific amount of time. Say you want to redraw it every 10 milliseconds, and 
want to scroll 100 lines one at a time... that means that it would take 1 
second to do this 100 line scroll. You will notice that on Mozilla, if you 
click the scrollbar, it immediately jumps to the next position. On IE, it 
takes longer (approx. half a second). There are a various number of scroll 
conditions:
A) Dragging the scroll tab
B) Clicking the scrollbar away from the tab
C) Page Down, Page Up
D) Clicking the arrows on the scrollbar
E) Highlighting text
F) Mousewheel
G) Panning/autoscroll (future)

This is a game of tradeoffs. There is no sure fire algorithm for figuring out 
what will work on each system.

We need to start with how long a user is willing to wait for the page to 
actually scroll. If it instantaneously moves to the next position like in 
Mozilla currently, there is no room for smooth scrolling. Therefore, we need 
to come up with an amount of time the user is willing to wait without getting 
impatient. If you are scrolling 1000 lines 1 line at a time with 10ms 
increments, the user might say, "Uhm, I could read the text while scrolling, 
but I would like it to take a little less than 10 seconds!". 

Here are some questions we need to answer:

1) How are we going to determine the smallest increment of time between 
redraws without bogging down a system?

Realize that you can't guarantee that the number of lines you scroll will have 
any affect on the redraw time. Can we determine based on queuing of the timer 
callback function? Maybe if it appears that the callback function isn't 
getting serviced enough, we can increase the amount of time between redraws we 
could keep a hold of this new wait value maybe for the rest of the time 
Mozilla is open (Do we want to carry a performance-evaluation between uses? 
What if part of the hardware changes). The problem with this is we are 
reacting to the computer getting so bogged down that even the timer doesn't 
get serviced. This could surely interfere in a negative way with other timer-
dependant applications. And how do we determine a proper new value that won't 
bog down the system quite a bit but not quite enough to not affect timer 
operations? Perhaps we could pick the slowest system you would ever run 
Mozilla on and find a good value based on that system. 

2) How smooth do you want it?

Rememember before where I said a user wouldn't want to wait 10 seconds for 
1000 lines to scroll smoothly? Obviously, if a user is scrolling in large 
increments, he doesn't care about reading the text and is probably looking 
more for large visual cues and not trying to read the text. Therefore, the 
more the user wants to move within the page, the bigger the scroll should be.

---

In the end, it really boils down to picking a unit of time that would work 
well for most systems, having an ability to determine if its too ambitious 
(queued timer callbacks), and reacting in those cases (simply making up for 
the lost scrolls by one big scroll). Internet Explorer uses up about 90% of my 
CPU for smooth scrolling on my PII 366 while currently Mozilla only uses about 
50% for its regular scrolling. Maybe that's about what we should aim for. If 
it only uses up 10% of a Pentium 4, then so what? This is a silly reason to 
demand all of someone's processor time. Don't they buy the faster systems so 
that they have the power for useful things, not silly things like this? We 
aren't designing a 3d application ;-)

---

Tal: The scrolling function would probably be in a loop until the scroll 
finished, but the actual scrolling would be done on the timer callbacks. When 
the scroll were finished, the scrolling function would pick that up from 
something the callback functions changed, and return to the calling function. 
Don't forget, though, that the scrolling function should yield to the system 
every loop since aggressive loops can bring down a system.

Neil: Timers (or maybe if Mozilla had a sleep function) is the only way to go. 
Without a timebase, everything breaks down and we run the risk of calling 
redraw even more than 1000 times a second!

---

Remember: Comment #18. Make sure that the code doesn't interfere with the 
scrolling that would be necessary for autoscroll. You can probably use your 
best judgement for that. Is there any way you can keep two versions of each 
scroll function? Perhaps you can pass an extra parameter to the scrolling 
functions that says the maximum time in milliseconds you (the programmer of 
various portions of Mozilla speaking for the user) are willing to wait per 
scroll (0 meaning no smooth-scrolling).

---

I know I have probably repeated what others here have said. Don't get offended 
if I did, I'm not trying to steal your ideas.
With regard to the latest comments above, how about someone examines how 
internet explorer does it? We can then see if this could be applied to mozilla.
umm, a quick solution for windows users...

can't we just call the windows api to do the smooth scrolling for us.
until we can implement one for moz.?
Waheed: No. 

Mozilla doesn't use Windows APIs to do scrolling.

Anyway, even if we could, unless its cross-platform forget it. We don't want 
to start getting into making Mozilla work different ways on different OSes. 
Its opening a pandora's box. Their are enough cross-platform inconsistancies 
as it is.

Regardless, it wouldn't be possible because we do scrolling internally.
Andrew: Its probably somewhere on msdn.microsoft.com. Couldn't you find it? 
There is no need to decompile IE. ;-)

Either way, the way I said will work, and who says IE does it the best way? I 
know they don't do panning and autoscroll the best way.
why decompile ie if you can decompile opera, which smoothscrolls much smoother
on my system.
attention folks:  there *is* a smooth scrolling implementation for mozilla. 
let's try to keep the discussion on deficiencies of that implementation, as well
as other problems it may introduce.  

talking about complex high-level algorithms and stealing proprietary code only
adds noise.  if there is a problem with the existing smooth scrolling that needs
to be solved, let's solve it.
Can someone *please* write some UI and a pref so the rest of us can see this? 
I don't particularly want to set up a build environment just to see what this 
feature looks like.
OK, so there's a UI, but since we have an implementation, what about adding it 
to the build and setting it OFF by default? Can't hurt!
I'd still like to know how IE does it or how Opera does it, maybe they do it the
same way, maybe not. I heard that within some countries it's legal to do reverse
engeneering if you do so to track back interferences with a compiled software
and the software you are developing. We could claim IE causes problems with
Mozilla and decompile it.

To answer #74:
There are two ways of doing something. Just doing it or first thinking how it
can be done best and then doing it. The existing implementation is the first
one, people here discuss the second one. To compare this to another example:
DivX is the first one, because DivX3 was a cracked MS codec, so they just had to
make their own one and the result was DivX4 that was even worse than their
cracked codec of MS at very low bitrates. The makers of Ogg Vorbis are now
making a video codec, too and so far they did nothing for months to discuss how
to do it best. Will this lead somewhere? Well, Ogg is the best sound compression
standard I know, much better than MP3, so yes, it leads somewhere.
tgos, can you identify a problem with the functionality with the 1st implementation?
Neil, I can't test it, but from what I read here, it will scroll faster on
faster machines and slower and slower machines. Just image you play a game and
it would run faster on fast machines and slower on slow machines? A game runs
the same speed on every machine, it just runs "smoother" on fast machines and
less "smooth" on slower machines. Smooth scrolling gets very annoying if it gets
very slow and you must wait ages to have the action performed.

Also I don't know how Mozilla scrolls at all. Does it re-render the page during
scrolling? If so, one could convert the whole page into a static picture, scroll
that and once the scrolling is done, the page is re-rendered again. This would
freeze dynamic content during the scroll operation (except maybe for Java and
plugins), but would that be a problem? Scrolling a picture is simple block-copy
and certainly faster than re-painting it often. Or does Mozilla use a
back-buffer? If so, one could make the back-buffer bigger than the viewport,
which also helps to optimize smooth scrolling. Smooth scrolling should be as
smooth as possible and use as little CPU cycles as possible.
this bug is not about the efficiency of scrolling or making scrolling work the
same all all hardware or changing the (important) redraw code to accomodate eye
candy.  this bug is about making use of the existing scrolling api to create a
smooth scrolling effect.  if you think that "mozilla is slower on slower
machines" is a bug, file another one.

the input given here is generally good, constructive stuff, but it is also way
outside the scope of getting something working for 99.999% of the users.  no one
has yet demonstrated that using a timer would be beneficial at all, and I think
that's the first step in taking on a more complex approach.
neil: "no one has yet demonstrated that using a timer would be beneficial at 
all"

Why don't you try to disprove it?
I'm going to take a look at the patches and test them. Before this gets in, 
this should include a large amount of testing so we don't screw up scrolling.

Please test this on as many systems as possible and provide performance 
information including memory bandwidth usage, and processor usage on as many 
systems as possible.

Neil: What happens if some part of the code wants to scroll the doc without 
using smooth scrolling but the pref is enabled? Is there a way to override the 
pref.
Keywords: polish
Whiteboard: (testing needed)
Good to see a head of steam building on this one - it's a real usability issue 
IMHO. It would be nice if we could get some sort of solution into 1.2 if poss.

I'm now off to set up a build environment to test the patch.
As I noticed some discussion about decompiling ie or opera, it came to my mind
that there is kind of smooth scrolling in open-office.org too. As far as I know
only if you click into the scroll bar while working with writer module.
I would also like to see smooth scrolling implemented in Mozilla. I am on
Windows XP and the only thing holding me back from Mozilla is the smooth
scrolling in IE6. It should definitely be an option, and as an option, it can't
hurt anybody.
Neil: I understand you don't like the timer solution because it is more complex 
than the for-loop version. I agree with u, and there should be sufficient 
testing before discarding a simple solution for a complex one.

Not using timers creates the following *potential* problems:

1) Rate of scrolling should be uniform: The pixels scrolled per millisec should 
be the approximately same regardless of the CPU or the complexity of the page. 
With timers u don't have to do much, since the timer maintains an almost smooth 
rate. With the for loop, the delay between each minor scroll has to be 
pain-stakingly calculated to ensure the uniform scroll rate.

2) GUI will be unresponsive while smooth scrolling: During the loop, the GUI 
will be unresponsive until the scroll event handler has finished scrolling *all* 
its little increments. In the timer version, the GUI will be more responsive 
because the timer gives back control of the GUI thread once its done rendering 
each minor scroll increment.

There is no delay code inside the for-loop currently. Please add that and we can 
test it on various machines with various pages and get some feedback.
Also consider the future; Mozilla developers 
will continue to optimize the code and CPUs 
will get faster.

Smooth scrolling implemented with a loop would 
gradually lose its "smoothness" as the time 
the loop takes to run gradually (inevitably) 
shrinks. From a user's point of view this would 
be seen as one big jump when he upgrades his 
browser and/or system.

That said, a loop implementation could possibly 
serve as a stopgap while a more sophisticated 
timer implementation is developed, as long as 
the API stays the same, sinse this feature 
seems to be important to people.
I tried a little experiment with both opera and IE:

1. Load a long page
2. Move the mouse cursor over a button (say home) in the toolbar. Button gets 
highligted immediately.
3. Hold down the down arrow key to start the smooth scroll
4. Without releasing down arrow, move the cursor to another button (reload) on 
the toolbar
5. *** The new button is not highligted immediately ***. It either gets
   highlighted after scrolling stopped or at least has a significant delay
   before highliting the new button.

My conclusion: 
Both IE and Opera *don't* use a timer. They probably use a for-loop style code 
since the gui (e.g. toolbar) is not very responsive during smooth scrolling.

"They probably use a for-loop style code 
since the gui (e.g. toolbar) is not very responsive during smooth scrolling."

Any code that makes the gui potentially unresponsive should be avoided. 
Further evidence for the need of a timer.
Greg: I disagree. Stopgaps should only be used for things that can't be fixed 
right the first time. Usually, this is for bugs that need to be adressed at 
least to some degree (i.e. disabling a feature) until it can be fully 
corrected. Adding this incorrectly would cause more trouble than it is worth 
and probably lead to more bugs and never being correctly implemented.
Comment on attachment 94488 [details] [diff] [review]
use nsIPrefService, a tad more comments

this patch does not play nice with phoenix.  a new one is coming.
Attachment #94488 - Attachment is obsolete: true
I'm resolving this a dupe of 174049 because there is almost zero interest in
getting this into mozilla-proper.  plus, the patch in 174049 is better.

*** This bug has been marked as a duplicate of 174049 ***
Status: NEW → RESOLVED
Closed: 24 years ago22 years ago
Resolution: --- → DUPLICATE
It can't be a dupe if its for different products... depends perhaps.
Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
Has this idea been deep-sixed for some reason?
*** Bug 183698 has been marked as a duplicate of this bug. ***
Bug 174049 is no longer a Phoenix-specific RFE, so we can might as well dupe
this again.

*** This bug has been marked as a duplicate of 174049 ***
Status: REOPENED → RESOLVED
Closed: 22 years ago22 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: