perf(ui): the dialogs you type in no longer sit on a blurred backdrop

A backdrop-filter covers the whole window and is recomputed every time
anything above it repaints. Behind these dialogs is an application that
never stops moving — CAT polls four times a second, spots arrive, meters
sweep, maps redraw — so the filter was being recomputed continuously, and
each keystroke's repaint dragged a full-window blur with it. That is why
the lag was felt in Preferences and nowhere else, and why fixing the
cluster macros did not end it.

Worse in one place: the cluster server editor opens FROM Preferences, so
its overlay was the SECOND full-window filter stacked over the first.
That is exactly where the delay was first reported.

The dialogs an operator types in for minutes — Preferences, the cluster
editor, the QSO editor, bulk edit, alert rules, award definitions — now
dim the background harder instead of blurring it. Everything else keeps
the blur: a confirmation you click through in a second costs nothing.
This commit is contained in:
2026-09-08 00:00:47 +02:00
parent 55fbfa4499
commit 3c7ea2d894
7 changed files with 30 additions and 14 deletions
+15 -6
View File
@@ -8,14 +8,23 @@ const DialogTrigger = DialogPrimitive.Trigger;
const DialogPortal = DialogPrimitive.Portal;
const DialogClose = DialogPrimitive.Close;
// blur=false drops the backdrop filter and dims harder instead.
//
// A backdrop-filter over the whole window is recomputed every time anything
// above it repaints — and underneath this one sits an application that never
// stops moving: CAT polls four times a second, spots arrive, meters sweep, maps
// redraw. On a long-lived dialog with text fields in it, that shows as a delay
// between the key and the letter. Ornament is not worth a keyboard that feels
// slow, so the dialogs an operator TYPES in for minutes at a time turn it off.
const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay> & { blur?: boolean }
>(({ className, blur = true, ...props }, ref) => (
<DialogPrimitive.Overlay
ref={ref}
className={cn(
'fixed inset-0 z-50 bg-stone-900/40 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
'fixed inset-0 z-50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
blur ? 'bg-stone-900/40 backdrop-blur-sm' : 'bg-stone-900/60',
className,
)}
{...props}
@@ -25,10 +34,10 @@ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & { hideClose?: boolean; hideOverlay?: boolean }
>(({ className, children, hideClose, hideOverlay, ...props }, ref) => (
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & { hideClose?: boolean; hideOverlay?: boolean; overlayBlur?: boolean }
>(({ className, children, hideClose, hideOverlay, overlayBlur, ...props }, ref) => (
<DialogPortal>
{!hideOverlay && <DialogOverlay />}
{!hideOverlay && <DialogOverlay blur={overlayBlur} />}
<DialogPrimitive.Content
ref={ref}
className={cn(