From b7a5dea0a0ebd4fb5cc3782a64881df48c763714 Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Mon, 23 Dec 2024 23:35:51 -0500 Subject: [PATCH] Fix Term Widget not registering pointer events (#1614) This is a bit janky. The problem is that we were placing the `xterm-viewport` div, which contains the scroll observer for the xterm contents, at a higher z-index than the xterm contents, meaning that the contents couldn't register any pointer events. If we don't put a z-index, though, the scroll bar can't accept pointer events. To get around this, I've added two observer divs, which control whether the contents or the viewport have pointer event priority. The first div, the `term-scrollbar-show-observer`, sits above where the scrollbar will be rendered. When the user hovers over it, it will cause the viewport div to move to a z-index above the contents. It will also enable a second div, the `term-scrollbar-hide-observer`, which sits above the viewport and the term contents, but not blocking the scrollbar. When the user hovers over this div (indicating their mouse has left the scrollbar), the viewport div is moved back to its original z-index and the hide observer is set to `display: none`. This gives pointer event priority back to the contents div. This resolves an issue where the user could not click links in the terminal output. Resolves #1357 --- frontend/app/view/term/term.scss | 53 +++++++++++++++++++++----------- frontend/app/view/term/term.tsx | 23 ++++++++++++-- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/frontend/app/view/term/term.scss b/frontend/app/view/term/term.scss index 7006a7728..81d9688f0 100644 --- a/frontend/app/view/term/term.scss +++ b/frontend/app/view/term/term.scss @@ -36,23 +36,23 @@ overflow: hidden; } - .term-cmd-toolbar { - display: flex; - flex-direction: row; - height: 24px; - border-bottom: 1px solid var(--border-color); - overflow: hidden; - align-items: center; + .term-cmd-toolbar { + display: flex; + flex-direction: row; + height: 24px; + border-bottom: 1px solid var(--border-color); + overflow: hidden; + align-items: center; - .term-cmd-toolbar-text { - font: var(--fixed-font); - flex-grow: 1; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - padding: 0 5px; - } - } + .term-cmd-toolbar-text { + font: var(--fixed-font); + flex-grow: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: 0 5px; + } + } .term-connectelem { flex-grow: 1; @@ -126,10 +126,27 @@ } } + .term-scrollbar-show-observer { + z-index: calc(var(--zindex-xterm-viewport-overlay) - 1); + position: absolute; + top: 0; + right: 0; + height: 100%; + width: 12px; + } + + .term-scrollbar-hide-observer { + z-index: calc(var(--zindex-xterm-viewport-overlay) + 1); + display: none; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: calc(100% - 12px); + } + .terminal { .xterm-viewport { - z-index: var(--zindex-xterm-viewport-overlay); - &::-webkit-scrollbar { width: 6px; height: 6px; diff --git a/frontend/app/view/term/term.tsx b/frontend/app/view/term/term.tsx index d6ad8eec9..4ab7996d7 100644 --- a/frontend/app/view/term/term.tsx +++ b/frontend/app/view/term/term.tsx @@ -848,7 +848,19 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => { termModeRef.current = termMode; }, [termMode]); - let stickerConfig = { + const scrollbarHideObserverRef = React.useRef(null); + const onScrollbarShowObserver = React.useCallback(() => { + const termViewport = viewRef.current.getElementsByClassName("xterm-viewport")[0] as HTMLDivElement; + termViewport.style.zIndex = "var(--zindex-xterm-viewport-overlay)"; + scrollbarHideObserverRef.current.style.display = "block"; + }, []); + const onScrollbarHideObserver = React.useCallback(() => { + const termViewport = viewRef.current.getElementsByClassName("xterm-viewport")[0] as HTMLDivElement; + termViewport.style.zIndex = "auto"; + scrollbarHideObserverRef.current.style.display = "none"; + }, []); + + const stickerConfig = { charWidth: 8, charHeight: 16, rows: model.termRef.current?.terminal.rows ?? 24, @@ -862,7 +874,14 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => { -
+
+
+
+
); };