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 theBrowserWindowis instantiated with PiP dimensions andalwaysOnTopsettings.popout-preload.js– Preload script injected into the pop‑out context; can expose safe IPC wrappers viacontextBridgefor UI toggles.src/ipc/player.js– Dedicated IPC module for player controls; appropriate location for extending window management handlers.
Summary
- Root cause: The PiP
BrowserWindowinindex.jsdefaults to standard window stacking behavior without thealwaysOnTopflag. - Static fix: Add
alwaysOnTop: trueto the constructor options increatePopoutWindow(). - Dynamic fix: Implement
ipcMain.handle('popout:set-always-on-top', ...)to toggle visibility viasetAlwaysOnTop(). - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →