Skip to content

Instantly share code, notes, and snippets.

@ergosteur
Last active September 9, 2025 17:57
Show Gist options
  • Select an option

  • Save ergosteur/ef4dba76a099178402830b8d41cfee12 to your computer and use it in GitHub Desktop.

Select an option

Save ergosteur/ef4dba76a099178402830b8d41cfee12 to your computer and use it in GitHub Desktop.
Firefox SSB Creator - Linux Firefox "Web App"
#!/bin/bash
# --- Script to create a Firefox Single-Site Browser (SSB) ---
# V8: Implements a slim, auto-hiding toolbar instead of a fully hidden one.
# Original idea /u/Apoema - https://www.reddit.com/r/firefox/comments/li2lqg/comment/gn2sltw/
# Made with AI assistance in case you couldn't tell by the excessive use of emoji.
echo "πŸ”₯ Firefox SSB Creator (v8) πŸ”₯"
echo "------------------------------"
# --- 1. Check for Dependencies ---
if ! command -v firefox &> /dev/null; then
echo "❌ Error: 'firefox' is not installed or not in your PATH." >&2
exit 1
fi
if ! command -v curl &> /dev/null; then
echo "❌ Error: 'curl' is not installed or not in your PATH." >&2
exit 1
fi
# ==============================================================================
# --- STAGE 1: GATHER ALL USER INPUT ---
# ==============================================================================
echo "Step 1: Please provide the application details."
read -p " Enter the name for your application (e.g., Google Calendar): " APP_NAME
if [[ -z "$APP_NAME" ]]; then
echo "❌ Error: Application name cannot be empty." >&2
exit 1
fi
read -p " Enter the full URL (e.g., https://calendar.google.com): " APP_URL
if [[ -z "$APP_URL" ]]; then
echo "❌ Error: URL cannot be empty." >&2
exit 1
fi
echo ""
echo "Step 2: Please choose an icon for the application."
read -p " [A]uto-detect (default), [U]RL, system [N]ame, or [S]kip? " ICON_CHOICE
case ${ICON_CHOICE^^} in
U)
ICON_MODE="URL"
read -p " Enter the URL for the icon image: " ICON_DATA
;;
N)
ICON_MODE="NAME"
read -p " Enter a system icon name (e.g., 'google-calendar', 'slack'): " ICON_DATA
;;
S)
ICON_MODE="SKIP"
;;
*)
ICON_MODE="AUTO"
;;
esac
echo "----------------------------------------------------"
echo "βœ… All information gathered. Proceeding with setup..."
echo "----------------------------------------------------"
# ==============================================================================
# --- STAGE 2: PERFORM ACTIONS ---
# ==============================================================================
# --- 3. Set Up Variables ---
APP_NAME_SANITIZED=$(echo "$APP_NAME" | tr -s ' ' '-' | tr -cd '[:alnum:]_-')
PROFILE_NAME="ssb-$APP_NAME_SANITIZED"
WM_CLASS="$APP_NAME_SANITIZED-SSB"
FIREFOX_DIR="$HOME/.mozilla/firefox"
PROFILE_DIR="$FIREFOX_DIR/$PROFILE_NAME"
APPS_DIR="$HOME/.local/share/applications"
ICONS_DIR="$HOME/.local/share/icons/hicolor/128x128/apps"
# --- 4. Check for Existing Profile ---
if [ -d "$PROFILE_DIR" ]; then
echo "❌ Error: A profile named '$PROFILE_NAME' already exists." >&2
echo "To remove it, run 'firefox -P' from your terminal or visit 'about:profiles' in Firefox." >&2
exit 1
fi
# --- 5. Create Profile, Preferences, and Directories ---
mkdir -p "$APPS_DIR" "$ICONS_DIR"
echo "βš™οΈ Creating new Firefox profile: $PROFILE_NAME..."
firefox --headless -CreateProfile "$PROFILE_NAME $PROFILE_DIR" > /dev/null 2>&1
if [ ! -d "$PROFILE_DIR" ]; then
echo "❌ Error: Failed to create profile directory." >&2
exit 1
fi
echo "βš™οΈ Setting preferences to use system title bar..."
cat <<EOF > "$PROFILE_DIR/user.js"
// --- Preferences for SSB ---
// 1. Force system title bar (set both for compatibility)
user_pref("browser.tabs.drawInTitlebar", false);
user_pref("browser.tabs.inTitlebar", 0);
// 2. Enable userChrome.css customizations
user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);
EOF
echo "βš™οΈ Applying custom CSS for a slim, auto-hiding toolbar..."
CHROME_DIR="$PROFILE_DIR/chrome"
mkdir -p "$CHROME_DIR"
# This CSS creates a slim tab bar that auto-hides along with the address bar.
cat <<'EOF' > "$CHROME_DIR/userChrome.css"
/* 1. Make the tab bar slim and compact */
#TabsToolbar {
--tab-min-height: 28px !important;
margin-bottom: -4px !important; /* Pulls the nav-bar up slightly */
}
.tab-background {
margin-block: 2px !important;
}
.tab-label-container {
font-size: 0.9em;
}
/* 2. Auto-hide the entire navigator toolbox (tabs and URL bar) */
:root:not([customizing]) #navigator-toolbox:not(:hover):not(:focus-within) {
max-height: 5px; /* Leaves a small sliver visible as a hint */
min-height: 0;
opacity: 0.2;
transition: all 0.2s ease-in-out;
}
/* 3. When hovered, expand the toolbox to its natural height */
:root:not([customizing]) #navigator-toolbox:hover,
:root:not([customizing]) #navigator-toolbox:focus-within {
max-height: 100px; /* Make this large enough to show everything */
opacity: 1;
}
EOF
# --- 6. Process and Set Icon ---
ICON_FILE_PATH="$ICONS_DIR/$PROFILE_NAME.png"
ICON_NAME="$PROFILE_NAME"
echo "βš™οΈ Processing icon choice..."
case $ICON_MODE in
URL)
if curl -sL "$ICON_DATA" -o "$ICON_FILE_PATH"; then echo "βœ… Icon downloaded successfully from URL."; else echo "⚠️ Warning: Could not download icon from URL. A generic web icon will be used."; ICON_NAME="web-browser"; fi ;;
NAME)
ICON_NAME="$ICON_DATA"
echo "βœ… Using system icon name '$ICON_NAME'." ;;
SKIP)
ICON_NAME="web-browser"
echo "βœ… Skipping icon, will use a generic icon." ;;
AUTO)
if curl -sL "https://www.google.com/s2/favicons?sz=128&domain_url=${APP_URL}" -o "$ICON_FILE_PATH"; then echo "βœ… Icon auto-detected and downloaded successfully."; else echo "⚠️ Warning: Could not auto-detect icon. A generic web icon will be used."; ICON_NAME="web-browser"; fi ;;
esac
# --- 7. Create Desktop File ---
echo "βš™οΈ Creating application shortcut (.desktop file)..."
DESKTOP_FILE_PATH="$APPS_DIR/$PROFILE_NAME.desktop"
cat <<EOF > "$DESKTOP_FILE_PATH"
[Desktop Entry]
Version=1.0
Type=Application
Name=$APP_NAME
Comment=Run $APP_NAME as a standalone web application
Exec=firefox --name=$WM_CLASS --class=$WM_CLASS --no-remote -P "$PROFILE_NAME" "$APP_URL"
Icon=$ICON_NAME
Terminal=false
StartupNotify=true
Categories=Network;WebBrowser;
StartupWMClass=$WM_CLASS
EOF
# --- 8. Finalize ---
update-desktop-database -q "$APPS_DIR"
echo ""
echo "πŸŽ‰ All done! πŸŽ‰"
echo "The app '$APP_NAME' is now available in your application launcher."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment