-
Notifications
You must be signed in to change notification settings - Fork 51
多窗口功能的一些优化和问题修复 #160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
多窗口功能的一些优化和问题修复 #160
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -57,8 +57,8 @@ async function handleCloseTab(id: string, event: Event) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ── Tab 拖拽分离检测 ──────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 鼠标超出窗口边界的阈值(px),避免微小越界误触发 */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const TEAR_OFF_THRESHOLD = 30; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 鼠标超出 Tab 栏边界的阈值(px),避免微小越界误触发 */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const TEAR_OFF_THRESHOLD = 20; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 拖拽期间的状态 */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let dragState: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -79,13 +79,34 @@ let dragState: { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| initialOffsetY: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 缓存的窗口边界 */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let cachedBounds: { x: number; y: number; width: number; height: number } | null = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 缓存的 Tab 栏屏幕边界(用于多 Tab 分离检测) */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let cachedTabBarBounds: { x: number; y: number; width: number; height: number } | null = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 判断屏幕坐标是否在窗口外 */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function isOutsideWindow(screenX: number, screenY: number): boolean { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!cachedBounds) return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { x, y, width, height } = cachedBounds; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 保存被隐藏的 ghost 元素引用,tear-off 结束后清理 */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let _ghostEl: HTMLElement | null = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 隐藏 SortableJS ghost 元素(Tab 脱离 Tab 栏时调用,类似 Chrome 标签拽出后消失) */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function hideGhost() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (_ghostEl) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const el = tabContainerRef.value?.querySelector(".ghost") as HTMLElement | null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (el) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _ghostEl = el; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| el.style.display = "none"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 恢复 SortableJS ghost 元素(取消 tear-off 时调用) */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function showGhost() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (_ghostEl) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _ghostEl.style.display = ""; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _ghostEl = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+98
to
+105
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** 恢复 SortableJS ghost 元素(取消 tear-off 时调用) */ | |
| function showGhost() { | |
| if (_ghostEl) { | |
| _ghostEl.style.display = ""; | |
| _ghostEl = null; | |
| } | |
| } | |
| /** 恢复 SortableJS ghost 元素(取消 tear-off 或拖拽结束时调用) */ | |
| function showGhost() { | |
| // 尝试恢复当前 DOM 中的 ghost 元素的 display,即使 _ghostEl 已被其他逻辑清空 | |
| const container = tabContainerRef.value; | |
| if (container) { | |
| const ghostEl = container.querySelector(".ghost") as HTMLElement | null; | |
| if (ghostEl && ghostEl.style.display === "none") { | |
| ghostEl.style.display = ""; | |
| } | |
| } | |
| // 同时处理通过 hideGhost() 缓存过的元素,确保其样式被恢复 | |
| if (_ghostEl) { | |
| _ghostEl.style.display = ""; | |
| _ghostEl = null; | |
| } | |
| } | |
| // 全局监听拖拽结束事件,确保无论 tear-off 是否成功,ghost 样式都会被恢复 | |
| const handleGlobalDragEnd = () => { | |
| showGhost(); | |
| }; | |
| onMounted(() => { | |
| window.addEventListener("dragend", handleGlobalDragEnd); | |
| }); | |
| onUnmounted(() => { | |
| window.removeEventListener("dragend", handleGlobalDragEnd); | |
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updateMergePreviewnow sendstab:merge-preview-updateevery time the cursor moves while staying over the same target window. Given the 16ms drag intervals, this can create very high-frequency IPC traffic and renderer-side layout work. Consider throttling these updates (e.g., only send at most once per animation frame or every N ms) and/or only sending when the X position actually changes enough to affect the insertion index.