From d3619e7acdb01e6f3841336b737ec90051905ca0 Mon Sep 17 00:00:00 2001 From: John Factotum <50942278+johnfactotum@users.noreply.github.com> Date: Sat, 27 May 2023 02:30:36 +0800 Subject: [PATCH] Make touchscreen/touchpad gesture 1-to-1 For the reflowable renderer only. This breaks gestures for fixed-layout. Fixes #862 --- src/book-viewer.js | 33 ++++++++++++++------------------- src/foliate-js | 2 +- src/reader/reader.js | 9 +++++++++ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/book-viewer.js b/src/book-viewer.js index a8dc17de..6a3e294c 100644 --- a/src/book-viewer.js +++ b/src/book-viewer.js @@ -253,7 +253,8 @@ GObject.registerClass({ .catch(e => console.error(e)), })) - // handle scroll and swipe events + // handle scroll events + let isDiscrete = true, dxLast, dyLast const scrollPageAsync = utils.debounce((dx, dy) => { if (Math.abs(dx) > Math.abs(dy)) { if (dx > 0) return this.goRight() @@ -266,30 +267,24 @@ GObject.registerClass({ this.#webView.add_controller(utils.connect(new Gtk.EventControllerScroll({ flags: Gtk.EventControllerScrollFlags.BOTH_AXES, }), { + 'scroll-begin': () => isDiscrete = false, 'scroll': (_, dx, dy) => { if (this.#pinchFactor > 1) return false if (this.viewSettings.scrolled) return false - scrollPageAsync(dx, dy) - return true - }, - })) - this.add_controller(utils.connect(new Gtk.GestureSwipe({ - propagation_phase: Gtk.PropagationPhase.CAPTURE, - touch_only: true, - }), { - 'swipe': (_, vx, vy) => { - if (this.#pinchFactor > 1) return false - if (Math.max(Math.abs(vx), Math.abs(vy)) < 200) return false - if (this.viewSettings.scrolled) return false - if (Math.abs(vx) > Math.abs(vy)) { - if (vx > 0) return this.goLeft() - else if (vx < 0) return this.goRight() - } else { - if (vy > 0) return this.prev() - else if (vy < 0) return this.next() + if (isDiscrete) scrollPageAsync(dx, dy) + else { + dxLast = dx + dyLast = dy + this.#exec('reader.scrollBy', [dx, dy]) } return true }, + 'scroll-end': () => { + if (dxLast != null) this.#exec('reader.snap', [dxLast, dyLast]) + isDiscrete = false + dxLast = null + dyLast = null + }, })) const applyStyle = () => this.#applyStyle().catch(e => console.error(e)) diff --git a/src/foliate-js b/src/foliate-js index a9681ee7..abcd87ed 160000 --- a/src/foliate-js +++ b/src/foliate-js @@ -1 +1 @@ -Subproject commit a9681ee7eb52e6c7ab665bf7cb3a892d524f3c4e +Subproject commit abcd87ed9a9c45033bbb36170a3fda524751f3e5 diff --git a/src/reader/reader.js b/src/reader/reader.js index 513d394d..0c37f9e3 100644 --- a/src/reader/reader.js +++ b/src/reader/reader.js @@ -351,6 +351,15 @@ class Reader { return null } } + + // wrap these renderer methods + // because `FoliateWebView.exec()` can only pass one argument + scrollBy([x, y]) { + return this.view.renderer.scrollBy?.(x, y) + } + snap([x, y]) { + return this.view.renderer.snap?.(x, y) + } } globalThis.init = () => document.getElementById('file-input').click()