Fix scrolling glitch during preview

Typing while in preview mode would occasionally lead to a scrolling
glitch, where scroll would briefly be at 0, before jumping to the
location it was supposed to be in in the first case.

This happened due to the async nature of JS calls, in the following
scenario:
1. Load
2. Read started
3. Read finished
4. Read started
5. Load
6. Read finished

The results from op 4 would be invalid due to loading in-between, and
handling the result in 6 would set the wrong scroll value.

This change ensures results are discarded whenever we are waiting for
them and a new load starts.
github/fork/yochananmarqos/patch-1
Gonçalo Silva 2019-05-08 04:11:35 +01:00
parent 16382d9574
commit c5abc531e0
1 changed files with 10 additions and 4 deletions

View File

@ -42,6 +42,7 @@ e.scrollTop = (e.scrollHeight - e.clientHeight) * scale;
self.state_loaded = False self.state_loaded = False
self.state_load_failed = False self.state_load_failed = False
self.state_discard_result = False
self.state_waiting = False self.state_waiting = False
self.timeout_id = None self.timeout_id = None
@ -56,6 +57,7 @@ e.scrollTop = (e.scrollHeight - e.clientHeight) * scale;
def on_load_changed(self, _web_view, event): def on_load_changed(self, _web_view, event):
self.state_loaded = event >= WebKit2.LoadEvent.COMMITTED and not self.state_load_failed self.state_loaded = event >= WebKit2.LoadEvent.COMMITTED and not self.state_load_failed
self.state_load_failed = False self.state_load_failed = False
self.state_discard_result = event == WebKit2.LoadEvent.STARTED and self.state_waiting
self.pending_scroll_scale = self.scroll_scale self.pending_scroll_scale = self.scroll_scale
self.state_loop() self.state_loop()
@ -74,16 +76,20 @@ e.scrollTop = (e.scrollHeight - e.clientHeight) * scale;
def read_scroll_scale(self): def read_scroll_scale(self):
self.state_waiting = True self.state_waiting = True
self.run_javascript( self.run_javascript(
self.GET_SCROLL_SCALE_JS, None, self.sync_scroll_scale) self.GET_SCROLL_SCALE_JS, None, self.finish_read_scroll_scale)
def write_scroll_scale(self, scroll_scale): def write_scroll_scale(self, scroll_scale):
self.run_javascript( self.run_javascript(
self.SET_SCROLL_SCALE_JS.format(scroll_scale), None, None) self.SET_SCROLL_SCALE_JS.format(scroll_scale), None, None)
def sync_scroll_scale(self, _web_view, result): def finish_read_scroll_scale(self, _web_view, result):
self.state_waiting = False self.state_waiting = False
result = self.run_javascript_finish(result) if not self.state_discard_result:
self.state_loop(result.get_js_value().to_double()) result = self.run_javascript_finish(result)
self.state_loop(result.get_js_value().to_double())
else:
self.state_discard_result = False
self.state_loop()
def state_loop(self, scroll_scale=None, delay=16): # 16ms ~ 60hz def state_loop(self, scroll_scale=None, delay=16): # 16ms ~ 60hz
# Remove any pending callbacks # Remove any pending callbacks