mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 10:46:35 +01:00
Use native scrollbars for main scrollbars
Use native widgets to render main scrollbars (scrollbars of the main webview widget, not iframes etc). It makes the scrollbars on body element invisible and instead draws native widgets on the space for scrollbars. Comes with possibility to disable it, enabled by default.
This commit is contained in:
parent
83444d8851
commit
64b48f6899
@ -215,6 +215,8 @@ SOURCES += \
|
||||
webengine/webinspector.cpp \
|
||||
webengine/webpage.cpp \
|
||||
webengine/webview.cpp \
|
||||
webengine/webscrollbar.cpp \
|
||||
webengine/webscrollbarmanager.cpp \
|
||||
webtab/searchtoolbar.cpp \
|
||||
webtab/tabbedwebview.cpp \
|
||||
webtab/webtab.cpp \
|
||||
@ -397,6 +399,8 @@ HEADERS += \
|
||||
webengine/webinspector.h \
|
||||
webengine/webpage.h \
|
||||
webengine/webview.h \
|
||||
webengine/webscrollbar.h \
|
||||
webengine/webscrollbarmanager.h \
|
||||
webtab/searchtoolbar.h \
|
||||
webtab/tabbedwebview.h \
|
||||
webtab/webtab.h \
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "profilemanager.h"
|
||||
#include "html5permissions/html5permissionsdialog.h"
|
||||
#include "searchenginesdialog.h"
|
||||
#include "webscrollbarmanager.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QInputDialog>
|
||||
@ -277,6 +278,7 @@ Preferences::Preferences(BrowserWindow* window)
|
||||
ui->animateScrolling->setChecked(settings.value("AnimateScrolling", true).toBool());
|
||||
ui->wheelScroll->setValue(settings.value("wheelScrollLines", qApp->wheelScrollLines()).toInt());
|
||||
ui->xssAuditing->setChecked(settings.value("XSSAuditing", false).toBool());
|
||||
ui->useNativeScrollbars->setChecked(settings.value("UseNativeScrollbars", true).toBool());
|
||||
|
||||
foreach (int level, WebView::zoomLevels()) {
|
||||
ui->defaultZoomLevel->addItem(QString("%1%").arg(level));
|
||||
@ -973,6 +975,7 @@ void Preferences::saveSettings()
|
||||
settings.setValue("DefaultZoomLevel", ui->defaultZoomLevel->currentIndex());
|
||||
settings.setValue("XSSAuditing", ui->xssAuditing->isChecked());
|
||||
settings.setValue("closeAppWithCtrlQ", ui->closeAppWithCtrlQ->isChecked());
|
||||
settings.setValue("UseNativeScrollbars", ui->useNativeScrollbars->isChecked());
|
||||
#ifdef Q_OS_WIN
|
||||
settings.setValue("CheckDefaultBrowser", ui->checkDefaultBrowser->isChecked());
|
||||
#endif
|
||||
@ -1070,6 +1073,8 @@ void Preferences::saveSettings()
|
||||
mApp->desktopNotifications()->loadSettings();
|
||||
mApp->autoFill()->loadSettings();
|
||||
mApp->networkManager()->loadSettings();
|
||||
|
||||
WebScrollBarManager::instance()->loadSettings();
|
||||
}
|
||||
|
||||
Preferences::~Preferences()
|
||||
|
@ -1117,6 +1117,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="useNativeScrollbars">
|
||||
<property name="text">
|
||||
<string>Use native scrollbars</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
@ -2374,8 +2381,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>560</width>
|
||||
<height>70</height>
|
||||
<width>96</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
||||
|
@ -161,6 +161,11 @@ void WebPage::scroll(int x, int y)
|
||||
runJavaScript(QSL("window.scrollTo(window.scrollX + %1, window.scrollY + %2)").arg(x).arg(y), WebPage::SafeJsWorld);
|
||||
}
|
||||
|
||||
void WebPage::setScrollPosition(const QPointF &pos)
|
||||
{
|
||||
runJavaScript(QSL("window.scrollTo(%1, %2)").arg(pos.x()).arg(pos.y()), WebPage::SafeJsWorld);
|
||||
}
|
||||
|
||||
void WebPage::scheduleAdjustPage()
|
||||
{
|
||||
if (view()->isLoading()) {
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
WebHitTestResult hitTestContent(const QPoint &pos) const;
|
||||
|
||||
void scroll(int x, int y);
|
||||
void setScrollPosition(const QPointF &pos);
|
||||
|
||||
bool javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString* result) Q_DECL_OVERRIDE;
|
||||
bool javaScriptConfirm(const QUrl &securityOrigin, const QString &msg) Q_DECL_OVERRIDE;
|
||||
|
89
src/lib/webengine/webscrollbar.cpp
Normal file
89
src/lib/webengine/webscrollbar.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/* ============================================================
|
||||
* QupZilla - Qt web browser
|
||||
* Copyright (C) 2016 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 "webscrollbar.h"
|
||||
#include "webview.h"
|
||||
#include "webpage.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
|
||||
WebScrollBar::WebScrollBar(Qt::Orientation orientation, WebView *view)
|
||||
: QScrollBar(orientation)
|
||||
, m_view(view)
|
||||
{
|
||||
setFocusProxy(m_view);
|
||||
resize(sizeHint());
|
||||
|
||||
connect(this, &QScrollBar::valueChanged, this, &WebScrollBar::performScroll);
|
||||
connect(view, &WebView::focusChanged, this, [this]() { update(); });
|
||||
}
|
||||
|
||||
int WebScrollBar::thickness() const
|
||||
{
|
||||
return orientation() == Qt::Vertical ? width() : height();
|
||||
}
|
||||
|
||||
void WebScrollBar::updateValues(const QSize &viewport)
|
||||
{
|
||||
setMinimum(0);
|
||||
setParent(m_view->overlayWidget());
|
||||
|
||||
m_blockScrolling = true;
|
||||
|
||||
if (orientation() == Qt::Vertical) {
|
||||
setFixedHeight(viewport.height());
|
||||
move(m_view->width() - width(), 0);
|
||||
setPageStep(viewport.height());
|
||||
setMaximum(std::max(0, m_view->page()->contentsSize().toSize().height() - viewport.height()));
|
||||
setValue(m_view->page()->scrollPosition().toPoint().y());
|
||||
} else {
|
||||
setFixedWidth(viewport.width());
|
||||
move(0, m_view->height() - height());
|
||||
setPageStep(viewport.width());
|
||||
setMaximum(std::max(0, m_view->page()->contentsSize().toSize().width() - viewport.width()));
|
||||
setValue(m_view->page()->scrollPosition().toPoint().x());
|
||||
}
|
||||
|
||||
m_blockScrolling = false;
|
||||
|
||||
setVisible(maximum() > minimum());
|
||||
}
|
||||
|
||||
void WebScrollBar::performScroll()
|
||||
{
|
||||
if (m_blockScrolling) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPointF pos = m_view->page()->scrollPosition();
|
||||
|
||||
if (orientation() == Qt::Vertical) {
|
||||
pos.setY(value());
|
||||
} else {
|
||||
pos.setX(value());
|
||||
}
|
||||
|
||||
m_view->page()->setScrollPosition(pos);
|
||||
}
|
||||
|
||||
void WebScrollBar::paintEvent(QPaintEvent *ev)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.fillRect(ev->rect(), m_view->page()->backgroundColor());
|
||||
QScrollBar::paintEvent(ev);
|
||||
}
|
46
src/lib/webengine/webscrollbar.h
Normal file
46
src/lib/webengine/webscrollbar.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* ============================================================
|
||||
* QupZilla - Qt web browser
|
||||
* Copyright (C) 2016 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 WEBSCROLLBAR_H
|
||||
#define WEBSCROLLBAR_H
|
||||
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "qzcommon.h"
|
||||
|
||||
class WebView;
|
||||
|
||||
class WebScrollBar : public QScrollBar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WebScrollBar(Qt::Orientation orientation, WebView *view);
|
||||
|
||||
int thickness() const;
|
||||
void updateValues(const QSize &viewport);
|
||||
|
||||
private:
|
||||
void performScroll();
|
||||
void paintEvent(QPaintEvent *ev) override;
|
||||
|
||||
WebView *m_view;
|
||||
bool m_blockScrolling = false;
|
||||
};
|
||||
|
||||
#endif // WEBSCROLLBAR_H
|
186
src/lib/webengine/webscrollbarmanager.cpp
Normal file
186
src/lib/webengine/webscrollbarmanager.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
/* ============================================================
|
||||
* QupZilla - Qt web browser
|
||||
* Copyright (C) 2016 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 "webscrollbarmanager.h"
|
||||
#include "webscrollbar.h"
|
||||
#include "webview.h"
|
||||
#include "webpage.h"
|
||||
#include "mainapplication.h"
|
||||
#include "scripts.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QWebEngineProfile>
|
||||
#include <QWebEngineScriptCollection>
|
||||
|
||||
Q_GLOBAL_STATIC(WebScrollBarManager, qz_web_scrollbar_manager)
|
||||
|
||||
class WebScrollBarCornerWidget : QWidget
|
||||
{
|
||||
public:
|
||||
explicit WebScrollBarCornerWidget(WebView *view)
|
||||
: QWidget()
|
||||
, m_view(view)
|
||||
{
|
||||
}
|
||||
|
||||
void updateVisibility(bool visible, int thickness)
|
||||
{
|
||||
if (visible) {
|
||||
setParent(m_view->overlayWidget());
|
||||
resize(thickness, thickness);
|
||||
move(m_view->width() - width(), m_view->height() - height());
|
||||
show();
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent *ev) override
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.fillRect(ev->rect(), m_view->page()->backgroundColor());
|
||||
QWidget::paintEvent(ev);
|
||||
}
|
||||
|
||||
WebView *m_view;
|
||||
};
|
||||
|
||||
struct ScrollBarData {
|
||||
~ScrollBarData() {
|
||||
delete vscrollbar;
|
||||
delete hscrollbar;
|
||||
delete corner;
|
||||
}
|
||||
|
||||
WebScrollBar *vscrollbar;
|
||||
WebScrollBar *hscrollbar;
|
||||
WebScrollBarCornerWidget *corner;
|
||||
};
|
||||
|
||||
WebScrollBarManager::WebScrollBarManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
void WebScrollBarManager::loadSettings()
|
||||
{
|
||||
m_enabled = Settings().value(QSL("Web-Browser-Settings/UseNativeScrollbars"), true).toBool();
|
||||
|
||||
if (!m_enabled) {
|
||||
for (WebView *view : m_scrollbars.keys()) {
|
||||
removeWebView(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebScrollBarManager::addWebView(WebView *view)
|
||||
{
|
||||
if (!m_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete m_scrollbars.value(view);
|
||||
|
||||
ScrollBarData *data = new ScrollBarData;
|
||||
data->vscrollbar = new WebScrollBar(Qt::Vertical, view);
|
||||
data->hscrollbar = new WebScrollBar(Qt::Horizontal, view);
|
||||
data->corner = new WebScrollBarCornerWidget(view);
|
||||
m_scrollbars[view] = data;
|
||||
|
||||
auto updateValues = [=]() {
|
||||
const int thickness = data->vscrollbar->thickness();
|
||||
const QSize viewport = viewportSize(view, thickness);
|
||||
data->vscrollbar->updateValues(viewport);
|
||||
data->hscrollbar->updateValues(viewport);
|
||||
data->corner->updateVisibility(data->vscrollbar->isVisible() && data->hscrollbar->isVisible(), thickness);
|
||||
};
|
||||
|
||||
connect(view, &WebView::viewportResized, this, updateValues);
|
||||
connect(view->page(), &WebPage::contentsSizeChanged, this, updateValues);
|
||||
connect(view->page(), &WebPage::scrollPositionChanged, this, updateValues);
|
||||
|
||||
if (m_scrollbars.size() == 1) {
|
||||
createUserScript();
|
||||
}
|
||||
}
|
||||
|
||||
void WebScrollBarManager::removeWebView(WebView *view)
|
||||
{
|
||||
if (m_scrollbars.size() == 1) {
|
||||
removeUserScript();
|
||||
}
|
||||
|
||||
disconnect(view, 0, this, 0);
|
||||
disconnect(view->page(), 0, this, 0);
|
||||
|
||||
delete m_scrollbars.take(view);
|
||||
}
|
||||
|
||||
WebScrollBarManager *WebScrollBarManager::instance()
|
||||
{
|
||||
return qz_web_scrollbar_manager();
|
||||
}
|
||||
|
||||
void WebScrollBarManager::createUserScript()
|
||||
{
|
||||
Q_ASSERT(!m_scrollbars.isEmpty());
|
||||
|
||||
const int thickness = (*m_scrollbars.begin())->vscrollbar->thickness();
|
||||
|
||||
QWebEngineScript script;
|
||||
script.setName(QSL("_qupzilla_scrollbar"));
|
||||
script.setInjectionPoint(QWebEngineScript::DocumentReady);
|
||||
script.setWorldId(WebPage::SafeJsWorld);
|
||||
script.setSourceCode(Scripts::setCss(QSL("body::-webkit-scrollbar{width:%1px;height:%1px;}").arg(thickness)));
|
||||
mApp->webProfile()->scripts()->insert(script);
|
||||
}
|
||||
|
||||
void WebScrollBarManager::removeUserScript()
|
||||
{
|
||||
QWebEngineScript script = mApp->webProfile()->scripts()->findScript(QSL("_qupzilla_scrollbar"));
|
||||
mApp->webProfile()->scripts()->remove(script);
|
||||
}
|
||||
|
||||
QSize WebScrollBarManager::viewportSize(WebView *view, int thickness) const
|
||||
{
|
||||
QSize viewport = view->size();
|
||||
const QSize content = view->page()->contentsSize().toSize();
|
||||
|
||||
// Check both axis
|
||||
if (content.width() - viewport.width() > 0) {
|
||||
viewport.setHeight(viewport.height() - thickness);
|
||||
}
|
||||
|
||||
if (content.height() - viewport.height() > 0) {
|
||||
viewport.setWidth(viewport.width() - thickness);
|
||||
}
|
||||
|
||||
// Check again against adjusted size
|
||||
if (viewport.height() == view->height() && content.width() - viewport.width() > 0) {
|
||||
viewport.setHeight(viewport.height() - thickness);
|
||||
}
|
||||
|
||||
if (viewport.width() == view->width() && content.height() - viewport.height() > 0) {
|
||||
viewport.setWidth(viewport.width() - thickness);
|
||||
}
|
||||
|
||||
return viewport;
|
||||
}
|
50
src/lib/webengine/webscrollbarmanager.h
Normal file
50
src/lib/webengine/webscrollbarmanager.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* ============================================================
|
||||
* QupZilla - Qt web browser
|
||||
* Copyright (C) 2016 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 WEBSCROLLBARMANAGER_H
|
||||
#define WEBSCROLLBARMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
|
||||
class WebView;
|
||||
|
||||
class WebScrollBarManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WebScrollBarManager(QObject *parent = 0);
|
||||
|
||||
void loadSettings();
|
||||
|
||||
void addWebView(WebView *view);
|
||||
void removeWebView(WebView *view);
|
||||
|
||||
static WebScrollBarManager *instance();
|
||||
|
||||
private:
|
||||
void createUserScript();
|
||||
void removeUserScript();
|
||||
QSize viewportSize(WebView *view, int thickness) const;
|
||||
|
||||
bool m_enabled = true;
|
||||
QHash<WebView*, struct ScrollBarData*> m_scrollbars;
|
||||
};
|
||||
|
||||
#endif // WEBSCROLLBARMANAGER_H
|
@ -34,6 +34,7 @@
|
||||
#include "webinspector.h"
|
||||
#include "scripts.h"
|
||||
#include "webhittestresult.h"
|
||||
#include "webscrollbarmanager.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -88,6 +89,7 @@ WebView::WebView(QWidget* parent)
|
||||
WebView::~WebView()
|
||||
{
|
||||
WebInspector::unregisterView(this);
|
||||
WebScrollBarManager::instance()->removeWebView(this);
|
||||
}
|
||||
|
||||
QIcon WebView::icon() const
|
||||
@ -147,9 +149,12 @@ void WebView::setPage(WebPage *page)
|
||||
// Set default zoom level
|
||||
zoomReset();
|
||||
|
||||
// Actions needs to be initialized for every QWebPage change
|
||||
// Actions needs to be initialized for every QWebEnginePage change
|
||||
initializeActions();
|
||||
|
||||
// Scrollbars must be added only after QWebEnginePage is set
|
||||
WebScrollBarManager::instance()->addWebView(this);
|
||||
|
||||
mApp->plugins()->emitWebPageCreated(m_page);
|
||||
}
|
||||
|
||||
@ -1235,5 +1240,19 @@ bool WebView::eventFilter(QObject *obj, QEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
return QWebEngineView::eventFilter(obj, event);
|
||||
const bool res = QWebEngineView::eventFilter(obj, event);
|
||||
|
||||
if (obj == m_rwhvqt) {
|
||||
switch (event->type()) {
|
||||
case QEvent::FocusIn:
|
||||
case QEvent::FocusOut:
|
||||
emit focusChanged(hasFocus());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
static void setForceContextMenuOnMouseRelease(bool force);
|
||||
|
||||
signals:
|
||||
void focusChanged(bool);
|
||||
void viewportResized(QSize);
|
||||
void showNotification(QWidget*);
|
||||
void privacyChanged(bool);
|
||||
|
Loading…
Reference in New Issue
Block a user