1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 18:56:34 +01:00

Fix scrolling with high resolution mouse/touchpads

Use helper class to accumulate "common steps" of 120 angle delta.
This commit is contained in:
David Rosca 2017-01-21 12:23:24 +01:00
parent 9082c32bae
commit 5cc7dd080e
9 changed files with 197 additions and 22 deletions

View File

@ -218,6 +218,7 @@ SOURCES += \
webtab/searchtoolbar.cpp \ webtab/searchtoolbar.cpp \
webtab/tabbedwebview.cpp \ webtab/tabbedwebview.cpp \
webtab/webtab.cpp \ webtab/webtab.cpp \
tools/wheelhelper.cpp \
HEADERS += \ HEADERS += \
3rdparty/fancytabwidget.h \ 3rdparty/fancytabwidget.h \
@ -399,6 +400,7 @@ HEADERS += \
webtab/searchtoolbar.h \ webtab/searchtoolbar.h \
webtab/tabbedwebview.h \ webtab/tabbedwebview.h \
webtab/webtab.h \ webtab/webtab.h \
tools/wheelhelper.h \
FORMS += \ FORMS += \
adblock/adblockaddsubscriptiondialog.ui \ adblock/adblockaddsubscriptiondialog.ui \

View File

@ -1,7 +1,7 @@
/* ============================================================ /* ============================================================
* QupZilla - WebKit based browser * QupZilla - Qt web browser
* Copyright (C) 2013-2014 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com> * Copyright (C) 2013-2014 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
* Copyright (C) 2014-2016 David Rosca <nowrep@gmail.com> * Copyright (C) 2014-2017 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -615,8 +615,24 @@ void ComboTabBar::wheelEvent(QWheelEvent* event)
{ {
event->accept(); event->accept();
if (qzSettings->alwaysSwitchTabsWithWheel) { if (qzSettings->alwaysSwitchTabsWithWheel || (!m_mainTabBarWidget->isOverflowed() && !m_pinnedTabBarWidget->isOverflowed())) {
setCurrentNextEnabledIndex(event->delta() > 0 ? -1 : 1); m_wheelHelper.processEvent(event);
while (WheelHelper::Direction direction = m_wheelHelper.takeDirection()) {
switch (direction) {
case WheelHelper::WheelUp:
case WheelHelper::WheelLeft:
setCurrentNextEnabledIndex(-1);
break;
case WheelHelper::WheelDown:
case WheelHelper::WheelRight:
setCurrentNextEnabledIndex(1);
break;
default:
break;
}
}
return; return;
} }
@ -636,10 +652,6 @@ void ComboTabBar::wheelEvent(QWheelEvent* event)
m_mainTabBarWidget->scrollByWheel(event); m_mainTabBarWidget->scrollByWheel(event);
} }
} }
if (!m_mainTabBarWidget->isOverflowed() && !m_pinnedTabBarWidget->isOverflowed()) {
setCurrentNextEnabledIndex(event->delta() > 0 ? -1 : 1);
}
} }
bool ComboTabBar::eventFilter(QObject* obj, QEvent* ev) bool ComboTabBar::eventFilter(QObject* obj, QEvent* ev)

View File

@ -1,7 +1,7 @@
/* ============================================================ /* ============================================================
* QupZilla - WebKit based browser * QupZilla - Qt web browser
* Copyright (C) 2013-2014 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com> * Copyright (C) 2013-2014 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
* Copyright (C) 2014-2016 David Rosca <nowrep@gmail.com> * Copyright (C) 2014-2017 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@
#define COMBOTABBAR_H #define COMBOTABBAR_H
#include "qzcommon.h" #include "qzcommon.h"
#include "wheelhelper.h"
#include <QTabBar> #include <QTabBar>
#include <QScrollBar> #include <QScrollBar>
@ -203,6 +204,8 @@ private:
bool m_usesScrollButtons; bool m_usesScrollButtons;
bool m_blockCurrentChangedSignal; bool m_blockCurrentChangedSignal;
WheelHelper m_wheelHelper;
friend class TabBarHelper; friend class TabBarHelper;
friend class TabStackedWidget; friend class TabStackedWidget;
}; };

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* QupZilla - WebKit based browser * QupZilla - Qt web browser
* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2017 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -122,13 +122,23 @@ void ButtonWithMenu::setCurrentIndex(int index, bool emitSignal)
void ButtonWithMenu::wheelEvent(QWheelEvent* event) void ButtonWithMenu::wheelEvent(QWheelEvent* event)
{ {
if (event->delta() > 0) { m_wheelHelper.processEvent(event);
while (WheelHelper::Direction direction = m_wheelHelper.takeDirection()) {
switch (direction) {
case WheelHelper::WheelUp:
case WheelHelper::WheelLeft:
selectPreviousItem(); selectPreviousItem();
} break;
else {
selectNextItem();
}
case WheelHelper::WheelDown:
case WheelHelper::WheelRight:
selectNextItem();
break;
default:
break;
}
}
event->accept(); event->accept();
} }

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* QupZilla - WebKit based browser * QupZilla - Qt web browser
* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2017 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,7 +21,7 @@
#include <QVariant> #include <QVariant>
#include "toolbutton.h" #include "toolbutton.h"
#include "qzcommon.h" #include "wheelhelper.h"
// Only to be used in WebSearchBar // Only to be used in WebSearchBar
class ButtonWithMenu : public ToolButton class ButtonWithMenu : public ToolButton
@ -88,6 +88,7 @@ private:
QMenu* m_menu; QMenu* m_menu;
QVector<Item> m_items; QVector<Item> m_items;
Item m_currentItem; Item m_currentItem;
WheelHelper m_wheelHelper;
}; };
// Hint to QVector to use std::realloc on item moving // Hint to QVector to use std::realloc on item moving

View File

@ -0,0 +1,78 @@
/* ============================================================
* QupZilla - Qt web browser
* Copyright (C) 2017 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "wheelhelper.h"
#include <QWheelEvent>
WheelHelper::WheelHelper()
{
}
void WheelHelper::reset()
{
m_wheelDelta = 0;
m_directions.clear();
}
void WheelHelper::processEvent(QWheelEvent *event)
{
int delta = event->angleDelta().x() ? event->angleDelta().x() : event->angleDelta().y();
bool directionY = delta == event->angleDelta().y();
// When scroll to both directions, prefer the major one
if (event->angleDelta().x() && event->angleDelta().y()) {
if (std::abs(event->angleDelta().y()) > std::abs(event->angleDelta().x())) {
delta = event->angleDelta().y();
directionY = true;
} else {
delta = event->angleDelta().x();
directionY = false;
}
}
// Reset when direction changes
if ((delta < 0 && m_wheelDelta > 0) || (delta > 0 && m_wheelDelta < 0)) {
m_wheelDelta = 0;
}
m_wheelDelta += delta;
// Angle delta 120 for common "one click"
// See: http://qt-project.org/doc/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop
while (m_wheelDelta >= 120) {
m_wheelDelta -= 120;
if (directionY) {
m_directions.enqueue(WheelUp);
} else {
m_directions.enqueue(WheelLeft);
}
}
while (m_wheelDelta <= -120) {
m_wheelDelta += 120;
if (directionY) {
m_directions.enqueue(WheelDown);
} else {
m_directions.enqueue(WheelRight);
}
}
}
WheelHelper::Direction WheelHelper::takeDirection()
{
return m_directions.isEmpty() ? None : m_directions.dequeue();
}

View File

@ -0,0 +1,49 @@
/* ============================================================
* QupZilla - Qt web browser
* Copyright (C) 2017 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef WHEELHELPER_H
#define WHEELHELPER_H
#include <QQueue>
#include "qzcommon.h"
class QWheelEvent;
class QUPZILLA_EXPORT WheelHelper
{
public:
enum Direction {
None = 0,
WheelUp,
WheelDown,
WheelLeft,
WheelRight
};
explicit WheelHelper();
void reset();
void processEvent(QWheelEvent *event);
Direction takeDirection();
private:
int m_wheelDelta = 0;
QQueue<Direction> m_directions;
};
#endif // WHEELHELPER_H

View File

@ -1019,11 +1019,29 @@ void WebView::_wheelEvent(QWheelEvent *event)
} }
if (event->modifiers() & Qt::ControlModifier) { if (event->modifiers() & Qt::ControlModifier) {
event->delta() > 0 ? zoomIn() : zoomOut(); m_wheelHelper.processEvent(event);
while (WheelHelper::Direction direction = m_wheelHelper.takeDirection()) {
switch (direction) {
case WheelHelper::WheelUp:
case WheelHelper::WheelLeft:
zoomIn();
break;
case WheelHelper::WheelDown:
case WheelHelper::WheelRight:
zoomOut();
break;
default:
break;
}
}
event->accept(); event->accept();
return; return;
} }
m_wheelHelper.reset();
// QtWebEngine ignores QApplication::wheelScrollLines() and instead always scrolls 3 lines // QtWebEngine ignores QApplication::wheelScrollLines() and instead always scrolls 3 lines
if (event->spontaneous()) { if (event->spontaneous()) {
const qreal multiplier = QApplication::wheelScrollLines() / 3.0; const qreal multiplier = QApplication::wheelScrollLines() / 3.0;

View File

@ -23,6 +23,7 @@
#include "qzcommon.h" #include "qzcommon.h"
#include "loadrequest.h" #include "loadrequest.h"
#include "wheelhelper.h"
class WebPage; class WebPage;
class LoadRequest; class LoadRequest;
@ -189,6 +190,7 @@ private:
bool m_firstLoad; bool m_firstLoad;
QPointer<QWidget> m_rwhvqt; QPointer<QWidget> m_rwhvqt;
WheelHelper m_wheelHelper;
static bool s_forceContextMenuOnMouseRelease; static bool s_forceContextMenuOnMouseRelease;
}; };