From 621839dc17af93ac7906d8816883c504c9ade8c2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 21 Jan 2014 08:37:21 +0100 Subject: [PATCH] First attempt at a scrolling indicator --- qutebrowser/widgets/browser.py | 36 ++++++++++++++++++++++++++++++- qutebrowser/widgets/mainwindow.py | 1 + qutebrowser/widgets/statusbar.py | 7 ++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/qutebrowser/widgets/browser.py b/qutebrowser/widgets/browser.py index e87303b29..bc67d17ee 100644 --- a/qutebrowser/widgets/browser.py +++ b/qutebrowser/widgets/browser.py @@ -1,6 +1,6 @@ import logging -from PyQt5.QtCore import QUrl, pyqtSignal, Qt, QPoint +from PyQt5.QtCore import QUrl, pyqtSignal, Qt, QPoint, QEvent from PyQt5.QtPrintSupport import QPrintPreviewDialog from PyQt5.QtWebKitWidgets import QWebView @@ -11,6 +11,8 @@ class TabbedBrowser(TabWidget): cur_progress = pyqtSignal(int) # Progress of the current tab changed cur_load_finished = pyqtSignal(bool) # Current tab finished loading + # Current tab changed scroll position + cur_scroll_perc_changed = pyqtSignal(int, int) keypress = pyqtSignal('QKeyEvent') _url_stack = [] # Stack of URLs of closed tabs @@ -30,6 +32,7 @@ class TabbedBrowser(TabWidget): lambda *args: self._filter_signals(self.cur_progress, *args)) tab.loadFinished.connect( lambda *args: self._filter_signals(self.cur_load_finished, *args)) + tab.scroll_pos_changed.connect(self._scroll_pos_changed_handler) # FIXME should we really bind this to loadStarted? Sometimes the URL # isn't set correctly at this point, e.g. when doing # setContent(..., baseUrl=QUrl('foo')) @@ -166,9 +169,24 @@ class TabbedBrowser(TabWidget): tab = self.widget(idx) self.cur_progress.emit(tab.progress) + def _scroll_pos_changed_handler(self, point): + """Gets a QPoint() of the new position from a BrowserTab. If it's the + current tab, it calculates the percentage and emits + cur_scroll_perc_changed. + """ + sender = self.sender() + if sender != self.currentWidget(): + return + size = sender.page().mainFrame().contentsSize() + perc_x = 100 / size.width() * point.x() + perc_y = 100 / size.height() * point.y() + self.cur_scroll_perc_changed.emit(perc_x, perc_y) + class BrowserTab(QWebView): """One browser tab in TabbedBrowser""" progress = 0 + scroll_pos_changed = pyqtSignal('QPoint') + _scroll_pos = QPoint(-1, -1) def __init__(self, parent): super().__init__(parent) @@ -176,6 +194,7 @@ class BrowserTab(QWebView): frame.setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) frame.setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) self.loadProgress.connect(self.set_progress) + self.installEventFilter(self) self.show() def openurl(self, url): @@ -186,3 +205,18 @@ class BrowserTab(QWebView): def set_progress(self, prog): self.progress = prog + + def eventFilter(self, watched, e): + """Dirty hack to emit a signal if the scroll position changed. + + We listen to repaint requests here, in the hope a repaint will always + be requested when scrolling, and if the scroll position actually + changed, we emit a signal. + """ + if watched == self and e.type() == QEvent.Paint: + new_pos = self.page().mainFrame().scrollPosition() + if self._scroll_pos != new_pos: + logging.debug("Updating scroll position") + self.scroll_pos_changed.emit(new_pos) + self._scroll_pos = new_pos + return super().eventFilter(watched, e) diff --git a/qutebrowser/widgets/mainwindow.py b/qutebrowser/widgets/mainwindow.py index bde609745..6477d007e 100644 --- a/qutebrowser/widgets/mainwindow.py +++ b/qutebrowser/widgets/mainwindow.py @@ -26,6 +26,7 @@ class MainWindow(QMainWindow): self.tabs.cur_progress.connect(self.status.prog.set_progress) self.tabs.cur_load_finished.connect(self.status.prog.load_finished) + self.tabs.cur_scroll_perc_changed.connect(self.status.txt.set_perc) self.status.cmd.esc_pressed.connect(self.tabs.setFocus) #self.retranslateUi(MainWindow) diff --git a/qutebrowser/widgets/statusbar.py b/qutebrowser/widgets/statusbar.py index de77c08d2..3e6a3d54e 100644 --- a/qutebrowser/widgets/statusbar.py +++ b/qutebrowser/widgets/statusbar.py @@ -116,6 +116,13 @@ class StatusText(QLabel): """Setter to be used as a Qt slot""" self.keystring = s + def set_perc(self, x, y): + """Setter to be used as a Qt slot""" + if y == 0: + self.scrollperc = '[top]' + else: + self.scrollperc = '[{}%]'.format(y) + def update(self): """Update the text displayed""" self.setText(' '.join([self.keystring, self.error, self.text,