From 7adc8ab2d61c63bdcf6eba16fde90979c03725fe Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 15 Jul 2016 12:52:27 +0200 Subject: [PATCH] QtWebEngine: Implement scroll position based on JS --- qutebrowser/browser/browsertab.py | 5 ++- qutebrowser/browser/webengine/webenginetab.py | 42 ++++++++++++------- qutebrowser/javascript/scroll.js | 25 +++++++++++ 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 30979d255..fa91bc37f 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -354,6 +354,9 @@ class AbstractScroller(QObject): self._tab = tab self._widget = None + def _init_widget(self, widget): + self._widget = widget + def pos_px(self): raise NotImplementedError @@ -513,7 +516,7 @@ class AbstractTab(QWidget): self._layout = WrapperLayout(widget, self) self._widget = widget self.history._history = widget.history() - self.scroll._widget = widget + self.scroll._init_widget(widget) self.caret._widget = widget self.zoom._widget = widget self.search._widget = widget diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index a03ab24e4..322e72c25 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -182,6 +182,14 @@ class WebEngineScroller(browsertab.AbstractScroller): """QtWebEngine implementations related to scrolling.""" + def __init__(self, tab, parent=None): + super().__init__(tab, parent) + self._pos_perc = (None, None) + + def _init_widget(self, widget): + super()._init_widget(widget) + self._on_scroll_pos_changed() + def _key_press(self, key, count=1): # FIXME:qtwebengine Abort scrolling if the minimum/maximum was reached. press_evt = QKeyEvent(QEvent.KeyPress, key, Qt.NoModifier, 0, 0, 0) @@ -193,24 +201,25 @@ class WebEngineScroller(browsertab.AbstractScroller): QApplication.postEvent(recipient, press_evt) QApplication.postEvent(recipient, release_evt) + @pyqtSlot() + def _on_scroll_pos_changed(self): + def update_scroll_pos_perc(jsret): + assert len(jsret) == 2, jsret + self._pos_perc = jsret + self.perc_changed.emit(*jsret) + + js_code = """ + {scroll_js} + scroll_pos_perc(); + """.format(scroll_js=utils.read_file('javascript/scroll.js')) + self._tab.run_js_async(js_code, update_scroll_pos_perc) + def pos_px(self): log.stub() return QPoint(0, 0) def pos_perc(self): - page = self._widget.page() - try: - size = page.contentsSize() - pos = page.scrollPosition() - except AttributeError: - # Added in Qt 5.7 - log.stub('on Qt < 5.7') - return (None, None) - else: - # FIXME:qtwebengine is this correct? - perc_x = 100 / size.width() * pos.x() - perc_y = 100 / size.height() * pos.y() - return (perc_x, perc_y) + return self._pos_perc def to_perc(self, x=None, y=None): js_code = """ @@ -409,5 +418,8 @@ class WebEngineTab(browsertab.AbstractTab): view.iconChanged.connect(self.icon_changed) except AttributeError: log.stub('iconChanged, on Qt < 5.7') - # FIXME:qtwebengine stub this? - # view.scroll.pos_changed.connect(self.scroll.perc_changed) + try: + page.scrollPositionChanged.connect( + self.scroll._on_scroll_pos_changed) + except AttributeError: + log.stub('scrollPositionChanged, on Qt < 5.7') diff --git a/qutebrowser/javascript/scroll.js b/qutebrowser/javascript/scroll.js index 77076d1bb..b15edf3d4 100644 --- a/qutebrowser/javascript/scroll.js +++ b/qutebrowser/javascript/scroll.js @@ -38,3 +38,28 @@ function scroll_delta_page(x, y) { var dy = document.documentElement.clientHeight * y; window.scrollBy(dx, dy); } + +function scroll_pos_perc() { + var elem = document.documentElement; + var dx = (elem.scrollWidth - elem.clientWidth); + var dy = (elem.scrollHeight - elem.clientHeight); + + var perc_x, perc_y; + + if (dx === 0) { + perc_x = 0; + } else { + perc_x = 100 / dx * window.scrollX; + } + + if (dy === 0) { + perc_y = 0; + } else { + perc_y = 100 / dy * window.scrollY; + } + + // console.log(perc_x); + // console.log(perc_y); + + return [perc_x, perc_y]; +}