forked from Mirrors/apostrophe
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
parent
16382d9574
commit
c5abc531e0
|
@ -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
|
||||||
|
if not self.state_discard_result:
|
||||||
result = self.run_javascript_finish(result)
|
result = self.run_javascript_finish(result)
|
||||||
self.state_loop(result.get_js_value().to_double())
|
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
|
||||||
|
|
Loading…
Reference in New Issue