feat: GStack Browser icon — custom .icns replaces Chromium's Dock icon

- Generated 1024px icon: dark terminal window with amber prompt cursor
- Converted to .icns with all macOS sizes (16-1024px, 1x and 2x)
- build-app.sh copies icon into both the outer .app and bundled Chromium's
  Resources (Chromium's process owns the Dock icon, not the launcher)
- browser-manager.ts patches Chromium's icon at runtime for dev mode too
- Both the Dock and Cmd+Tab now show the GStack icon
This commit is contained in:
Garry Tan
2026-03-31 07:31:06 -07:00
parent 19e3ae3466
commit 672c3a740b
3 changed files with 36 additions and 0 deletions
+15
View File
@@ -277,6 +277,21 @@ export class BrowserManager {
.replace(/Google Chrome for Testing/g, 'GStack Browser');
fs.writeFileSync(chromePlist, patched);
}
// Replace Chromium's Dock icon with ours (Chromium's process owns the Dock icon)
const iconCandidates = [
path.join(__dirname, '..', '..', 'scripts', 'app', 'icon.icns'), // repo dev mode
path.join(process.env.HOME || '', '.claude', 'skills', 'gstack', 'scripts', 'app', 'icon.icns'), // global install
];
const iconSrc = iconCandidates.find(p => fs.existsSync(p));
if (iconSrc) {
const chromeResources = path.join(chromeContentsDir, 'Resources');
// Read original icon name from plist
const iconMatch = plistContent.match(/<key>CFBundleIconFile<\/key>\s*<string>([^<]+)<\/string>/);
let origIcon = iconMatch ? iconMatch[1] : 'app';
if (!origIcon.endsWith('.icns')) origIcon += '.icns';
const destIcon = path.join(chromeResources, origIcon);
try { fs.copyFileSync(iconSrc, destIcon); } catch { /* non-fatal */ }
}
}
} catch {
// Non-fatal: app name just stays as Chrome for Testing
Binary file not shown.
+21
View File
@@ -96,6 +96,27 @@ if [ -f "$CHROMIUM_PLIST" ]; then
plutil -convert xml1 "$CHROMIUM_STRINGS" 2>/dev/null || true
sed -i '' "s/Google Chrome for Testing/$APP_NAME/g" "$CHROMIUM_STRINGS" 2>/dev/null || true
fi
# Replace Chromium's icon with ours so the Dock shows the GStack icon
# (Chromium's process owns the Dock icon, not our launcher)
ICON_SRC="$SCRIPT_DIR/app/icon.icns"
if [ -f "$ICON_SRC" ]; then
CHROMIUM_RESOURCES="$APP_DIR/Contents/Resources/chromium/$(basename "$CHROME_APP")/Contents/Resources"
# Find the original icon filename from Chromium's plist
ORIG_ICON=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIconFile" "$CHROMIUM_PLIST" 2>/dev/null || echo "app")
# Add .icns extension if not present
[[ "$ORIG_ICON" != *.icns ]] && ORIG_ICON="${ORIG_ICON}.icns"
cp "$ICON_SRC" "$CHROMIUM_RESOURCES/$ORIG_ICON"
echo " Replaced Chromium icon → $ORIG_ICON"
fi
fi
# ─── Step 3c: App icon ────────────────────────────────────────────
ICON_SRC="$SCRIPT_DIR/app/icon.icns"
if [ -f "$ICON_SRC" ]; then
cp "$ICON_SRC" "$APP_DIR/Contents/Resources/icon.icns"
echo " App icon installed"
else
echo " WARNING: No icon.icns found at $ICON_SRC — app will use default icon"
fi
# ─── Step 4: Info.plist ──────────────────────────────────────────