desktop-pet-app 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/main/index.js +66 -1
- package/package.json +1 -1
package/out/main/index.js
CHANGED
|
@@ -3144,6 +3144,67 @@ async function dutyLoop(adapter) {
|
|
|
3144
3144
|
}
|
|
3145
3145
|
}
|
|
3146
3146
|
}
|
|
3147
|
+
const TAKEOVER_TIMEOUT_MS = 5e3;
|
|
3148
|
+
const TAKEOVER_POLL_MS = 100;
|
|
3149
|
+
function takeOverRunningInstance() {
|
|
3150
|
+
if (process.platform === "win32") return false;
|
|
3151
|
+
const pid = readLockOwnerPid();
|
|
3152
|
+
if (!pid) return false;
|
|
3153
|
+
if (!processIsDesktopPet(pid)) {
|
|
3154
|
+
logger.warn("single-instance lock held by an unrelated process, refusing to take over", { pid });
|
|
3155
|
+
return false;
|
|
3156
|
+
}
|
|
3157
|
+
logger.info("taking over running instance", { pid });
|
|
3158
|
+
try {
|
|
3159
|
+
process.kill(pid, "SIGTERM");
|
|
3160
|
+
} catch {
|
|
3161
|
+
return true;
|
|
3162
|
+
}
|
|
3163
|
+
if (waitForExit(pid, TAKEOVER_TIMEOUT_MS)) return true;
|
|
3164
|
+
logger.warn("instance did not exit after SIGTERM, forcing", { pid });
|
|
3165
|
+
try {
|
|
3166
|
+
process.kill(pid, "SIGKILL");
|
|
3167
|
+
} catch {
|
|
3168
|
+
return true;
|
|
3169
|
+
}
|
|
3170
|
+
return waitForExit(pid, 1e3);
|
|
3171
|
+
}
|
|
3172
|
+
function readLockOwnerPid() {
|
|
3173
|
+
let target;
|
|
3174
|
+
try {
|
|
3175
|
+
target = node_fs.readlinkSync(node_path.join(electron.app.getPath("userData"), "SingletonLock"));
|
|
3176
|
+
} catch {
|
|
3177
|
+
return void 0;
|
|
3178
|
+
}
|
|
3179
|
+
const hostPrefix = `${node_os.hostname()}-`;
|
|
3180
|
+
if (!target.startsWith(hostPrefix)) return void 0;
|
|
3181
|
+
const pid = Number(target.slice(hostPrefix.length));
|
|
3182
|
+
return Number.isSafeInteger(pid) && pid > 0 ? pid : void 0;
|
|
3183
|
+
}
|
|
3184
|
+
function processIsDesktopPet(pid) {
|
|
3185
|
+
try {
|
|
3186
|
+
const command = node_child_process.execFileSync("/bin/ps", ["-p", String(pid), "-o", "command="], { encoding: "utf8" });
|
|
3187
|
+
return /desktop[- ]pet/i.test(command);
|
|
3188
|
+
} catch {
|
|
3189
|
+
return false;
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
function waitForExit(pid, timeoutMs) {
|
|
3193
|
+
const deadline = Date.now() + timeoutMs;
|
|
3194
|
+
while (Date.now() < deadline) {
|
|
3195
|
+
if (!processAlive(pid)) return true;
|
|
3196
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, TAKEOVER_POLL_MS);
|
|
3197
|
+
}
|
|
3198
|
+
return !processAlive(pid);
|
|
3199
|
+
}
|
|
3200
|
+
function processAlive(pid) {
|
|
3201
|
+
try {
|
|
3202
|
+
process.kill(pid, 0);
|
|
3203
|
+
return true;
|
|
3204
|
+
} catch {
|
|
3205
|
+
return false;
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3147
3208
|
const trayIcon1xPath = path.join(__dirname, "./chunks/tray-iconTemplate-BIK86F-0.png");
|
|
3148
3209
|
const trayIcon2xPath = path.join(__dirname, "./chunks/tray-iconTemplate@2x-B19HpcaE.png");
|
|
3149
3210
|
let tray;
|
|
@@ -3182,8 +3243,12 @@ if (profileDirectory) {
|
|
|
3182
3243
|
electron.app.setPath("userData", node_path.resolve(profileDirectory));
|
|
3183
3244
|
}
|
|
3184
3245
|
registerAccountProtocol();
|
|
3185
|
-
|
|
3246
|
+
let singleInstance = electron.app.requestSingleInstanceLock();
|
|
3247
|
+
if (!singleInstance && takeOverRunningInstance()) {
|
|
3248
|
+
singleInstance = electron.app.requestSingleInstanceLock();
|
|
3249
|
+
}
|
|
3186
3250
|
if (!singleInstance) {
|
|
3251
|
+
logger.warn("another instance is running, quitting");
|
|
3187
3252
|
electron.app.quit();
|
|
3188
3253
|
} else {
|
|
3189
3254
|
electron.app.on("second-instance", (_event, argv) => {
|