Skip to content

fix(wework): prevent rename input drag - #2646

Merged
qdaxb merged 1 commit into
mainfrom
fix/runtime-chat-rename-drag
Aug 12, 2026
Merged

qdaxb merged 1 commit into
mainfrom
fix/runtime-chat-rename-drag

Conversation

@qdaxb

@qdaxb qdaxb commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

What changed

  • Register each sidebar sortable row as the dnd-kit keyboard activator node.
  • Prevent keyboard drag activation when Space originates from the rename input or another nested interactive element.
  • Keep normal keyboard and pointer sorting behavior unchanged.
  • Add unit and desktop E2E coverage for right-click rename followed by Space input.
  • Extend the desktop verification bridge with context-menu and keyboard-code support used by the regression.

Why

The rename dialog is rendered through a React portal beneath the sortable row in the React tree. Pressing Space in its input bubbled to dnd-kit KeyboardSensor. Because the sortable row had no activatorNode registered, dnd-kit could not reject the nested input event and started dragging the conversation.

Validation

  • pnpm --dir wework test --run src/components/layout/DesktopSidebar.test.tsx src/e2e/desktop-control-keyboard.test.ts (102 passed)
  • pnpm --dir wework lint (passed; 4 pre-existing warnings)
  • pnpm --dir wework typecheck
  • node --check wework/e2e/desktop/modules/conversation-layout.mjs
  • node --check wework/scripts/ai-verify.mjs
  • Full pre-push Wework checks: ESLint, TypeScript, and unit tests passed
  • Isolated real Tauri verification:
    • sortable row + Space set data-dragging=true
    • Escape cleared the drag state
    • right-click conversation → rename → Space left data-dragging unset and the dialog usable

@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The sidebar pointer sensor now rejects multi-click events. The runtime conversation rename test simulates a double-click on the task drag activator and verifies that dragging and reordering do not start before the rename dialog opens.

Changes

Sidebar double-click guard

Layer / File(s) Summary
Pointer guard and rename regression test
wework/src/components/layout/sidebarDragActivator.ts, wework/src/components/layout/DesktopSidebar.test.tsx
SidebarPointerSensor rejects pointer events with more than one click. The rename test verifies that a double-click does not start dragging or invoke task reordering before opening the rename dialog.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: icycrystal4, micro66

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: preventing drag behavior when using the rename input.
✨ 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/runtime-chat-rename-drag

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.

@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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@wework/src/components/layout/sidebarDragActivator.ts`:
- Around line 18-23: Replace the PointerEvent.detail check in
sidebarDragActivator.ts with explicit click-sequence tracking so a genuine
second pointer click cannot begin dragging after activation distance; update
DesktopSidebar.test.tsx to dispatch the real pointer-event sequence instead of
injecting detail: 2. Add isolated Tauri and CI desktop E2E coverage for the
double-click drag behavior in both affected files, preserving normal
single-click dragging.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6aa8a060-b1f4-4b97-937c-1282b24a0244

📥 Commits

Reviewing files that changed from the base of the PR and between 5ed1422 and dc24a0d.

📒 Files selected for processing (2)
  • wework/src/components/layout/DesktopSidebar.test.tsx
  • wework/src/components/layout/sidebarDragActivator.ts

Comment on lines +18 to +23
if (
!event.isPrimary ||
event.button !== 0 ||
event.detail > 1 ||
!isSidebarDragActivatorTarget(event.target)
) {

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- repository guidance ---'
find . -name AGENTS.md -o -name DESIGN.md | sort
printf '%s\n' '--- sensor source ---'
sed -n '1,180p' wework/src/components/layout/sidebarDragActivator.ts
printf '%s\n' '--- test context ---'
sed -n '2220,2330p' wework/src/components/layout/DesktopSidebar.test.tsx
printf '%s\n' '--- related usages ---'
rg -n --glob '!node_modules' 'sidebarDragActivator|isSidebarDragActivatorTarget|detail\s*[:=]|pointerDown|doubleClick' wework/src/components/layout
printf '%s\n' '--- tracked diff summary ---'
git diff --stat -- wework/src/components/layout/sidebarDragActivator.ts wework/src/components/layout/DesktopSidebar.test.tsx

Repository: wecode-ai/Wegent

Length of output: 9424


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- root guidance ---'
cat AGENTS.md
printf '%s\n' '--- Wework guidance ---'
cat wework/AGENTS.md
printf '%s\n' '--- design guidance sections ---'
rg -n -C 2 'drag|double|click|pointer|interaction|desktop|Tauri' wework/DESIGN.md | head -160
printf '%s\n' '--- sensor integration ---'
sed -n '1,180p' wework/src/components/layout/SidebarSortableList.tsx
rg -n -C 5 'SidebarPointerSensor|useSensors|activationConstraint|onDoubleClick|onClick' wework/src/components/layout wework/src
printf '%s\n' '--- package/runtime versions ---'
rg -n '"`@dnd-kit/core`"|"tauri"|"electron"|"vitest"|"playwright"' wework/package.json package.json wework/pnpm-lock.yaml pnpm-lock.yaml 2>/dev/null | head -100
printf '%s\n' '--- pointer test cases ---'
sed -n '2070,2180p' wework/src/components/layout/DesktopSidebar.test.tsx
sed -n '2500,2585p' wework/src/components/layout/DesktopSidebar.test.tsx

Repository: wecode-ai/Wegent

Length of output: 50373


🌐 Web query:

Pointer Events specification PointerEvent detail attribute pointerdown click count

💡 Result:

In the Pointer Events specification, the detail attribute for PointerEvent objects (such as pointerdown, pointerup, pointermove, etc.) is specified to be 0 [1][2][3]. While PointerEvent inherits from UIEvent—which defines the detail attribute to represent the current click count for events like click and mousedown [4]—the Pointer Events specification explicitly mandates that for all pointer events, the detail attribute should be 0 [2][3]. This is distinct from standard MouseEvents, where the detail property may indicate the click count [1][4]. Developers should not rely on the PointerEvent.detail property to track click counts [1]. To track click counts, one should continue to use the standard click event [5], which is generated after the pointer interaction sequence and correctly populates the detail attribute [1][5].

Citations:


🌐 Web query:

Tauri webview PointerEvent detail pointerdown double click WebView2 WKWebView

💡 Result:

The PointerEvent detail property is not reliably used for detecting double-clicks across WebViews (WebView2 or WKWebView) and is fundamentally designed to be 0 for pointerdown and pointerup events in the W3C specification [1]. 1. PointerEvent detail behavior: According to the W3C Pointer Events specification, the detail property is intended for click counts only on specific events like click or auxclick, and it is defined to be zero for all other PointerEvent types, including pointerdown and pointerup [1]. It is not a standardized way to track double-clicks at the pointer event level [2][1]. 2. WebView2 and WKWebView limitations: Neither WebView2 (Windows) nor WKWebView (macOS/iOS) provides native high-level pointer-based double-click event support [2][3][4]. Developers often encounter issues where double-clicks are interpreted as two distinct single clicks rather than a single double-click action [3][5]. While some platform-specific native controls have double-click listeners, these often do not expose their state to the webview's internal DOM event stream [5]. 3. Recommended approach: To reliably detect double-clicks in a cross-platform Tauri application, you should implement a manual debounce or timing mechanism in JavaScript [2][6]. By tracking the time elapsed between consecutive pointerdown events on the same target, you can manually determine if a sequence qualifies as a double-click [2][6]. Example implementation logic: - Store the timestamp and position of the last pointerdown event [6]. - On a new pointerdown, calculate the time difference from the previous event [6]. - If the time difference is below a specific threshold (e.g., 300ms) and the position change is minimal, treat it as a double-click [6]. Be aware that Tauri applications running on WebView2 or WKWebView may inherit platform-specific quirks regarding pointer types (e.g., occasional fallback to mouse type) [7] and cursor update behaviors near window edges [8], which can sometimes complicate input handling, but the fundamental lack of a detail-based double-click mechanism in PointerEvent remains consistent across these platforms [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- Wework guidance: relevant rules ---'
rg -n -C 3 'Tauri|real|E2E|drag|desktop|verification|test' wework/AGENTS.md
printf '%s\n' '--- Design guidance: relevant rules ---'
rg -n -C 3 'drag|double|click|pointer|interaction' wework/DESIGN.md
printf '%s\n' '--- sortable integration ---'
cat -n wework/src/components/layout/SidebarSortableList.tsx | sed -n '1,150p'
printf '%s\n' '--- local sensor references only ---'
rg -n -C 8 'SidebarPointerSensor|onDoubleClick|doubleClick|activationConstraint' wework/src/components/layout
printf '%s\n' '--- package versions ---'
rg -n '"(`@dnd-kit/core`|`@tauri-apps`|tauri|playwright|vitest)"' wework/package.json package.json wework/pnpm-lock.yaml pnpm-lock.yaml 2>/dev/null | head -120
printf '%s\n' '--- dnd-kit source files ---'
find node_modules wework/node_modules -path '*`@dnd-kit`*core*' -type f 2>/dev/null | head -30

Repository: wecode-ai/Wegent

Length of output: 38642


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- normative Pointer Events text ---'
curl -L --fail --silent --show-error https://www.w3.org/TR/pointerevents3/ \
  | tr '\n' ' ' \
  | sed 's/<[^>]*>/ /g; s/[[:space:]]\+/ /g' \
  | grep -o -E '.{0,350}(detail attribute|detail.*0|click count).{0,500}' \
  | head -10
printf '%s\n' '--- local test-event construction ---'
rg -n -C 4 'createEvent|PointerEvent|detail' node_modules/.pnpm/@testing-library+dom* node_modules/.pnpm/@testing-library+user-event* wework/src/test* wework 2>/dev/null \
  | head -160
printf '%s\n' '--- PointerSensor implementation ---'
rg -n -C 12 'class PointerSensor|static activators|activationConstraint|onActivation' \
  node_modules/.pnpm/@dnd-kit+core@6.3.1*/node_modules/@dnd-kit/core/dist 2>/dev/null \
  | head -220
printf '%s\n' '--- available browser runtimes ---'
for command in chromium chromium-browser google-chrome google-chrome-stable firefox; do
  command -v "$command" || true
done
printf '%s\n' '--- test scripts and desktop E2E entry points ---'
rg -n -C 2 'ai:verify|e2e:desktop|desktop' wework/package.json package.json .github 2>/dev/null | head -160

Repository: wecode-ai/Wegent

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -e
python3 - <<'PY'
from html.parser import HTMLParser
from urllib.request import urlopen

class Text(HTMLParser):
    def __init__(self):
        super().__init__()
        self.parts = []
    def handle_data(self, data):
        value = ' '.join(data.split())
        if value:
            self.parts.append(value)

html = urlopen('https://www.w3.org/TR/pointerevents3/', timeout=20).read()
parser = Text()
parser.feed(html.decode('utf-8', 'replace'))
text = '\n'.join(parser.parts)
terms = ('detail', 'click count', 'PointerEvent interface')
lines = text.splitlines()
for index, line in enumerate(lines):
    if any(term.lower() in line.lower() for term in terms):
        start = max(0, index - 2)
        end = min(len(lines), index + 4)
        print(f'--- lines {start + 1}-{end} ---')
        print('\n'.join(lines[start:end]))
PY

printf '%s\n' '--- testing-library event creation ---'
find node_modules/.pnpm -path '*`@testing-library`+dom*' -type f -name '*.js' -print0 2>/dev/null |
  xargs -0 rg -n -C 5 'createEvent|PointerEvent|detail' |
  head -180

printf '%s\n' '--- dnd-kit PointerSensor implementation ---'
find node_modules/.pnpm -path '*`@dnd-kit`+core@6.3.1*' -type f -name '*.js' -print0 2>/dev/null |
  xargs -0 rg -n -C 14 'class PointerSensor|static activators|activationConstraint' |
  head -260

Repository: wecode-ai/Wegent

Length of output: 2441


🏁 Script executed:

#!/bin/bash
set -o pipefail
printf '%s\n' '--- normative Pointer Events text ---'
curl -L --fail --silent --show-error https://www.w3.org/TR/pointerevents3/ |
python3 -c '
import sys
from html.parser import HTMLParser

class Text(HTMLParser):
    def __init__(self):
        super().__init__()
        self.parts = []
    def handle_data(self, data):
        value = " ".join(data.split())
        if value:
            self.parts.append(value)

parser = Text()
parser.feed(sys.stdin.read())
lines = "\n".join(parser.parts).splitlines()
for i, line in enumerate(lines):
    if any(term in line.lower() for term in ("detail", "click count", "pointerevent interface")):
        print(f"--- lines {max(0, i-2)+1}-{min(len(lines), i+4)} ---")
        print("\n".join(lines[max(0, i-2):min(len(lines), i+4)]))
'
printf '%s\n' '--- testing-library event creation ---'
find node_modules/.pnpm -path '*`@testing-library`+dom*' -type f -name '*.js' -print0 2>/dev/null |
  xargs -0 rg -n -C 5 'createEvent|PointerEvent|detail' 2>/dev/null |
  head -180 || true
printf '%s\n' '--- dnd-kit PointerSensor implementation ---'
find node_modules/.pnpm -path '*`@dnd-kit`+core@6.3.1*' -type f -name '*.js' -print0 2>/dev/null |
  xargs -0 rg -n -C 14 'class PointerSensor|static activators|activationConstraint' 2>/dev/null |
  head -260 || true

Repository: wecode-ai/Wegent

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- Pointer Events attribute rule ---'
curl -L --fail --silent --show-error https://www.w3.org/TR/pointerevents3/ |
python3 -c '
import re, sys
html = sys.stdin.read()
for needle in (
    "For all pointer events in the table above",
    "The detail",
    "The detail attribute",
):
    match = re.search(r".{0,500}" + re.escape(needle) + r".{0,900}", html, re.S | re.I)
    if match:
        text = re.sub(r"<[^>]*>", " ", match.group(0))
        text = re.sub(r"\s+", " ", text).strip()
        print(text)
'

printf '%s\n' '--- testing-library pointer event factory ---'
EVENT_FILE='node_modules/.pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/dist/events.js'
MAP_FILE='node_modules/.pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/dist/event-map.js'
sed -n '1,180p' "$EVENT_FILE"
sed -n '608,624p' "$MAP_FILE"

printf '%s\n' '--- dnd-kit pointer sensor source ---'
CORE_FILE=$(find node_modules/.pnpm -path '*`@dnd-kit`+core@6.3.1*/node_modules/@dnd-kit/core/dist/core.cjs.development.js' -print -quit)
printf 'file=%s\n' "$CORE_FILE"
rg -n -C 18 'class PointerSensor|PointerSensor.activators|activationConstraint' "$CORE_FILE" | head -220

printf '%s\n' '--- read-only behavior verifier ---'
python3 - <<'PY'
from pathlib import Path
import re

sensor = Path("wework/src/components/layout/sidebarDragActivator.ts").read_text()
test = Path("wework/src/components/layout/DesktopSidebar.test.tsx").read_text()

assert "event.detail > 1" in sensor
assert re.search(r"fireEvent\.pointerDown\(dragActivator,[\s\S]{0,500}?detail:\s*2", test)

def accepts(detail: int) -> bool:
    return not (detail > 1)

print({"production_pointer_event_detail": 0, "sensor_accepts": accepts(0)})
print({"test_injected_detail": 2, "sensor_accepts": accepts(2)})
assert accepts(0) is True
assert accepts(2) is False
print("The test exercises a rejected synthetic detail value, while a conforming pointerdown detail value passes.")
PY

Repository: wecode-ai/Wegent

Length of output: 12115


Stop using PointerEvent.detail to suppress double-click drags.

The Pointer Events specification defines detail as 0 for pointer events. The test injects detail: 2, so it rejects a synthetic value that a real pointerdown does not provide. A real second click can therefore start dragging after the 6px activation distance.

Track the click sequence explicitly in sidebarDragActivator.ts. Update DesktopSidebar.test.tsx to dispatch the real pointer sequence. Add isolated Tauri and CI desktop E2E coverage.

📍 Affects 2 files
  • wework/src/components/layout/sidebarDragActivator.ts#L18-L23 (this comment)
  • wework/src/components/layout/DesktopSidebar.test.tsx#L2271-L2303
🤖 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/sidebarDragActivator.ts` around lines 18 - 23,
Replace the PointerEvent.detail check in sidebarDragActivator.ts with explicit
click-sequence tracking so a genuine second pointer click cannot begin dragging
after activation distance; update DesktopSidebar.test.tsx to dispatch the real
pointer-event sequence instead of injecting detail: 2. Add isolated Tauri and CI
desktop E2E coverage for the double-click drag behavior in both affected files,
preserving normal single-click dragging.

Source: Coding guidelines

@qdaxb
qdaxb force-pushed the fix/runtime-chat-rename-drag branch from dc24a0d to 260caba Compare August 12, 2026 17:58
@qdaxb qdaxb changed the title fix(wework): prevent rename double-click drag fix(wework): prevent rename input drag Aug 12, 2026
@qdaxb
qdaxb added this pull request to the merge queue Aug 12, 2026
Merged via the queue into main with commit bef777f Aug 12, 2026
56 checks passed
@qdaxb
qdaxb deleted the fix/runtime-chat-rename-drag branch August 12, 2026 18:34
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