Make scroll bars hideable

This commit is contained in:
Florian Bruhin 2014-05-16 14:20:37 +02:00
parent 13a5f41f63
commit 1bfbdd79e4
7 changed files with 75 additions and 30 deletions

1
TODO
View File

@ -86,7 +86,6 @@ Improvements / minor features
QNetworkManager.setCache() and use a QNetworkDiskCache probably
- clear cookies command
- keybind/aliases should have completion for commands/arguments
- Hiding scrollbars
- Ctrl+A/X to increase/decrease last number in URL
- logging contexts
- Add more element-selection-detection code (with options?) based on:

View File

@ -24,7 +24,7 @@ from tempfile import mkstemp
from functools import partial
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import pyqtSlot, Qt, QObject, QProcess
from PyQt5.QtCore import pyqtSlot, Qt, QObject, QProcess, QPoint
from PyQt5.QtGui import QClipboard
from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog
@ -78,10 +78,19 @@ class CurCommandDispatcher(QObject):
perc = float(perc)
perc = utils.check_overflow(perc, 'int', fatal=False)
frame = self._tabs.currentWidget().page_.currentFrame()
m = frame.scrollBarMaximum(orientation)
if m == 0:
return
frame.setScrollBarValue(orientation, int(m * perc / 100))
if orientation == Qt.Horizontal:
right = frame.contentsSize().width()
viewsize = frame.geometry().width()
x = (right - viewsize) * perc / 100
y = frame.scrollPosition().y()
elif orientation == Qt.Vertical:
bottom = frame.contentsSize().height()
viewsize = frame.geometry().height()
x = frame.scrollPosition().x()
y = (bottom - viewsize) * perc / 100
else:
raise ValueError("Invalid orientation {}".format(orientation))
frame.setScrollPosition(QPoint(x, y))
def _prevnext(self, prev, newtab):
"""Inner logic for {tab,}{prev,next}page."""

View File

@ -22,7 +22,7 @@ import shlex
import os.path
from sre_constants import error as RegexError
from PyQt5.QtCore import QUrl
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QColor
from PyQt5.QtNetwork import QNetworkProxy
@ -650,6 +650,25 @@ class ZoomPerc(Perc):
# FIXME we should validate the percentage is in the list here.
class ScrollBarPolicy(BaseType):
"""Base class for scroll bar policies."""
valid_values = ValidValues(
('as-needed', "Show a scroll bar when the content is too large."),
('always', "Always show a scroll bar."),
('never', "Never show a scroll bar."),
)
def transform(self, value):
mapping = {
'as-needed': Qt.ScrollBarAsNeeded,
'always': Qt.ScrollBarAlwaysOn,
'never': Qt.ScrollBarAlwaysOff,
}
return mapping[value]
class HintMode(BaseType):
"""Base class for the hints -> mode setting."""

View File

@ -197,6 +197,14 @@ DATA = OrderedDict([
SettingValue(types.ShellCommand(placeholder=True), 'gvim -f "{}"'),
"The editor (and arguments) to use for the open_editor binding. "
"Use {} for the filename. Gets split via shutils."),
('show-scroll-bar-horizontal',
SettingValue(types.ScrollBarPolicy(), 'never'),
"Whether to show horizontal scrollbar for web content."),
('show-scroll-bar-vertical',
SettingValue(types.ScrollBarPolicy(), 'never'),
"Whether to show vertical scrollbar for web content."),
)),
('network', sect.KeyValue(

View File

@ -142,7 +142,7 @@ class TabbedBrowser(TabWidget):
tab.loadStarted.connect(self._filter.create(self.cur_load_started))
tab.statusBarMessage.connect(
self._filter.create(self.cur_statusbar_message))
tab.scroll_pos_changed.connect(
tab.scroll_perc_changed.connect(
self._filter.create(self.cur_scroll_perc_changed))
tab.url_text_changed.connect(
self._filter.create(self.cur_url_text_changed))

View File

@ -50,4 +50,4 @@ class Percentage(TextBase):
def on_tab_changed(self, idx):
"""Update scroll position when tab changed."""
tab = self.sender().widget(idx)
self.set_perc(*tab.scroll_pos)
self.set_perc(*tab.scroll_perc)

View File

@ -54,14 +54,14 @@ class WebView(QWebView):
We need this rather than signals to make createWindow
work.
progress: loading progress of this page.
scroll_pos: The current scroll position as (x%, y%) tuple.
scroll_perc: The current scroll position as (x%, y%) tuple.
_url_text: The current URL as string.
Accessed via url_text property.
_load_status: loading status of this page (index into LoadStatus)
Accessed via load_status property.
_has_ssl_errors: Whether SSL errors occured during loading.
_zoom: A NeighborList with the zoom levels.
_old_scroll_pos: The old scroll position.
_old_scroll_perc: The old scroll position.
_shutdown_callback: Callback to be called after shutdown.
_open_target: Where to open the next tab ("normal", "tab", "bgtab")
_force_open_target: Override for _open_target.
@ -69,7 +69,7 @@ class WebView(QWebView):
_destroyed: Dict of all items to be destroyed on shtudown.
Signals:
scroll_pos_changed: Scroll percentage of current tab changed.
scroll_perc_changed: Scroll percentage of current tab changed.
arg 1: x-position in %.
arg 2: y-position in %.
linkHovered: QWebPages linkHovered signal exposed.
@ -77,7 +77,7 @@ class WebView(QWebView):
url_text_changed: Current URL string changed.
"""
scroll_pos_changed = pyqtSignal(int, int)
scroll_perc_changed = pyqtSignal(int, int)
linkHovered = pyqtSignal(str, str, str)
load_status_changed = pyqtSignal(str)
url_text_changed = pyqtSignal(str)
@ -86,8 +86,8 @@ class WebView(QWebView):
super().__init__(parent)
self._load_status = LoadStatus.none
self.tabbedbrowser = parent
self.scroll_pos = (-1, -1)
self._old_scroll_pos = (-1, -1)
self.scroll_perc = (-1, -1)
self._old_scroll_perc = (-1, -1)
self._shutdown_callback = None
self._open_target = Target.normal
self._force_open_target = None
@ -111,7 +111,10 @@ class WebView(QWebView):
self.loadProgress.connect(lambda p: setattr(self, 'progress', p))
self.page_.networkAccessManager().sslErrors.connect(
lambda *args: setattr(self, '_has_ssl_errors', True))
# FIXME find some way to hide scrollbars without setScrollBarPolicy
self.page_.mainFrame().setScrollBarPolicy(
Qt.Horizontal, config.get('general', 'show-scroll-bar-horizontal'))
self.page_.mainFrame().setScrollBarPolicy(
Qt.Vertical, config.get('general', 'show-scroll-bar-vertical'))
def __repr__(self):
return "WebView(url='{}')".format(
@ -386,8 +389,17 @@ class WebView(QWebView):
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update tab config when config was changed."""
if section == 'general' and option in ['zoom-levels', 'default-zoom']:
self._init_neighborlist()
if section == 'general':
if option in ['zoom-levels', 'default-zoom']:
self._init_neighborlist()
elif option == 'show-scroll-bar-horizontal':
self.page_.mainFrame().setScrollBarPolicy(
Qt.Horizontal,
config.get('general', 'show-scroll-bar-horizontal'))
elif option == 'show-scroll-bar-vertical':
self.page_.mainFrame().setScrollBarPolicy(
Qt.Vertical,
config.get('general', 'show-scroll-bar-vertical'))
@pyqtSlot('QMouseEvent')
def on_mouse_event(self, evt):
@ -475,23 +487,21 @@ class WebView(QWebView):
e: The QPaintEvent.
Emit:
scroll_pos_changed; If the scroll position changed.
scroll_perc_changed; If the scroll position changed.
Return:
The superclass event return value.
"""
frame = self.page_.mainFrame()
new_pos = (frame.scrollBarValue(Qt.Horizontal),
frame.scrollBarValue(Qt.Vertical))
if self._old_scroll_pos != new_pos:
self._old_scroll_pos = new_pos
logging.debug("Updating scroll position")
m = (frame.scrollBarMaximum(Qt.Horizontal),
frame.scrollBarMaximum(Qt.Vertical))
perc = (round(100 * new_pos[0] / m[0]) if m[0] != 0 else 0,
round(100 * new_pos[1] / m[1]) if m[1] != 0 else 0)
self.scroll_pos = perc
self.scroll_pos_changed.emit(*perc)
new_pos = frame.scrollPosition()
if self._old_scroll_perc != new_pos:
self._old_scroll_perc = new_pos
max_x = frame.contentsSize().width() - frame.geometry().width()
max_y = frame.contentsSize().height() - frame.geometry().height()
perc = (round(100 * new_pos.x() / max_x) if max_x != 0 else 0,
round(100 * new_pos.y() / max_y) if max_y != 0 else 0)
self.scroll_perc = perc
self.scroll_perc_changed.emit(*perc)
# Let superclass handle the event
return super().paintEvent(e)