Commit Graph

9 Commits

Author SHA1 Message Date
Comfy Org PR Bot
b66a181879 [backport core/1.32] Feat: Alt+Drag to clone - Vue Nodes (#6860)
Backport of #6789 to `core/1.32`

Automatically created by backport workflow.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6860-backport-core-1-32-Feat-Alt-Drag-to-clone-Vue-Nodes-2b46d73d365081e0ac21c1dc61189a7c)
by [Unito](https://www.unito.io)

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: github-actions <github-actions@github.com>
2025-11-23 13:24:14 -07:00
Johnpaul Chiwetelu
14d94da52b Fix Node Event Handlers for Shift Click (#6262)
This pull request refactors the node selection and pointer interaction
logic in the Vue node graph editor to improve multi-selection behavior,
clarify event handling, and enhance test coverage. The main change is to
defer multi-select toggle actions (such as ctrl+click for
selection/deselection) from pointer down to pointer up, preventing
premature selection state changes and making drag interactions more
robust. The drag initiation logic is also refined to only start dragging
after the pointer moves beyond a threshold, and new composable methods
are introduced for granular node selection control.

**Node selection and pointer event handling improvements:**
* Refactored multi-select (ctrl/cmd/shift+click) logic in
`useNodeEventHandlersIndividual`: selection toggling is now deferred to
pointer up, and pointer down only brings the node to front without
changing selection state. The previous `hasMultipleNodesSelected`
function and related logic were removed for clarity.
[[1]](diffhunk://#diff-8d3820a1ca9c569bce00671fdd6290af81315ae11b8f3d6f29a5a9d30379d084L18-L35)
[[2]](diffhunk://#diff-8d3820a1ca9c569bce00671fdd6290af81315ae11b8f3d6f29a5a9d30379d084L57-L73)
[[3]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aL112-L116)
[[4]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aR127-R143)
* Added new composable methods `deselectNode` and
`toggleNodeSelectionAfterPointerUp` to `useNodeEventHandlersIndividual`
for more granular control over node selection, and exposed them in the
returned API.
[[1]](diffhunk://#diff-8d3820a1ca9c569bce00671fdd6290af81315ae11b8f3d6f29a5a9d30379d084R210-R245)
[[2]](diffhunk://#diff-8d3820a1ca9c569bce00671fdd6290af81315ae11b8f3d6f29a5a9d30379d084L251-R259)

**Pointer interaction and drag behavior changes:**
* Updated `useNodePointerInteractions` to track pointer down/up state
and only start dragging after the pointer moves beyond a pixel
threshold. Multi-select toggling is now handled on pointer up, not
pointer down, and selection state is read from the actual node manager
for accuracy.
[[1]](diffhunk://#diff-b50f38fec4f988dcbee7b7adf2b3425ae1e40a7ff10439ecbcb380dfa0a05ee1R6-R10)
[[2]](diffhunk://#diff-b50f38fec4f988dcbee7b7adf2b3425ae1e40a7ff10439ecbcb380dfa0a05ee1R33-R34)
[[3]](diffhunk://#diff-b50f38fec4f988dcbee7b7adf2b3425ae1e40a7ff10439ecbcb380dfa0a05ee1R44-R53)
[[4]](diffhunk://#diff-b50f38fec4f988dcbee7b7adf2b3425ae1e40a7ff10439ecbcb380dfa0a05ee1R76-R110)
[[5]](diffhunk://#diff-b50f38fec4f988dcbee7b7adf2b3425ae1e40a7ff10439ecbcb380dfa0a05ee1R122-R123)
[[6]](diffhunk://#diff-b50f38fec4f988dcbee7b7adf2b3425ae1e40a7ff10439ecbcb380dfa0a05ee1L131-R175)

**Test suite enhancements:**
* Improved and expanded tests for pointer interactions and selection
logic, including new cases for ctrl+click selection toggling on pointer
up, drag threshold behavior, and mocking of new composable methods.
[[1]](diffhunk://#diff-8d94b444c448b346f5863e859c75f67267439a56a02baf44b385af1c6945effdR9-R11)
[[2]](diffhunk://#diff-8d94b444c448b346f5863e859c75f67267439a56a02baf44b385af1c6945effdR35-R56)
[[3]](diffhunk://#diff-8d94b444c448b346f5863e859c75f67267439a56a02baf44b385af1c6945effdR100-R102)
[[4]](diffhunk://#diff-8d94b444c448b346f5863e859c75f67267439a56a02baf44b385af1c6945effdL144-R181)
[[5]](diffhunk://#diff-8d94b444c448b346f5863e859c75f67267439a56a02baf44b385af1c6945effdL155-R196)
[[6]](diffhunk://#diff-8d94b444c448b346f5863e859c75f67267439a56a02baf44b385af1c6945effdL196-R247)
[[7]](diffhunk://#diff-8d94b444c448b346f5863e859c75f67267439a56a02baf44b385af1c6945effdL276-R336)
[[8]](diffhunk://#diff-8d94b444c448b346f5863e859c75f67267439a56a02baf44b385af1c6945effdR348-R423)
* Updated test setup and assertions for node event handlers, ensuring
selection changes are only triggered at the correct event phase and that
drag and multi-select logic is covered.
[[1]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aL4-R7)
[[2]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aR92)

These changes make node selection more predictable and user-friendly,
and ensure drag and multi-select actions behave consistently in both the
UI and the test suite.

fix https://github.com/Comfy-Org/ComfyUI_frontend/issues/6128



https://github.com/user-attachments/assets/582804d0-1d21-4ba0-a161-6582fb379352
2025-11-19 11:32:20 -08:00
Johnpaul Chiwetelu
4cb03cf052 Select Vue Nodes After Drag (#5863)
This pull request refactors the node selection logic in the Vue nodes
event handler composable to simplify the function signature and improve
single vs. multi-selection behavior. The main change is the removal of
the `wasDragging` parameter from the `handleNodeSelect` function, with
selection logic now determined by the current selection state. Related
test code is updated to match the new function signature.

**Node selection logic improvements:**

* Refactored the `handleNodeSelect` function in
`useNodeEventHandlersIndividual` to remove the `wasDragging` parameter,
making the function signature simpler and relying on selection state to
handle single vs. multi-selection.
* Updated the selection logic to check if multiple nodes are already
selected using `isLGraphNode`, and only perform single selection if not.

**Code and test updates:**

* Updated all calls to `handleNodeSelect` in the composable to remove
the `wasDragging` argument, ensuring consistent usage throughout the
codebase.
[[1]](diffhunk://#diff-8d3820a1ca9c569bce00671fdd6290af81315ae11b8f3d6f29a5a9d30379d084L125-R123)
[[2]](diffhunk://#diff-8d3820a1ca9c569bce00671fdd6290af81315ae11b8f3d6f29a5a9d30379d084L146-R144)
[[3]](diffhunk://#diff-8d3820a1ca9c569bce00671fdd6290af81315ae11b8f3d6f29a5a9d30379d084L173-R171)
* Updated all related test cases to use the new `handleNodeSelect`
signature without the third parameter.
[[1]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aL105-R105)
[[2]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aL125-R125)
[[3]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aL144-R144)
[[4]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aL162-R162)
[[5]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aL174-R174)
[[6]](diffhunk://#diff-89bfc2a05201c6ff7116578efa45f96097594eb346f18446c70aa7125ab1811aL187-R187)

**Utility import:**

* Added an import for `isLGraphNode` from `@/utils/litegraphUtil` to
support the updated selection logic.## Summary

<!-- One sentence describing what changed and why. -->


## Screenshots (if applicable)



https://github.com/user-attachments/assets/71e856d3-afc2-497d-826e-5b485066e7fe

---------

Co-authored-by: github-actions <github-actions@github.com>
2025-10-09 20:48:03 -07:00
Alexander Brown
8133bd4b7b Refactor: Composable disentangling (#5695)
## Summary

Prerequisite refactor/cleanup to use a global store instead of having
nodes throw up events to a parent component that stores a reference to a
singleton service that itself bootstraps and synchronizes with a
separate service to maintain a partially reactive but not fully reactive
set of states that describe some but not all aspects of the nodes on
either the litegraph, the vue side, or both.

## Changes

- **What**: Refactoring, the behavior should not change.
- **Dependencies**: A type utility to help with Vue component props

## Review Focus

Is there something about the current structure that this could affect
that would not be caught by our tests or using the application?

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5695-Refactor-Composable-disentangling-2746d73d365081e6938ce656932f3e36)
by [Unito](https://www.unito.io)
2025-09-20 13:06:42 -07:00
Christian Byrne
bc85d4e87b Make Vue nodes read-only when in panning mode (#5574)
## Summary

Integrated Vue node components with canvas panning mode to prevent UI
interference during navigation.

## Changes

- **What**: Added
[canCapturePointerEvents](https://docs.comfy.org/guide/vue-nodes)
computed property to `useCanvasInteractions` composable that checks
canvas read-only state
- **What**: Modified Vue node components (LGraphNode, NodeWidgets) to
conditionally handle pointer events based on canvas navigation mode
- **What**: Updated node event handlers to respect panning mode and
forward events to canvas when appropriate

## Review Focus

Event forwarding logic in panning mode and pointer event capture state
management across Vue node hierarchy.

```mermaid
graph TD
    A[User Interaction] --> B{Canvas in Panning Mode?}
    B -->|Yes| C[Forward to Canvas]
    B -->|No| D[Handle in Vue Component]
    C --> E[Canvas Navigation]
    D --> F[Node Selection/Widget Interaction]

    G[canCapturePointerEvents] --> H{read_only === false}
    H -->|Yes| I[Allow Vue Events]
    H -->|No| J[Block Vue Events]

    style A fill:#f9f9f9,stroke:#333,color:#000
    style E fill:#f9f9f9,stroke:#333,color:#000
    style F fill:#f9f9f9,stroke:#333,color:#000
    style I fill:#e1f5fe,stroke:#01579b,color:#000
    style J fill:#ffebee,stroke:#c62828,color:#000
```

## Screenshots




https://github.com/user-attachments/assets/00dc5e4a-2b56-43be-b92e-eaf511e52542

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5574-Make-Vue-nodes-read-only-when-in-panning-mode-26f6d73d3650818c951cd82c8fe58972)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2025-09-18 15:43:35 -07:00
Alexander Brown
b264685052 lint: add tsconfig for browser_tests, fix existing violations (#5633)
## Summary

See https://typescript-eslint.io/blog/project-service/ for context.
Creates a browser_tests specific tsconfig so that they can be linted.

Does not add a package.json script to do the linting yet, but `pnpm exec
eslint browser_tests` should work for now.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5633-lint-add-tsconfig-for-browser_tests-fix-existing-violations-2726d73d3650819d8ef2c4b0abc31e14)
by [Unito](https://www.unito.io)
2025-09-18 11:35:44 -07:00
Christian Byrne
6349ceee6c [refactor] Improve renderer domain organization (#5552)
* [refactor] Improve renderer architecture organization

Building on PR #5388, this refines the renderer domain structure:

**Key improvements:**
- Group all transform utilities in `transform/` subdirectory for better cohesion
- Move canvas state to dedicated `renderer/core/canvas/` domain
- Consolidate coordinate system logic (TransformPane, useTransformState, sync utilities)

**File organization:**
- `renderer/core/canvas/canvasStore.ts` (was `stores/graphStore.ts`)
- `renderer/core/layout/transform/` contains all coordinate system utilities
- Transform sync utilities co-located with core transform logic

This creates clearer domain boundaries and groups related functionality
while building on the foundation established in PR #5388.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Clean up linter-modified files

* Fix import paths and clean up unused imports after rebase

- Update all remaining @/stores/graphStore references to @/renderer/core/canvas/canvasStore
- Remove unused imports from selection toolbox components
- All tests pass, only reka-ui upstream issue remains in typecheck

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* [auto-fix] Apply ESLint and Prettier fixes

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
2025-09-14 21:28:08 -07:00
Johnpaul Chiwetelu
c051c3a507 Drag Multiple Vue Nodes (#5459)
* feat: enhance dragging functionality to support multiple selected nodes

* feat: enhance node selection handling to support drag state detection

* feat: enhance node selection handling to support drag state detection

* fix: update event trigger from pointer down to pointer up in LGraphNode tests
2025-09-11 17:25:23 -07:00
Christian Byrne
43ab1c9b09 Add z-index management in Vue Nodes based on interaction recency (#5429)
* fix z-index on selection for vue nodes

* fix unused export

* refactor to DDD

* Use Tailwind utility for pointer events instead of inline style

Move pointer-events: auto from inline style to Tailwind class
pointer-events-auto as suggested in PR review.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Rename defaultSource to layoutSource parameter

Rename parameter in useNodeZIndex options interface for better
clarity as suggested in PR review.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Improve test mocking pattern with vi.mocked approach

Replace global mock object with per-test vi.mocked pattern
and proper Partial typing instead of as any, as suggested
in PR review.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* [auto-fix] Apply ESLint and Prettier fixes

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
2025-09-09 15:02:24 -07:00