← back to Desktop Dotbar
electron-main.js.bak-single-20260916T174147Z
102 lines
// Electron shell: a true always-on-top strip across the top of the desktop.
// Spawns the local server, then floats a frameless bar above every window
// (including fullscreen) at 'screen-saver' level. Grows only when a dropdown opens.
'use strict';
const { app, BrowserWindow, ipcMain, screen } = require('electron');
const { spawn } = require('child_process');
const http = require('http');
const fs = require('fs');
const path = require('path');
const DIR = __dirname;
const PANEL_H = 360;
const BAR_DEFAULT = 48, BAR_MIN = 22, BAR_MAX = 140;
const BARH_FILE = path.join(DIR, '.barh');
let win, serverProc, PORT = null;
let isOpen = false; // is a dropdown panel open
let barH = readBarH(); // resizable strip height (persisted)
function clampBar(h) { return Math.max(BAR_MIN, Math.min(BAR_MAX, Math.round(h || BAR_DEFAULT))); }
function readBarH() { try { return clampBar(parseInt(fs.readFileSync(BARH_FILE, 'utf8'), 10)); } catch { return BAR_DEFAULT; } }
function writeBarH() { try { fs.writeFileSync(BARH_FILE, String(barH)); } catch {} }
function portFromFile() { try { return parseInt(fs.readFileSync(path.join(DIR, '.port'), 'utf8'), 10); } catch { return null; } }
function alive(port) {
return new Promise(res => {
if (!port) return res(false);
const r = http.get({ host: '127.0.0.1', port, path: '/health', timeout: 800 }, x => { x.resume(); res(x.statusCode === 200); });
r.on('error', () => res(false)); r.on('timeout', () => { r.destroy(); res(false); });
});
}
// The launcher (start-bar.command) starts the node server; we just wait for it.
async function ensureServer() {
for (let i = 0; i < 50; i++) {
const p = portFromFile();
if (await alive(p)) return p;
await new Promise(r => setTimeout(r, 200));
}
// last resort: spawn it ourselves via Electron-as-node
serverProc = spawn(process.execPath, [path.join(DIR, 'server.js')], {
stdio: 'ignore', env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' } });
for (let i = 0; i < 30; i++) {
await new Promise(r => setTimeout(r, 200));
const p = portFromFile();
if (await alive(p)) return p;
}
return portFromFile() || 9787;
}
function bounds(open) {
const wa = screen.getPrimaryDisplay().workArea; // excludes the menu bar
return { x: wa.x, y: wa.y, width: wa.width, height: open ? barH + PANEL_H : barH };
}
// Apply the current barH (+ open state) to the window and tell the renderer its strip height.
function applyBounds() { if (!win) return; win.setBounds(bounds(isOpen)); try { win.setAlwaysOnTop(true, 'screen-saver'); win.moveTop(); } catch {} }
function pushBarH() { if (win) try { win.webContents.send('dotbar:barH', barH); } catch {} }
// setBarH fires on EVERY pointermove during a grip drag, so keep it cheap: resize the window and
// mirror the height to the renderer live, but do NOT re-assert always-on-top per frame (the 2s
// `raise` interval covers that) and do NOT hit the disk per frame — persist once, debounced, after
// the drag settles. Resize is the sole affordance now (keyboard resize was dropped, DTD 2026-09-16).
let _persistTimer = null;
function setBarH(h) {
barH = clampBar(h);
if (win) win.setBounds(bounds(isOpen)); // live resize only; no per-frame moveTop
pushBarH();
clearTimeout(_persistTimer); _persistTimer = setTimeout(writeBarH, 300);
}
async function createWindow() {
PORT = await ensureServer();
win = new BrowserWindow({
...bounds(false),
type: 'panel', // NSPanel: floats above normal windows, non-activating
frame: false, resizable: false, movable: true, minimizable: false, maximizable: false,
fullscreenable: false, skipTaskbar: true, hasShadow: false, transparent: false,
focusable: false, backgroundColor: '#14161a',
webPreferences: { preload: path.join(DIR, 'preload.js'), contextIsolation: true, nodeIntegration: false },
});
win.setAlwaysOnTop(true, 'screen-saver'); // above normal + fullscreen windows
win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
win.loadURL(`http://127.0.0.1:${PORT}/`);
// Re-assert top without the off→on toggle (which caused a visible drop-flicker).
// setAlwaysOnTop(true, ...) re-elevates on its own, including after setBounds.
const raise = () => { try { win.setAlwaysOnTop(true, 'screen-saver'); win.moveTop(); } catch {} };
const dbg = (tag) => { if (process.env.DOTBAR_DEBUG !== '1') return; try { fs.appendFileSync(path.join(DIR, 'debug.log'),
JSON.stringify({ tag, t: new Date().toISOString(), bounds: win.getBounds(), visible: win.isVisible(), onTop: win.isAlwaysOnTop() }) + '\n'); } catch {} };
win.webContents.on('did-finish-load', () => { raise(); pushBarH(); dbg('did-finish-load'); });
win.webContents.on('did-fail-load', (_e, code, desc) => dbg('FAIL:' + code + ':' + desc));
setInterval(raise, 2000); // re-assert top above other apps
ipcMain.on('dotbar:setOpen', (_e, open) => { isOpen = !!open; applyBounds(); });
ipcMain.on('dotbar:setBarH', (_e, h) => setBarH(h)); // absolute height (grip edge-drag)
ipcMain.on('dotbar:quit', () => app.quit());
}
app.on('window-all-closed', () => app.quit());
app.on('before-quit', () => { if (serverProc) try { serverProc.kill(); } catch {} });
app.whenReady().then(() => {
if (app.dock) app.dock.hide(); // accessory app: panels float above active apps
createWindow().catch(e => console.log('DOTBAR: createWindow ERROR', e && e.stack || e));
});
process.on('uncaughtException', e => console.log('DOTBAR: uncaught', e && e.stack || e));