Theseus: right-click Dev Panel entry

Add "Open Dev Panel" (toggling to "Close Dev Panel" when open) and
"Inspect element" to the page right-click menu, the tab-strip tab menu,
and the link-window page menu. F12 doubles as the airplane-mode toggle
in some environments, so users were accidentally cutting their
connection while reaching for DevTools; a visible menu entry is the
discoverability escape hatch.

- Shared helpers (devToolsOpenMode / toggleTabDevTools /
  inspectTabElement) read the existing devToolsDock setting so the
  menu and the F12 shortcut always open in the same place.
- Skipped on add-on tabs, which have their own loading model.
- New Settings toggle "Right-click menu entry" under Developer tools
  lets users hide it; off by default is false (i.e. shown).
This commit is contained in:
Hermes Dev 2026-10-30 16:51:34 +02:00
parent f76ca4f9f4
commit 69390f20fb
2 changed files with 69 additions and 0 deletions

63
main.js
View file

@ -733,6 +733,11 @@ const SETTINGS_DEFAULTS = {
// forced closed; the two share the right area (add-on sidebar keeps its
// width, DevTools takes what's left).
devToolsDock: "bottom", // bottom | sidebar | two-sidebars
// Show an "Open Dev Panel" / "Inspect element" entry in the page right-
// click menu and in the tab-strip tab menu. F12 and Ctrl+Shift+I always
// work regardless of this; the menu entry is just a discoverability
// escape hatch for users who hit the F12-vs-airplane-mode foot-gun.
contextMenuDevTools: true,
};
// Applying the theme via nativeTheme.themeSource makes prefers-color-scheme update
// in every renderer (chrome, settings, popover, page views) with no per-view IPC.
@ -5265,6 +5270,30 @@ function styleScrollbars(wc) {
// fast during startup), fire once explicitly.
try { if (!wc.isLoading()) inject(); } catch {}
}
// DevTools dock resolution shared by the F12 shortcut and the context-menu
// entries below. Keeps the three call-sites honest about the settings mapping.
function devToolsOpenMode() {
return settings.devToolsDock === "sidebar" ? "right"
: settings.devToolsDock === "two-sidebars" ? "right"
: "bottom";
}
function toggleTabDevTools(wc) {
if (!wc || wc.isDestroyed?.()) return;
try {
if (wc.isDevToolsOpened()) { wc.closeDevTools(); return; }
wc.openDevTools({ mode: devToolsOpenMode() });
try { wc.devToolsWebContents?.focus?.(); } catch {}
} catch {}
}
function inspectTabElement(wc, x, y) {
if (!wc || wc.isDestroyed?.()) return;
try {
if (!wc.isDevToolsOpened()) wc.openDevTools({ mode: devToolsOpenMode() });
const px = Number(x), py = Number(y);
if (Number.isFinite(px) && Number.isFinite(py)) wc.inspectElement(Math.round(px), Math.round(py));
try { wc.devToolsWebContents?.focus?.(); } catch {}
} catch {}
}
function createTab(initial, opts = {}) {
const id = ++tabSeq;
// Non-settings tabs get home-preload so the built-in home page can round-
@ -5741,6 +5770,21 @@ function createTab(initial, opts = {}) {
{ label: "Image (PNG)…", click: () => savePageAsImage(wc).catch((e) => console.warn("save-png:", e?.message)) },
]},
);
// Dev Panel entry. The F12 shortcut doubles as the airplane-mode toggle
// in some environments, so a right-click escape hatch avoids users
// flipping their connection off while debugging. Skipped on add-on
// tabs (which have their own loading model) and when the user has
// turned the entry off in Settings. Inspect element uses the click
// point Electron hands us; it also opens the panel if closed.
if (!tab.addonId && settings.contextMenuDevTools !== false) {
const open = (() => { try { return wc.isDevToolsOpened(); } catch { return false; } })();
const inspectAt = { x: p.x, y: p.y };
items.push(
{ type: "separator" },
{ label: "Inspect element", click: () => inspectTabElement(wc, inspectAt.x, inspectAt.y) },
{ label: open ? "Close Dev Panel" : "Open Dev Panel", accelerator: "F12", click: () => toggleTabDevTools(wc) },
);
}
if (tab.webapp) {
const inst = webapps.find(tab.webapp.key);
items.push({ type: "separator" }, inst
@ -6681,6 +6725,16 @@ ipcMain.handle("tab-context-menu-popup", (e, tabId, rect) => {
{ label: t.muted ? "Unmute" : "Mute", click: () => {
try { t.view.webContents.setAudioMuted(!t.muted); t.muted = !t.muted; emitTabs(); } catch {}
} },
// Dev Panel toggle on the tab-strip menu — mirrors the page right-click
// entry so users can reach it without clicking into the page first.
...(!t.addonId && settings.contextMenuDevTools !== false ? [
{ type: "separator" },
{
label: (() => { try { return t.view.webContents.isDevToolsOpened() ? "Close Dev Panel" : "Open Dev Panel"; } catch { return "Open Dev Panel"; } })(),
accelerator: "F12",
click: () => toggleTabDevTools(t.view?.webContents),
},
] : []),
{ type: "separator" },
{ label: "Close", click: () => closeTab(t.id) },
];
@ -12168,6 +12222,15 @@ async function openLinkWindow(input) {
{ label: "Forward", enabled: wc.navigationHistory.canGoForward(), click: () => wc.navigationHistory.goForward() },
{ label: "Reload", click: () => wc.reload() },
);
if (settings.contextMenuDevTools !== false) {
const open = (() => { try { return wc.isDevToolsOpened(); } catch { return false; } })();
const ix = p.x, iy = p.y;
items.push(
{ type: "separator" },
{ label: "Inspect element", click: () => inspectTabElement(wc, ix, iy) },
{ label: open ? "Close Dev Panel" : "Open Dev Panel", accelerator: "F12", click: () => toggleTabDevTools(wc) },
);
}
Menu.buildFromTemplate(items).popup({ window: w });
});
linkWindows.add(w);

View file

@ -382,6 +382,7 @@
<label class="polrow"><input type="radio" name="devToolsDock" value="sidebar"><span><b>Right sidebar</b> <span class="pmuted">— DevTools takes the right side. If an add-on sidebar is open, it hides while DevTools is up.</span></span></label>
<label class="polrow"><input type="radio" name="devToolsDock" value="two-sidebars"><span><b>Two sidebars</b> <span class="pmuted">— DevTools opens on the right, and the add-on sidebar stays where it is. The two share the right area.</span></span></label>
</div>
<label class="polrow" style="margin-top:4px"><input type="checkbox" id="contextMenuDevTools"><span><b>Right-click menu entry</b> <span class="pmuted">— show "Open Dev Panel" and "Inspect element" in the page and tab right-click menus. F12 and Ctrl+Shift+I keep working either way.</span></span></label>
</div>
<h2 class="sub" style="margin-top:1.8rem">Registries</h2>
@ -2521,6 +2522,11 @@
r.checked = (r.value === devToolsDock);
r.addEventListener("change", () => { if (r.checked) C.set("devToolsDock", r.value); });
});
const cmDev = document.getElementById("contextMenuDevTools");
if (cmDev) {
cmDev.checked = s.contextMenuDevTools !== false;
cmDev.addEventListener("change", () => { C.set("contextMenuDevTools", !!cmDev.checked); });
}
// ---- Plug-ins: Ariadne's Thread + Aegis --------------------------------
// Two views per plug-in that share one truth source: