Merge branch 'dev' into rc

This commit is contained in:
David Heinemeier Hansson
2026-05-07 11:23:17 +02:00
31 changed files with 386 additions and 93 deletions
+1
View File
@@ -69,6 +69,7 @@ GROUP_DESCRIPTIONS[tz]="Timezone selection"
GROUP_DESCRIPTIONS[update]="Omarchy and system updates"
GROUP_DESCRIPTIONS[version]="Version and channel information"
GROUP_DESCRIPTIONS[voxtype]="Voxtype dictation"
GROUP_DESCRIPTIONS[weather]="Weather status"
GROUP_DESCRIPTIONS[webapp]="Web app launchers"
GROUP_DESCRIPTIONS[wifi]="Wi-Fi helpers"
GROUP_DESCRIPTIONS[windows]="Windows VM management"
+1
View File
@@ -18,6 +18,7 @@ if [[ -f $FIRST_RUN_MODE ]]; then
bash "$OMARCHY_PATH/install/first-run/gnome-theme.sh"
bash "$OMARCHY_PATH/install/first-run/gtk-primary-paste.sh"
bash "$OMARCHY_PATH/install/first-run/elephant.sh"
omarchy-hook-install post-update "$OMARCHY_PATH/install/first-run/install-voxtype.hook"
sudo rm -f /etc/sudoers.d/first-run
bash "$OMARCHY_PATH/install/first-run/welcome.sh"
+11 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# omarchy:summary=Run a named hook, like post-update (available in ~/.config/omarchy/hooks/post-update).
# omarchy:summary=Run a named hook from ~/.config/omarchy/hooks/<name> and ~/.config/omarchy/hooks/<name>.d/.
# omarchy:args=[name] [args...]
set -e
@@ -12,8 +12,17 @@ fi
HOOK=$1
HOOK_PATH="$HOME/.config/omarchy/hooks/$1"
HOOK_DIR="$HOOK_PATH.d"
shift
if [[ -f $HOOK_PATH ]]; then
bash "$HOOK_PATH" "$@"
bash "$HOOK_PATH" "$@" || echo "Hook failed: $HOOK_PATH"
fi
if [[ -d $HOOK_DIR ]]; then
for hook in "$HOOK_DIR"/*; do
[[ -f $hook ]] || continue
[[ $hook == *.sample ]] && continue
bash "$hook" "$@" || echo "Hook failed: $hook"
done
fi
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
# omarchy:summary=Install a hook into ~/.config/omarchy/hooks/<type>.d/
# omarchy:group=hook
# omarchy:name=install
# omarchy:args=<type> <file>
# omarchy:examples=omarchy hook install post-update ~/my-hook
set -e
if (( $# != 2 )); then
echo "Usage: omarchy-hook-install <type> <file>"
exit 1
fi
HOOK_TYPE=$1
HOOK_FILE=$2
HOOK_DIR="$HOME/.config/omarchy/hooks/$HOOK_TYPE.d"
HOOK_NAME=$(basename "$HOOK_FILE")
HOOK_PATH="$HOOK_DIR/$HOOK_NAME"
if [[ ! -f $HOOK_FILE ]]; then
echo "Hook file not found: $HOOK_FILE"
exit 1
fi
mkdir -p "$HOOK_DIR"
cp "$HOOK_FILE" "$HOOK_PATH"
chmod 755 "$HOOK_PATH"
echo "Installed $HOOK_TYPE hook: $HOOK_PATH"
+8 -2
View File
@@ -68,10 +68,16 @@ sddm_dir="/usr/share/sddm/themes/omarchy"
sddm_template="$HOME/.local/share/omarchy/default/sddm/omarchy/Main.qml"
sed \
-e "s/#000000/#$bg_hex/g" \
-e "s/#1a1b26/#$bg_hex/g" \
-e "s/#ffffff/#$text_hex/g" \
-e 's|source: "logo.svg"|source: "logo.png"|' \
"$sddm_template" | sudo tee "$sddm_dir/Main.qml" >/dev/null
sudo cp "$logo_path" "$sddm_dir/logo.png"
for asset in bullet.png entry.png lock.png; do
sudo cp "$staging_dir/$asset" "$sddm_dir/$asset"
done
for asset in entry lock; do
magick "$staging_dir/$asset.png" -channel RGB +level-colors "#f7768e","#f7768e" "$staging_dir/$asset-failed.png"
sudo cp "$staging_dir/$asset-failed.png" "$sddm_dir/$asset-failed.png"
done
sudo rm -f "$sddm_dir/logo.svg"
+1 -1
View File
@@ -21,5 +21,5 @@ if gum confirm "Install Voxtype + AI model (~150MB) to enable dictation?"; then
voxtype setup systemd
omarchy-restart-waybar
notify-send " Voxtype Dictation Ready" "Hold F9 (or toggle Super + Ctrl + X) to dictate.\nEdit ~/.config/voxtype/config.toml for options." -t 10000
notify-send " Voxtype Dictation Ready" "Hold F9 to dictate (or toggle with Super + Ctrl + X)." -t 10000
fi
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
# omarchy:summary=Returns a weather condition icon, adjusted for live sunrise and sunset.
weather_data=$(curl -fsS --max-time 3 "https://wttr.in?format=j1" 2>/dev/null | jq -er '[.current_condition[0].weatherCode, .weather[0].astronomy[0].sunrise, .weather[0].astronomy[0].sunset] | select(all(. != null and . != "")) | @tsv' 2>/dev/null) || exit 1
IFS=$'\t' read -r weather_code sunrise sunset <<< "$weather_data"
if [[ ! $weather_code =~ ^[0-9]+$ || ! $sunrise =~ ^[0-9]{1,2}:[0-9]{2}\ [AP]M$ || ! $sunset =~ ^[0-9]{1,2}:[0-9]{2}\ [AP]M$ ]]; then
exit 1
fi
now_epoch=$(date +%s)
sunrise_epoch=$(date -d "today $sunrise" +%s 2>/dev/null || echo 0)
sunset_epoch=$(date -d "today $sunset" +%s 2>/dev/null || echo 0)
if (( sunrise_epoch > 0 && sunset_epoch > 0 && (now_epoch < sunrise_epoch || now_epoch >= sunset_epoch) )); then
night=true
else
night=false
fi
case $weather_code in
113) [[ $night == "true" ]] && icon="" || icon="" ;;
116) [[ $night == "true" ]] && icon="" || icon="" ;;
119|122) icon="" ;;
143|248|260) icon="" ;;
176|263|266|293|296|353) [[ $night == "true" ]] && icon="" || icon="" ;;
179|227|230|323|326|368) [[ $night == "true" ]] && icon="" || icon="" ;;
182|185|281|284|311|314|317|320|350|362|365|374|377) icon="" ;;
200|386|389|392|395) icon="" ;;
299|302|305|308|356|359) icon="" ;;
329|332|335|338|371) icon="" ;;
*) icon="" ;;
esac
printf '%s\n' "$icon"
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
# omarchy:summary=Returns a formatted weather status string with temperature and wind speed.
weather=$(curl -fsS --max-time 4 "https://wttr.in?format=%l|%t|%w" 2>/dev/null | tr -d '\n')
if [[ -z $weather ]]; then
echo "Weather unavailable"
exit 1
fi
IFS='|' read -r place temperature wind <<< "$weather"
place=${place%%,*}
place=${place^}
format_temperature() {
local celsius=${1#+}
celsius=${celsius//°/}
celsius=${celsius%C}
echo "${celsius}°c / $((celsius * 9 / 5 + 32))°f"
}
temperature=$(format_temperature "$temperature")
wind=${wind//km\// km/}
echo "$(omarchy-weather-icon) $place · Temperature $temperature · Wind $wind"
@@ -1,7 +1,7 @@
#!/bin/bash
# This hook is called with the current battery percentage when the low battery
# notification is sent. To put it into use, remove .sample from the name.
# notification is sent. To put it into use, remove .sample from this file name.
SOUND_FILE="/usr/share/sounds/freedesktop/stereo/dialog-warning.oga"
@@ -1,7 +1,7 @@
#!/bin/bash
# This hook is called with the snake-cased name of the font that has just been set.
# To put it into use, remove .sample from the name.
# To put it into use, remove .sample from this file name.
# Example: Show the name of the theme that was just set.
# Example: Show the name of the font that was just set.
# notify-send -u low "New font" "Your new font is $1"
@@ -1,7 +1,7 @@
#!/bin/bash
# This hook is called after an Omarchy system update has been performed.
# To put it into use, remove .sample from the name.
# To put it into use, remove .sample from this file name.
# Example: Show notification after the system has been updated.
# notify-send -u low "Update Performed" "Your system is now up to date"
@@ -1,7 +1,7 @@
#!/bin/bash
# This hook is called with the snake-cased name of the theme that has just been set.
# To put it into use, remove .sample from the name.
# To put it into use, remove .sample from this file name.
# Example: Show the name of the theme that was just set.
# notify-send -u low "New theme" "Your new theme is $1"
+8 -1
View File
@@ -5,7 +5,7 @@
"spacing": 0,
"height": 26,
"modules-left": ["custom/omarchy", "hyprland/workspaces"],
"modules-center": ["clock", "custom/update", "custom/voxtype", "custom/screenrecording-indicator", "custom/idle-indicator", "custom/notification-silencing-indicator"],
"modules-center": ["clock", "custom/weather", "custom/update", "custom/voxtype", "custom/screenrecording-indicator", "custom/idle-indicator", "custom/notification-silencing-indicator"],
"modules-right": [
"group/tray-expander",
"bluetooth",
@@ -66,6 +66,13 @@
"tooltip": false,
"on-click-right": "omarchy-launch-floating-terminal-with-presentation omarchy-tz-select"
},
"custom/weather": {
"exec": "$OMARCHY_PATH/default/waybar/weather.sh",
"return-type": "json",
"interval": 600,
"tooltip": false,
"on-click": "notify-send -u low \"$(omarchy-weather-status)\""
},
"network": {
"format-icons": ["󰤯", "󰤟", "󰤢", "󰤥", "󰤨"],
"format": "{icon}",
+11
View File
@@ -67,6 +67,17 @@ tooltip {
margin-left: 8.75px;
}
#custom-weather {
margin-left: 7.5px;
margin-right: 7.5px;
}
#custom-weather.unavailable {
min-width: 0;
margin: 0;
padding: 0;
}
.hidden {
opacity: 0;
}
+1
View File
@@ -49,6 +49,7 @@ bindd = SUPER CTRL, R, Transcode, exec, omarchy-menu transcode
# Waybar-less information
bindd = SUPER CTRL ALT, T, Show time, exec, notify-send -u low " $(date +"%A %H:%M · %d %B %Y · Week %V")"
bindd = SUPER CTRL ALT, B, Show battery remaining, exec, notify-send -u low "$(omarchy-battery-status)"
bindd = SUPER CTRL ALT, W, Show weather, exec, notify-send -u low "$(omarchy-weather-status)"
# Control panels
bindd = SUPER CTRL, A, Audio controls, exec, omarchy-launch-audio
+3
View File
@@ -29,6 +29,9 @@ on-button-left=exec sh -c 'omarchy-notification-dismiss "Update System"; omarchy
[summary~="Learn Keybindings"]
on-button-left=exec sh -c 'omarchy-notification-dismiss "Learn Keybindings"; omarchy-menu-keybindings'
[summary~="Install Dictation with Voxtype"]
on-button-left=exec sh -c 'omarchy-notification-dismiss "Install Dictation with Voxtype"; omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-install'
[summary~="Screenshot copied & saved"]
max-icon-size=80
format=<b>%s</b>\n%b
@@ -0,0 +1,94 @@
import shlex
import shutil
from gi import require_version
require_version("Nautilus", "4.1")
from gi.repository import GObject, Gio, Nautilus
SUPPORTED_MIME_PREFIXES = ("image/", "video/")
SUPPORTED_EXTENSIONS = {
".jpg", ".jpeg", ".png", ".webp", ".gif", ".heic", ".avif",
".mp4", ".mov", ".m4v", ".mkv", ".webm", ".avi",
}
class TranscodeAction(GObject.GObject, Nautilus.MenuProvider):
def _launch_transcode(self, paths):
wrapper = shutil.which("omarchy-launch-floating-terminal-with-presentation")
binary = shutil.which("omarchy-transcode")
if not wrapper or not binary:
return
if len(paths) == 1:
cmd = shlex.join([binary, paths[0]])
else:
cmd = "; ".join(
f"echo {shlex.quote(f'Transcoding {path}')} && "
f"{shlex.join([binary, path])} || true"
for path in paths
)
Gio.Subprocess.new([wrapper, cmd], Gio.SubprocessFlags.NONE)
def _is_supported(self, file):
mime = file.get_mime_type() or ""
if mime.startswith(SUPPORTED_MIME_PREFIXES):
return True
location = file.get_location()
if not location:
return False
path = location.get_path() or ""
lower = path.lower()
return any(lower.endswith(ext) for ext in SUPPORTED_EXTENSIONS)
def _selected_paths(self, files):
paths = []
seen = set()
for file in files:
if file.is_directory():
continue
if not self._is_supported(file):
continue
location = file.get_location()
if not location:
continue
path = location.get_path()
if path and path not in seen:
seen.add(path)
paths.append(path)
return paths
def _make_item(self, paths):
label = "Transcode" if len(paths) == 1 else f"Transcode {len(paths)} items"
item = Nautilus.MenuItem(
name="OmarchyTranscodeNautilus::transcode",
label=label,
icon="media-playback-start",
)
item.connect("activate", self._on_activate, paths)
return item
def _on_activate(self, _menu, paths):
self._launch_transcode(paths)
def _tools_available(self):
return bool(
shutil.which("omarchy-launch-floating-terminal-with-presentation")
and shutil.which("omarchy-transcode")
)
def get_file_items(self, *args):
files = args[0] if len(args) == 1 else args[1]
if not self._tools_available():
return []
paths = self._selected_paths(files)
if not paths:
return []
return [self._make_item(paths)]
+95 -78
View File
@@ -2,98 +2,115 @@ import QtQuick 2.0
import SddmComponents 2.0
Rectangle {
id: root
width: 640
height: 480
color: "#000000"
id: root
width: 640
height: 480
color: "#1a1b26"
property string currentUser: userModel.lastUser
property int sessionIndex: {
for (var i = 0; i < sessionModel.rowCount(); i++) {
var name = (sessionModel.data(sessionModel.index(i, 0), Qt.DisplayRole) || "").toString()
if (name.indexOf("uwsm") !== -1)
return i
}
return sessionModel.lastIndex
property string currentUser: userModel.lastUser
property bool loginFailed: false
property int sessionIndex: {
for (var i = 0; i < sessionModel.rowCount(); i++) {
var name = (sessionModel.data(sessionModel.index(i, 0), Qt.DisplayRole) || "").toString()
if (name.indexOf("uwsm") !== -1)
return i
}
return sessionModel.lastIndex
}
Connections {
target: sddm
function onLoginFailed() {
root.loginFailed = true
password.text = ""
password.focus = true
}
function onLoginSucceeded() {
root.loginFailed = false
}
}
Column {
anchors.centerIn: parent
spacing: 40
Image {
id: logo
source: "logo.png"
width: Math.min(sourceSize.width, root.width * 0.8)
height: sourceSize.width > 0 ? Math.round(width * sourceSize.height / sourceSize.width) : 0
fillMode: Image.PreserveAspectFit
anchors.horizontalCenter: parent.horizontalCenter
}
Connections {
target: sddm
function onLoginFailed() {
errorMessage.text = "Login failed"
password.text = ""
password.focus = true
}
function onLoginSucceeded() {
errorMessage.text = ""
}
}
Row {
anchors.horizontalCenter: parent.horizontalCenter
spacing: 15
Column {
anchors.centerIn: parent
spacing: root.height * 0.04
width: parent.width
Image {
source: root.loginFailed ? "lock-failed.png" : "lock.png"
width: 34
height: 38
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: entry.width
height: entry.height
Image {
source: "logo.svg"
width: root.width * 0.35
height: Math.round(width * sourceSize.height / sourceSize.width)
fillMode: Image.PreserveAspectFit
anchors.horizontalCenter: parent.horizontalCenter
id: entry
source: root.loginFailed ? "entry-failed.png" : "entry.png"
anchors.centerIn: parent
}
Row {
anchors.horizontalCenter: parent.horizontalCenter
spacing: root.width * 0.007
anchors.left: parent.left
anchors.leftMargin: 20
anchors.verticalCenter: parent.verticalCenter
spacing: 5
Text {
text: "\uf023"
color: "#ffffff"
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: root.height * 0.025
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
width: root.width * 0.17
height: root.height * 0.04
color: "#000000"
border.color: "#ffffff"
border.width: 1
clip: true
TextInput {
id: password
anchors.fill: parent
anchors.margins: root.height * 0.008
verticalAlignment: TextInput.AlignVCenter
echoMode: TextInput.Password
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: root.height * 0.02
font.letterSpacing: root.height * 0.004
passwordCharacter: "\u2022"
color: "#ffffff"
focus: true
Keys.onPressed: {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
sddm.login(root.currentUser, password.text, root.sessionIndex)
event.accepted = true
}
}
}
Repeater {
model: Math.min(password.text.length, 21)
Image {
source: "bullet.png"
width: 7
height: 7
}
}
}
Text {
id: errorMessage
text: ""
color: "#f7768e"
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: root.height * 0.018
anchors.horizontalCenter: parent.horizontalCenter
TextInput {
id: password
anchors.fill: parent
anchors.leftMargin: 20
anchors.rightMargin: 20
verticalAlignment: TextInput.AlignVCenter
echoMode: TextInput.Password
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: 24
font.letterSpacing: 5
passwordCharacter: "\u2022"
color: "transparent"
selectionColor: "transparent"
selectedTextColor: "transparent"
focus: true
onTextChanged: root.loginFailed = false
Keys.onPressed: {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
sddm.login(root.currentUser, password.text, root.sessionIndex)
event.accepted = true
}
}
}
}
}
Component.onCompleted: password.forceActiveFocus()
}
Component.onCompleted: password.forceActiveFocus()
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

-1
View File
@@ -1 +0,0 @@
<svg fill="none" height="285" viewBox="0 0 1215 285" width="1215" xmlns="http://www.w3.org/2000/svg"><g fill="#9ece6a"><path clip-rule="evenodd" d="m720 120h-15v15h-14.998v14.999l-60.002.001v15.002l90-.002v.002h.002l-.002 89.998h-15v15h-13v15h-17v-89.998h-45v90l-45-.002v-89.998h-14.998v-30h14.998v-15.002h-14.998v-30.001h14.998v-75h15v-14.997h15v-15.002h105.002zm-90-.001h45v-74.997h-45z" fill-rule="evenodd"/><path clip-rule="evenodd" d="m105 30.002h15v14.997h15v180.001h-15v15h-15v15.002h-75v-15.002h-15v-15h-15v-180.001h15v-14.997h15v-15.002h75zm-60 194.998h45v-179.998h-45z" fill-rule="evenodd"/><path d="m300 15h60v15h15v14.999h15v180.001h-15v15h-15v15h-15l-.004-209.998h-44.994v-.002h-.002v210.002h-45v-210h-44.998v179.997h-.002v30.003h-15v-15.002h-15v-15h-14.998v-180.001h14.998v-14.999h15v-15h60v-15h45z"/><path clip-rule="evenodd" d="m555 225h-15v15h-15v15h-15v-105.001l-44.998.001v105.002h-45.002v-105.002h-15v-30.001h15v-75h15.002v-14.997h15v-15.002h105zm-89.998-105.001h44.998v-74.997h-44.998z" fill-rule="evenodd"/><path d="m885 75h-15v15h-15v15h-15v-59.998h-45v179.998h45v-59.998h15v14.997h15v15.001h15v30h-15v15h-15v15.002l-105-.002v-210.001h14.998v-14.997h15.002v-15.002h105z"/><path d="m960 119.999h45v-104.999h15v15h15v14.999h15v75.001h15v15h-15v90h-15v15h-15v15h-15v-105h-45v105.002l-45-.002v-105h-30v-15h15v-15.001h15v-75h15v-14.997h15v-15.002h15z"/><path d="m1125 119.999h45v-104.999h15v15h15v15h15v180h-15v15h-15v15.002l-75-.002v-15h-15v-15h-15v-45.001h15v-14.997-.002h30v60h45v-75h-90v-105.001h15v-14.997h15v-15.002h15z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
icon=$(omarchy-weather-icon 2>/dev/null)
if [[ -n $icon ]]; then
icon=$(printf '%s' "$icon" | sed 's/["\\]/\\&/g')
printf '{"text":"%s"}\n' "$icon"
else
printf '{"text":"","class":"unavailable"}\n'
fi
+1
View File
@@ -2,3 +2,4 @@ EXTENSIONS_DIR="$HOME/.local/share/nautilus-python/extensions"
mkdir -p "$EXTENSIONS_DIR"
cp "$OMARCHY_PATH/default/nautilus-python/extensions/localsend.py" "$EXTENSIONS_DIR/"
cp "$OMARCHY_PATH/default/nautilus-python/extensions/transcode.py" "$EXTENSIONS_DIR/"
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
set -e
# Remove this hook after use
rm -f "$0"
notify-send " Install Dictation with Voxtype" "Click to install voice dictation for Omarchy." -u critical
+3 -3
View File
@@ -1,7 +1,7 @@
echo "Add sample low battery notification hook"
mkdir -p ~/.config/omarchy/hooks
mkdir -p ~/.config/omarchy/hooks/battery-low.d
if [[ ! -f ~/.config/omarchy/hooks/battery-low.sample ]]; then
cp "$OMARCHY_PATH/config/omarchy/hooks/battery-low.sample" ~/.config/omarchy/hooks/battery-low.sample
if [[ ! -f ~/.config/omarchy/hooks/battery-low.d/play-warning-sound.sample ]]; then
cp "$OMARCHY_PATH/config/omarchy/hooks/battery-low.d/play-warning-sound.sample" ~/.config/omarchy/hooks/battery-low.d/play-warning-sound.sample
fi
+3
View File
@@ -0,0 +1,3 @@
echo "Add Transcode entry to Nautilus context menu"
source $OMARCHY_PATH/install/config/nautilus-python.sh
+29
View File
@@ -0,0 +1,29 @@
echo "Add weather widget to Waybar"
WAYBAR_CONFIG="$HOME/.config/waybar/config.jsonc"
WAYBAR_STYLE="$HOME/.config/waybar/style.css"
if [[ -f $WAYBAR_CONFIG ]]; then
if ! grep -q '"custom/weather"' "$WAYBAR_CONFIG"; then
sed -i 's/"modules-center": \["clock",/"modules-center": ["clock", "custom\/weather",/' "$WAYBAR_CONFIG"
sed -i '/"network": {/i\ "custom/weather": {\n "exec": "$OMARCHY_PATH/default/waybar/weather.sh",\n "return-type": "json",\n "interval": 600,\n "tooltip": false,\n "on-click": "notify-send -u low \\"$(omarchy-weather-status)\\""\n },' "$WAYBAR_CONFIG"
fi
fi
if [[ -f $WAYBAR_STYLE ]] && ! grep -q '#custom-weather' "$WAYBAR_STYLE"; then
cat >>"$WAYBAR_STYLE" <<'EOF'
#custom-weather {
margin-left: 7.5px;
margin-right: 7.5px;
}
#custom-weather.unavailable {
min-width: 0;
margin: 0;
padding: 0;
}
EOF
fi
omarchy-restart-waybar