Файли
openidea/src/platform/pageSwipe.ts
T
Jaw 053a2c37d8 feat(macos): navigate editor history with trackpad swipes (#1934)
Closes #1836. AppKit reports page swipes (three-finger NSEventTypeSwipe and two-finger page swipes) outside the web view's key/mouse events, so the desktop shell now forwards them as SwipeLeft / SwipeRight keymap strokes that can be recorded and remapped. Every macOS preset (IntelliJ, Eclipse, VS Code) binds SwipeRight to Back and SwipeLeft to Forward; two-finger swipes over horizontally scrollable content still scroll, and turning off the system page-swipe gesture disables navigation.

Co-authored-by: jaw52 <[email protected]>
2026-11-08 01:16:31 +08:00

39 рядки
1.7 KiB
TypeScript

import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { isTauri } from "./ipc";
import { nativeDropPoint } from "./nativeDrop";
export type PageSwipe = "SwipeLeft" | "SwipeRight";
export const PAGE_SWIPE_EVENT = "ide:page-swipe";
export function isPageSwipe(stroke: unknown): stroke is PageSwipe {
return stroke === "SwipeLeft" || stroke === "SwipeRight";
}
/** Preserve a whole scroll gesture inside wide content, even when it starts at an edge. */
export function ownsHorizontalScroll(element: Element | null): boolean {
for (let el = element; el; el = el.parentElement) {
// Terminal applications consume wheel events themselves (including alternate-screen apps).
if (el.classList.contains("xterm") || el.hasAttribute("data-wheel-scroll")) return true;
const overflow = getComputedStyle(el).overflowX;
if (el.scrollWidth > el.clientWidth && /^(auto|scroll|overlay)$/.test(overflow)) return true;
}
return false;
}
export function installPageSwipeTracking(target: Window): () => void {
const candidate = (event: Event) => {
if (!isTauri()) return;
const { id, x, y } = (event as CustomEvent<{ id: number; x: number; y: number }>).detail;
const point = nativeDropPoint({ x, y });
const element = target.document.elementFromPoint(point.x, point.y);
if (!element || ownsHorizontalScroll(element)) return;
void getCurrentWebviewWindow().emitTo(
{ kind: "WebviewWindow", label: getCurrentWebviewWindow().label },
"ide://page-swipe-track",
id,
);
};
target.addEventListener("ide:page-swipe-candidate", candidate);
return () => target.removeEventListener("ide:page-swipe-candidate", candidate);
}