Add 2D horizontal wheel scrolling support

- Handle both deltaX and deltaY from wheel events
- Convert horizontal wheel deltas to pixels based on deltaMode
- Apply horizontal scrolling using native scrollLeft when not in fit mode
- Support trackpad 2-finger horizontal swipes and mouse horizontal wheels
- Maintain same scaling and deltaMode handling for both axes
- Unify all scrolling inputs (touch, wheel vertical, wheel horizontal)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Mario Zechner 2025-06-18 04:40:14 +02:00
parent 13460ea4d4
commit 86123cabbd

View file

@ -333,36 +333,49 @@ export class Terminal extends LitElement {
private setupScrolling() { private setupScrolling() {
if (!this.container) return; if (!this.container) return;
// Handle wheel events with pixel-based scrolling // Handle wheel events with pixel-based scrolling (both vertical and horizontal)
this.container.addEventListener( this.container.addEventListener(
'wheel', 'wheel',
(e) => { (e) => {
e.preventDefault(); e.preventDefault();
const lineHeight = this.fontSize * 1.2; const lineHeight = this.fontSize * 1.2;
let deltaPixels = 0; let deltaPixelsY = 0;
let deltaPixelsX = 0;
// Convert wheel delta to pixels based on deltaMode // Convert wheel deltas to pixels based on deltaMode
switch (e.deltaMode) { switch (e.deltaMode) {
case WheelEvent.DOM_DELTA_PIXEL: case WheelEvent.DOM_DELTA_PIXEL:
// Already in pixels // Already in pixels
deltaPixels = e.deltaY; deltaPixelsY = e.deltaY;
deltaPixelsX = e.deltaX;
break; break;
case WheelEvent.DOM_DELTA_LINE: case WheelEvent.DOM_DELTA_LINE:
// Convert lines to pixels // Convert lines to pixels
deltaPixels = e.deltaY * lineHeight; deltaPixelsY = e.deltaY * lineHeight;
deltaPixelsX = e.deltaX * lineHeight;
break; break;
case WheelEvent.DOM_DELTA_PAGE: case WheelEvent.DOM_DELTA_PAGE:
// Convert pages to pixels (assume page = viewport height) // Convert pages to pixels (assume page = viewport height)
deltaPixels = e.deltaY * (this.actualRows * lineHeight); deltaPixelsY = e.deltaY * (this.actualRows * lineHeight);
deltaPixelsX = e.deltaX * (this.actualRows * lineHeight);
break; break;
} }
// Apply scaling for comfortable scrolling speed // Apply scaling for comfortable scrolling speed
const scrollScale = 0.5; const scrollScale = 0.5;
deltaPixels *= scrollScale; deltaPixelsY *= scrollScale;
deltaPixelsX *= scrollScale;
this.scrollViewportPixels(deltaPixels); // Apply vertical scrolling (our custom pixel-based)
if (Math.abs(deltaPixelsY) > 0) {
this.scrollViewportPixels(deltaPixelsY);
}
// Apply horizontal scrolling (native browser scrollLeft) - only if not in horizontal fit mode
if (Math.abs(deltaPixelsX) > 0 && !this.fitHorizontally) {
this.container.scrollLeft += deltaPixelsX;
}
}, },
{ passive: false } { passive: false }
); );