How to Keep Streambert’s Picture‑in‑Picture Pop‑Out Window Always on Top

Set alwaysOnTop: true in the BrowserWindow constructor options inside index.js or call setAlwaysOnTop(true) on the window instance to force Streambert’s PiP pop‑out to stay above all other applications.

Streambert is an Electron‑based streaming client that provides picture‑in‑picture (PiP) functionality through a dedicated pop‑out window. By default, this Streambert picture‑in‑picture pop‑out window behaves like a standard browser window and can be hidden behind other apps. This guide explains how to modify the truelockmc/streambert source code to keep the PiP window permanently visible.

Understanding the PiP Window Architecture

Streambert creates the pop‑out window from the Electron main process. In index.js, the application instantiates a BrowserWindow with specific parameters—480×270 dimensions, frameless borders, and resizable handles—to host the detached video stream. By default, this window lacks the always‑on‑top attribute, meaning it respects the normal OS window stacking order and can be obscured when users switch to other applications.

Enabling Always on Top

You can enforce the always‑on‑top behavior either at window creation or dynamically at runtime.

Method 1: Configuration at Creation

The most reliable approach is to add the alwaysOnTop property directly to the window configuration object in index.js. This ensures the flag is active immediately when the PiP window opens.

// index.js - Main Electron entry point
const { BrowserWindow } = require('electron');
const path = require('path');

function createPopoutWindow(url) {
  const popoutWindow = new BrowserWindow({
    width: 480,
    height: 270,
    frame: false,
    resizable: true,
    // Force window to stay above all others
    alwaysOnTop: true,
    webPreferences: {
      preload: path.join(__dirname, 'popout-preload.js'),
    },
  });

  popoutWindow.loadURL(url);
  return popoutWindow;
}

Method 2: Runtime Toggle via IPC

For applications that require a user‑accessible toggle, expose an IPC channel that calls setAlwaysOnTop() on the window reference. This allows the renderer process to change the behavior without recreating the window.

Add the following handler in index.js (or extend src/ipc/player.js):

const { BrowserWindow, ipcMain } = require('electron');

// IPC channel to toggle always-on-top dynamically
ipcMain.handle('popout:set-always-on-top', (event, flag) => {
  const win = BrowserWindow.fromWebContents(event.sender);
  if (win) {
    win.setAlwaysOnTop(flag);
  }
});

In your renderer process (or React component), invoke this channel:

import { ipcRenderer } from 'electron';
import { useState } from 'react';

function AlwaysOnTopToggle() {
  const [isOnTop, setIsOnTop] = useState(true);

  const toggle = async () => {
    const newState = !isOnTop;
    await ipcRenderer.invoke('popout:set-always-on-top', newState);
    setIsOnTop(newState);
  };

  return (
    <button onClick={toggle}>
      {isOnTop ? 'Disable' : 'Enable'} Always on Top
    </button>
  );
}

Key Source Files

The following files in the truelockmc/streambert repository control the PiP window behavior:

  • index.js – Main process entry point where the BrowserWindow is instantiated with PiP dimensions and alwaysOnTop settings.
  • popout-preload.js – Preload script injected into the pop‑out context; can expose safe IPC wrappers via contextBridge for UI toggles.
  • src/ipc/player.js – Dedicated IPC module for player controls; appropriate location for extending window management handlers.

Summary

  • Root cause: The PiP BrowserWindow in index.js defaults to standard window stacking behavior without the alwaysOnTop flag.
  • Static fix: Add alwaysOnTop: true to the constructor options in createPopoutWindow().
  • Dynamic fix: Implement ipcMain.handle('popout:set-always-on-top', ...) to toggle visibility via setAlwaysOnTop().
  • Prerequisite: Changes must be made in the main process; the preload script (popout-preload.js) facilitates secure communication between the renderer and main process.

Frequently Asked Questions

Why does the Streambert PiP window hide behind other apps by default?

Electron BrowserWindow instances default to normal OS window layering unless explicitly configured. The createPopoutWindow function in index.js does not include alwaysOnTop: true in its initial options, so the window follows standard focus rules and can be obscured by other applications.

Can I toggle always-on-top without restarting Streambert?

Yes. Call popoutWindow.setAlwaysOnTop(boolean) on the existing window instance at runtime. Expose this functionality through an IPC channel (e.g., popout:set-always-on-top) so the renderer process can trigger it via UI controls without requiring an application restart.

Where should I register the IPC handler for window management?

Register the handler in index.js alongside other main‑process setup code, or consolidate it in src/ipc/player.js if your fork organizes IPC logic by feature domain. Ensure the handler uses BrowserWindow.fromWebContents(event.sender) to obtain the correct window reference.

Does the always-on-top setting persist across window closes?

No. The alwaysOnTop state is tied to the specific BrowserWindow instance. When the PiP window is closed and reopened via createPopoutWindow(), the new instance will only preserve the setting if you hardcode alwaysOnTop: true in the constructor options. Runtime toggles do not persist for future windows unless you store the preference and read it during initialization.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →