Watch
1
0
Fork
You've already forked dotfiles
0

Add configuration for GNOME

This commit is contained in:
Alexander Hess 2026-08-03 14:30:55 +02:00
commit c5f9769acf
Signed by: alexander
GPG key ID: B46EDB4DFC26805D
24 changed files with 4188 additions and 0 deletions

31
.local/bin/dark-theme-toggle Executable file
View file

@ -0,0 +1,31 @@
#!/bin/sh
# Triggered by <Control><Alt>d
# as defined in [org/gnome/settings-daemon/plugins/media-keys]
# in ~/.config/gnome-settings/key-bindings.ini
set -eu
Interface=org.gnome.desktop.interface
Background=org.gnome.desktop.background
# Keep in sync with "primary-color" in [org/gnome/desktop/background]
DARK_COLOR='#054A55'
LIGHT_COLOR='#DEEDF1'
if [ "$(gsettings get $Interface color-scheme)" = "'prefer-dark'" ]; then
gsettings set $Interface color-scheme 'prefer-light'
gsettings set $Background primary-color "$LIGHT_COLOR"
gsettings set $Background secondary-color "$LIGHT_COLOR"
else
gsettings set $Interface color-scheme 'prefer-dark'
gsettings set $Background primary-color "$DARK_COLOR"
gsettings set $Background secondary-color "$DARK_COLOR"
fi

View file

@ -0,0 +1,34 @@
#!/bin/sh
# Make the `GSettings` schemas of all user-installed GNOME Shell extensions
# visible to a plain `gsettings`, by symlinking the *.gschema.xml files
# into the user schema directory and compiling them
#
# Idempotent: Re-running refreshes the links, prunes dangling ones
# (e.g., from removed extensions), and recompiles
set -eu
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
EXTENSIONS_DIR="$XDG_DATA_HOME/gnome-shell/extensions"
SCHEMAS_DIR="$XDG_DATA_HOME/glib-2.0/schemas"
mkdir -p "$SCHEMAS_DIR"
# Prune symlinks whose target no longer exists
find "$SCHEMAS_DIR" -maxdepth 1 -type l ! -exec test -e {} \; -exec rm -v -- {} \;
# Link every schema shipped by an extension
for xml in "$EXTENSIONS_DIR"/*/schemas/*.gschema.xml; do
[ -e "$xml" ] || continue # because the glob does not expand if empty
echo " $(basename "$xml")"
ln -sf -- "$xml" "$SCHEMAS_DIR/"
done
glib-compile-schemas "$SCHEMAS_DIR"

View file

@ -120,6 +120,13 @@ if [ -x "$XDG_BIN_HOME/generate-shell-completions" ]; then
fi
if [ -f "$HOME/.config/systemd/user/restore-gnome.service" ]; then
systemctl --user daemon-reload
systemctl --user enable restore-gnome.service
systemctl --user status --no-pager restore-gnome.service || true
fi
echo ""
echo "The dotfiles were installed successfully (branch: $DOTFILES_BRANCH)"
echo ""

View file

@ -0,0 +1,85 @@
#!/bin/sh
# Triggered by <Alt><Shift>Left
# as defined in [org/gnome/settings-daemon/plugins/media-keys]
# in ~/.config/gnome-settings/key-bindings.ini
#
# This script ensures "Night Light" is forced on
# if it was not yet on by schedule
# and makes the screen a bit cooler than it currently is
#
# The default warmth is restored at login by ~/.local/bin/restore-gnome
set -eu
# GNOME's GUI lets one choose between 1700 and 4700 only,
# and 6500 is the point where no color correction is applied at all
# while 1000 is the absolute minimum supported by the OS
_MIN_TEMPERATURE=1200
_MAX_TEMPERATURE=4700
notify() {
ID_FILE="${XDG_RUNTIME_DIR}/night-light-notification-id"
_id=$(cat "$ID_FILE" 2>/dev/null || true)
if [ -n "$_id" ]; then
notify-send -p -t 5000 --replace-id="$_id" "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE"
else
notify-send -p -t 5000 "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE"
fi
}
Schema=org.gnome.settings-daemon.plugins.color
active=$(gdbus call --session \
--dest org.gnome.SettingsDaemon.Color \
--object-path /org/gnome/SettingsDaemon/Color \
--method org.freedesktop.DBus.Properties.Get \
org.gnome.SettingsDaemon.Color NightLightActive)
current=$(gsettings get $Schema night-light-temperature | awk '{print $2}')
# 500 = (4700 - 1700 + 500) / 7
# => Seven steps spanning more than the range in the GUI,
# mainly because we want to allow a bit more warmth (i.e., +500)
new=$((current + 500))
if [ "$new" -gt $_MAX_TEMPERATURE ]; then
new=$_MAX_TEMPERATURE
fi
gsettings set $Schema night-light-temperature "uint32 $new"
# Force "Night Light" on, saving a <Control><Alt>n call,
# with the same settings as in ~/.local/bin/night-light-toggle-schedule
if [ "$active" = "(<false>,)" ]; then
gsettings set $Schema night-light-enabled true
gsettings set $Schema night-light-schedule-automatic false
gsettings set $Schema night-light-schedule-from 0.0
gsettings set $Schema night-light-schedule-to 24.0
fi
if [ "$current" -ge $_MAX_TEMPERATURE ]; then
if [ "$active" = "(<false>,)" ]; then
notify "is now forced on and already as cool as it gets (${_MAX_TEMPERATURE}K)"
else
notify "is already as cool as it gets (${_MAX_TEMPERATURE}K)"
fi
else
if [ "$active" = "(<false>,)" ]; then
notify "is now forced on at ${new}K"
fi
fi

View file

@ -0,0 +1,85 @@
#!/bin/sh
# Triggered by <Alt><Shift>Right
# as defined in [org/gnome/settings-daemon/plugins/media-keys]
# in ~/.config/gnome-settings/key-bindings.ini
#
# This script ensures "Night Light" is forced on
# if it was not yet on by schedule
# and makes the screen a bit warmer than it currently is
#
# The default warmth is restored at login by ~/.local/bin/restore-gnome
set -eu
# GNOME's GUI lets one choose between 1700 and 4700 only,
# and 6500 is the point where no color correction is applied at all
# while 1000 is the absolute minimum supported by the OS
_MIN_TEMPERATURE=1200
_MAX_TEMPERATURE=4700
notify() {
ID_FILE="${XDG_RUNTIME_DIR}/night-light-notification-id"
_id=$(cat "$ID_FILE" 2>/dev/null || true)
if [ -n "$_id" ]; then
notify-send -p -t 5000 --replace-id="$_id" "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE"
else
notify-send -p -t 5000 "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE"
fi
}
Schema=org.gnome.settings-daemon.plugins.color
active=$(gdbus call --session \
--dest org.gnome.SettingsDaemon.Color \
--object-path /org/gnome/SettingsDaemon/Color \
--method org.freedesktop.DBus.Properties.Get \
org.gnome.SettingsDaemon.Color NightLightActive)
current=$(gsettings get $Schema night-light-temperature | awk '{print $2}')
# 500 = (4700 - 1700 + 500) / 7
# => Seven steps spanning more than the range in the GUI,
# mainly because we want to allow a bit more warmth (i.e., +500)
new=$((current - 500))
if [ "$new" -lt $_MIN_TEMPERATURE ]; then
new=$_MIN_TEMPERATURE
fi
gsettings set $Schema night-light-temperature "uint32 $new"
# Force "Night Light" on, saving a <Control><Alt>n call,
# with the same settings as in ~/.local/bin/night-light-toggle-schedule
if [ "$active" = "(<false>,)" ]; then
gsettings set $Schema night-light-enabled true
gsettings set $Schema night-light-schedule-automatic false
gsettings set $Schema night-light-schedule-from 0.0
gsettings set $Schema night-light-schedule-to 24.0
fi
if [ "$current" -le $_MIN_TEMPERATURE ]; then
if [ "$active" = "(<false>,)" ]; then
notify "is now forced on and already as warm as it gets (${_MIN_TEMPERATURE}K)"
else
notify "is already as warm as it gets (${_MIN_TEMPERATURE}K)"
fi
else
if [ "$active" = "(<false>,)" ]; then
notify "is now forced on at ${new}K"
fi
fi

View file

@ -0,0 +1,68 @@
#!/bin/sh
# Triggered by <Alt><Shift>n
# as defined in [org/gnome/settings-daemon/plugins/media-keys]
# in ~/.config/gnome-settings/key-bindings.ini
#
# See ~/.local/bin/night-light-toggle-schedule
# for the other half of the toggling logic
# and extensive documentation
set -eu
notify() {
ID_FILE="${XDG_RUNTIME_DIR}/night-light-notification-id"
_id=$(cat "$ID_FILE" 2>/dev/null || true)
if [ -n "$_id" ]; then
notify-send -p -t 5000 --replace-id="$_id" "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE"
else
notify-send -p -t 5000 "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE"
fi
}
Schema=org.gnome.settings-daemon.plugins.color
if [ "$(gsettings get $Schema night-light-enabled)" = "true" ]; then
active_before=$(gdbus call --session \
--dest org.gnome.SettingsDaemon.Color \
--object-path /org/gnome/SettingsDaemon/Color \
--method org.freedesktop.DBus.Properties.Get \
org.gnome.SettingsDaemon.Color NightLightActive)
gsettings set $Schema night-light-enabled false
if [ "$active_before" = "(<false>,)" ]; then
notify "is now disabled, but the screen was not tinted anyways"
fi
else
gsettings set $Schema night-light-enabled true
# We could start from our default warmth, as defined
# in [org/gnome/settings-daemon/plugins/color]
# in ~/.config/gnome-settings/misc.ini
# but choose not to do that because the default
# warmth is reset anyways after a reboot
# gsettings set $Schema night-light-temperature "uint32 2200"
# Give the settings daemon a moment to recompute "NightLightActive"
sleep 0.1
active_after=$(gdbus call --session \
--dest org.gnome.SettingsDaemon.Color \
--object-path /org/gnome/SettingsDaemon/Color \
--method org.freedesktop.DBus.Properties.Get \
org.gnome.SettingsDaemon.Color NightLightActive)
if [ "$active_after" = "(<false>,)" ]; then
notify "is now enabled, but the schedule keeps it off for now"
fi
fi

View file

@ -0,0 +1,102 @@
#!/bin/sh
# Triggered by <Control><Alt>n
# as defined in [org/gnome/settings-daemon/plugins/media-keys]
# in ~/.config/gnome-settings/key-bindings.ini
#
# Night Light control:
#
# - <Control><Alt>n => "when" toggle
# + "Force" the screen to be warm right now!
# (Turns Night Light on if it was off, and keeps it on all day)
# + "Un-force" the Night Light into the local evening schedule
# - <Alt><Shift>n => "if" toggle
# Plain on/off switch for the Night Light feature
#
# Neither key binding changes what the other controls, so they don't fight.
#
# Making the screen cooler or warmer with <Alt><Shift>Left/Right
# also forces "Night Light" on because adjusting this implies
# that the user wants to use it.
#
# State machine:
# TARGET STATE
# +--------------------------+--------------------------+
# CURRENT STATE | nl-toggle-schedule | nl-toggle-enabled |
# +--------------------------+--------------------------+--------------------------+
# | disabled, automatic | enabled, force | enabled, automatic (*) |
# | disabled, force | enabled, force | enabled, force |
# | enabled, automatic | enabled, force (*) | disabled, automatic (*) |
# | enabled, force | enabled, automatic (*) | disabled, force |
# +--------------------------+--------------------------+--------------------------+
# (*) There are four cases where a user does not perceive a change on the screen.
# Then, a notification is shown instead.
#
# See ~/.local/bin/night-light-toggle-enabled for the other half of the toggling logic
set -eu
notify() {
ID_FILE="${XDG_RUNTIME_DIR}/night-light-notification-id"
_id=$(cat "$ID_FILE" 2>/dev/null || true)
if [ -n "$_id" ]; then
notify-send -p -t 5000 --replace-id="$_id" "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE"
else
notify-send -p -t 5000 "Night Light" "$1" > "$ID_FILE" || rm -f "$ID_FILE"
fi
}
Schema=org.gnome.settings-daemon.plugins.color
active_before=$(gdbus call --session \
--dest org.gnome.SettingsDaemon.Color \
--object-path /org/gnome/SettingsDaemon/Color \
--method org.freedesktop.DBus.Properties.Get \
org.gnome.SettingsDaemon.Color NightLightActive)
automatic=$(gsettings get $Schema night-light-schedule-automatic)
enabled=$(gsettings get $Schema night-light-enabled)
if [ "$automatic" = "true" ] || [ "$enabled" = "false" ]; then
# Force "Night Light" enabled, enabling it if needed
gsettings set $Schema night-light-enabled true
gsettings set $Schema night-light-schedule-automatic false
gsettings set $Schema night-light-schedule-from 0.0
gsettings set $Schema night-light-schedule-to 24.0
if [ "$active_before" = "(<true>,)" ] && [ "$automatic" = "true" ]; then
notify "is now forced to stay on and no longer on an automatic schedule"
fi
else
# Back to the live location's schedule
gsettings set $Schema night-light-schedule-automatic true
gsettings set $Schema night-light-schedule-from 18.0
gsettings set $Schema night-light-schedule-to 6.0
if [ "$active_before" = "(<true>,)" ]; then
# Give the settings daemon a moment to recompute "NightLightActive"
sleep 0.1
active_after=$(gdbus call --session \
--dest org.gnome.SettingsDaemon.Color \
--object-path /org/gnome/SettingsDaemon/Color \
--method org.freedesktop.DBus.Properties.Get \
org.gnome.SettingsDaemon.Color NightLightActive)
if [ "$active_after" = "(<true>,)" ]; then
notify "is still on because of an automatic schedule"
fi
fi
fi

64
.local/bin/patch-forge Executable file
View file

@ -0,0 +1,64 @@
#!/bin/sh
# Patch `forge` to draw a border on all tiled and unfocused windows
#
# Idempotent: Re-running on a patched file changes nothing
set -eu
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
WINDOW_JS="$XDG_DATA_HOME/gnome-shell/extensions/forge@jmmaranan.com/lib/extension/window.js"
[ -w "$WINDOW_JS" ] || { echo "Not writable or missing: $WINDOW_JS" >&2; exit 1; }
grep -q "showUnfocusedBorders" "$WINDOW_JS" && { echo "Already patched"; exit 0; }
# Call our method after the focused border is drawn
sed -i '/^ updateBorderLayout() {$/,/^ }$/ s|this\.showWindowBorders();|this.showWindowBorders();\n this.showUnfocusedBorders();|' "$WINDOW_JS"
# Append the method right after `updateBorderLayout()`
awk '
/^ updateBorderLayout\(\) \{$/ { inFn=1 }
inFn && /^ \}$/ {
print
print ""
print " showUnfocusedBorders() {"
print " if (!this.ext.settings.get_boolean(\"focus-border-toggle\")) return;"
print " this.tree.nodeWindows.forEach((nodeWindow) => {"
print " let metaWindow = nodeWindow.nodeValue;"
print " if (!metaWindow || metaWindow === this.focusMetaWindow) return;"
print " if (metaWindow.minimized || metaWindow.is_fullscreen()) return;"
print " if (metaWindow.get_workspace() !== global.workspace_manager.get_active_workspace()) return;"
print " let maximized = false;"
print " try { maximized = metaWindow.is_maximized(); }"
print " catch (e) { maximized = metaWindow.get_maximized() === 3; }"
print " if (maximized) return;"
print " if (nodeWindow.parentNode.isTabbed() || nodeWindow.parentNode.isStacked()) return;"
print " let windowActor = metaWindow.get_compositor_private();"
print " if (!windowActor || !windowActor.border) return;"
print " let border = windowActor.border;"
print " border.set_style_class_name(\"window-unfocused-border\");"
print " let rect = metaWindow.get_frame_rect();"
print " let inset = 3;"
print " border.set_size(rect.width + inset * 2, rect.height + inset * 2);"
print " border.set_position(rect.x - inset, rect.y - inset);"
print " border.show();"
print " if (global.window_group && global.window_group.contains(border)) {"
print " global.window_group.remove_child(border);"
print " global.window_group.insert_child_above(border, windowActor);"
print " }"
print " });"
print " }"
inFn=0
next
}
{ print }
' "$WINDOW_JS" > "$WINDOW_JS.tmp" && mv "$WINDOW_JS.tmp" "$WINDOW_JS"
echo "Patched: $WINDOW_JS"

75
.local/bin/randomize-background Executable file
View file

@ -0,0 +1,75 @@
#!/bin/sh
# Determine the next wallpaper by round robin from the cloud
# and install it as the background files referenced in
# ~/.config/gnome-settings/{misc,shell-extensions}.ini
#
# Candidates:
# - Pairs => Both "<name>-d.jpg" and "<name>-l.jpg" exist
# - Singles => Any other "*.jpg" not following the -d/-l scheme,
# used as dark and light at the same time
set -eu
SOURCE_DIR="$HOME/Cloud/Null-Tech/Backgrounds"
TARGET_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/backgrounds"
STATE_FILE="${XDG_STATE_HOME:-$HOME/.local/state}/current-background.txt"
[ -d "$SOURCE_DIR" ] || { echo "No such folder: $SOURCE_DIR" >&2; exit 1; }
# One candidate per line, tab-separated: <dark-file> <light-file>
candidates=$(
for jpg in "$SOURCE_DIR"/*.jpg; do
[ -e "$jpg" ] || continue # because the glob does not expand if empty
case "$jpg" in
*-d.jpg) # Complete pairs only
stem="${jpg%-d.jpg}"
[ -f "$stem-l.jpg" ] && printf '%s\t%s\n' "$jpg" "$stem-l.jpg"
;;
*-l.jpg) # Already handled via its "-d" counterpart above
;;
*) # A single file to be used for both modes
printf '%s\t%s\n' "$jpg" "$jpg"
;;
esac
done
)
if [ -z "$candidates" ]; then
echo "No usable *.jpg files in: $SOURCE_DIR" >&2
exit 1
fi
echo "Found $(printf '%s\n' "$candidates" | wc -l) candidate(s)"
# The glob expands alphabetically => "$candidates" is already sorted
# => Pick the first candidate sorting strictly after the last-used one,
# falling back to the first (e.g., for start, wrap-around, or missing state file)
last=$(cat "$STATE_FILE" 2>/dev/null || true)
chosen=$(printf '%s\n' "$candidates" | awk -F '\t' -v last="$last" '$1 > last { print; exit }')
[ -n "$chosen" ] || chosen=$(printf '%s\n' "$candidates" | head -n 1)
dark=$(printf '%s' "$chosen" | cut -f 1)
light=$(printf '%s' "$chosen" | cut -f 2)
echo "Chosen: $(basename "$dark")"
mkdir -p "$TARGET_DIR" "$(dirname "$STATE_FILE")"
cp -- "$dark" "$TARGET_DIR/dark.jpg"
cp -- "$light" "$TARGET_DIR/light.jpg"
printf '%s\n' "$dark" > "$STATE_FILE"
echo "Installed as: $TARGET_DIR/{dark,light}.jpg"

147
.local/bin/restore-gnome Executable file
View file

@ -0,0 +1,147 @@
#!/bin/sh
# Restore the GNOME settings from ~/.config/gnome-settings/*.ini
#
# `dconf load` merges into the existing state, implying
# that keys removed from the *.ini files would still be active
# => Reset the subtrees we fully manage first,
# which makes the resulting state deterministic
set -eu
XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
BACKUP_DIR="$XDG_STATE_HOME/gnome-settings-backups"
SETTINGS_DIR="$XDG_CONFIG_HOME/gnome-settings"
# Subtrees either
# - fully described by the *.ini files
# - or reset to their defaults
#
# Note: Keep in sync with the `grep`s in ~/.local/bin/verify-dconf
RESET_PATHS="
/ca/desrt/dconf-editor/
/org/freedesktop/ibus/panel/
/org/freedesktop/tracker/
/org/gnome/baobab/
/org/gnome/calculator/
/org/gnome/calendar/
/org/gnome/Characters/
/org/gnome/clocks/
/org/gnome/Connections/
/org/gnome/Contacts/
/org/gnome/control-center/
/org/gnome/desktop/
/org/gnome/Disks/
/org/gnome/evince/
/org/gnome/Extensions/
/org/gnome/file-roller/
/org/gnome/gedit/
/org/gnome/gnome-system-monitor/
/org/gnome/Loupe/
/org/gnome/maps/
/org/gnome/mutter/
/org/gnome/nautilus/
/org/gnome/nm-applet/
/org/gnome/portal/
/org/gnome/settings-daemon/
/org/gnome/shell/
/org/gnome/simple-scan/
/org/gnome/software/
/org/gnome/system/location/
/org/gnome/terminal/
/org/gnome/TextEditor/
/org/gnome/Totem/
/org/gnome/tweaks/
/org/gnome/Weather/
/org/gnome/GWeather4/
/org/gtk/
/system/
"
if ! command -v dconf >/dev/null 2>&1; then
echo "dconf is not installed => Nothing to do" >&2
exit 0
fi
if [ ! -d "$SETTINGS_DIR" ]; then
echo "No settings found at: $SETTINGS_DIR" >&2
exit 1
fi
echo "Backing up current GNOME settings to: $BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
dconf dump / > "$BACKUP_DIR/$(date +%Y%m%d-%H%M%S).ini"
# Keep the ten most recent backups
# shellcheck disable=SC2012 # File names are timestamps => `ls` is safe
ls -1t "$BACKUP_DIR"/*.ini | tail -n +11 | xargs -r rm --
echo "Resetting managed subtrees in dconf"
for path in $RESET_PATHS; do
echo " $path"
dconf reset -f "$path"
done
# forge's `patchCss()` writes its stylesheet backup to a path built from a
# property that no longer exists, yielding "~/undefined.bak"
# => Patch the path in the installed extension
THEME_JS="$XDG_DATA_HOME/gnome-shell/extensions/forge@jmmaranan.com/lib/shared/theme.js"
if [ -w "$THEME_JS" ]; then
sed -i 's|this\.configMgr\.stylesheetFileName + "\.bak"|configCss.get_path() + ".bak"|' "$THEME_JS"
fi
echo "Import GNOME extensions' schemas"
SCHEMAS="$HOME/.local/bin/import-gnome-extension-schemas"
if [ -x "$SCHEMAS" ]; then
"$SCHEMAS" || echo "WARN: importing GNOME extension schemas failed" >&2
fi
echo "Loading GNOME settings from: $SETTINGS_DIR"
for file in "$SETTINGS_DIR"/*.ini; do
[ -e "$file" ] || continue # because the glob does not expand if empty
echo " $(basename "$file")"
sed "s|/home/user|$HOME|g" "$file" | dconf load /
done
for file in "$SETTINGS_DIR"/local/*.ini; do
[ -e "$file" ] || continue # because the glob does not expand if empty
echo " $(basename "$file")"
sed "s|/home/user|$HOME|g" "$file" | dconf load /
done
echo "Patching forge"
# Draw a whitish border on unfocused windows as well
PATCH="$HOME/.local/bin/patch-forge"
if [ -x "$PATCH" ]; then
"$PATCH" || echo "WARN: forge border patch failed" >&2
fi
echo "Restored GNOME to the defaults defined in ~/.config/gnome-settings"

139
.local/bin/restore-nextcloud Executable file
View file

@ -0,0 +1,139 @@
#!/usr/bin/env bash
# This script ensures my `nextcloud` clients operate in a uniform way
set -eu
CFG="${XDG_CONFIG_HOME:-$HOME/.config}/Nextcloud/nextcloud.cfg"
SERVER_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/Nextcloud/server.txt"
XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share}
FORCE=0
[ "${1:-}" = "--force" ] && FORCE=1
if [ -r "$SERVER_FILE" ]; then
SERVER_URL=$(head -n 1 "$SERVER_FILE")
elif [ "$FORCE" -eq 1 ]; then
SERVER_URL=""
echo "WARN: $SERVER_FILE not found, leaving the server URL unmanaged" >&2
else
echo "Server URL not found at: $SERVER_FILE" >&2
echo ""
echo "Create it with a single line, e.g., 'https://cloud.example.com'," >&2
echo "or re-run with --force to skip the URL settings" >&2
exit 1
fi
if ! command -v crudini >/dev/null 2>&1; then
echo "crudini is not installed => Cannot configure nextcloud" >&2
exit 1
fi
del_key() { # section key
crudini --del "$CFG" "$1" "$2"
}
set_key() { # section key value
crudini --set "$CFG" "$1" "$2" "$3"
}
# Stop `nextcloud`
nextcloud --quit 2>/dev/null || true
for _ in $(seq 30); do
pgrep -x nextcloud >/dev/null || break
sleep 0.5
done
if pgrep -x nextcloud >/dev/null; then
echo "Nextcloud did not exit; aborting" >&2
exit 1
fi
mkdir -p "$(dirname "$CFG")"
touch "$CFG"
# Configure base settings for `nextcloud`
if [ -n "$SERVER_URL" ]; then
set_key General forceOverrideServerUrl true
set_key General overrideServerUrl "$SERVER_URL"
fi
set_key General overrideLocalDir "$HOME/Cloud"
set_key General launchOnSystemStartup true
set_key General monoIcons true
set_key General crashReporter false
# Windows-only, kept for completeness
set_key General showInExplorerNavigationPane true
set_key General optionalServerNotifications false
set_key General showCallNotifications false
set_key General showChatNotifications false
set_key General isVfsEnabled false
set_key General confirmExternalStorage true
set_key General useNewBigFolderSizeLimit false
set_key General newBigFolderSizeLimit 999
set_key General notifyExistingFoldersOverLimit false
set_key General stopSyncingExistingFoldersOverLimit false
set_key General moveToTrash true
set_key General promptDeleteAllFiles true
set_key Proxy type 0
# Make `nextcloud` sync at full speed, with sane fallback limits
# Modes:
# - 0 => unlimited
# - -1 => automatic limit
# - +1 => manually set limit
# Limits:
# - values are in KBytes/s
# - we assume line speeds of 100/30 Mbit/s, to be capped at 80%
set_key BWLimit useDownloadLimit 0
# 100 Mbit/s / 8 => 12500 KBytes/s * 0.8 => 10000
set_key BWLimit downloadLimit 10000
set_key BWLimit useUploadLimit 0
# 30 Mbit/s / 8 => 3750 KBytes/s * 0.8 => 3000
set_key BWLimit uploadLimit 3000
set_key Nextcloud remotePollInterval 60000
# Because of a bug, `nextcloud` wants to create logs at a deprecated location
# => An empty file at that location makes `nextcloud` use the new location
# inside ~/.config/Nextcloud
rm -rf "$XDG_DATA_HOME/Nextcloud"
touch "$XDG_DATA_HOME/Nextcloud"
# Resume `nextcloud`
nextcloud --background &
disown

43
.local/bin/verify-dconf Executable file
View file

@ -0,0 +1,43 @@
#!/bin/sh
# List GNOME `dconf` keys that are live but not described by ~/.config/gnome-settings/*.ini
set -eu
# Keep in sync with the `RESET_PATHS` in ~/.local/bin/restore-gnome
FILTER='^(org/gnome/|org/gtk/|org/freedesktop/(ibus|tracker)/|ca/desrt/|system/)'
DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gnome-settings"
flat() {
awk '/^\[/ { s = substr($0, 2, length($0) - 2); next }
/^[A-Za-z0-9][A-Za-z0-9_-]*=/ { i = index($0, "="); print s "/" substr($0, 1, i - 1) }'
}
live=$(mktemp) || exit 1
managed=$(mktemp) || exit 1
trap 'rm -f "$live" "$managed"' EXIT INT TERM
dconf dump / | flat | grep -E "$FILTER" | sort -u > "$live"
find "$DIR" -maxdepth 2 -type f -name '*.ini' -exec cat {} + \
| sed "s|/home/user|$HOME|g" \
| flat | grep -E "$FILTER" | sort -u > "$managed"
echo ""
echo "== Live keys NOT in the ~/.config/gnome-settings/*.ini files =="
comm -23 "$live" "$managed"
echo ""
echo ""
echo "== Keys in the ~/.config/gnome-settings/*.ini files but NOT live =="
comm -13 "$live" "$managed"
echo ""