mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-26 07:45:34 +00:00
fix: popovers issue with mouse passthrough
fix: issues with HUD bar not registering clicks properly
This commit is contained in:
@@ -36,6 +36,7 @@ export default function App() {
|
||||
document.documentElement.classList.add("hud-overlay-window");
|
||||
document.body.classList.add("hud-overlay-window");
|
||||
document.getElementById("root")?.classList.add("hud-overlay-window");
|
||||
window.electronAPI?.hudOverlaySetIgnoreMouse?.(true);
|
||||
} else if (type === "update-toast") {
|
||||
document.documentElement.style.overflow = "visible";
|
||||
document.body.style.overflow = "visible";
|
||||
|
||||
@@ -33,6 +33,7 @@ import { MicPopover } from "./popovers/MicPopover";
|
||||
import { MorePopover } from "./popovers/MorePopover";
|
||||
import { SourcePopover } from "./popovers/SourcePopover";
|
||||
import { WebcamPopover } from "./popovers/WebcamPopover";
|
||||
import { HudInteractionContext } from "./contexts/HudInteractionContext";
|
||||
import { MarqueeText } from "./SourceSelector";
|
||||
import styles from "./LaunchWindow.module.css";
|
||||
|
||||
@@ -173,7 +174,7 @@ function LaunchWindowContent() {
|
||||
recordingWebcamPreviewContainerRef,
|
||||
});
|
||||
|
||||
const { handleHudMouseLeave, beginInteractiveHudAction } = useLaunchHudInteractionState({
|
||||
const { handleHudMouseEnter, handleHudMouseLeave, beginInteractiveHudAction } = useLaunchHudInteractionState({
|
||||
openId,
|
||||
projectBrowserOpen,
|
||||
setProjectBrowserOpen,
|
||||
@@ -428,17 +429,20 @@ function LaunchWindowContent() {
|
||||
const hudMode = finalizing ? "finalizing" : recording ? "recording" : "idle";
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-full flex justify-center bg-transparent overflow-visible items-end pb-5"
|
||||
style={{ height: "100vh" }}
|
||||
>
|
||||
<HudInteractionContext.Provider value={{ onMouseEnter: handleHudMouseEnter, onMouseLeave: handleHudMouseLeave }}>
|
||||
<div
|
||||
className="w-full flex justify-center bg-transparent overflow-visible items-end pb-5 pointer-events-none"
|
||||
style={{ height: "100vh" }}
|
||||
>
|
||||
<div
|
||||
ref={hudContentRef}
|
||||
className="flex items-center overflow-visible flex-col-reverse"
|
||||
onMouseEnter={() => window.electronAPI?.hudOverlaySetIgnoreMouse?.(false)}
|
||||
onMouseLeave={handleHudMouseLeave}
|
||||
className="flex items-center overflow-visible flex-col-reverse pointer-events-none"
|
||||
>
|
||||
<div className="flex flex-col items-center pointer-events-auto">
|
||||
<div
|
||||
className="flex flex-col items-center pointer-events-auto"
|
||||
onMouseEnter={handleHudMouseEnter}
|
||||
onMouseLeave={handleHudMouseLeave}
|
||||
>
|
||||
<div
|
||||
ref={hudBarTransformRef}
|
||||
style={{
|
||||
@@ -510,7 +514,7 @@ function LaunchWindowContent() {
|
||||
{showRecordingWebcamPreview && (
|
||||
<div
|
||||
ref={recordingWebcamPreviewContainerRef}
|
||||
className={`${styles.recordingWebcamPreview} ${styles.electronNoDrag}`}
|
||||
className={`${styles.recordingWebcamPreview} ${styles.electronNoDrag} pointer-events-auto`}
|
||||
title={t("recording.webcam")}
|
||||
style={{
|
||||
transform: `translate(${webcamPreviewOffset.x}px, ${webcamPreviewOffset.y}px)`,
|
||||
@@ -519,6 +523,8 @@ function LaunchWindowContent() {
|
||||
onPointerMove={handleWebcamPreviewPointerMove}
|
||||
onPointerUp={handleWebcamPreviewPointerUp}
|
||||
onPointerCancel={handleWebcamPreviewPointerUp}
|
||||
onMouseEnter={handleHudMouseEnter}
|
||||
onMouseLeave={handleHudMouseLeave}
|
||||
>
|
||||
<video
|
||||
ref={setRecordingWebcamPreviewNode}
|
||||
@@ -532,7 +538,7 @@ function LaunchWindowContent() {
|
||||
</div>
|
||||
|
||||
{projectBrowserOpen ? (
|
||||
<div className={styles.electronNoDrag}>
|
||||
<div className={`${styles.electronNoDrag} pointer-events-auto`}>
|
||||
<ProjectBrowserDialog
|
||||
open={projectBrowserOpen}
|
||||
onOpenChange={setProjectBrowserOpen}
|
||||
@@ -546,5 +552,6 @@ function LaunchWindowContent() {
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</HudInteractionContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ export const SourceSelector = React.memo(function SourceSelector({
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={onOpenChange}>
|
||||
<Popover open={open} onOpenChange={onOpenChange} modal={false}>
|
||||
<PopoverTrigger asChild>{trigger}</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="launch-theme w-80 p-0 source-selector-popover"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { createContext, useContext } from "react";
|
||||
|
||||
interface HudInteractionContextType {
|
||||
onMouseEnter: () => void;
|
||||
onMouseLeave: (event: any) => void;
|
||||
}
|
||||
|
||||
export const HudInteractionContext = createContext<HudInteractionContextType | null>(null);
|
||||
|
||||
export function useHudInteraction() {
|
||||
const context = useContext(HudInteractionContext);
|
||||
if (!context) {
|
||||
throw new Error("useHudInteraction must be used within a HudInteractionProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@@ -17,9 +17,18 @@ export function useLaunchHudInteractionState({
|
||||
}) {
|
||||
const anyPopoverOpenRef = useRef(false);
|
||||
const projectBrowserOpenRef = useRef(false);
|
||||
const isMouseOverHudRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
anyPopoverOpenRef.current = openId !== null;
|
||||
if (openId === null) {
|
||||
// Proactively check if we should ignore mouse when popover closes
|
||||
setTimeout(() => {
|
||||
if (!isMouseOverHudRef.current && !anyPopoverOpenRef.current) {
|
||||
window.electronAPI?.hudOverlaySetIgnoreMouse?.(true);
|
||||
}
|
||||
}, 150);
|
||||
}
|
||||
}, [openId]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -34,29 +43,45 @@ export function useLaunchHudInteractionState({
|
||||
|
||||
const beginInteractiveHudAction = useCallback(() => {
|
||||
setProjectBrowserOpen(false);
|
||||
isMouseOverHudRef.current = true;
|
||||
window.electronAPI?.hudOverlaySetIgnoreMouse?.(false);
|
||||
}, [setProjectBrowserOpen]);
|
||||
|
||||
const handleHudMouseEnter = useCallback(() => {
|
||||
isMouseOverHudRef.current = true;
|
||||
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
||||
window.electronAPI?.hudOverlaySetIgnoreMouse?.(false);
|
||||
}, []);
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
const handleHudMouseLeave = useCallback((event: MouseEvent<HTMLDivElement>) => {
|
||||
const nextTarget = event.relatedTarget;
|
||||
if (nextTarget instanceof Node && event.currentTarget.contains(nextTarget)) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
isMouseOverHudRef.current = false;
|
||||
|
||||
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
||||
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
if (
|
||||
!isHudDraggingRef.current &&
|
||||
!isWebcamPreviewDraggingRef.current &&
|
||||
!webcamPreviewDragStartRef.current &&
|
||||
!anyPopoverOpenRef.current &&
|
||||
!projectBrowserOpenRef.current
|
||||
!projectBrowserOpenRef.current &&
|
||||
!isMouseOverHudRef.current
|
||||
) {
|
||||
// If a popover is open, we can still ignore mouse if the mouse is truly gone,
|
||||
// but we give a bit more breathing room (the 300ms timeout).
|
||||
window.electronAPI?.hudOverlaySetIgnoreMouse?.(true);
|
||||
}
|
||||
});
|
||||
}, 300);
|
||||
}, [isHudDraggingRef, isWebcamPreviewDraggingRef, webcamPreviewDragStartRef]);
|
||||
|
||||
return {
|
||||
handleHudMouseEnter,
|
||||
handleHudMouseLeave,
|
||||
beginInteractiveHudAction,
|
||||
};
|
||||
|
||||
@@ -74,12 +74,12 @@ export function HudPopover({
|
||||
align?: "start" | "center" | "end";
|
||||
}) {
|
||||
return (
|
||||
<Popover open={open} onOpenChange={onOpenChange}>
|
||||
<Popover open={open} onOpenChange={onOpenChange} modal={false}>
|
||||
<PopoverTrigger asChild>{trigger}</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className={`launch-theme ${styles.menuCard} ${styles.electronNoDrag}`}
|
||||
unstyled
|
||||
side="bottom"
|
||||
side="top"
|
||||
align={align}
|
||||
sideOffset={8}
|
||||
avoidCollisions
|
||||
|
||||
Reference in New Issue
Block a user