fix: 修复SSH终端还原布局溢出
- 约束xterm容器最小宽度并隐藏旧画布溢出 - 在布局绘制前同步终端与远端PTY尺寸
This commit is contained in:
1 parent
198139648d
commit
82b53c043b
1 file changed
+20
-8
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useRef, useEffect } from "react";
|
import { useState, useRef, useEffect, useLayoutEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -173,11 +173,12 @@ export function TerminalDialog({
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [open, serverId, authReady]);
|
}, [open, serverId, authReady]);
|
||||||
|
|
||||||
// 容器尺寸变化时 fit 并同步远端 PTY // Logan.Li
|
// 在浏览器绘制前完成 fit,避免最大化还原时短暂显示旧宽度画布。 // Logan.Li
|
||||||
useEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!open || !authReady) return;
|
if (!open || !authReady) return;
|
||||||
|
|
||||||
let cleanup: (() => void) | undefined;
|
let cleanup: (() => void) | undefined;
|
||||||
|
let fitFrame = 0;
|
||||||
let retry = 0;
|
let retry = 0;
|
||||||
|
|
||||||
const attach = () => {
|
const attach = () => {
|
||||||
@@ -190,15 +191,23 @@ export function TerminalDialog({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cleanup = attachTerminalResize(container, fit, term, ws);
|
cleanup = attachTerminalResize(container, fit, term, ws);
|
||||||
|
const applyFit = () => {
|
||||||
try {
|
try {
|
||||||
fitTerminal(fit, term, ws);
|
fitTerminal(fit, term, ws);
|
||||||
} catch {
|
} catch {
|
||||||
/* noop */
|
/* noop */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
applyFit();
|
||||||
|
// 下一帧再校准一次,兼容 Radix Dialog 全屏样式刚提交的场景。 // Logan.Li
|
||||||
|
fitFrame = requestAnimationFrame(applyFit);
|
||||||
|
};
|
||||||
|
|
||||||
attach();
|
attach();
|
||||||
return () => cleanup?.();
|
return () => {
|
||||||
|
if (fitFrame) cancelAnimationFrame(fitFrame);
|
||||||
|
cleanup?.();
|
||||||
|
};
|
||||||
}, [open, authReady, fullscreen]);
|
}, [open, authReady, fullscreen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -208,7 +217,7 @@ export function TerminalDialog({
|
|||||||
// 禁用 Radix Dialog 默认的 ESC 关闭:终端内 vi/top 等会用到 ESC,关闭只能点头部 X 按钮 // Logan.Li
|
// 禁用 Radix Dialog 默认的 ESC 关闭:终端内 vi/top 等会用到 ESC,关闭只能点头部 X 按钮 // Logan.Li
|
||||||
onEscapeKeyDown={(e) => e.preventDefault()}
|
onEscapeKeyDown={(e) => e.preventDefault()}
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-[var(--dg-bg-secondary)] border-[var(--dg-border)] p-0 gap-0",
|
"min-w-0 overflow-hidden bg-[var(--dg-bg-secondary)] border-[var(--dg-border)] p-0 gap-0",
|
||||||
// 禁用 CSS 过渡:终端窗口应该即时缩放,不需要动画
|
// 禁用 CSS 过渡:终端窗口应该即时缩放,不需要动画
|
||||||
"!duration-0 !transition-none",
|
"!duration-0 !transition-none",
|
||||||
fullscreen
|
fullscreen
|
||||||
@@ -239,7 +248,7 @@ export function TerminalDialog({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<button
|
<button
|
||||||
onClick={() => setFullscreen(!fullscreen)}
|
onClick={() => setFullscreen((current) => !current)}
|
||||||
className="p-1.5 rounded hover:bg-[var(--dg-bg-hover)] text-[var(--dg-text-secondary)]"
|
className="p-1.5 rounded hover:bg-[var(--dg-bg-hover)] text-[var(--dg-text-secondary)]"
|
||||||
>
|
>
|
||||||
{fullscreen ? (
|
{fullscreen ? (
|
||||||
@@ -301,10 +310,13 @@ export function TerminalDialog({
|
|||||||
{/* 终端容器 */}
|
{/* 终端容器 */}
|
||||||
{authReady && (
|
{authReady && (
|
||||||
<div
|
<div
|
||||||
className="relative bg-[#0a0e14]"
|
className="relative min-w-0 overflow-hidden bg-[#0a0e14]"
|
||||||
style={{ height: fullscreen ? "calc(100vh - 49px)" : "520px" }}
|
style={{ height: fullscreen ? "calc(100vh - 49px)" : "520px" }}
|
||||||
>
|
>
|
||||||
<div ref={containerRef} className="xterm-terminal-host h-full" />
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
className="xterm-terminal-host h-full min-w-0"
|
||||||
|
/>
|
||||||
<SessionWatermark className="opacity-60" />
|
<SessionWatermark className="opacity-60" />
|
||||||
<TerminalLoadingOverlay
|
<TerminalLoadingOverlay
|
||||||
show={!hasOutput}
|
show={!hasOutput}
|
||||||
|
|||||||
Reference in new issue
Block a user