From fe7a8db2314dc24b1051e40e4a18408bb6810342 Mon Sep 17 00:00:00 2001 From: RumovZ Date: Tue, 18 Jan 2022 10:12:57 +0100 Subject: [PATCH] Selectively disable zoom (#1602) * Make webview zoom optional Also suppress mouse wheel zooming. * Disable zoom for top and bottom bars in main view * Factor in macos zoom by scrolling and refactor --- qt/aqt/main.py | 2 ++ qt/aqt/utils.py | 20 ++++++++++++++++++++ qt/aqt/webview.py | 14 +++++++++----- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/qt/aqt/main.py b/qt/aqt/main.py index 9abfebb72..184e028cd 100644 --- a/qt/aqt/main.py +++ b/qt/aqt/main.py @@ -869,12 +869,14 @@ title="{}" {}>{}""".format( # toolbar tweb = self.toolbarWeb = AnkiWebView(title="top toolbar") tweb.setFocusPolicy(Qt.FocusPolicy.WheelFocus) + tweb.disable_zoom() self.toolbar = aqt.toolbar.Toolbar(self, tweb) # main area self.web = MainWebView(self) # bottom area sweb = self.bottomWeb = AnkiWebView(title="bottom toolbar") sweb.setFocusPolicy(Qt.FocusPolicy.WheelFocus) + sweb.disable_zoom() # add in a layout self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) diff --git a/qt/aqt/utils.py b/qt/aqt/utils.py index 409177b8c..356963313 100644 --- a/qt/aqt/utils.py +++ b/qt/aqt/utils.py @@ -1002,6 +1002,22 @@ def no_arg_trigger(func: Callable) -> Callable: return pyqtSlot()(func) # type: ignore +def is_zoom_event(evt: QEvent) -> bool: + """If the event will trigger zoom. + + Includes zoom by pinching, Ctrl-scrolling, and Meta-scrolling, + where scrolling may be triggered by mouse wheel or gesture. + """ + + return isinstance(evt, QNativeGestureEvent) or ( + isinstance(evt, QWheelEvent) + and ( + (is_mac and KeyboardModifiersPressed().meta) + or KeyboardModifiersPressed().control + ) + ) + + class KeyboardModifiersPressed: "Util for type-safe checks of currently-pressed modifier keys." @@ -1022,6 +1038,10 @@ class KeyboardModifiersPressed: def alt(self) -> bool: return bool(self._modifiers & Qt.KeyboardModifier.AltModifier) + @property + def meta(self) -> bool: + return bool(self._modifiers & Qt.KeyboardModifier.MetaModifier) + # add-ons attempting to import isMac from this module :-( _deprecated_names = DeprecatedNamesMixinForModule(globals()) diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py index 0130caafd..12e73f25b 100644 --- a/qt/aqt/webview.py +++ b/qt/aqt/webview.py @@ -13,7 +13,7 @@ from anki.utils import is_lin, is_mac, is_win from aqt import colors, gui_hooks from aqt.qt import * from aqt.theme import theme_manager -from aqt.utils import askUser, openLink, showInfo, tr +from aqt.utils import askUser, is_zoom_event, openLink, showInfo, tr serverbaseurl = re.compile(r"^.+:\/\/[^\/]+") @@ -241,6 +241,7 @@ class AnkiWebView(QWebEngineView): self._pendingActions: list[tuple[str, Sequence[Any]]] = [] self.requiresCol = True self.setPage(self._page) + self._disable_zoom = False self.resetHandlers() self._filterSet = False @@ -255,18 +256,21 @@ class AnkiWebView(QWebEngineView): def set_title(self, title: str) -> None: self.title = title # type: ignore[assignment] + def disable_zoom(self) -> None: + self._disable_zoom = True + def eventFilter(self, obj: QObject, evt: QEvent) -> bool: - # disable pinch to zoom gesture - if isinstance(evt, QNativeGestureEvent): + if self._disable_zoom and is_zoom_event(evt): return True - elif ( + + if ( isinstance(evt, QMouseEvent) and evt.type() == QEvent.Type.MouseButtonRelease ): if evt.button() == Qt.MouseButton.MiddleButton and is_lin: self.onMiddleClickPaste() return True - return False + return False def set_open_links_externally(self, enable: bool) -> None: