Skip to content
This repository was archived by the owner on Jul 23, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions themes/46e90a10-0c6b-4696-bfe1-ab303680b110/chrome.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

/*
This mod relies on privileged JavaScript APIs to fetch OS memory.
Please refer to the Readme tab for the required userChrome.js installation script!
*/
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
120 changes: 120 additions & 0 deletions themes/46e90a10-0c6b-4696-bfe1-ab303680b110/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

# Tab Memory Hover

Displays memory usage for the currently hovered tab inside Zen Browser's native hover card.

Because this mod uses privileged OS-level memory APIs (`ChromeUtils.requestProcInfo`), it cannot be installed simply via CSS. You must install the JavaScript code manually using `fx-autoconfig`.

## Installation Instructions

1. Ensure you have [fx-autoconfig](https://github.com/MrOtherGuy/fx-autoconfig) set up in your Zen Browser profile.
2. In your profile folder, navigate to the `chrome/JS/` directory.
3. Create a new file named `tab-memory-hover.uc.js`.
4. Copy and paste the script below into that file.
5. Restart your browser!

### The Script (`tab-memory-hover.uc.js`)

// ==UserScript==
// @name Tab Memory Hover
// @description Displays memory usage inside the tab hover card.
// @author Zen Community
// @include main
// ==/UserScript==

(function() {
window.addEventListener("popupshowing", async (e) => {
const panel = e.target;
if (panel.id !== "tab-preview-panel") return;

let memoryContainer = panel.querySelector(".tab-preview-memory-container");
let memoryValue;

if (!memoryContainer) {
memoryContainer = document.createElement("div");
memoryContainer.className = "tab-preview-memory-container";

Object.assign(memoryContainer.style, {
display: "flex",
alignItems: "center",
gap: "6px",
marginTop: "4px",
fontSize: "0.95em",
color: "var(--text-color-deemphasized, gray)"
});

const icon = document.createElement("span");
icon.textContent = "💾";
icon.style.opacity = "0.8";

memoryValue = document.createElement("span");
memoryValue.className = "tab-preview-memory-value";
memoryValue.style.fontWeight = "500";

memoryContainer.appendChild(icon);
memoryContainer.appendChild(memoryValue);

const textContainer = panel.querySelector(".tab-preview-text-container");
if (textContainer) {
textContainer.appendChild(memoryContainer);
}
} else {
memoryValue = memoryContainer.querySelector(".tab-preview-memory-value");
}

memoryValue.textContent = "Calculating...";
memoryContainer.hidden = false;

const tab = panel.triggerNode || panel.anchorNode;
if (!tab || !tab.linkedBrowser) {
memoryContainer.hidden = true;
return;
}

if (tab.getAttribute("pending")) {
memoryValue.textContent = "Sleeping";
return;
}

try {
const browser = tab.linkedBrowser;
const osPid = browser.frameLoader?.remoteTab?.osPid || -1;
const bcId = browser.browsingContext?.id || -1;

const procInfo = await ChromeUtils.requestProcInfo();

let foundBytes = 0;

// Check the parent process first just in case
if (procInfo.pid === osPid) {
foundBytes = procInfo.memory || procInfo.residentSetSize || procInfo.memorySize || 0;
}

// Scan children
for (const child of procInfo.children) {
if (child.pid === osPid) {
foundBytes = child.memory || child.residentSetSize || child.memorySize || 0;
}

for (const win of child.windows) {
if (win.outerWindowId === bcId) {
foundBytes = child.memory || child.residentSetSize || child.memorySize || 0;
}
}
}

if (foundBytes > 0) {
let str = foundBytes < 1073741824 ?
`${Math.round(foundBytes / 1048576)} MB` :
`${(foundBytes / 1073741824).toFixed(1)} GB`;
memoryValue.textContent = str;
} else {
memoryContainer.hidden = true;
}

} catch(err) {
console.error("TabMemoryHover Error:", err);
memoryContainer.hidden = true;
}
});
})();
14 changes: 14 additions & 0 deletions themes/46e90a10-0c6b-4696-bfe1-ab303680b110/theme.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "46e90a10-0c6b-4696-bfe1-ab303680b110",
"name": "Tab Memory Hover",
"description": "Displays process memory usage inside the tab hover card (requires userChrome.js).",
"homepage": "https://github.com/shaun6jrome",
"style": "https://raw.githubusercontent.com/zen-browser/theme-store/main/themes/46e90a10-0c6b-4696-bfe1-ab303680b110/chrome.css",
"readme": "https://raw.githubusercontent.com/zen-browser/theme-store/main/themes/46e90a10-0c6b-4696-bfe1-ab303680b110/readme.md",
"image": "https://raw.githubusercontent.com/zen-browser/theme-store/main/themes/46e90a10-0c6b-4696-bfe1-ab303680b110/image.png",
"author": "shaun6jrome",
"version": "1.0.0",
"tags": [],
"createdAt": "2026-07-04",
"updatedAt": "2026-07-04"
}
Loading