← 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));