Skip to content

Instantly share code, notes, and snippets.

@CliftonH
Created December 10, 2025 21:27
Show Gist options
  • Select an option

  • Save CliftonH/f60af359652b76514895c48402576f5c to your computer and use it in GitHub Desktop.

Select an option

Save CliftonH/f60af359652b76514895c48402576f5c to your computer and use it in GitHub Desktop.
titleBarOverlay setWindowButtonPosition calculation bug
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
font-family: system-ui;
}
.titlebar {
position: fixed;
width: 100%;
height: 32px;
background: #1A1D21;
border-bottom: 1px solid #ccc;
-webkit-app-region: drag;
}
.content {
padding: 20px;
-webkit-app-region: no-drag;
}
button {
margin: 5px;
padding: 10px 20px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="titlebar"></div>
<div class="content">
<h3>titleBarOverlay Bug Test</h3>
<p>Click buttons to change zoom:</p>
<button onclick="setZoom(0.7)">70%</button>
<button onclick="setZoom(1.0)">100%</button>
<button onclick="setZoom(1.5)">150%</button>
</div>
<script>
const { ipcRenderer } = require('electron');
function setZoom(zoom) {
ipcRenderer.send('set-zoom', zoom);
}
setZoom(1.0);
</script>
</body>
</html>
const { app, BrowserWindow, ipcMain } = require('electron');
let windowWithoutOverlay;
let windowWithOverlay;
app.whenReady().then(() => {
// Window WITHOUT titleBarOverlay - works correctly
windowWithoutOverlay = new BrowserWindow({
width: 500,
height: 300,
x: 100,
y: 100,
title: 'Without titleBarOverlay',
titleBarStyle: 'hidden',
trafficLightPosition: { x: 12, y: 6 },
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
windowWithoutOverlay.loadFile('index.html');
// Window WITH titleBarOverlay - bug occurs
windowWithOverlay = new BrowserWindow({
width: 500,
height: 300,
x: 650,
y: 100,
title: 'With titleBarOverlay',
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#f0f0f0',
symbolColor: '#000000',
height: 31,
},
trafficLightPosition: { x: 12, y: 6 },
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
windowWithOverlay.loadFile('index.html');
});
// Handle zoom - same formula for both windows
ipcMain.on('set-zoom', (_, zoom) => {
[windowWithOverlay, windowWithoutOverlay].forEach((window) => {
window.webContents.setZoomFactor(zoom);
const titlebarHeight = 32;
const buttonHeight = 16;
// Center the buttons vertically
const y = Math.floor((titlebarHeight / 2) * zoom - buttonHeight / 2);
window.setWindowButtonPosition({
x: Math.round(12 * zoom),
y
});
const hasOverlay = window === windowWithOverlay;
console.log(`Window ${hasOverlay ? 'WITH' : 'WITHOUT'} overlay - Zoom: ${zoom}, Y: ${y}`);
});
});
{
"name": "rude-waves-compute-umsad",
"productName": "rude-waves-compute-umsad",
"description": "My Electron application description",
"keywords": [],
"main": "./main.js",
"version": "1.0.0",
"author": "chensley",
"scripts": {
"start": "electron ."
},
"dependencies": {},
"devDependencies": {
"electron": "39.1.1"
}
}
/**
* This file is loaded via the <script> tag in the index.html file and will
* be executed in the renderer process for that window. No Node.js APIs are
* available in this process because `nodeIntegration` is turned off and
* `contextIsolation` is turned on. Use the contextBridge API in `preload.js`
* to expose Node.js functionality from the main process.
*/
/* styles.css */
/* Add styles here to customize the appearance of your app */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment