Apologies, but there is an alternative available that comes with a few limitations:
Here's an example of a title bar in react-ts that tracks mouse movement during dragging:
function Header({ leading, navigation, following }: HeaderProps) {
const navigate = useNavigate();
const [, startTransition] = useTransition();
const [dragging, setDragging] = useState(false);
return (
<div
className="titleBar"
onMouseDown={() => {
setDragging(true);
}}
onMouseUp={() => {
setDragging(false);
}}
onMouseLeave={() => {
setDragging(false);
}}
onMouseMove={(e) => {
if (dragging) {
window.electron.ipcRenderer.sendMessage(
'window',
'move',
e.movementX,
e.movementY
);
}
}}
>
<div className="flexrow_start">
{leading}
<div>
{navigation.map((info, index) => (
<button
type="button"
onClick={(e) => {
e.preventDefault();
startTransition(() => {
navigate(info.destination ?? '/');
});
}}
key={index}
>
{info.content}
</button>
))}
</div>
</div>
{following !== undefined && (
<div className="flexrow_end"> {following}</div>
)}
</div>
);
}
In your main.ts file:
ipcMain.on('window', (e, arg, arg2, arg3) => {
switch (arg as string) {
// action triggered from element in header for minimizing window
case 'min':
mainWindow?.minimize();
break;
// action triggered from element in header for maximizing window
case 'max':
if (mainWindow?.isMaximized()) {
mainWindow.unmaximize();
} else {
mainWindow?.maximize();
}
break;
// action triggered from element in header for closing app
case 'close':
app.quit();
break;
// movement handler for header element dragging
case 'move':
console.log(arg2, arg3);
mainWindow?.setPosition(
mainWindow.getPosition()[0] + arg2,
mainWindow.getPosition()[1] + arg3
);
break;
default:
break;
}
});
.titleBar{
height: 50px;
display: flex;
justify-content: space-between;
}
.titleBar:hover{
cursor: grab;
}
NOTE: This solution may not work optimally when moving the electron app between displays. If you have a workaround for this issue, please feel free to share in the comments. Thank you!