Skip to content

fix(wework): prevent terminal panel resize lag - #2058

Merged
qdaxb merged 2 commits into
mainfrom
fix/terminal-panel-resize-lag
Jul 19, 2026
Merged

qdaxb merged 2 commits into
mainfrom
fix/terminal-panel-resize-lag

Conversation

@qdaxb

@qdaxb qdaxb commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

What changed

  • update the bottom terminal panel height imperatively during drag and commit React state only when dragging finishes
  • handle pointer cancellation and clean up pending animation frames
  • add a focused regression test proving terminal content does not rerender during drag
  • add a reusable isolated-Tauri drag verification command and document it

Why

Every animation frame previously updated React state for the whole bottom workspace panel. That repeatedly rerendered the terminal subtree while xterm also observed, fitted, and synchronized its changing container size, creating an expensive render/measure/resize cascade that made the divider lag and eventually feel stuck.

Impact

The terminal divider now tracks the pointer smoothly while preserving the existing min/max bounds and final panel height. Terminal content remains mounted and responsive throughout resizing.

Validation

  • pnpm --filter wework test — 181 files / 1820 tests passed
  • focused Prettier and ESLint checks passed
  • pre-push ESLint, TypeScript, and unit-test gates passed
  • isolated real-Tauri verification passed for opening the terminal, expanding it, shrinking it, and expanding it again

Summary by CodeRabbit

  • New Features
    • Added a new drag interaction command to desktop verification and automation workflows, including required destination selection.
  • Bug Fixes
    • Improved bottom workspace panel resizing behavior for smoother pointer-drag interactions.
    • Resizing now handles pointer cancel events more reliably and resets interaction styling after completion.
  • Tests
    • Added coverage to ensure resize updates are performed efficiently during pointer dragging and only at expected times.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 22e6e513-61aa-4f99-b9a6-046b8c6e8f42

📥 Commits

Reviewing files that changed from the base of the PR and between eb55659 and 6bb6a4d.

📒 Files selected for processing (3)
  • wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.test.tsx
  • wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts
  • wework/src/e2e/automation.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.test.tsx
  • wework/src/e2e/automation.ts
  • wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts

📝 Walkthrough

Walkthrough

The PR adds drag support to desktop verification commands and automation, and changes bottom-panel resizing to use imperative DOM height updates with pointer-cancel handling. It also adds coverage for resize rendering and height behavior.

Changes

Bottom panel resize behavior

Layer / File(s) Summary
Imperative panel resizing and validation
wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts, wework/src/components/layout/workspace-panels/BottomWorkspacePanel.tsx, wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.test.tsx
The resize hook binds a panel ref, applies height through animation frames, handles pointercancel, and is tested for height updates and render counts.

Desktop drag verification

Layer / File(s) Summary
Drag command wiring and execution
wework/scripts/ai-verify.mjs, wework/src/e2e/automation.ts, wework/AGENTS.md
The CLI recognizes drag, requires --target, and documents the verification step; automation dispatches pointer events between origin and target selectors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AIVerifyCLI
  participant DesktopAutomation
  participant DOMElement
  AIVerifyCLI->>DesktopAutomation: dispatch drag with selector and target
  DesktopAutomation->>DOMElement: validate origin and target
  DesktopAutomation->>DOMElement: dispatch pointerdown, pointermove, pointerup
  DOMElement-->>DesktopAutomation: return origin text
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: fixing lag in terminal panel resizing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/terminal-panel-resize-lag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qdaxb
qdaxb marked this pull request as ready for review July 19, 2026 23:00
@qdaxb

qdaxb commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts (1)

158-160: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Capture the pointer to ensure reliable drag events outside the window.

When the user drags near the edge of the screen, the cursor can easily leave the Tauri webview boundary. Without pointer capture, the webview will stop receiving pointermove and pointerup events, which can leave the panel stuck in a resizing state indefinitely.

Call setPointerCapture on the event target so that all subsequent pointer events are routed to it until the pointer is released.

🛠️ Proposed fix
   const handleResizeStart = (event: PointerEvent<HTMLDivElement>) => {
     event.preventDefault()
+    event.currentTarget.setPointerCapture(event.pointerId)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts`
around lines 158 - 160, Update handleResizeStart to call setPointerCapture with
the event’s pointerId on the event target immediately after preventing the
default action, ensuring subsequent resize pointer events remain routed to the
target outside the webview boundary.
🧹 Nitpick comments (2)
wework/src/e2e/automation.ts (1)

377-391: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the dispatchDesktopControlPointerEvent helper for consistency and correct event delegation.

Dispatching pointermove and pointerup directly on document bypasses the MouseEvent fallback logic provided by dispatchDesktopControlPointerEvent. Furthermore, dispatching on document instead of a DOM element causes the event's native target to be document, which can break React's synthetic event delegation since React listens at the root container rather than the document.

Because desktopControlEventOptions sets bubbles: true, dispatching these events on the destination target element will correctly bubble up to document for any global listeners, while preserving the abstraction and React compatibility.

♻️ Proposed refactor
   const startOptions = { ...desktopControlEventOptions(element), buttons: 1 }
   const endOptions = { ...desktopControlEventOptions(target), buttons: 1 }
   dispatchDesktopControlPointerEvent(element, 'pointerdown', startOptions)
-  document.dispatchEvent(new PointerEvent('pointermove', endOptions))
-  document.dispatchEvent(new PointerEvent('pointerup', { ...endOptions, buttons: 0 }))
+  dispatchDesktopControlPointerEvent(target, 'pointermove', endOptions)
+  dispatchDesktopControlPointerEvent(target, 'pointerup', { ...endOptions, buttons: 0 })
   return element.textContent?.trim() ?? ''
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wework/src/e2e/automation.ts` around lines 377 - 391, Update
dragDesktopControlElement to dispatch the pointermove and pointerup events
through dispatchDesktopControlPointerEvent on the destination target element
instead of constructing events on document. Preserve the existing endOptions
values and pointerup buttons: 0 behavior while retaining the pointerdown
dispatch on the source element.
wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts (1)

150-156: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Clean up side-effects if unmounted during an active resize.

If the panel is unmounted while being dragged (e.g., by a hot-reload or a keyboard shortcut), the pointermove, pointerup, and pointercancel listeners will remain attached to the document, and the document.body cursor will remain stuck as row-resize.

Consider using an AbortController to cleanly remove the event listeners on unmount and revert the global body styles.

🛠️ Proposed refactor

Keep track of the abort controller in a ref, and abort it during cleanup:

+  const abortControllerRef = useRef<AbortController | null>(null)
+
   useEffect(() => {
     return () => {
       if (resizeFrameRef.current !== null) {
         window.cancelAnimationFrame(resizeFrameRef.current)
       }
+      if (abortControllerRef.current) {
+        abortControllerRef.current.abort()
+        document.body.style.cursor = ''
+        document.body.style.userSelect = ''
+      }
     }
   }, [])

Then, update handleResizeStart and finishResize to use the signal:

    const finishResize = () => {
      abortControllerRef.current?.abort()
      abortControllerRef.current = null
      // ... (remove the manual document.removeEventListener calls)
    }
    
    // ...
    abortControllerRef.current = new AbortController()
    const { signal } = abortControllerRef.current
    document.addEventListener('pointermove', handleMove, { signal })
    document.addEventListener('pointerup', handleUp, { signal })
    document.addEventListener('pointercancel', handleCancel, { signal })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts`
around lines 150 - 156, Update the resize lifecycle around handleResizeStart and
finishResize to store an AbortController in a ref, register pointermove,
pointerup, and pointercancel listeners with its signal, and abort it when
resizing finishes or the component unmounts. Ensure cleanup also resets
document.body cursor styles and clears the controller ref, while preserving the
existing animation-frame cancellation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts`:
- Around line 158-160: Update handleResizeStart to call setPointerCapture with
the event’s pointerId on the event target immediately after preventing the
default action, ensuring subsequent resize pointer events remain routed to the
target outside the webview boundary.

---

Nitpick comments:
In `@wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts`:
- Around line 150-156: Update the resize lifecycle around handleResizeStart and
finishResize to store an AbortController in a ref, register pointermove,
pointerup, and pointercancel listeners with its signal, and abort it when
resizing finishes or the component unmounts. Ensure cleanup also resets
document.body cursor styles and clears the controller ref, while preserving the
existing animation-frame cancellation.

In `@wework/src/e2e/automation.ts`:
- Around line 377-391: Update dragDesktopControlElement to dispatch the
pointermove and pointerup events through dispatchDesktopControlPointerEvent on
the destination target element instead of constructing events on document.
Preserve the existing endOptions values and pointerup buttons: 0 behavior while
retaining the pointerdown dispatch on the source element.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 754f1876-09c9-4cce-b4d5-4e0b3cfa2e5a

📥 Commits

Reviewing files that changed from the base of the PR and between 6bc0c79 and eb55659.

📒 Files selected for processing (6)
  • wework/AGENTS.md
  • wework/scripts/ai-verify.mjs
  • wework/src/components/layout/workspace-panels/BottomWorkspacePanel.tsx
  • wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.test.tsx
  • wework/src/components/layout/workspace-panels/useResizableWorkspacePanel.ts
  • wework/src/e2e/automation.ts

@qdaxb

qdaxb commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review findings in 6bb6a4d:

  • added safe pointer capture for reliable drag completion
  • added active-resize cleanup on finish and unmount, with regression coverage
  • retained document-level move/up dispatch because the product listens on document and target-level dispatch failed the real Tauri drag verification; routed those events through the shared fallback helper instead

Revalidated with 142 focused tests, lint/format checks, pre-push ESLint/TypeScript/unit tests, and real Tauri expand/shrink screenshots.

@qdaxb
qdaxb merged commit 4a755f5 into main Jul 19, 2026
29 checks passed
@qdaxb
qdaxb deleted the fix/terminal-panel-resize-lag branch July 19, 2026 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant