ComfyUI_frontend icon indicating copy to clipboard operation
ComfyUI_frontend copied to clipboard

[Bug]: Missing onMouseUp node events

Open paccerdk opened this issue 6 months ago • 2 comments

Frontend Version

v1.18.10

Expected Behavior

When releasing mouse button, onMouseUp event should always be emitted

Actual Behavior

onMouseUp doesn't get emitted after onMouseDown unless there is a mouse move inbetween

https://github.com/user-attachments/assets/33c98fd0-5dc8-409e-b226-b5c3dfbd0a98

Steps to Reproduce

The following code was used to create a minimal replication / demonstration of the issue:

import { app } from "../../scripts/app.js";

app.registerExtension({
    name: "MouseEventBug",
    
    async beforeRegisterNodeDef(nodeType, nodeData, app) {
        if (nodeType.comfyClass == "Mouse Event Bug") {
            
            // logging array
            nodeType.prototype.debugEvents = [];
            nodeType.prototype.maxEvents = 10;
                
            // draw debug text
            nodeType.prototype.onDrawForeground = function(ctx) {
                ctx.font = "14px Arial";
                ctx.fillStyle = "#ffffff";
                ctx.textAlign = "left";
                
                for (let i = 0; i < this.debugEvents.length; i++) {
                    ctx.fillText(this.debugEvents[i], 10, 30 + (i * 20));
                }
            };
            
            nodeType.prototype.onMouseDown = function(e, pos, canvas) {
                this.logEvent("Mouse DOWN");
                return true; 
                // original events ignored for code simplicity, bug happens in both cases
            };
            
            nodeType.prototype.onMouseMove = function(e, pos, canvas) {
                this.logEvent("Mouse MOVE");
                return true;
            };
            
            nodeType.prototype.onMouseUp = function(e, pos, canvas) {
                this.logEvent("Mouse UP");
                return true;
            };
            
            // helper method used for the logging
            nodeType.prototype.logEvent = function(text) {
                this.debugEvents.unshift(text);
                
                if (this.debugEvents.length > this.maxEvents) {
                    this.debugEvents.pop();
                }
                
                app.graph.setDirtyCanvas(true, true);
            };
        }
    }
});

Debug Logs

Starting ComfyUI...
Checkpoint files will always be loaded safely.
Total VRAM 24576 MB, total RAM 32419 MB
pytorch version: 2.7.0+cu128
Enabled fp16 accumulation.
Set vram state to: NORMAL_VRAM
Device: cuda:0 NVIDIA GeForce RTX 3090 : cudaMallocAsync
Using pytorch attention
Python version: 3.12.10 (tags/v3.12.10:0cc8128, Apr  8 2025, 12:21:36) [MSC v.1943 64 bit (AMD64)]
ComfyUI version: 0.3.34
ComfyUI frontend version: 1.18.10
[Prompt Server] web root: E:\comfyui_drag_test\python_embeded\Lib\site-packages\comfyui_frontend_package\static

Import times for custom nodes:
   0.0 seconds: E:\comfyui_drag_test\ComfyUI\custom_nodes\websocket_image_save.py
   0.0 seconds: E:\comfyui_drag_test\ComfyUI\custom_nodes\mouseeventbug

Starting server

To see the GUI go to: http://127.0.0.1:8188

Browser Logs

Mouse Event Debug extension loaded load and start tracking of workflow workflows/Unsaved Workflow (2).json [workflowStore] open workflow workflows/Unsaved Workflow (2).json

Setting JSON

What browsers do you use to access the UI ?

Mozilla Firefox

Other Information

The bug was reproduced in a completely new and freshly downloaded portable ComfyUI v0.3.34 with default settings, and no other custom nodes

┆Issue is synchronized with this Notion page by Unito

paccerdk avatar May 16 '25 19:05 paccerdk

Just to confirm, I've also experienced the same issue.

fredconex avatar May 16 '25 19:05 fredconex

Hi there, is this impacting an existing custom node, or one that's being written? For existing code - no worries, found the issue.

If you're creating new custom nodes, CanvasPointer is the current way to handle clicks - it requires less boilerplate code, and ensures people get the same "click / drag" experience for everything.

node.onMouseDown = function(e: CanvasPointerEvent, pos: Point, canvas: LGraphCanvas) {
  const { pointer } = canvas
  pointer.onClick = (upEvent: CanvasPointerEvent) => {
    // Regular click event
  }

  pointer.onDragStart = () => {
    // The pointer is being dragged
    // Includes logic to prevent unintended micro-dragging
  }

  // ...
}

See CanvasPointer.ts for full details.

webfiltered avatar May 17 '25 02:05 webfiltered