Streambert Custom Frameless Titlebar on Windows and Linux: Complete Implementation Guide
Streambert implements a custom frameless titlebar on Windows and Linux by detecting the host platform at startup, conditionally rendering a React-based WindowTitlebar component, and exposing window-control APIs through Electron's preload script to handle minimize, maximize, and close actions.
The truelockmc/streambert repository uses Electron's BrowserWindow with titleBarStyle: "hidden" to create a chrome-less application window. When the app launches on Windows or Linux, it injects a custom draggable titlebar that matches the application's streaming interface, ensuring consistent cross-platform aesthetics while maintaining native window management functionality.
Platform Detection in App.jsx
The implementation begins in src/App.jsx where the renderer process queries the main process for the host platform. The application calls window.electron.getPlatform() during initialization and stores the result in React state.
When the platform resolves to "win32" or "linux", two critical actions occur:
- State Update – A boolean flag
hasCustomTitlebarbecomes true, triggering a conditional render - CSS Hook – The code sets
document.documentElement.setAttribute("data-win-titlebar", "1")to enable platform-specific styling rules
// src/App.jsx – Platform detection and conditional rendering
const [platform, setPlatform] = useState("");
useEffect(() => {
window.electron?.getPlatform().then((p) => {
setPlatform(p);
if (p === "win32" || p === "linux") {
document.documentElement.setAttribute("data-win-titlebar", "1");
}
});
}, []);
const hasCustomTitlebar = platform === "win32" || platform === "linux";
return (
<>
{hasCustomTitlebar && <WindowTitlebar />}
{/* Application routes and components */}
</>
);
Source: src/App.jsx#L11-L38
The WindowTitlebar React Component
The WindowTitlebar component in src/components/WindowTitlebar.jsx renders the draggable bar and window controls. It utilizes the -webkit-app-region: drag CSS property to make the bar behave like a native titlebar, allowing users to click and drag the entire window from the custom UI element.
The component maintains internal state for the maximized status and syncs with the main process through IPC listeners:
// src/components/WindowTitlebar.jsx
export default function WindowTitlebar() {
const [maximized, setMaximized] = useState(false);
const applyMaximizedState = (isMax) => {
setMaximized(isMax);
if (isMax) {
document.documentElement.setAttribute("data-maximized", "1");
} else {
document.documentElement.removeAttribute("data-maximized");
}
};
useEffect(() => {
if (!window.electron) return;
// Initialize state
window.electron.windowIsMaximized?.().then(applyMaximizedState);
// Listen for state changes from main process
const handler = window.electron.onWindowMaximize?.(applyMaximizedState);
return () => window.electron.offWindowMaximize?.(handler);
}, []);
const minimize = () => window.electron?.windowMinimize();
const toggleMaximize = () => window.electron?.windowToggleMaximize();
const close = () => window.electron?.windowClose();
return (
<div className="window-titlebar" style={{ WebkitAppRegion: "drag" }}>
<div style={{ WebkitAppRegion: "no-drag" }}>STREAMBERT</div>
<div style={{ WebkitAppRegion: "no-drag" }}>
<button onClick={minimize}>Minimize</button>
<button onClick={toggleMaximize}>
{maximized ? "Restore" : "Maximize"}
</button>
<button onClick={close}>Close</button>
</div>
</div>
);
}
Source: src/components/WindowTitlebar.jsx
IPC Bridge in the Preload Script
The preload script exposes a secure API surface for window management through contextBridge.exposeInMainWorld. This allows the renderer process to invoke main process methods without exposing the full Node.js or Electron API.
The following methods are injected into the global window.electron object:
windowMinimize()– Invokeswindow-minimizeIPC channelwindowToggleMaximize()– Invokeswindow-toggle-maximizeIPC channelwindowClose()– Invokeswindow-closeIPC channelwindowIsMaximized()– Returns promise with current maximized stateonWindowMaximize(callback)– Registers listener for maximize state changesoffWindowMaximize(handler)– Removes maximize state listenergetPlatform()– Returns the host platform string (win32,linux,darwin)
// preload.js – IPC exposure for custom titlebar controls
contextBridge.exposeInMainWorld("electron", {
windowMinimize: () => ipcRenderer.invoke("window-minimize"),
windowToggleMaximize: () => ipcRenderer.invoke("window-toggle-maximize"),
windowClose: () => ipcRenderer.invoke("window-close"),
windowIsMaximized: () => ipcRenderer.invoke("window-is-maximized"),
onWindowMaximize: (callback) => {
const handler = (_, value) => callback(value);
ipcRenderer.on("window-maximized", handler);
return handler;
},
offWindowMaximize: (handler) => {
ipcRenderer.removeListener("window-maximized", handler);
},
getPlatform: () => ipcRenderer.invoke("get-platform"),
});
Source: preload.js#L46-L58
CSS Integration and Styling
The global stylesheet in src/styles/global.css leverages the data-win-titlebar HTML attribute to conditionally apply styles only when the custom titlebar is present. This ensures the application layout adjusts correctly to accommodate the 32-pixel draggable region at the top of the window.
A specific rule at line 1019 handles fullscreen video player scenarios, ensuring the custom titlebar remains accessible or properly hidden depending on the viewing mode:
/* src/styles/global.css – Titlebar visibility in fullscreen mode */
[data-player-fullscreen] .window-titlebar {
/* Maintains bar visibility or adjusts z-index during fullscreen playback */
}
Source: src/styles/global.css#L1019
End-to-End Execution Flow
- Application Startup – Main process creates a
BrowserWindowwithtitleBarStyle: "hidden"and loads the renderer - Platform Query –
App.jsxexecuteswindow.electron.getPlatform()and setsdata-win-titlebar="1"on the document element for supported platforms - Component Mount – React renders
<WindowTitlebar />which immediately querieswindowIsMaximized()to sync initial state - User Interaction – Clicking minimize, maximize, or close buttons invokes the corresponding preload API, which sends IPC messages to the main process
- State Synchronization – The main process broadcasts
window-maximizedevents when the window state changes, updating the component's button icons (maximize vs. restore)
Summary
- Platform Detection occurs in
src/App.jsxusingwindow.electron.getPlatform(), enabling the custom titlebar only on Windows and Linux - WindowTitlebar Component provides a draggable region using
WebkitAppRegion: "drag"and three control buttons usingWebkitAppRegion: "no-drag" - IPC Layer in
preload.jsexposeswindowMinimize(),windowToggleMaximize(), andwindowClose()methods that communicate with the main process - CSS Hooks leverage the
data-win-titlebarattribute to conditionally style the application when the custom chrome is present - State Management uses a combination of initial async queries and event listeners (
onWindowMaximize) to keep the UI synchronized with the actual window state
Frequently Asked Questions
How does Streambert detect whether to show the custom titlebar?
The application calls window.electron.getPlatform() in src/App.jsx during the initial render cycle. If the returned string equals "win32" or "linux", the code sets hasCustomTitlebar to true and injects the <WindowTitlebar /> component. This detection happens before the main UI renders, ensuring no visual flicker between native and custom chrome.
What Electron APIs enable the window controls to function?
The preload script exposes IPC channels that map to BrowserWindow methods in the main process. Specifically, windowMinimize() invokes win.minimize(), windowToggleMaximize() calls win.maximize() or win.unmaximize() depending on current state, and windowClose() executes win.close(). These are bridged through ipcRenderer.invoke() and ipcRenderer.on() for asynchronous communication.
Why does the custom titlebar use WebkitAppRegion CSS properties?
The -webkit-app-region: drag property allows HTML elements to behave like native titlebars, enabling users to click and drag the entire application window from that region. Conversely, -webkit-app-region: no-drag applied to the control buttons ensures that clicking minimize, maximize, or close does not initiate a window drag operation, maintaining expected desktop application behavior.
How does the application handle maximized state synchronization?
The WindowTitlebar component initializes its state by calling window.electron.windowIsMaximized(), which returns a promise resolving to the current maximized boolean. It then registers a listener via window.electron.onWindowMaximize() that updates React state whenever the main process emits window-maximized events. This bidirectional sync ensures the maximize/restore button icon accurately reflects the window state even when changed via OS shortcuts or taskbar interactions.
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 →