Theseus 0.3.124: Open-with label trimmed; file assocs auto-on; Settings sidebar gets System (holds Names & Certificates)

Open-with menu label — Windows was showing the per-extension ProgID's
default value, which was set to "Theseus HTML Document". That looked
verbose next to the real brand name, and the per-ext label never changed
regardless of which extension the user right-clicked. Shortened to just
"Theseus Navigator". The ApplicationDescription under Capabilities is
dropped too — Default Apps uses it as a tooltip and the sentence it held
was noise.

File associations are now auto-registered on first launch. The toggle in
Settings is dropped: the entries live under HKCU with no admin, cause no
harm by being present, and the common case (right-click an .html on your
desktop, see Theseus in the Open-with menu) is strictly better than the
previous "toggle it on first" step. Two per-profile flags remember the
rollout (fileAssocsAutoApplied) and the one-time 0.3.124 label rewrite
(fileAssocsLabelFixed_1); a user who removes the entries by hand stays
opted out.

Settings sidebar — the Plug-ins nav entry is renamed System and now holds
a chevron to Names & Certificates (which is no longer a separate top-
level nav entry). The underlying section id stays "plugins" so the
plugins-ariadne / plugins-aegis crumbs and any existing deep links keep
working. Names & Certificates picks up a System › crumb at the top.
This commit is contained in:
Local Dev 2026-10-27 21:50:06 +02:00
parent 1d4e85f1d2
commit de1a5e18d4
3 changed files with 47 additions and 24 deletions

36
main.js
View file

@ -12329,7 +12329,12 @@ async function setFileAssociations(on) {
const classes = `HKCU\\Software\\Classes`;
const caps = `HKCU\\Software\\Theseus Navigator\\Capabilities`;
if (on) {
await regAdd(`${classes}\\${WIN_PROGID}`, "", "Theseus HTML Document");
// The ProgID's default value is the friendly name Windows shows in the
// Open-with menu AND in the file-type column of Explorer. Keep it short
// — "Theseus Navigator" — not a long "Theseus HTML Document" per
// extension. ApplicationDescription under Capabilities is also dropped;
// Default Apps picks it up as a tooltip and the long sentence was noisy.
await regAdd(`${classes}\\${WIN_PROGID}`, "", "Theseus Navigator");
await regAdd(`${classes}\\${WIN_PROGID}\\DefaultIcon`, "", `${exe},0`);
await regAdd(`${classes}\\${WIN_PROGID}\\shell\\open\\command`, "", openCmd);
for (const ext of FILE_ASSOC_EXTS) {
@ -12339,7 +12344,6 @@ async function setFileAssociations(on) {
// Windows Settings → Default Apps for each listed extension.
await regAdd(caps, "ApplicationName", "Theseus Navigator");
await regAdd(caps, "ApplicationIcon", `${exe},0`);
await regAdd(caps, "ApplicationDescription", "A browser that follows the thread.");
for (const ext of FILE_ASSOC_EXTS) await regAdd(`${caps}\\FileAssociations`, ext, WIN_PROGID);
for (const p of DEFAULT_BROWSER_PROTOS) await regAdd(`${caps}\\URLAssociations`, p, WIN_PROGID);
await regAdd(`HKCU\\Software\\RegisteredApplications`, "Theseus Navigator", "Software\\Theseus Navigator\\Capabilities");
@ -12376,6 +12380,30 @@ ipcMain.handle("default-browser-state", () => ({
}));
ipcMain.handle("default-browser-set", (_e, on) => setAsDefaultBrowser(!!on));
ipcMain.handle("file-assocs-set", (_e, on) => setFileAssociations(!!on));
// Auto-register the HKCU "Open with Theseus" entries on first launch so
// double-clicking an .html / .pdf / .svg / .xhtml file (or picking it from
// an Open-with menu) just works, with no toggle to flip in Settings. Two
// per-profile flags:
// fileAssocsAutoApplied — first-run rollout. Once set, never auto-apply
// again, so a user who removes the association
// by hand (registry or Default Apps) stays opted
// out across restarts.
// fileAssocsLabelFixed_1 — one-time re-write for 0.3.124+: the old progid
// default was "Theseus HTML Document" which looked
// verbose next to the per-extension entry in the
// Open-with menu. Rewriting it to "Theseus
// Navigator" is idempotent and only fires once.
function autoApplyFileAssociations() {
if (process.platform !== "win32") return;
const needFirstRun = !settings.fileAssocsAutoApplied;
const needLabelFix = settings.fileAssocsAutoApplied && !settings.fileAssocsLabelFixed_1 && hasFileAssociations();
if (!needFirstRun && !needLabelFix) return;
setFileAssociations(true).then(() => {
if (needFirstRun) settings.fileAssocsAutoApplied = true;
settings.fileAssocsLabelFixed_1 = true;
try { saveSettings(); } catch {}
}).catch((e) => console.warn("auto file assocs:", e?.message));
}
ipcMain.handle("open-system-defaults", () => openSystemDefaultApps());
if (!process.env.THESEUS_NO_AUTOSTART && !app.requestSingleInstanceLock()) {
// Another Theseus owns this profile; it got our argv via second-instance.
@ -12455,6 +12483,10 @@ if (!process.env.THESEUS_NO_AUTOSTART && !app.requestSingleInstanceLock()) {
// "restart to apply" chip instead of finding out in Settings.
// boot-time poll now runs from onChromeReady; interval poll (4 h) is fine here.
setInterval(() => pollAddonUpdates("interval"), 4 * 60 * 60 * 1000);
// Register the Windows Open-with entries on first run — no toggle, no
// UAC, no user step. Deferred past the toolbar paint so the one-shot
// reg.exe fan-out never gets in the way of launch.
setTimeout(() => { try { autoApplyFileAssociations(); } catch {} }, 5_000);
// Launched from an installed app's shortcut: just that app's window; the
// browser window comes up on the next plain launch (second-instance).
const appUrl = webapps.appUrlFromArgv(process.argv);

View file

@ -1,6 +1,6 @@
{
"name": "theseus-navigator",
"version": "0.3.123",
"version": "0.3.124",
"license": "MPL-2.0",
"description": "Theseus Navigator — a browser that follows the thread. By Silent Mode, a Deviant project.",
"author": "Silent Mode",

View file

@ -319,8 +319,7 @@
<a data-sec="passwords">Passwords</a>
<a data-sec="performance">Performance</a>
<a data-sec="privacy">Privacy</a>
<a data-sec="names">Names &amp; Certificates</a>
<a data-sec="plugins">Plug-ins</a>
<a data-sec="plugins">System</a>
<a data-sec="ariadne">Ariadne's Thread</a>
<a data-sec="aegis">Aegis</a>
<a data-sec="addons">Extensions</a>
@ -342,13 +341,6 @@
</div>
<label class="sw"><input type="checkbox" id="defaultBrowser"><span class="track"><span class="knob"></span></span></label>
</div>
<div class="row" id="fileAssocsRow" hidden>
<div class="txt">
<div class="t">Show "Open with Theseus" in file menus</div>
<div class="d">Right-click an <code>.html</code>, <code>.htm</code>, <code>.pdf</code>, <code>.svg</code> or <code>.xhtml</code> file and Theseus appears in the Open-with menu. Theseus opens it as a local-file tab.</div>
</div>
<label class="sw"><input type="checkbox" id="fileAssocs"><span class="track"><span class="knob"></span></span></label>
</div>
<!-- Theseus Shield — chevron opens the Shield add-on's own panel; the
toggle on the right flips it on/off. State comes from listAddons(). -->
<div class="row" id="generalShieldRow">
@ -494,6 +486,7 @@
these toggles, no further UI churn. Each row's "Not wired yet" caption
goes away as its adapter lights up. -->
<section id="names" hidden>
<div class="crumb"><a data-go="plugins">System</a> ›</div>
<h1>Names &amp; Certificates</h1>
<p class="lede">Decide which name systems Theseus can resolve, and which certificate roots it will trust. BNS (<i>.x</i>, <i>.bch</i>, <i>.sia</i>, …) is always on; everything else is off by default.</p>
@ -602,9 +595,12 @@
</p>
</section>
<!-- "System" (section id stays "plugins" so existing deep links and the
plugins-ariadne / plugins-aegis sub-page crumbs keep working — the
nav just reads System in the sidebar now). -->
<section id="plugins" hidden>
<h1>Plug-ins</h1>
<p class="lede">Silent Mode components that live alongside Theseus — each with its own on/off, updates and settings page. Ariadne's Thread and Aegis now have their own entries in the sidebar.</p>
<h1>System</h1>
<p class="lede">The Silent Mode components that live alongside Theseus and the name systems the browser can resolve.</p>
<div class="row" style="justify-content:flex-end;gap:8px"><a class="btn" style="text-decoration:none;display:inline-flex;align-items:center" href="https://theseus.x/plug-ins/" target="_blank" rel="noopener" title="Current signed versions, hashes and how plug-ins update">About plug-ins on theseus.x ↗</a></div>
<div class="row link" data-go="ariadne">
<div class="txt"><div class="t">Ariadne's Thread</div><div class="d">System-wide BCDN resolver.</div></div>
@ -614,6 +610,10 @@
<div class="txt"><div class="t">Aegis</div><div class="d">Built-in multi-chain wallet.</div></div>
<span class="chev">›</span>
</div>
<div class="row link" data-go="names">
<div class="txt"><div class="t">Names &amp; Certificates</div><div class="d">Which name systems Theseus can resolve, and which certificate roots it trusts.</div></div>
<span class="chev">›</span>
</div>
<!-- Hidden hooks: the plug-in init code wires several controls below by
id (status, toggles, install/update/apply buttons). Keep them in the
DOM so the sub-pages (plugins-ariadne / plugins-aegis) still work;
@ -1363,17 +1363,14 @@
// (today: everything other than Windows).
(async () => {
const row = document.getElementById("defaultBrowserRow");
const assocRow = document.getElementById("fileAssocsRow");
const defBrowser = document.getElementById("defaultBrowser");
const assoc = document.getElementById("fileAssocs");
const openSys = document.getElementById("openSysDefaults");
async function refresh() {
try {
const d = await cfg.defaultBrowserState();
if (!d.supported) return;
row.hidden = false; assocRow.hidden = false;
row.hidden = false;
defBrowser.checked = !!d.isDefault;
assoc.checked = !!d.hasAssocs;
} catch {}
}
defBrowser.addEventListener("change", async () => {
@ -1383,12 +1380,6 @@
if (defBrowser.checked) await cfg.openSystemDefaults();
setTimeout(refresh, 1000);
});
assoc.addEventListener("change", async () => {
assoc.disabled = true;
try { await cfg.setFileAssocs(assoc.checked); }
finally { assoc.disabled = false; }
setTimeout(refresh, 600);
});
openSys.addEventListener("click", () => cfg.openSystemDefaults());
refresh();
})();