Add configuration for GNOME
This commit is contained in:
parent
97420532e0
commit
c5f9769acf
24 changed files with 4188 additions and 0 deletions
31
.local/bin/dark-theme-toggle
Executable file
31
.local/bin/dark-theme-toggle
Executable 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
|
||||
34
.local/bin/import-gnome-extension-schemas
Executable file
34
.local/bin/import-gnome-extension-schemas
Executable 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"
|
||||
|
|
@ -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 ""
|
||||
|
|
|
|||
85
.local/bin/night-light-make-cooler
Executable file
85
.local/bin/night-light-make-cooler
Executable 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
|
||||
85
.local/bin/night-light-make-warmer
Executable file
85
.local/bin/night-light-make-warmer
Executable 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
|
||||
68
.local/bin/night-light-toggle-enabled
Executable file
68
.local/bin/night-light-toggle-enabled
Executable 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
|
||||
102
.local/bin/night-light-toggle-schedule
Executable file
102
.local/bin/night-light-toggle-schedule
Executable 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
64
.local/bin/patch-forge
Executable 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
75
.local/bin/randomize-background
Executable 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
147
.local/bin/restore-gnome
Executable 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
139
.local/bin/restore-nextcloud
Executable 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
43
.local/bin/verify-dconf
Executable 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 ""
|
||||
Loading…
Reference in a new issue