fix(embedded-mpv): detect MatDialog overlays, not just CDK backdrops

The command palette is a MatDialog with a transparent backdrop, and the
prior MutationObserver-only detector did not reliably catch it across
overlay-container instantiation timing — the player kept rendering at full
bounds while the palette was open and continued occluding it. Subscribe
directly to MatDialog.afterOpened / afterAllClosed for the authoritative
"any modal dialog open" signal, and keep the OverlayContainer mutation
observer as a fallback for non-dialog CDK overlays. Either signal flips
overlayActive, hiding the embedded MPV view as before.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: f957cd9849e0
This commit is contained in:
4grayandClaude Opus 4.7 committed 2026-05-05 09:23:32 +02:00
1 parent 2b0287c2f1
commit 32779f99a4
1 file changed
+22 -11
@@ -1,29 +1,40 @@
import { Injectable, inject, signal } from '@angular/core';
import { OverlayContainer } from '@angular/cdk/overlay';
import { MatDialog } from '@angular/material/dialog';
@Injectable({ providedIn: 'root' })
export class EmbeddedMpvOverlayVisibilityService {
readonly overlayActive = signal(false);
private readonly overlayContainer = inject(OverlayContainer);
private readonly dialog = inject(MatDialog);
private observer: MutationObserver | null = null;
constructor() {
if (typeof MutationObserver === 'undefined') {
return;
this.dialog.afterOpened.subscribe(() => this.recompute());
this.dialog.afterAllClosed.subscribe(() => this.recompute());
if (typeof MutationObserver !== 'undefined') {
const container = this.overlayContainer.getContainerElement();
this.observer = new MutationObserver(() => this.recompute());
this.observer.observe(container, {
childList: true,
subtree: true,
});
}
const container = this.overlayContainer.getContainerElement();
this.observer = new MutationObserver(() => this.recompute(container));
this.observer.observe(container, { childList: true, subtree: true });
this.recompute(container);
this.recompute();
}
private recompute(container: HTMLElement): void {
const hasBackdrop =
container.querySelector('.cdk-overlay-backdrop') !== null;
if (this.overlayActive() !== hasBackdrop) {
this.overlayActive.set(hasBackdrop);
private recompute(): void {
const dialogOpen = this.dialog.openDialogs.length > 0;
const backdropPresent =
this.overlayContainer
.getContainerElement()
.querySelector('.cdk-overlay-backdrop') !== null;
const next = dialogOpen || backdropPresent;
if (this.overlayActive() !== next) {
this.overlayActive.set(next);
}
}
}