두 macOS 한정 버그 묶음: 1. autostart --hidden 으로 spawn 시 quickCapture (NSPanel) 만 떠 있어 dock running indicator (점) 가 표출 안 됨 — NSPanel 은 NSApp main window 로 register 안 됨. inboxWindow 를 hidden 상태로 미리 create + ready-to-show 시점에 showInactive → hide trick 으로 NSApp 에 register, 사용자 화면 깜빡임 없이 dock 점 켜짐. 2. SettingsPage 의 자동실행 mismatch 경고가 macOS 에서 false positive. macOS 13+ 의 SMAppService API 가 args 옵션 무시 + unsigned/Electron 앱에 대해 executableWillLaunchAtLogin 을 자주 false 로 반환 → 정상 등록 상태에서도 경고 떠 있음. AutostartDiagnostic 결과에 platform 필드 추가, willLaunch 신호는 win32 에서만 mismatch 판정에 사용. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
64 lines
2.5 KiB
TypeScript
64 lines
2.5 KiB
TypeScript
import electron from 'electron';
|
|
import { execFile } from 'node:child_process';
|
|
const { app } = electron;
|
|
|
|
/**
|
|
* v0.2.7 F12 deeper fix — 자동 실행 진단 정보 수집.
|
|
*
|
|
* Electron 의 `app.getLoginItemSettings()` 는 args 가 매칭돼야만 정확한 상태를 반환 →
|
|
* `args: ['--hidden']` 으로 등록 vs `args: undefined` 로 조회하면 mismatch 가 발생할 수 있다.
|
|
* 그래서 두 호출 결과를 모두 노출 (withArgs / noArgs) + Win 에서는 registry 직접 조회까지.
|
|
*/
|
|
export interface AutostartState {
|
|
withArgs: { openAtLogin: boolean; executableWillLaunchAtLogin: boolean };
|
|
noArgs: { openAtLogin: boolean; executableWillLaunchAtLogin: boolean };
|
|
execPath: string;
|
|
/**
|
|
* 플랫폼 분기용. macOS 13+ 의 SMAppService API 는 args 옵션 무시 + unsigned/Electron
|
|
* 앱에 대해 executableWillLaunchAtLogin 이 false 를 반환할 수 있어, mismatch 판정에서
|
|
* 해당 신호를 제외해야 false positive 방지 가능.
|
|
*/
|
|
platform: NodeJS.Platform;
|
|
registryPath?: string;
|
|
registryValue?: string | null;
|
|
}
|
|
|
|
const WIN_REGISTRY_PATH = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';
|
|
const WIN_REGISTRY_KEY = 'Inkling';
|
|
|
|
export async function collectAutostartState(): Promise<AutostartState> {
|
|
const w = app.getLoginItemSettings({ args: ['--hidden'] });
|
|
const n = app.getLoginItemSettings();
|
|
const state: AutostartState = {
|
|
withArgs: { openAtLogin: w.openAtLogin, executableWillLaunchAtLogin: w.executableWillLaunchAtLogin },
|
|
noArgs: { openAtLogin: n.openAtLogin, executableWillLaunchAtLogin: n.executableWillLaunchAtLogin },
|
|
execPath: process.execPath,
|
|
platform: process.platform
|
|
};
|
|
if (process.platform === 'win32') {
|
|
state.registryPath = `${WIN_REGISTRY_PATH}\\${WIN_REGISTRY_KEY}`;
|
|
state.registryValue = await readRegistrySilent();
|
|
}
|
|
return state;
|
|
}
|
|
|
|
/**
|
|
* `reg query` 로 HKCU\\...\\Run\\Inkling 의 값을 조회.
|
|
* 키가 없으면 reg.exe 가 exit 1 → silent fallback (null).
|
|
*
|
|
* promisify(execFile) 대신 직접 Promise 로 wrapping — 테스트에서 vi.mock 이
|
|
* `util.promisify.custom` symbol 을 보전하지 못해 stdout 이 undefined 가 되는 이슈 회피.
|
|
*/
|
|
function readRegistrySilent(): Promise<string | null> {
|
|
return new Promise((resolve) => {
|
|
execFile('reg', ['query', WIN_REGISTRY_PATH, '/v', WIN_REGISTRY_KEY], (err, stdout) => {
|
|
if (err) {
|
|
resolve(null);
|
|
return;
|
|
}
|
|
const m = stdout.match(/REG_SZ\s+(.+)/);
|
|
resolve(m && m[1] ? m[1].trim() : null);
|
|
});
|
|
});
|
|
}
|