--- kdelibs-3.5.1/khtml/khtmlview.cpp 2006-03-07 08:23:42.000000000 -0500 +++ kdelibs-3.5.1/khtml/khtmlview.cpp.new 2006-03-08 10:04:42.000000000 -0500 @@ -150,6 +150,9 @@ KHTMLViewPrivate() : underMouse( 0 ), underMouseNonShared( 0 ), visibleWidgets( 107 ) +#ifndef NO_SMOOTH_SCROLL_HACK + , dx(0), dy(0), ddx(0), ddy(0), rdx(0), rdy(0), scrolling(false) +#endif { #ifndef KHTML_NO_CARET m_caretViewContext = 0; @@ -393,6 +396,18 @@ int m_mouseScroll_byY : 4; QTimer *m_mouseScrollTimer; QWidget *m_mouseScrollIndicator; +#ifndef NO_SMOOTH_SCROLL_HACK + QTimer timer2; + int dx; + int dy; + // Step size * 16 and residual to avoid huge difference between 1px/step and 2px/step + int ddx; + int ddy; + int rdx; + int rdy; + bool scrolling; +#endif + }; #ifndef QT_NO_TOOLTIP @@ -501,6 +516,12 @@ init(); viewport()->show(); +#ifndef NO_SMOOTH_SCROLL_HACK +#define timer timer2 + connect(&d->timer, SIGNAL(timeout()), this, SLOT(scrollTick())); +#undef timer +#endif + } KHTMLView::~KHTMLView() @@ -1681,8 +1702,16 @@ d->scrollSuspendPreActivate = false; if( _ke->key() == Key_Shift && d->scrollSuspendPreActivate && _ke->state() == Qt::ShiftButton && !(KApplication::keyboardMouseState() & Qt::ShiftButton)) + { if (d->scrollTimerId) - d->scrollSuspended = !d->scrollSuspended; + { + d->scrollSuspended = !d->scrollSuspended; +#ifndef NO_SMOOTH_SCROLL_HACK + if( d->scrollSuspended ) + stopScrolling(); +#endif + } + } if (d->accessKeysEnabled) { @@ -3221,7 +3250,11 @@ else { d->scrollBarMoved = true; +#ifndef NO_SMOOTH_SCROLL_HACK + scrollViewWheelEvent( e ); +#else QScrollView::viewportWheelEvent( e ); +#endif QMouseEvent *tempEvent = new QMouseEvent( QEvent::MouseMove, QPoint(-1,-1), QPoint(-1,-1), Qt::NoButton, e->state() ); emit viewportMouseMoveEvent ( tempEvent ); @@ -4395,4 +4428,112 @@ #endif // KHTML_NO_CARET +#ifndef NO_SMOOTH_SCROLL_HACK +#define timer timer2 + +// All scrolls must be completed within 240ms of last keypress +static const int SCROLL_TIME = 240; +// Each step is 20 ms == 50 frames/second +static const int SCROLL_TICK = 20; + +void KHTMLView::scrollBy(int dx, int dy) +{ + KConfigGroup cfg( KGlobal::config(), "KDE" ); + if( !cfg.readBoolEntry( "SmoothScrolling", true )) { + QScrollView::scrollBy( dx, dy ); + return; + } + // scrolling destination + int full_dx = d->dx + dx; + int full_dy = d->dy + dy; + + // scrolling speed + int ddx = 0; + int ddy = 0; + + int steps = SCROLL_TIME/SCROLL_TICK; + + ddx = (full_dx*16)/steps; + ddy = (full_dy*16)/steps; + + // don't go under 1px/step + if (ddx > 0 && ddx < 16) ddx = 16; + if (ddy > 0 && ddy < 16) ddy = 16; + if (ddx < 0 && ddx > -16) ddx = -16; + if (ddy < 0 && ddy > -16) ddy = -16; + + d->dx = full_dx; + d->dy = full_dy; + d->ddx = ddx; + d->ddy = ddy; + + if (!d->scrolling) { + scrollTick(); + startScrolling(); + } +} + +void KHTMLView::scrollTick() { + if (d->dx == 0 && d->dy == 0) { + stopScrolling(); + return; + } + + int tddx = d->ddx + d->rdx; + int tddy = d->ddy + d->rdy; + + int ddx = tddx / 16; + int ddy = tddy / 16; + d->rdx = tddx % 16; + d->rdy = tddy % 16; + + if (d->dx > 0 && ddx > d->dx) ddx = d->dx; + else + if (d->dx < 0 && ddx < d->dx) ddx = d->dx; + + if (d->dy > 0 && ddy > d->dy) ddy = d->dy; + else + if (d->dy < 0 && ddy < d->dy) ddy = d->dy; + + d->dx -= ddx; + d->dy -= ddy; + +// QScrollView::setContentsPos( contentsX() + ddx, contentsY() + ddy); + QScrollView::scrollBy(ddx, ddy); +} + +void KHTMLView::startScrolling() +{ + d->scrolling = true; + d->timer.start(SCROLL_TICK, false); +} + +void KHTMLView::stopScrolling() +{ + d->timer.stop(); + d->dx = d->dy = 0; + d->scrolling = false; +} + +// Overloaded from QScrollView and QScrollBar +void KHTMLView::scrollViewWheelEvent( QWheelEvent *e ) +{ + int pageStep = verticalScrollBar()->pageStep(); + int lineStep = verticalScrollBar()->lineStep(); + int step = QMIN( QApplication::wheelScrollLines()*lineStep, pageStep ); + if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) + step = pageStep; + + if(e->orientation() == Horizontal) + scrollBy(-((e->delta()*step)/120), 0); + else if(e->orientation() == Vertical) + scrollBy(0,-((e->delta()*step)/120)); + + e->accept(); +} + +#undef timer + +#endif // NO_SMOOTH_SCROLL_HACK + #undef DEBUG_CARETMODE --- kdelibs-3.5.1/khtml/khtmlview.h 2006-03-08 10:07:22.000000000 -0500 +++ kdelibs-3.5.1/khtml/khtmlview.h.new 2006-03-08 10:06:36.000000000 -0500 @@ -177,6 +177,11 @@ void hideAccessKeys(); void repaintAccessKeys(); void findAheadActive( bool ); +//#define NO_SMOOTH_SCROLL_HACK +#ifndef NO_SMOOTH_SCROLL_HACK + public slots: + void scrollBy(int dx, int dy); +#endif protected: void clear(); @@ -207,10 +212,25 @@ void contentsContextMenuEvent ( QContextMenuEvent *_ce ); void doAutoScroll(); void timerEvent ( QTimerEvent * ); + +#ifndef NO_SMOOTH_SCROLL_HACK + void startScrolling(); + void stopScrolling(); +#ifndef QT_NO_WHEELEVENT + void scrollViewWheelEvent( QWheelEvent* e ); +#endif +#endif + + protected slots: void slotPaletteChanged(); void slotScrollBarMoved(); - +#ifndef NO_SMOOTH_SCROLL_HACK + void scrollTick(); +#else + void scrollTick() {}; // moc cannot handle #if +#endif + private slots: void tripleClickTimeout(); void findTimeout();