Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 36 additions & 23 deletions electron/main.cts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ let smtcWorker: Worker | null = null;

const isMac = process.platform === 'darwin';
const isWin = process.platform === 'win32';
const isLinux = process.platform === 'linux';
const isDev = !app.isPackaged;

if (isDev) {
Expand All @@ -28,6 +29,9 @@ function getSystemConfig() {
}

console.log("[SYS] Hardware Acceleration: FORCED ENABLED");
if (isLinux) {
app.commandLine.appendSwitch('enable-transparent-visuals');
}

// SURGICAL FIX FOR VIDEO BLACKOUT & OCCLUSION
app.commandLine.appendSwitch('disable-features', 'CalculateNativeWinOcclusion,WindowOcclusion,HardwareMediaKeyHandling,MediaSessionService');
Expand Down Expand Up @@ -140,7 +144,7 @@ function createWindow() {

// Mac: use `bounds` (full screen incl. menu bar + Dock area) instead of `workArea`.
// This prevents macOS from clipping the transparent window at the Dock boundary.
const macScreen = isMac ? primary.bounds : primary.workArea;
const macScreen = isMac || isLinux ? primary.bounds : primary.workArea;
const winWidth = isWin ? 6000 : macScreen.width;
const winHeight = isWin ? 4000 : macScreen.height;
const winX = isWin ? x : macScreen.x;
Expand All @@ -158,11 +162,11 @@ function createWindow() {
backgroundColor: '#00000000', // Explicit transparent alpha channel to fix Windows DWM occlusion blurring
alwaysOnTop: true,
skipTaskbar: true,
type: (isWin ? 'toolbar' : 'panel') as 'toolbar', // Win: toolbar (DWM throttle fix) | Mac: panel (NSPanel, floats above Dock)
type: (isMac ? 'panel' : 'toolbar') as any, // Win/Linux: toolbar (DWM throttle fix / Taskbar hide) | Mac: panel (NSPanel, floats above Dock)
resizable: false,
maximizable: false,
enableLargerThanScreen: isWin,
hasShadow: isMac ? false : true, // Mac: prevent native shadow being cast on invisible transparent divs (ghost stroke)
hasShadow: (isMac || isLinux) ? false : true, // Mac/Linux: prevent native shadow being cast on invisible transparent divs (ghost stroke)
icon: path.join(__dirname, '../build/icon.png'),
webPreferences: {
nodeIntegration: false,
Expand All @@ -175,13 +179,13 @@ function createWindow() {
mainWindow.setMinimumSize(6000, 4000);
mainWindow.setMaximumSize(12000, 12000);
mainWindow.setSize(6000, 4000);
} else if (isMac) {
} else if (isMac || isLinux) {
mainWindow.setMinimumSize(winWidth, winHeight);
mainWindow.setSize(winWidth, winHeight);
}
// Win: screen-saver (highest DWM level) | Mac: floating (above Dock, below TCC prompts)
mainWindow.setAlwaysOnTop(true, isMac ? 'floating' : 'screen-saver', 1);
if (isMac) {
mainWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 1);
if (isMac || isLinux) {
// Ensure KoBar stays above Dock, Mission Control overlays, and full-screen apps on macOS
mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
mainWindow.setAlwaysOnTop(true, 'floating', 1); // re-enforce after workspace registration
Expand Down Expand Up @@ -211,8 +215,8 @@ function createWindow() {
if (!isHidden) {
mainWindow.show();
}
mainWindow.setAlwaysOnTop(true, isMac ? 'floating' : 'screen-saver', 1);
if (isMac) {
mainWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 1);
if (isMac || isLinux) {
// Re-enforce workspace visibility after window is fully loaded
mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
mainWindow.setAlwaysOnTop(true, 'floating', 1);
Expand Down Expand Up @@ -242,7 +246,7 @@ function createWindow() {
// Re-enforce Always on Top when losing focus to taskbar
mainWindow.on('blur', () => {
if (!isAwaitingPinTarget && mainWindow) {
mainWindow.setAlwaysOnTop(true, 'screen-saver', 1);
mainWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 1);
}
});
}
Expand Down Expand Up @@ -291,7 +295,7 @@ function calculatePrimaryCenterPosition(): { x: number; y: number } {
const primary = screen.getPrimaryDisplay();
const wa = primary.workArea; // { x, y, width, height } in OS coords

if (isMac) {
if (isMac || isLinux) {
return { x: wa.x, y: wa.y };
}

Expand All @@ -313,7 +317,7 @@ function teleportToPrimaryCenter(showWindow = true) {
if (showWindow) {
mainWindow.show();
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.setAlwaysOnTop(true, 'screen-saver', 1);
mainWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 1);
mainWindow.focus();
}

Expand Down Expand Up @@ -373,7 +377,7 @@ function startClipboardPolling() {
}
}
}
}, isMac ? 1000 : 500);
}, (isMac || isLinux) ? 1000 : 500);
}

function stopClipboardPolling() {
Expand Down Expand Up @@ -473,8 +477,17 @@ app.whenReady().then(() => {
psProcess?.stdin?.write(`Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class K { [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); [DllImport("user32.dll")] public static extern short GetAsyncKeyState(int vKey); [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } }'\n`);
}

createWindow();
createTray();
if (isLinux) {
// Linux requires a delay after 'enable-transparent-visuals' for the compositor
// to be ready before creating transparent BrowserWindows.
setTimeout(() => {
createWindow();
createTray();
}, 1000);
} else {
createWindow();
createTray();
}

// Handle microphone permissions explicitly for voice-to-text
session.defaultSession.setPermissionCheckHandler((_webContents: WebContents | null, permission: string) => {
Expand Down Expand Up @@ -542,7 +555,7 @@ app.whenReady().then(() => {
});
psProcess.stdin!.write(psPinScript + '\n');
}
} else if (isMac) {
} else if (isMac || isLinux) {
if (mainWindow) {
mainWindow.setAlwaysOnTop(true, 'screen-saver', 1);
mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
Expand Down Expand Up @@ -655,8 +668,8 @@ ipcMain.handle('check-for-updates-manual', async () => {
});

ipcMain.on('enter-pin-targeting', () => {
if (isMac) {
// macOS: Panel windows don't fire blur events reliably.
if (isMac || isLinux) {
// macOS/Linux: Implement pseudo-pin: immediately elevate KoBar to screen-saver level.
// Implement pseudo-pin: immediately elevate KoBar to screen-saver level.
if (mainWindow) {
mainWindow.setAlwaysOnTop(true, 'screen-saver', 1);
Expand All @@ -683,7 +696,7 @@ ipcMain.on('unpin-current-window', () => {
}
allPinnedHwnds.delete(hwndToUnpin);
stopWindowTracking();
} else if (isMac && mainWindow) {
} else if ((isMac || isLinux) && mainWindow) {
mainWindow.setAlwaysOnTop(true, 'floating', 1);
pinnedHwnd = null;
mainWindow.webContents.send('pinned-window-changed', null);
Expand Down Expand Up @@ -1457,7 +1470,7 @@ ipcMain.handle('start-screenshot-capture', async () => {
// 7. Show KoBar back so the overlay React component becomes visible
if (mainWindow) {
mainWindow.show();
mainWindow.setAlwaysOnTop(true, isMac ? 'floating' : 'screen-saver', 1);
mainWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 1);
}

return {
Expand All @@ -1471,7 +1484,7 @@ ipcMain.on('cancel-screenshot', () => {
if (mainWindow) {
if (preScreenshotBounds) mainWindow.setBounds(preScreenshotBounds);
mainWindow.show();
mainWindow.setAlwaysOnTop(true, isMac ? 'floating' : 'screen-saver', 1);
mainWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 1);
}
});

Expand Down Expand Up @@ -1499,7 +1512,7 @@ ipcMain.handle('save-screenshot', async (_event, data: { buffer: string; format:
});

// Restore alwaysOnTop
if (mainWindow) mainWindow.setAlwaysOnTop(true, 'screen-saver', 1);
if (mainWindow) mainWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 1);

if (result.canceled || !result.filePath) return { success: false, reason: 'cancelled' };
savePath = result.filePath;
Expand Down Expand Up @@ -1528,7 +1541,7 @@ ipcMain.on('screenshot-session-complete', () => {
if (mainWindow) {
if (preScreenshotBounds) mainWindow.setBounds(preScreenshotBounds);
mainWindow.show();
mainWindow.setAlwaysOnTop(true, isMac ? 'floating' : 'screen-saver', 1);
mainWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 1);
}
});

Expand Down Expand Up @@ -1642,7 +1655,7 @@ function createPipWindow(videoUrl: string, title: string, albumArt?: string | nu
pipWindow.webContents.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';

pipWindow.setAspectRatio(16 / 9);
pipWindow.setAlwaysOnTop(true, isMac ? 'floating' : 'screen-saver', 2);
pipWindow.setAlwaysOnTop(true, (isMac || isLinux) ? 'floating' : 'screen-saver', 2);

const encodedUrl = encodeURIComponent(videoUrl);
const encodedTitle = encodeURIComponent(title);
Expand Down
1 change: 1 addition & 0 deletions electron/smtc-worker.cts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ let SMTCMonitor: any = null;
let smtcAvailable = false;

const isWin = process.platform === 'win32';
const isLinux = process.platform === 'linux';

if (isWin) {
try {
Expand Down
Loading
Loading