Skip to content

Commit a2b7375

Browse files
committed
fix(startup): full window launch, taskbar icon
1 parent 7d22b8a commit a2b7375

1 file changed

Lines changed: 55 additions & 32 deletions

File tree

app/windows/build.cjs

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const {
99
ipcMain,
1010
nativeImage,
1111
nativeTheme,
12+
screen,
1213
} = require("electron");
1314
const path = require("path");
1415
const fs = require("fs");
@@ -1785,10 +1786,31 @@ function log(msg) {
17851786
} catch (_) {}
17861787
}
17871788

1788-
function createWindow() {
1789+
/** Windows: resolve before the first show() or the taskbar often keeps a blank/generic icon. */
1790+
async function resolveBrowserWindowIcon() {
1791+
const fallback = nativeImageFromAppIcon();
1792+
if (process.platform !== "win32" || !app.isPackaged) return fallback;
1793+
const iconPaths = [resolveAppIconIcoPath(), process.execPath].filter(
1794+
(p) => p && (p === process.execPath || fs.existsSync(p)),
1795+
);
1796+
for (const p of iconPaths) {
1797+
for (const size of ["large", "normal"]) {
1798+
try {
1799+
const img = await app.getFileIcon(p, { size });
1800+
if (!img.isEmpty()) return img;
1801+
} catch (e) {
1802+
try {
1803+
log(`getFileIcon(${p}, ${size}): ${e?.message || e}`);
1804+
} catch (_) {}
1805+
}
1806+
}
1807+
}
1808+
return fallback;
1809+
}
1810+
1811+
async function createWindow() {
17891812
const appPath = app.getAppPath();
17901813
const distPath = path.join(appPath, "dist");
1791-
const windowIcon = nativeImageFromAppIcon();
17921814
const indexHtml = path.join(distPath, "index.html");
17931815

17941816
if (!isDev && !fs.existsSync(indexHtml)) {
@@ -1797,6 +1819,13 @@ function createWindow() {
17971819
return;
17981820
}
17991821

1822+
const windowIcon = await resolveBrowserWindowIcon();
1823+
if (process.platform === "win32" && app.isPackaged && (!windowIcon || windowIcon.isEmpty())) {
1824+
try {
1825+
log("warn: taskbar icon: resolveBrowserWindowIcon returned empty");
1826+
} catch (_) {}
1827+
}
1828+
18001829
// NSIS close-app uses PRODUCT_NAME (package.json → build.productName). The window title must
18011830
// match that string, not a URL — otherwise the installer cannot find/close the running app.
18021831
// Keep in sync with app/package.json "build.productName".
@@ -1816,37 +1845,21 @@ function createWindow() {
18161845
show: false,
18171846
});
18181847

1819-
// Windows: nativeImage.createFromPath(.exe) often returns an empty image; shell-extracted icons work for the taskbar.
1820-
if (process.platform === "win32" && app.isPackaged) {
1821-
const iconPaths = [resolveAppIconIcoPath(), process.execPath].filter(
1822-
(p) => p && (p === process.execPath || fs.existsSync(p)),
1823-
);
1824-
void (async () => {
1825-
for (const p of iconPaths) {
1826-
try {
1827-
const img = await app.getFileIcon(p, { size: "large" });
1828-
if (mainWindow.isDestroyed()) return;
1829-
if (!img.isEmpty()) {
1830-
mainWindow.setIcon(img);
1831-
return;
1832-
}
1833-
} catch (e) {
1834-
try {
1835-
log(`getFileIcon(${p}): ${e?.message || e}`);
1836-
} catch (_) {}
1837-
}
1848+
mainWindow.once("ready-to-show", () => {
1849+
// Edge-to-edge without WS_MAXIMIZE: on Windows, maximize() can interact badly with shell icons
1850+
// and some system shortcuts (e.g. Print Screen); filling the work area matches prior "fullscreen" intent.
1851+
try {
1852+
if (process.platform === "win32") {
1853+
const wa = screen.getPrimaryDisplay().workArea;
1854+
mainWindow.setBounds(wa);
1855+
} else {
1856+
mainWindow.maximize();
18381857
}
1858+
} catch (_) {
18391859
try {
1840-
log("warn: taskbar icon: getFileIcon found no usable image");
1860+
mainWindow.maximize();
18411861
} catch (_) {}
1842-
})();
1843-
}
1844-
1845-
mainWindow.once("ready-to-show", () => {
1846-
// Fill the display work area by default (fresh install, after update, new window).
1847-
try {
1848-
mainWindow.maximize();
1849-
} catch (_) {}
1862+
}
18501863
mainWindow.show();
18511864
});
18521865

@@ -1907,7 +1920,11 @@ app.whenReady().then(() => {
19071920
return net.fetch(pathToFileURL(resolved).toString());
19081921
});
19091922
}
1910-
createWindow();
1923+
createWindow().catch((e) => {
1924+
try {
1925+
log(`createWindow: ${e?.message || e}`);
1926+
} catch (_) {}
1927+
});
19111928
setupAutoUpdater();
19121929
});
19131930

@@ -1917,5 +1934,11 @@ app.on("window-all-closed", () => {
19171934
});
19181935

19191936
app.on("activate", () => {
1920-
if (BrowserWindow.getAllWindows().length === 0) createWindow();
1937+
if (BrowserWindow.getAllWindows().length === 0) {
1938+
createWindow().catch((e) => {
1939+
try {
1940+
log(`createWindow (activate): ${e?.message || e}`);
1941+
} catch (_) {}
1942+
});
1943+
}
19211944
});

0 commit comments

Comments
 (0)