summaryrefslogtreecommitdiff
path: root/src/web
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-15 12:43:53 -0300
committerGabriel Schneider <[email protected]>2026-09-15 17:24:42 -0300
commitc787d59a987ec601cd7b65399543afe6d37a615d (patch)
treeb593436d7aa4c37cb0e59eef5412dbb77ae5faad /src/web
parent8b0bed0427064794725f95cb7b020d7d96956975 (diff)
downloadpardes-c787d59a987ec601cd7b65399543afe6d37a615d.tar.gz
pardes-c787d59a987ec601cd7b65399543afe6d37a615d.zip
Route mouse thumb buttons to jump history
Diffstat (limited to 'src/web')
-rw-r--r--src/web/app.mjs27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/web/app.mjs b/src/web/app.mjs
index fcb9c23d..be61de89 100644
--- a/src/web/app.mjs
+++ b/src/web/app.mjs
@@ -7,7 +7,7 @@ const DEFAULT_BG = "#121212";
const decoder = new TextDecoder();
const encoder = new TextEncoder();
-const BUTTON = Object.freeze({ left: 0, middle: 1, right: 2, wheelUp: 3, wheelDown: 4, wheelLeft: 5, wheelRight: 6, none: 7 });
+const BUTTON = Object.freeze({ left: 0, middle: 1, right: 2, wheelUp: 3, wheelDown: 4, wheelLeft: 5, wheelRight: 6, none: 7, back: 8, forward: 9 });
const MOUSE = Object.freeze({ press: 0, release: 1, motion: 2, drag: 3 });
const SPECIAL_KEYS = Object.freeze({
Enter: 0x0d,
@@ -214,11 +214,22 @@ export class PardesRuntime {
return { x: rect.left + (col + 0.5) * this.cellWidth, y: rect.top + (row + 0.5) * this.cellHeight };
}
- pointerDown(event) {
+ mouseDown(event) {
event.preventDefault();
+ if (event.button !== 3 && event.button !== 4) return;
+ this.root.focus({ preventScroll: true });
+ const point = this.point(event);
+ this.wasm.pardes_mouse(pointerButton(event.button), MOUSE.press, point.col, point.row, modifiers(event));
+ }
+
+ pointerDown(event) {
+ // Mouse defaults are cancelled by mousedown. Cancelling pointerdown
+ // would suppress that stream, including thumb presses while left is held.
+ if (event.button === 3 || event.button === 4) return;
+ if (event.pointerType === "touch") event.preventDefault();
this.root.focus({ preventScroll: true });
- this.root.setPointerCapture?.(event.pointerId);
const point = this.point(event);
+ this.root.setPointerCapture?.(event.pointerId);
if (event.pointerType === "touch") {
const packed = this.wasm.pardes_chrome_target(point.col, point.row) >>> 0;
const chrome = packed !== 0xffffffff;
@@ -233,6 +244,7 @@ export class PardesRuntime {
}
pointerMove(event) {
+ if (event.button === 3 || event.button === 4) return;
const point = this.point(event);
const active = this.pointer?.id === event.pointerId ? this.pointer : null;
if (!active) {
@@ -268,6 +280,10 @@ export class PardesRuntime {
}
pointerUp(event) {
+ if (event.button === 3 || event.button === 4) {
+ event.preventDefault();
+ return;
+ }
const active = this.pointer?.id === event.pointerId ? this.pointer : null;
if (!active) return;
event.preventDefault();
@@ -303,6 +319,9 @@ export class PardesRuntime {
this.root.addEventListener("keydown", (event) => this.key(event));
this.root.addEventListener("paste", (event) => this.paste(event));
this.root.addEventListener("contextmenu", (event) => event.preventDefault());
+ this.root.addEventListener("auxclick", (event) => event.preventDefault());
+ // Mouse events retain additional button presses while another button is held.
+ this.root.addEventListener("mousedown", (event) => this.mouseDown(event));
this.root.addEventListener("pointerdown", (event) => this.pointerDown(event));
this.root.addEventListener("pointermove", (event) => this.pointerMove(event));
this.root.addEventListener("pointerup", (event) => this.pointerUp(event));
@@ -453,7 +472,7 @@ function modifiers(event) {
}
function pointerButton(button) {
- return button === 1 ? BUTTON.middle : button === 2 ? BUTTON.right : BUTTON.left;
+ return button === 1 ? BUTTON.middle : button === 2 ? BUTTON.right : button === 3 ? BUTTON.back : button === 4 ? BUTTON.forward : BUTTON.left;
}
function clamp(value, low, high) {