#!/bin/bash #determine if chromium is installed if command -v chromium >/dev/null || command -v chromium-browser >/dev/null || [ -d /snap/chromium ] || [ -d /var/lib/flatpak/app/org.chromium.Chromium ];then echo "Chromium is installed. Continuing..." else error "User error: Chromium is not installed! Failed to find either a 'chromium' command or 'chromium-browser' command. If you are sure Chromium is installed, please reach out to Botspot for this to be fixed." fi #determine where the Chromium customizations folder is. if [ -d /etc/chromium.d ];then folder=/etc/chromium.d elif [ -d /snap/chromium ] && [ -f /snap/bin/chromium ];then #if Snap Chromium is installed, make the customizations folder and later make a script to source its contents if [ ! -d /etc/chromium.d ];then sudo mkdir -p /etc/chromium.d fi folder=/etc/chromium.d elif [ -d /etc/chromium-browser/customizations ];then folder=/etc/chromium-browser/customizations else error "User error: Cannot find the directory where Chromium keeps its flags! Usually this would be /etc/chromium.d or /etc/chromium-browser/customizations. On your system, neither of these directories exist. Please reach out to Botspot for this to be fixed." fi #Fix edge case where both an old version of chromium and a newer version are installed simultaneously if [ -d /etc/chromium-browser/customizations ] && [ -d /etc/chromium.d ] && [ ! -L /etc/chromium-browser/customizations ];then #The $folder variable is /etc/chromium.d, but make /etc/chromium-browser/customizations pick up changes in /etc/chromium.d by using a symlink status -n "There are two Chromium customization folders on your system: /etc/chromium.d and /etc/chromium-browser/customizations.\nCreating a symlink to keep both locations synchronized..." #Move any customization files from /etc/chromium-browser/customizations to /etc/chromium.d, without overwriting anything sudo cp -nr /etc/chromium-browser/customizations /etc/chromium.d && \ sudo rm -rf /etc/chromium-browser/customizations && \ sudo ln -s /etc/chromium.d /etc/chromium-browser/customizations status_green Done fi #if Chromium is installed from Snap or Flatpak, make a script to source the contents of /etc/chromium.d if [ -d /snap/chromium ] || [ -d /var/lib/flatpak/app/org.chromium.Chromium ];then if [ -f $HOME/.chromium-browser.init ] && [ "$(sha1sum $HOME/.chromium-browser.init | awk '{print $1}')" != 'cead3a7e98ddd3dbfeea285736c89409a7d426cd' ];then warning "This script needs to create this file: ~/.chromium-browser.init, but it already exists!" read -N 1 -p "Enter Y to replace this file, or N to exit now." answer echo if [ "$answer" != Y ] && [ "$answer" != y ];then echo "User error: $HOME/.chromium-browser.init already exists and the user did not want to overwrite it." exit 1 fi fi #The ~/.chromium-browser.init file is the one single entrypoint for running scripts during a Snap Chromium's launch. #I encountered significant difficulty making this work. Normal Chromium-browser uses bash to source things, but Snap /snap/chromium/2003/bin/chromium.launcher is /bin/sh cat << "EOF" > $HOME/.chromium-browser.init #!/bin/sh eval "$(run-parts --list -- /etc/chromium.d | xargs cat)" EOF fi #detect if dark mode is currently enabled by this tool if [ -f "${folder}/dark_mode" ];then dark_mode=TRUE else dark_mode=FALSE fi #detect if dark mode for all websites is currently enabled by this tool if [ -f "${folder}/site_dark_mode" ];then site_dark_mode=TRUE else site_dark_mode=FALSE fi #detect current UI scale value if [ -f "${folder}/ui_scale" ];then ui_scale="$(cat "${folder}/ui_scale" | grep -o '\--force-device-scale-factor=.*' | tr -cd '0123456789.\n')" else ui_scale=1.00 fi #detect if google sync is currently enabled by this tool if [ -f "${folder}/apikeys" ];then google_sync=TRUE else google_sync=FALSE fi #detect if tab previews is currently enabled by this tool if [ -f "${folder}/tab_previews" ];then tab_previews=TRUE else tab_previews=FALSE fi #detect if various performance improvements are currently enabled by this tool if [ -f "${folder}/performance_improvements" ];then performance_improvements=TRUE else performance_improvements=FALSE fi #detect if the reduce_writes script is enabled if [ -f "${folder}/reduce_writes" ];then reduce_writes=TRUE else reduce_writes=FALSE fi #detect if Widevine is enabled if [ -d /opt/WidevineCdm ];then widevine=TRUE else widevine=FALSE fi #detect if Widevine can be enabled if [ $arch == 32 ];then widevine_possible=TRUE widevine_message=(--field="Enable Widevine DRM (for Netflix, Spotify)":CHK "$widevine") else widevine_possible=FALSE widevine_message=() fi #Set text of dialog window text="Better Chromium - by Botspot" #detect if chromium is running, and if so, remind the user to relaunch it when done if pgrep chromium >/dev/null || pgrep chromium-browser >/dev/null ;then text+=$'\n'"Changes will take effect after you relaunch Chromium." fi output="$(yad --center --form --width=410 --separator='\n' \ --title="Better Chromium" \ --window-icon="$(dirname "$0")/icon-64.png" \ --text="$text" \ --field="Enable Dark Mode":CHK "$dark_mode" \ --field="Dark Mode for all websites":CHK "$site_dark_mode" \ --field="Click to see more themes:LBL" '' \ --field="UI Scale: (default 1)":NUM "${ui_scale}!0.25..4!0.05!2" \ --field="Tab previews":CHK "$tab_previews" \ --field="Enable Google Sync":CHK "$google_sync" \ --field="Performance Improvements":CHK "$performance_improvements" \ --field="Reduce SD card writes":CHK "$reduce_writes" \ "${widevine_message[@]}")" button=$? if [ "$button" != 0 ];then echo "User error: Exiting now without making any changes." exit 1 fi echo "Received values:" dark_mode="$(sed -n 1p <<<"$output")" echo "dark_mode: $dark_mode" site_dark_mode="$(sed -n 2p <<<"$output")" echo "site_dark_mode: $site_dark_mode" #skip line 3 because that was an empty field from "Click to see more themes" links ui_scale="$(sed -n 4p <<<"$output")" echo "ui_scale: $ui_scale" tab_previews="$(sed -n 5p <<<"$output")" echo "tab_previews: $tab_previews" google_sync="$(sed -n 6p <<<"$output")" echo "google_sync: $google_sync" performance_improvements="$(sed -n 7p <<<"$output")" echo "performance_improvements: $performance_improvements" reduce_writes="$(sed -n 8p <<<"$output")" echo "reduce_writes: $reduce_writes" widevine="$(sed -n 9p <<<"$output")" echo "widevine: $widevine" echo #if user enabled reduce_writes or performance_improvements, and ZRAM is not installed, then recommend the More RAM app if [ ! -f /usr/bin/zram.sh ] && [ "$performance_improvements" == TRUE ] ;then yad --center --width=410 --separator='\n' \ --title="Better Chromium" \ --window-icon="$(dirname "$0")/icon-64.png" \ --text="You've chosen to improve Chromium's performance by adding a few flags to it. Further improvement is possible by installing the More RAM app on Pi-Apps. This increases usable RAM while avoiding a swap file." \ --button="Thanks for the tip - I'll check out More RAM.":0 &>/dev/null & elif [ ! -f /usr/bin/zram.sh ] && [ "$reduce_writes" == TRUE ] ;then yad --center --width=410 --separator='\n' \ --title="Better Chromium" \ --window-icon="$(dirname "$0")/icon-64.png" \ --text="You've chosen to reduce writes to the SD card. Further improvement is possible by installing the More RAM app on Pi-Apps. This increases usable RAM while avoiding a swap file." \ --button="Thanks for the tip - I'll check out More RAM.":0 &>/dev/null & fi # #write changes to chromium flag folder # status "Writing changes..." #add zzzz_combine_values script in all cases to combine --enable-features arguments echo "Creating workaround script at ${folder}/zzzz_combine_values" cat << "EOF" | sudo tee "${folder}/zzzz_combine_values" >/dev/null #This script combines multiple invocations of --enable-features and --disable-features into one argument so that Chromium does not ignore any. #Written by Botspot for the Pi-Apps Better Chromium script. IFS=' ' enable='' disable='' new_flags='' for word in $CHROMIUM_FLAGS ;do if [[ "$word" == '--enable-features='* ]];then enable+=",${word/--enable-features=/}" elif [[ "$word" == '--disable-features='* ]];then enable+=",${word/--disable-features=/}" else new_flags+=" $word" fi done #remove initial comma enable="${enable/,/}" disable="${disable/,/}" CHROMIUM_FLAGS="$new_flags" [ ! -z "$enable" ] && CHROMIUM_FLAGS+=" --enable-features=$enable" [ ! -z "$disable" ] && CHROMIUM_FLAGS+=" --disable-features=$disable" EOF #dark mode if [ "$dark_mode" == TRUE ];then #I found this flag on https://peter.sh/experiments/chromium-command-line-switches echo "Adding --force-dark-mode to ${folder}/dark_mode" cat << EOF | sudo tee "${folder}/dark_mode" >/dev/null export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --force-dark-mode" EOF else #dark mode set to false - so remove the file if [ -f "${folder}/dark_mode" ];then status "Removing ${folder}/dark_mode" fi sudo rm -f "${folder}/dark_mode" fi #dark mode for all websites if [ "$site_dark_mode" == TRUE ];then #I found this flag on https://peter.sh/experiments/chromium-command-line-switches echo "Adding --enable-features=WebContentsForceDark:inversion_method/cielab_based/image_behavior/none/foreground_lightness_threshold/150/background_lightness_threshold/150 to ${folder}/site_dark_mode" cat << EOF | sudo tee "${folder}/site_dark_mode" >/dev/null export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --enable-features=WebContentsForceDark:inversion_method/cielab_based/image_behavior/none/foreground_lightness_threshold/150/background_lightness_threshold/150" #WebContentsForceDark:increase_text_contrast/true" EOF else #dark mode set to false - so remove the file if [ -f "${folder}/site_dark_mode" ];then status "Removing ${folder}/site_dark_mode" fi sudo rm -f "${folder}/site_dark_mode" fi #UI scale if [ "$ui_scale" != 1.00 ];then #I found this flag on https://peter.sh/experiments/chromium-command-line-switches echo "Adding --device-scale-factor=${ui_scale} to ${folder}/ui_scale" cat << EOF | sudo tee "${folder}/ui_scale" >/dev/null export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --force-device-scale-factor=${ui_scale}" EOF else #ui scale set to 1.00 (default), so remove file if [ -f "${folder}/ui_scale" ];then status "Removing ${folder}/ui_scale" fi sudo rm -f "${folder}/ui_scale" fi #Tab previews if [ "$tab_previews" == TRUE ];then #I found this flag after experimenting with chrome://flags and chrome://version echo "Adding --enable-features=TabHoverCardImages to ${folder}/tab_previews" cat << EOF | sudo tee "${folder}/tab_previews" >/dev/null export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --enable-features=TabHoverCardImages" EOF else #tab previews set to false - so remove the file if [ -f "${folder}/tab_previews" ];then status "Removing ${folder}/tab_previews" fi sudo rm -f "${folder}/tab_previews" fi #google_sync if [ "$google_sync" == TRUE ];then #add a file from official Debian version of the chromium package echo "Adding GOOGLE_API_KEY, GOOGLE_DEFAULT_CLIENT_ID, and GOOGLE_DEFAULT_CLIENT_SECRET to ${folder}/apikeys" cat << EOF | sudo tee "${folder}/apikeys" >/dev/null # API keys found in chromium source code https://chromium.googlesource.com/experimental/chromium/src/+/b08bf82b0df37d15a822b478e23ce633616ed959/google_apis/google_api_keys.cc export GOOGLE_API_KEY="AIzaSyCkfPOPZXDKNn8hhgu3JrA62wIgC93d44k" export GOOGLE_DEFAULT_CLIENT_ID="77185425430.apps.googleusercontent.com" export GOOGLE_DEFAULT_CLIENT_SECRET="OTJgUOQcT7lO7GsGZq2G4IlT" EOF echo "Adding ${folder}/enable_sync script to enable sync settings when Chromium launches" cat << "EOF" | sudo tee "${folder}/enable_sync" >/dev/null #!/bin/bash profiles="$(find "$HOME/.config/chromium/" -maxdepth 1 -type d '(' -name Default -o -name 'Profile *' ')' | sed 's+.*/++g')" IFS=$'\n' for profile in $profiles ;do [ ! -f "$HOME/.config/chromium/$profile/Preferences" ] && continue sed -i 's/"signin":{"allowed":false}/"signin":{"allowed":true,"allowed_on_next_startup":true}/g' "$HOME/.config/chromium/$profile/Preferences" sed -i 's/"signin":{"allowed":false,"allowed_on_next_startup":false}/"signin":{"allowed":true,"allowed_on_next_startup":true}/g' "$HOME/.config/chromium/$profile/Preferences" sed -i 's/"signin":{"AccountReconcilor":{"kDiceMigrationOnStartup2":true},"allowed":false,"allowed_on_next_startup":false}/"signin":{"AccountReconcilor":{"kDiceMigrationOnStartup2":true},"allowed":true,"allowed_on_next_startup":true}/g' "$HOME/.config/chromium/$profile/Preferences" done EOF else #google sync set to false, so remove the file if [ -f "${folder}/apikeys" ];then status "Removing ${folder}/apikeys" fi #remove the script that enables sync setting if [ -f "${folder}/enable_sync" ];then status "Removing ${folder}/enable_sync" fi status "Disabling sync settings for all chromium profiles" #turn off sync setting for every profile profiles="$(find "$HOME/.config/chromium/" -maxdepth 1 -type d '(' -name Default -o -name 'Profile *' ')' | sed 's+.*/++g')" IFS=$'\n' for profile in $profiles ;do [ ! -f "$HOME/.config/chromium/$profile/Preferences" ] && continue sed -i 's/"signin":{"allowed":true}/"signin":{"allowed":false,"allowed_on_next_startup":false}/g' "$HOME/.config/chromium/$profile/Preferences" sed -i 's/"signin":{"allowed":true,"allowed_on_next_startup":true}/"signin":{"allowed":false,"allowed_on_next_startup":false}/g' "$HOME/.config/chromium/$profile/Preferences" sed -i 's/"signin":{"AccountReconcilor":{"kDiceMigrationOnStartup2":true},"allowed":true,"allowed_on_next_startup":true}/"signin":{"AccountReconcilor":{"kDiceMigrationOnStartup2":true},"allowed":false,"allowed_on_next_startup":false}/g' "$HOME/.config/chromium/$profile/Preferences" done sudo rm -f "${folder}/apikeys" "${folder}/enable_sync" fi #performance improvements if [ "$performance_improvements" == TRUE ];then #various chromium flags from https://forums.raspberrypi.com/viewtopic.php?t=199543 - I removed a few because they reduced stability or WebGL performance #More flags added from https://www.ghacks.net/2017/02/13/how-to-speed-up-the-vivaldi-web-browser/ #Some VA-API flags from https://ubuntuhandbook.org/index.php/2022/07/chromium-snap-package-to-finally-get-back-vaapi-hardware-decoding/ flags="--ignore-gpu-blacklist --enable-checker-imaging --cc-scroll-animation-duration-in-seconds=0.6 --disable-quic --enable-tcp-fast-open --enable-experimental-canvas-features --enable-scroll-prediction --enable-simple-cache-backend --max-tiles-for-interest-area=512 --num-raster-threads=4 --default-tile-height=512 --enable-features=VaapiVideoDecoder,VaapiVideoEncoder --disable-features=UseChromeOSDirectVideoDecoder --enable-accelerated-video-decode --enable-low-res-tiling --process-per-site" #The --process-per-site flag significantly decreases RAM usage and number of chromium processes, without any noticeable disadvantages. #Not using --enable-low-end-device-mode even though it helps, because scrolling image-heavy pages would crash with "background allocation failure" error. echo "Adding $flags to ${folder}/performance_improvements" cat << EOF | sudo tee "${folder}/performance_improvements" >/dev/null export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS $flags" EOF else #performance improvements set to false, so remove file if [ -f "${folder}/performance_improvements" ];then status "Removing ${folder}/performance_improvements" fi sudo rm -f "${folder}/performance_improvements" fi #reduce sd card writes if [ "$reduce_writes" == TRUE ];then #mount chromium files to tmpfs (script will run with user's privileges whenever Chromium is launched) #From: https://forums.raspberrypi.com/viewtopic.php?p=1865820 echo "Adding ${folder}/reduce_writes script to mount cache/ServiceWorker to /dev/shm when Chromium launches" cat << "EOF" | sudo tee "${folder}/reduce_writes" >/dev/null #!/bin/bash if [ ! -d /dev/shm ];then echo 'Better chromium "Reduce Writes" script: cannot mount folders to /dev/shm because that folder is missing!' else rm -rf /dev/shm/chromium mkdir -p /dev/shm/chromium profiles="$(find "$HOME/.config/chromium/" -maxdepth 1 -type d '(' -name Default -o -name 'Profile *' ')' | sed 's+.*/++g')" IFS=$'\n' for profile in $profiles ;do rm -rf "$HOME/.config/chromium/$profile/Service Worker" mkdir -p "/dev/shm/chromium/$profile/serviceWorker" ln -s "/dev/shm/chromium/$profile/serviceWorker" "$HOME/.config/chromium/$profile/Service Worker" done mkdir -p /dev/shm/chromium/cache rm -rf "$HOME/.cache/chromium" ln -s /dev/shm/chromium/cache/ "$HOME/.cache/chromium" fi EOF else if [ -f "${folder}/reduce_writes" ];then status "Removing ${folder}/reduce_writes" fi sudo rm -f "${folder}/reduce_writes" #clean up old symlinks profiles="$(find "$HOME/.config/chromium/" -maxdepth 1 -type d '(' -name Default -o -name 'Profile *' ')' | sed 's+.*/++g')" IFS=$'\n' for profile in $profiles ;do if [ -L "$HOME/.config/chromium/$profile/Service Worker" ];then rm -rf "$HOME/.config/chromium/$profile/Service Worker" fi done if [ -L "$HOME/.cache/chromium" ];then rm -rf "$HOME/.cache/chromium" fi fi #widevine if [ "$widevine_possible" == TRUE ] && [ "$widevine" == TRUE ] && [ ! -d /opt/WidevineCdm ];then #install Chromium Widevine app "${DIRECTORY}/manage" install "Chromium Widevine" elif [ "$widevine_possible" == TRUE ] && [ "$widevine" == FALSE ];then #disable Chromium Widevine if package_installed libwidevinecdm0 ;then sudo apt purge -y libwidevinecdm0 fi if [ -d /opt/WidevineCdm ];then #uninstall Chromium Widevine app "${DIRECTORY}/manage" uninstall "Chromium Widevine" fi fi if pgrep chromium >/dev/null || pgrep chromium-browser >/dev/null ;then status "Changes will take effect after you relaunch Chromium." fi true