feat(autostart): "Start with Windows" toggle
- PM.AutoStart wraps HKCU\Software\Microsoft\Windows\CurrentVersion\Run.
Value "PMServer" = "<exe>" -tray. Per-user, no admin required, shows
up in Task Manager → Startup so the user can override from there.
- UMainForm honours the -tray CLI flag (set by the registry entry):
after the server starts, MinimizeToTray via TThread.ForceQueue so the
app comes up directly in the tray with no visible window flash.
- Bridge cmd://autostart/{get,set} + Bridge.getAutoStart() /
setAutoStart() / onAutoStartStatus(). Settings exposes a toggle in
the Security section, visible only when Bridge.active (the PHP
frontend can't touch the registry).
- Toggle reads "on" only when the registered command matches the
current exe path, so a stale entry from a moved exe lets the user
re-enable to refresh.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ const API = (location.pathname.indexOf('/password-manager/') === 0)
|
||||
// Active only when running inside the Delphi-hosted WebView2 (API === '').
|
||||
// Falls back to navigator.clipboard for the standalone PHP frontend.
|
||||
const prefResolvers = {};
|
||||
let autoStartResolver = null;
|
||||
const Bridge = (() => {
|
||||
const active = (API === '');
|
||||
|
||||
@@ -188,6 +189,35 @@ const Bridge = (() => {
|
||||
r(value || '');
|
||||
}
|
||||
},
|
||||
|
||||
// ---- Start with Windows (HKCU Run registry) -----------------------
|
||||
getAutoStart() {
|
||||
if (!active) return Promise.resolve(false);
|
||||
return new Promise(resolve => {
|
||||
autoStartResolver = resolve;
|
||||
cmd('cmd://autostart/get');
|
||||
setTimeout(() => {
|
||||
if (autoStartResolver === resolve) {
|
||||
autoStartResolver = null;
|
||||
resolve(false);
|
||||
}
|
||||
}, 2000);
|
||||
});
|
||||
},
|
||||
setAutoStart(enabled) {
|
||||
if (!active) return;
|
||||
cmd('cmd://autostart/set?enabled=' + (enabled ? '1' : '0'));
|
||||
},
|
||||
onAutoStartStatus(enabled) {
|
||||
if (autoStartResolver) {
|
||||
const r = autoStartResolver;
|
||||
autoStartResolver = null;
|
||||
r(!!enabled);
|
||||
}
|
||||
state.autoStartEnabled = !!enabled;
|
||||
const cb = document.getElementById('settingAutoStart');
|
||||
if (cb) cb.checked = !!enabled;
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -4851,6 +4881,14 @@ function openSettings() {
|
||||
$('#settingAutofillFullCombo').textContent = autofillComboLabel(state.autofillHotkeyFull);
|
||||
$('#settingAutofillPwdCombo').textContent = autofillComboLabel(state.autofillHotkeyPwd);
|
||||
$('#settingAutofillHotkeysRow').style.display = Bridge.active ? '' : 'none';
|
||||
// Start-with-Windows toggle: only meaningful inside the Delphi host
|
||||
// (registry access). Hide for the PHP frontend.
|
||||
$('#settingAutoStartRow').style.display = Bridge.active ? '' : 'none';
|
||||
if (Bridge.active) {
|
||||
// Fire-and-forget: the bridge response updates the checkbox via
|
||||
// Bridge.onAutoStartStatus.
|
||||
Bridge.getAutoStart();
|
||||
}
|
||||
$('#settingUser').textContent = state.username;
|
||||
// Async: query server for recovery key state and update the label
|
||||
refreshRecoveryStatus();
|
||||
@@ -5436,6 +5474,13 @@ async function init() {
|
||||
toast('Breach check disabled');
|
||||
}
|
||||
});
|
||||
$('#settingAutoStart').addEventListener('change', e => {
|
||||
if (!Bridge.active) return;
|
||||
Bridge.setAutoStart(e.target.checked);
|
||||
toast(e.target.checked
|
||||
? 'Will start with Windows (in tray)'
|
||||
: 'Won’t start with Windows');
|
||||
});
|
||||
$('#settingAutofill').addEventListener('change', e => {
|
||||
state.autofillEnabled = e.target.checked;
|
||||
localStorage.setItem('autofillEnabled', state.autofillEnabled ? '1' : '0');
|
||||
|
||||
Reference in New Issue
Block a user