Skip to content

Commit

Permalink
Improve gesture behavior for panning, zooming
Browse files Browse the repository at this point in the history
  • Loading branch information
ekzhang committed Jul 16, 2023
1 parent 1f37fd9 commit 8d901c1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 15 deletions.
7 changes: 5 additions & 2 deletions src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"
/>

<title>sshx</title>
<meta property="og:title" content="sshx · share collaborative terminals" />
Expand All @@ -23,7 +26,7 @@

%sveltekit.head%
</head>
<body class="dark:bg-[#111] dark:text-white">
<body class="dark:bg-[#111111] dark:text-white">
<div>%sveltekit.body%</div>
</body>
</html>
7 changes: 6 additions & 1 deletion src/lib/Session.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,12 @@
}, 20);
</script>

<main class="p-8" class:cursor-nwse-resize={resizing !== -1}>
<!-- Wheel handler stops native macOS Chrome zooming on pinch. -->
<main
class="p-8"
class:cursor-nwse-resize={resizing !== -1}
on:wheel={(event) => event.preventDefault()}
>
<div
class="absolute top-8 left-1/2 -translate-x-1/2 pointer-events-none z-10"
>
Expand Down
58 changes: 46 additions & 12 deletions src/lib/ui/XTerm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,27 @@
let term: Terminal | null = null;
let loaded = false;
let focused = false;
let currentTitle = "Remote Terminal";
function handleWheelSkipXTerm(event: WheelEvent) {
event.preventDefault(); // Stop native macOS Chrome zooming on pinch.
event.stopPropagation();
termEl?.dispatchEvent(new WheelEvent(event.type, event));
}
function setFocused(isFocused: boolean, cursorLayer: HTMLDivElement) {
if (isFocused && !focused) {
focused = isFocused;
cursorLayer.removeEventListener("wheel", handleWheelSkipXTerm);
dispatch("focus");
} else if (!isFocused && focused) {
focused = isFocused;
cursorLayer.addEventListener("wheel", handleWheelSkipXTerm);
dispatch("blur");
}
}
const preloadBuffer: string[] = [];
write = (data: string) => {
Expand Down Expand Up @@ -131,23 +150,22 @@
currentTitle = title;
});
let currentlyFocused = false;
// Hack: We artificially disable scrolling when the terminal is not focused.
const cursorLayer = termEl.querySelector(
".xterm-cursor-layer",
)! as HTMLDivElement;
cursorLayer.addEventListener("wheel", handleWheelSkipXTerm);
const focusObserver = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (
mutation.type === "attributes" &&
mutation.attributeName === "class"
) {
// The "focus class is set directly by xterm.js, but there isn't any way to listen for it.
// The "focus" class is set directly by xterm.js, but there isn't any way to listen for it.
const target = mutation.target as HTMLElement;
const isFocused = target.classList.contains("focus");
if (isFocused && !currentlyFocused) {
currentlyFocused = isFocused;
dispatch("focus");
} else if (!isFocused && currentlyFocused) {
currentlyFocused = isFocused;
dispatch("blur");
}
setFocused(isFocused, cursorLayer);
}
}
});
Expand All @@ -171,7 +189,8 @@
</script>

<div
class="term-container opacity-95"
class="term-container"
class:focused
style:background={theme.background}
on:mousedown={() => dispatch("bringToFront")}
on:pointerdown={(event) => event.stopPropagation()}
Expand Down Expand Up @@ -202,12 +221,27 @@
class="inline-block px-4 py-2 transition-opacity duration-500"
bind:this={termEl}
style:opacity={loaded ? 1.0 : 0.0}
on:wheel={(event) => event.stopPropagation()}
on:wheel={(event) => {
if (focused) {
// Don't pan the page when scrolling while the terminal is selected.
// Conversely, we manually disable terminal scrolling unless it is currently selected.
event.stopPropagation();
}
}}
/>
</div>

<style lang="postcss">
.term-container {
@apply inline-block rounded-lg border border-gray-600 transition-transform duration-200;
@apply inline-block rounded-lg border border-zinc-700 opacity-90;
transition: transform 200ms, opacity 200ms;
}
.term-container:not(.focused) :global(.xterm) {
@apply cursor-default;
}
.term-container.focused {
@apply opacity-100;
}
</style>

0 comments on commit 8d901c1

Please sign in to comment.