Skip to content
Merged
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next2d/builder",
"version": "0.4.3",
"version": "0.4.4",
"description": "Multi-platform builder for Next2d Framework, supporting export to various platforms such as macOS, Windows, iOS, Android and Web(HTML)",
"author": "Toshiyuki Ienaga <ienaga@next2d.app>",
"license": "MIT",
Expand Down
13 changes: 10 additions & 3 deletions src/electron-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,16 @@ export const createElectronPackagerOptions = (
"extraResource": [resources, ...config.nativeBridge ? [path.join(path.dirname(resources), "native")] : []],
"ignore": [/^\/native(?:\/|$)/, /^\/resources(?:\/|$)/, /^\/icons(?:\/|$)/, /^\/forge\.config\.[cm]?js$/, /^\/entitlements\.plist$/, /(?:^|\/)steam_appid\.txt$/],
...os !== "linux" && config.icons[os] ? { "icon": path.resolve(root, config.icons[os]) } : {},
...os === "macos" && config.macos.localNetworkUsageDescription ? {
"extendInfo": { "NSLocalNetworkUsageDescription": config.macos.localNetworkUsageDescription },
"extendHelperInfo": { "NSLocalNetworkUsageDescription": config.macos.localNetworkUsageDescription }
...os === "macos" && (config.macos.localNetworkUsageDescription || config.window.overlay?.enabled) ? {
"extendInfo": {
...config.macos.localNetworkUsageDescription ? { "NSLocalNetworkUsageDescription": config.macos.localNetworkUsageDescription } : {},
// An overlay starts as an agent app (no Dock icon) so that a second launch, which quits at once,
// never shows one. The first instance shows its Dock icon itself (templates/electron/index.js).
...config.window.overlay?.enabled ? { "LSUIElement": true } : {}
},
...config.macos.localNetworkUsageDescription ? {
"extendHelperInfo": { "NSLocalNetworkUsageDescription": config.macos.localNetworkUsageDescription }
} : {}
} : {},
...os === "macos" && sign ? {
"osxSign": {
Expand Down
3 changes: 3 additions & 0 deletions templates/electron/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ const createWindow = async () => {

app.whenReady().then(async () => {
if (!hasLock) return;
// The overlay app is packaged as an agent app (LSUIElement) so a second launch never shows a Dock icon;
// the instance that keeps running shows it.
if (process.platform === "darwin" && overlay) app.dock?.show();
Menu.setApplicationMenu(process.platform === "darwin" ? Menu.buildFromTemplate([
{ role: "appMenu" }, { role: "editMenu" }, { role: "windowMenu" }
]) : null);
Expand Down
5 changes: 4 additions & 1 deletion tests/electron-overlay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const fakeElectron = (options = {}) => {
app: {
isPackaged: false, commandLine: { getSwitchValue: () => "", hasSwitch: () => false }, setName() {}, setPath() {},
requestSingleInstanceLock: () => { calls.push(["requestSingleInstanceLock"]); return options.lock !== false; },
dock: { hide: () => calls.push(["dock.hide"]) },
dock: { hide: () => calls.push(["dock.hide"]), show: () => calls.push(["dock.show"]) },
getPath: () => os.tmpdir(), on: (name, cb) => appListeners.set(name, cb), quit: () => calls.push(["quit"]), exit: (code) => calls.push(["exit", code]),
whenReady: () => new Promise((resolve) => { ready = resolve; })
},
Expand Down Expand Up @@ -235,6 +235,9 @@ test("a desktop overlay runs once: a second launch quits before any window or Do
const first = await startHost(t, { window: { overlay: { enabled: true, clickThrough: true } } });
assert.equal(first.windows.length, 1);
assert.equal(first.calls.some(([name]) => name === "exit"), false);
// The running instance shows its Dock icon itself (the app is packaged as an agent app).
assert.equal(first.calls.some(([name]) => name === "dock.show"), process.platform === "darwin");
assert.equal(denied.calls.some(([name]) => name === "dock.show"), false);
first.calls.length = 0;
first.appListeners.get("second-instance")();
assert.deepEqual(first.calls.filter(([name]) => name === "setAlwaysOnTop"), [["setAlwaysOnTop", true, "floating"]]);
Expand Down
9 changes: 9 additions & 0 deletions tests/electron.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ test("macOS local network purpose is opt-in and applied to the app and helpers",
assert.equal(createElectronPackagerOptions(root, config, "linux", root).extendHelperInfo, undefined);
fs.writeFileSync(path.join(root, "electron.config.json"), "{}");
assert.equal(createElectronPackagerOptions(root, readElectronConfig(root), "macos", root).extendInfo, undefined);
// An overlay is packaged as an agent app (no Dock icon until the running instance shows it).
fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify({ window: { overlay: { enabled: true } } }));
const overlay = createElectronPackagerOptions(root, readElectronConfig(root), "macos", root);
assert.deepEqual(overlay.extendInfo, { LSUIElement: true });
assert.equal(overlay.extendHelperInfo, undefined);
assert.equal(createElectronPackagerOptions(root, readElectronConfig(root), "windows", root).extendInfo, undefined);
fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify({ window: { overlay: { enabled: true } }, macos: { localNetworkUsageDescription: description } }));
assert.deepEqual(createElectronPackagerOptions(root, readElectronConfig(root), "macos", root).extendInfo, { NSLocalNetworkUsageDescription: description, LSUIElement: true });
fs.writeFileSync(path.join(root, "electron.config.json"), "{}");
for (const invalid of [null, 123, "", " ", "\0", "x".repeat(1001)]) {
fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify({
macos: { localNetworkUsageDescription: invalid }
Expand Down
Loading