From 2ed2383cd8008425210f9b944e2d32cb31c89dee Mon Sep 17 00:00:00 2001 From: Richard Stephens Date: Mon, 9 Oct 2023 15:58:24 +0200 Subject: [PATCH 1/2] fix: workround for spurious mouseleave events in chrome --- src/lib/VncScreen.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lib/VncScreen.tsx b/src/lib/VncScreen.tsx index 59222bd..2d4f7ba 100644 --- a/src/lib/VncScreen.tsx +++ b/src/lib/VncScreen.tsx @@ -342,7 +342,16 @@ const VncScreen: React.ForwardRefRenderFunction = (props handleClick(); }; - const handleMouseLeave = () => { + const handleMouseLeave = (e:any) => { + // https://github.com/roerohan/react-vnc/issues/5#issuecomment-1753065170 + // FIXME: We see spurious mouse leave events in Chrome when the user clicks + // on the canvas. + // This hack drops the mouseleave event if the target is the window object. + if (e.relatedTarget) { + if (e.relatedTarget.window) { + return; + } + } const rfb = getRfb(); if (!rfb) { return; From a652c7d014d98615c0a9cd50b7b1b7bc4fb3cf4c Mon Sep 17 00:00:00 2001 From: adryd Date: Fri, 9 Jan 2026 18:25:32 -0500 Subject: [PATCH 2/2] feat(vncscreen.tsx): allow customization of mouseenter and mouseleave events Currently the VncScreen component has hardcoded onMouseEnter and onMouseLeave events to focus and blur the noVNC rfb. This change allows customization of what happens with those events. --- src/lib/VncScreen.tsx | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/lib/VncScreen.tsx b/src/lib/VncScreen.tsx index 2d4f7ba..02ee308 100644 --- a/src/lib/VncScreen.tsx +++ b/src/lib/VncScreen.tsx @@ -1,5 +1,6 @@ import React, { forwardRef, + MouseEventHandler, useEffect, useImperativeHandle, useRef, @@ -37,6 +38,8 @@ export interface Props { onDesktopName?: EventListeners['desktopname']; onCapabilities?: EventListeners['capabilities']; onClippingViewport?: EventListeners['clippingviewport']; + onChildMouseLeave?: MouseEventHandler; + onChildMouseEnter?: MouseEventHandler; } export type VncScreenHandle = { @@ -84,6 +87,8 @@ const VncScreen: React.ForwardRefRenderFunction = (props autoConnect = true, retryDuration = 3000, debug = false, + onChildMouseLeave, + onChildMouseEnter, onConnect, onDisconnect, onCredentialsRequired, @@ -334,7 +339,7 @@ const VncScreen: React.ForwardRefRenderFunction = (props rfb.focus(); }; - const handleMouseEnter = () => { + const defaultHandleMouseEnter = () => { if (document.activeElement && document.activeElement instanceof HTMLElement) { document.activeElement.blur(); } @@ -342,21 +347,21 @@ const VncScreen: React.ForwardRefRenderFunction = (props handleClick(); }; - const handleMouseLeave = (e:any) => { + const defaultHandleMouseLeave = (e: React.MouseEvent) => { // https://github.com/roerohan/react-vnc/issues/5#issuecomment-1753065170 // FIXME: We see spurious mouse leave events in Chrome when the user clicks // on the canvas. - // This hack drops the mouseleave event if the target is the window object. - if (e.relatedTarget) { - if (e.relatedTarget.window) { - return; - } + // This hack drops the mouseleave event if the target is the noVNC mouse capture element + if ( + e.nativeEvent.relatedTarget && + (e.nativeEvent.relatedTarget as HTMLElement).id == "noVNC_mouse_capture_elem" + ) { + return; } const rfb = getRfb(); if (!rfb) { return; } - rfb.blur(); }; @@ -365,8 +370,8 @@ const VncScreen: React.ForwardRefRenderFunction = (props style={style} className={className} ref={screen} - onMouseEnter={handleMouseEnter} - onMouseLeave={handleMouseLeave} + onMouseEnter={onChildMouseEnter ?? defaultHandleMouseEnter} + onMouseLeave={onChildMouseLeave ?? defaultHandleMouseLeave} /> ); }