Theseus 0.3.103: sidebar panel context menu + Hermes icon framing

Right-click on a sidebar panel (WhatsApp, Telegram, LLMs, add-on panels
like Hermes) now opens a native menu with Copy image / Save image as /
Open link in new tab / Copy / Back / Forward / Reload. Previously the
sidebar views had no context-menu listener attached, so sites like
WhatsApp Web that intercept right-click left the user with no way to
copy an image.

Hermes mark in the sidebar strip now zooms to the V-fold and wings;
envelope body partially visible. The original viewBox had ~43% empty
space top-and-bottom, so the glyph rendered at ~15 px inside the 26 px
icon frame.
This commit is contained in:
Local Dev 2026-10-22 13:48:09 +03:00
parent c944952f04
commit b2fef43607
3 changed files with 62 additions and 23 deletions

File diff suppressed because one or more lines are too long

39
main.js
View file

@ -3819,6 +3819,42 @@ function lockPanelView(view) {
if (/^(?:https?|bns):/i.test(url)) createTab(url);
});
}
// Right-click menu for sidebar web views (quick-links like WhatsApp /
// Telegram, and add-on panels). Sites can override their own context menu
// (WhatsApp Web does, and drops "Copy image"); listening at the Electron
// layer guarantees a native menu with image / link / copy actions.
function installPanelContextMenu(view) {
const wc = view.webContents;
wc.on("context-menu", (_e, p) => {
const items = [];
const haveMain = !!win && !win.isDestroyed();
if (p.linkURL) {
items.push(
{ label: "Open link in new tab", enabled: haveMain, click: () => { createTab(p.linkURL); try { win.focus(); } catch {} } },
{ label: "Open link in new window", click: () => openLinkWindow(p.linkURL) },
{ label: "Copy link address", click: () => clipboard.writeText(p.linkURL) },
{ type: "separator" },
);
}
if (p.mediaType === "image" && p.srcURL) {
items.push(
{ label: "Open image in new tab", enabled: haveMain, click: () => { createTab(p.srcURL); try { win.focus(); } catch {} } },
{ label: "Save image as…", click: () => wc.downloadURL(p.srcURL) },
{ label: "Copy image", click: () => { try { wc.copyImageAt(p.x, p.y); } catch {} } },
{ label: "Copy image address", click: () => clipboard.writeText(p.srcURL) },
{ type: "separator" },
);
}
if (p.isEditable) items.push({ role: "cut" }, { role: "copy" }, { role: "paste" }, { type: "separator" });
else if (p.selectionText) items.push({ role: "copy" }, { type: "separator" });
items.push(
{ label: "Back", enabled: wc.navigationHistory.canGoBack(), click: () => wc.navigationHistory.goBack() },
{ label: "Forward", enabled: wc.navigationHistory.canGoForward(), click: () => wc.navigationHistory.goForward() },
{ label: "Reload", click: () => wc.reload() },
);
try { Menu.buildFromTemplate(items).popup({ window: win && !win.isDestroyed() ? win : undefined }); } catch {}
});
}
function addonIdForSender(sender) {
try {
const u = new URL(sender.getURL());
@ -5698,6 +5734,7 @@ function createWindow() {
// brand scrollbar the moment its DOM is ready.
sidebar = new WebContentsView({ webPreferences: { preload: path.join(__dirname, "sidebar-preload.js") } });
lockPanelView(sidebar);
installPanelContextMenu(sidebar);
raise(sidebar);
styleScrollbars(sidebar.webContents);
sidebar.setVisible(false);
@ -5727,6 +5764,7 @@ function createWindow() {
if (url && /^(?:https?|bns):/i.test(url)) createTab(url);
return { action: "deny" };
});
installPanelContextMenu(quickPanel);
try { quickPanel.setBackgroundColor(nativeTheme.shouldUseDarkColors ? "#0b0e14" : "#ffffff"); } catch {}
raise(quickPanel);
styleScrollbars(quickPanel.webContents);
@ -5734,6 +5772,7 @@ function createWindow() {
// Left add-on panels: same preload and IPC surface as the right sidebar.
leftPanel = new WebContentsView({ webPreferences: { preload: path.join(__dirname, "sidebar-preload.js") } });
lockPanelView(leftPanel);
installPanelContextMenu(leftPanel);
try { leftPanel.setBackgroundColor(nativeTheme.shouldUseDarkColors ? "#0b0e14" : "#ffffff"); } catch {}
raise(leftPanel);
styleScrollbars(leftPanel.webContents);

View file

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