Web: voice/stream pop-out opens briefly and immediately closes

(#861) Bug Fixed video voice

Observed behaviour

In the web app, clicking Pop-out call while in a voice call / watching a screenshare briefly opens a new popup window and then immediately closes it again. Expected behaviour: The popup window should remain open and render the call/stream. The issue is reproducible on the same self-hosted Fluxer instance in multiple browser/OS combinations:
  • Firefox on Linux
  • Chrome on Windows
While debugging, I observed that Fluxer calls window.open() twice for the same named popup target (fluxer-voice-popout:call:<channelId>). If I intercept only the second window.open() call and return the already existing popup window instead, the pop-out remains open and works correctly. The same workaround fixes the issue in both Firefox/Linux and Chrome/Windows. No interception of window.close() or other browser behaviour is required for the workaround.

Reproduction steps

  1. Open the self-hosted Fluxer instance in a web browser.
  2. Join a voice channel / call.
  3. Open a screenshare or call view.
  4. Click Pop-out call in the bottom-right corner.
  5. Observe that a popup window appears briefly and then immediately closes.

Build information

Stable Web 2026.920.41245, Linux (x64), Firefox 156.0, Locale en-US

Platform

Web

Instance

Self-hosted, v1, PostgreSQL, Docker

Evidence

The current browser pop-out implementation appears to open the same named window twice. PopoutWindowManager.ts opens the browser window when registering the pop-out:
const childWindow = window.open(
    'about:blank',
    descriptor.key,
    `width=${width},height=${height}`,
);
PopoutWindow.tsx then calls window.open() again using the same windowKey:
const features = `width=${initialSizeRef.current.width},height=${initialSizeRef.current.height}`;
const childWindow = window.open('about:blank', windowKey, features);
PopoutWindow.tsx also registers a pagehide handler which calls onClosed():
const handlePageHide = (): void => {
    if (closed) return;
    closed = true;
    onClosedRef.current(windowGeneration);
};

childWindow.addEventListener('pagehide', handlePageHide);
The effect cleanup then closes the child window:
return () => {
    disconnectThemeObserver();
    disconnectStylesheetObserver();
    childWindow.removeEventListener('pagehide', handlePageHide);
    closed = true;

    if (!childWindow.closed) {
        childWindow.close();
    }
};

Details

Observed call sequence

While debugging in Firefox, I instrumented window.open() in the main Fluxer window. Two calls to window.open() are made for the same named target, similar to:
window.open(
    "about:blank",
    "fluxer-voice-popout:call:<channelId>",
    "width=960,height=600"
)
The popup opens briefly and is then closed again. The cleanup stack traces back through the pop-out components, including:
PopoutWindow.tsx
VoicePopoutHost.tsx

Working diagnostic workaround

To test whether the second window.open() call is involved, I intercepted only subsequent calls for an already-open fluxer-voice-popout:* target and returned the existing window instead:
(() => {
    const originalOpen = window.open.bind(window);
    const popouts = new Map();

    window.open = (url, target, features) => {
        if (
            typeof target === "string" &&
            target.startsWith("fluxer-voice-popout:")
        ) {
            const existing = popouts.get(target);

            if (existing && !existing.closed) {
                return existing;
            }

            const popup = originalOpen(url, target, features);

            if (popup) {
                popouts.set(target, popup);
            }

            return popup;
        }

        return originalOpen(url, target, features);
    };
})();
With this workaround active, the pop-out remains open and the call/stream renders correctly. No interception of window.close() or other browser behaviour is required for the workaround.

Likely cause

The issue appears to be related to the pop-out lifecycle and the second window.open('about:blank', ...) call for the same named target. This is not Firefox-specific: the same behaviour is reproducible in Chrome on Windows. In both tested environments, intercepting the second window.open() call and returning the already existing Window object makes the pop-out work normally. The exact reason why the second call causes the pop-out lifecycle to be torn down has not been determined yet.

2 comments

Sign in with Fluxer to comment and vote.
Comment by @SolunaCG
RexSystem 1 vote originally by @SolunaCG on GitHub OP
Updated the report after additional testing. The issue is not Firefox-specific. It is also reproducible in Chrome on Windows on the same self-hosted instance, and the same window.open() workaround fixes it there as well. I updated the title, reproduction details and evidence accordingly.
Comment by @omstr
RexSystem 1 vote originally by @omstr on GitHub
Thanks for the detailed report, I did notice it wasn't browser specific, so I've spent mayybe too long fixing this issue and i'm unable to repro it anymore on a fairly strict firefox derivative and brave. I'll tag this issue in the PR i'll open