Merge pull request #2417 from basecamp/dev

Omarchy 3.1.0
This commit is contained in:
David Heinemeier Hansson
2025-10-19 09:27:33 +02:00
committed by GitHub
249 changed files with 3294 additions and 1616 deletions

9
.editorconfig Normal file
View File

@@ -0,0 +1,9 @@
root = true
[*]
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
charset = utf-8

View File

@@ -0,0 +1,2 @@
[Desktop Entry]
Hidden=true

View File

@@ -0,0 +1,2 @@
[Desktop Entry]
Hidden=true

View File

@@ -0,0 +1,2 @@
[Desktop Entry]
Hidden=true

View File

@@ -0,0 +1,2 @@
[Desktop Entry]
Hidden=true

View File

@@ -0,0 +1,2 @@
[Desktop Entry]
Hidden=true

View File

@@ -0,0 +1,2 @@
[Desktop Entry]
Hidden=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@@ -2,7 +2,7 @@
Name=Neovim Name=Neovim
GenericName=Text Editor GenericName=Text Editor
Comment=Edit text files Comment=Edit text files
Exec=$TERMINAL --class=nvim --title=nvim -e nvim -- %F Exec=omarchy-launch-editor %F
Terminal=false Terminal=false
Type=Application Type=Application
Keywords=Text;editor; Keywords=Text;editor;

View File

@@ -3,5 +3,12 @@
if [[ $# -eq 0 ]]; then if [[ $# -eq 0 ]]; then
echo "Adjust Apple Display Brightness by passing +5000 or -5000 (or any range from 0-60000)" echo "Adjust Apple Display Brightness by passing +5000 or -5000 (or any range from 0-60000)"
else else
sudo asdcontrol $(sudo asdcontrol --detect /dev/usb/hiddev* | grep ^/dev/usb/hiddev | cut -d: -f1) -- "$1" DEVICE="$(sudo asdcontrol --detect /dev/usb/hiddev* | grep ^/dev/usb/hiddev | cut -d: -f1)"
sudo asdcontrol "$DEVICE" -- "$1" >/dev/null
VALUE="$(sudo asdcontrol "$DEVICE" | awk -F= '/BRIGHTNESS=/{print $2+0}')"
swayosd-client \
--monitor "$(hyprctl monitors -j | jq -r '.[]|select(.focused==true).name')" \
--custom-icon display-brightness \
--custom-progress "$(awk -v v="$VALUE" 'BEGIN{printf "%.2f", v/60000}')" \
--custom-progress-text "$(( VALUE * 100 / 60000 ))%"
fi fi

View File

@@ -23,7 +23,13 @@ fi
next_sink=$(echo "$sinks" | jq -r ".[$next_sink_index]") next_sink=$(echo "$sinks" | jq -r ".[$next_sink_index]")
next_sink_name=$(echo "$next_sink" | jq -r '.name') next_sink_name=$(echo "$next_sink" | jq -r '.name')
next_sink_description=$(echo "$next_sink" | jq -r '.description') next_sink_description=$(echo "$next_sink" | jq -r '.description')
if [ "$next_sink_description" = "(null)" ] || [ "$next_sink_description" = "null" ] || [ -z "$next_sink_description" ]; then
sink_id=$(echo "$next_sink" | jq -r '.properties."object.id"')
next_sink_description=$(wpctl status | grep -E "\s+\*?\s+${sink_id}\." | sed -E 's/^.*[0-9]+\.\s+//' | sed -E 's/\s+\[.*$//')
fi
next_sink_volume=$(echo "$next_sink" | jq -r \ next_sink_volume=$(echo "$next_sink" | jq -r \
'.volume | to_entries[0].value.value_percent | sub("%"; "")') '.volume | to_entries[0].value.value_percent | sub("%"; "")')
next_sink_is_muted=$(echo "$next_sink" | jq -r '.mute') next_sink_is_muted=$(echo "$next_sink" | jq -r '.mute')

View File

@@ -8,7 +8,9 @@ if [[ -f "$FIRST_RUN_MODE" ]]; then
rm -f "$FIRST_RUN_MODE" rm -f "$FIRST_RUN_MODE"
bash "$OMARCHY_PATH/install/first-run/battery-monitor.sh" bash "$OMARCHY_PATH/install/first-run/battery-monitor.sh"
bash "$OMARCHY_PATH/install/first-run/cleanup-reboot-sudoers.sh"
bash "$OMARCHY_PATH/install/first-run/firewall.sh" bash "$OMARCHY_PATH/install/first-run/firewall.sh"
bash "$OMARCHY_PATH/install/first-run/dns-resolver.sh"
bash "$OMARCHY_PATH/install/first-run/gnome-theme.sh" bash "$OMARCHY_PATH/install/first-run/gnome-theme.sh"
sudo rm -f /etc/sudoers.d/first-run sudo rm -f /etc/sudoers.d/first-run

View File

@@ -8,31 +8,82 @@ if [[ ! -d "$OUTPUT_DIR" ]]; then
exit 1 exit 1
fi fi
# Selects region or output SCOPE=""
SCOPE="$1" AUDIO="false"
WEBCAM="false"
# Selects audio inclusion or not for arg in "$@"; do
AUDIO=$([[ $2 == "audio" ]] && echo "--audio") case "$arg" in
--with-audio) AUDIO="true" ;;
--with-webcam) WEBCAM="true" ;;
output|region) SCOPE="$arg" ;;
esac
done
cleanup_webcam() {
pkill -f "WebcamOverlay" 2>/dev/null
}
start_webcam_overlay() {
cleanup_webcam
# Get monitor scale
local scale=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .scale')
# Target width (base 360px, scaled to monitor)
local target_width=$(awk "BEGIN {printf \"%.0f\", 360 * $scale}")
# Try preferred 16:9 resolutions in order, use first available
local preferred_resolutions=("640x360" "1280x720" "1920x1080")
local video_size_arg=""
local available_formats=$(v4l2-ctl --list-formats-ext -d /dev/video0 2>/dev/null)
for resolution in "${preferred_resolutions[@]}"; do
if echo "$available_formats" | grep -q "$resolution"; then
video_size_arg="-video_size $resolution"
break
fi
done
ffplay -f v4l2 $video_size_arg -framerate 30 /dev/video0 \
-vf "scale=${target_width}:-1" \
-window_title "WebcamOverlay" \
-noborder \
-fflags nobuffer -flags low_delay \
-probesize 32 -analyzeduration 0 \
-loglevel quiet &
sleep 1
}
start_screenrecording() { start_screenrecording() {
local filename="$OUTPUT_DIR/screenrecording-$(date +'%Y-%m-%d_%H-%M-%S').mp4" local filename="$OUTPUT_DIR/screenrecording-$(date +'%Y-%m-%d_%H-%M-%S').mp4"
local audio_args=""
if lspci | grep -qi 'nvidia'; then # Merge audio tracks into one - separate tracks only play one at a time in most players
wf-recorder $AUDIO -f "$filename" -c libx264 -p crf=23 -p preset=medium -p movflags=+faststart "$@" & [[ "$AUDIO" == "true" ]] && audio_args="-a default_output|default_input"
else
wl-screenrec $AUDIO -f "$filename" --ffmpeg-encoder-options="-c:v libx264 -crf 23 -preset medium -movflags +faststart" "$@" &
fi
gpu-screen-recorder -w "$@" -f 60 -c mp4 -o "$filename" $audio_args &
toggle_screenrecording_indicator toggle_screenrecording_indicator
} }
stop_screenrecording() { stop_screenrecording() {
pkill -x wl-screenrec pkill -SIGINT -f "gpu-screen-recorder" # SIGINT required to save video properly
pkill -x wf-recorder
notify-send "Screen recording saved to $OUTPUT_DIR" -t 2000 # Wait a maximum of 5 seconds to finish before hard killing
local count=0
while pgrep -f "gpu-screen-recorder" >/dev/null && [ $count -lt 50 ]; do
sleep 0.1
count=$((count + 1))
done
sleep 0.2 # ensures the process is actually dead before we check if pgrep -f "gpu-screen-recorder" >/dev/null; then
pkill -9 -f "gpu-screen-recorder"
cleanup_webcam
notify-send "Screen recording error" "Recording process had to be force-killed. Video may be corrupted." -u critical -t 5000
else
cleanup_webcam
notify-send "Screen recording saved to $OUTPUT_DIR" -t 2000
fi
toggle_screenrecording_indicator toggle_screenrecording_indicator
} }
@@ -41,15 +92,51 @@ toggle_screenrecording_indicator() {
} }
screenrecording_active() { screenrecording_active() {
pgrep -x wl-screenrec >/dev/null || pgrep -x wf-recorder >/dev/null pgrep -f "gpu-screen-recorder" >/dev/null || pgrep -x slurp >/dev/null || pgrep -f "WebcamOverlay" >/dev/null
} }
if screenrecording_active; then if screenrecording_active; then
stop_screenrecording if pgrep -x slurp >/dev/null; then
pkill -x slurp 2>/dev/null
elif pgrep -f "WebcamOverlay" >/dev/null && ! pgrep -f "gpu-screen-recorder" >/dev/null; then
cleanup_webcam
else
stop_screenrecording
fi
elif [[ "$SCOPE" == "output" ]]; then elif [[ "$SCOPE" == "output" ]]; then
output=$(slurp -o) || exit 1 [[ "$WEBCAM" == "true" ]] && start_webcam_overlay
start_screenrecording -g "$output"
if ! output=$(slurp -o -f "%o"); then
[[ "$WEBCAM" == "true" ]] && cleanup_webcam
exit 1
fi
if [[ -z "$output" ]]; then
notify-send "Error" "Could not detect monitor" -u critical
[[ "$WEBCAM" == "true" ]] && cleanup_webcam
exit 1
fi
start_screenrecording "$output"
else else
region=$(slurp) || exit 1 [[ "$WEBCAM" == "true" ]] && start_webcam_overlay
start_screenrecording -g "$region"
scale=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .scale')
if ! region=$(slurp -f "%wx%h+%x+%y"); then
[[ "$WEBCAM" == "true" ]] && cleanup_webcam
exit 1
fi
if [[ "$region" =~ ^([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)$ ]]; then
w=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[1]} * $scale}")
h=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[2]} * $scale}")
x=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[3]} * $scale}")
y=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[4]} * $scale}")
scaled_region="${w}x${h}+${x}+${y}"
else
scaled_region="$region"
fi
start_screenrecording region -region "$scaled_region"
fi fi

View File

@@ -13,7 +13,7 @@ exit_screensaver() {
trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT
hyprctl keyword cursor:invisible true hyprctl keyword cursor:invisible true &>/dev/null
while true; do while true; do
effect=$(tte 2>&1 | grep -oP '{\K[^}]+' | tr ',' ' ' | tr ' ' '\n' | sed -n '/^beams$/,$p' | sort -u | shuf -n1) effect=$(tte 2>&1 | grep -oP '{\K[^}]+' | tr ',' ' ' | tr ' ' '\n' | sed -n '/^beams$/,$p' | sort -u | shuf -n1)

View File

@@ -8,10 +8,76 @@ if [[ ! -d "$OUTPUT_DIR" ]]; then
exit 1 exit 1
fi fi
pkill slurp || hyprshot -m ${1:-region} --raw | pkill slurp && exit 0
MODE="${1:-smart}"
PROCESSING="${2:-slurp}"
get_rectangles() {
local active_workspace=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .activeWorkspace.id')
hyprctl monitors -j | jq -r --arg ws "$active_workspace" '.[] | select(.activeWorkspace.id == ($ws | tonumber)) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"'
hyprctl clients -j | jq -r --arg ws "$active_workspace" '.[] | select(.workspace.id == ($ws | tonumber)) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"'
}
# Select based on mode
case "$MODE" in
region)
wayfreeze & PID=$!
sleep .1
SELECTION=$(slurp 2>/dev/null)
kill $PID 2>/dev/null
;;
windows)
wayfreeze & PID=$!
sleep .1
SELECTION=$(get_rectangles | slurp -r 2>/dev/null)
kill $PID 2>/dev/null
;;
fullscreen)
SELECTION=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"')
;;
smart|*)
RECTS=$(get_rectangles)
wayfreeze & PID=$!
sleep .1
SELECTION=$(echo "$RECTS" | slurp 2>/dev/null)
kill $PID 2>/dev/null
# If the selction area is L * W < 20, we'll assume you were trying to select whichever
# window or output it was inside of to prevent accidental 2px snapshots
if [[ "$SELECTION" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]]; then
if (( ${BASH_REMATCH[3]} * ${BASH_REMATCH[4]} < 20 )); then
click_x="${BASH_REMATCH[1]}"
click_y="${BASH_REMATCH[2]}"
while IFS= read -r rect; do
if [[ "$rect" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+) ]]; then
rect_x="${BASH_REMATCH[1]}"
rect_y="${BASH_REMATCH[2]}"
rect_width="${BASH_REMATCH[3]}"
rect_height="${BASH_REMATCH[4]}"
if (( click_x >= rect_x && click_x < rect_x+rect_width && click_y >= rect_y && click_y < rect_y+rect_height )); then
SELECTION="${rect_x},${rect_y} ${rect_width}x${rect_height}"
break
fi
fi
done <<< "$RECTS"
fi
fi
;;
esac
[ -z "$SELECTION" ] && exit 0
if [[ $PROCESSING == "slurp" ]]; then
grim -g "$SELECTION" - |
satty --filename - \ satty --filename - \
--output-filename "$OUTPUT_DIR/screenshot-$(date +'%Y-%m-%d_%H-%M-%S').png" \ --output-filename "$OUTPUT_DIR/screenshot-$(date +'%Y-%m-%d_%H-%M-%S').png" \
--early-exit \ --early-exit \
--actions-on-enter save-to-clipboard \ --actions-on-enter save-to-clipboard \
--save-after-copy \ --save-after-copy \
--copy-command 'wl-copy' --copy-command 'wl-copy'
else
grim -g "$SELECTION" - | wl-copy
fi

View File

@@ -2,10 +2,16 @@
# Go from current active terminal to its child shell process and run cwd there # Go from current active terminal to its child shell process and run cwd there
terminal_pid=$(hyprctl activewindow | awk '/pid:/ {print $2}') terminal_pid=$(hyprctl activewindow | awk '/pid:/ {print $2}')
shell_pid=$(pgrep -P "$terminal_pid" | head -n1) shell_pid=$(pgrep -P "$terminal_pid" | tail -n1)
if [[ -n $shell_pid ]]; then if [[ -n $shell_pid ]]; then
readlink -f "/proc/$shell_pid/cwd" 2>/dev/null || echo "$HOME" cwd=$(readlink -f "/proc/$shell_pid/cwd" 2>/dev/null)
if [[ -d $cwd ]]; then
echo "$cwd"
else
echo "$HOME"
fi
else else
echo "$HOME" echo "$HOME"
fi fi

View File

@@ -1,8 +0,0 @@
#!/bin/bash
notify-send " Updating time and timezone..."
sudo systemctl restart systemd-timesyncd
sudo tzupdate
new_timezone=$(timedatectl show -p Timezone --value)
omarchy-restart-waybar
notify-send " Time updated and timezone set to $new_timezone"

View File

@@ -28,6 +28,8 @@ if [[ -n "$font_name" && "$font_name" != "CNCLD" ]]; then
omarchy-restart-waybar omarchy-restart-waybar
omarchy-restart-swayosd omarchy-restart-swayosd
omarchy-restart-walker omarchy-restart-walker
omarchy-hook font-set "$font_name"
else else
echo "Font '$font_name' not found." echo "Font '$font_name' not found."
exit 1 exit 1

14
bin/omarchy-hook Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/bash
if [[ $# -lt 1 ]]; then
echo "Usage: omarchy-hook [name] [args...]"
exit 1
fi
HOOK=$1
HOOK_PATH="$HOME/.config/omarchy/hooks/$1"
shift
if [[ -f $HOOK_PATH ]]; then
bash "$HOOK_PATH" "$@"
fi

View File

@@ -1,9 +1,9 @@
#!/bin/bash #!/bin/bash
options=("MySQL" "PostgreSQL" "Redis" "MongoDB" "MariaDB") options=("MySQL" "PostgreSQL" "Redis" "MongoDB" "MariaDB" "MSSQL")
if [[ "$#" -eq 0 ]]; then if [[ "$#" -eq 0 ]]; then
choices=$(printf "%s\n" "${options[@]}" | gum choose --header "Select databases (space to select, return to install, esc to cancel)") || main_menu choices=$(printf "%s\n" "${options[@]}" | gum choose --header "Select database (return to install, esc to cancel)") || main_menu
else else
choices="$@" choices="$@"
fi fi
@@ -16,6 +16,7 @@ if [[ -n "$choices" ]]; then
MariaDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:3306:3306" --name=mariadb11 -e MARIADB_ROOT_PASSWORD= -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true mariadb:11.8 ;; MariaDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:3306:3306" --name=mariadb11 -e MARIADB_ROOT_PASSWORD= -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true mariadb:11.8 ;;
Redis) sudo docker run -d --restart unless-stopped -p "127.0.0.1:6379:6379" --name=redis redis:7 ;; Redis) sudo docker run -d --restart unless-stopped -p "127.0.0.1:6379:6379" --name=redis redis:7 ;;
MongoDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:27017:27017" --name mongodb -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin123 mongo:noble ;; MongoDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:27017:27017" --name mongodb -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin123 mongo:noble ;;
MSSQL) sudo docker run -d --restart unless-stopped -p "127.0.0.1:1433:1433" --name mssql -e MSSQL_PID=Developer -e ACCEPT_EULA=Y -e "MSSQL_SA_PASSWORD=@dmin123" mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 ;;
esac esac
done done
else else

View File

@@ -4,5 +4,5 @@ echo "Installing all dependencies..."
omarchy-pkg-add dropbox dropbox-cli libappindicator-gtk3 python-gpgme nautilus-dropbox omarchy-pkg-add dropbox dropbox-cli libappindicator-gtk3 python-gpgme nautilus-dropbox
echo "Starting Dropbox..." echo "Starting Dropbox..."
uwsm app -- dropbox-cli start &>/dev/null & uwsm-app -- dropbox-cli start &>/dev/null &
echo "See Dropbox icon behind  hover tray in top right and right-click for setup." echo "See Dropbox icon behind  hover tray in top right and right-click for setup."

View File

@@ -14,6 +14,6 @@ omarchy-pkg-add $package
echo "Setting $package as new default terminal..." echo "Setting $package as new default terminal..."
sed -i "/export TERMINAL=/ c\export TERMINAL=$package" ~/.config/uwsm/default sed -i "/export TERMINAL=/ c\export TERMINAL=$package" ~/.config/uwsm/default
# Relaunch is needed for new default to take effect # Restart is needed for new default to take effect
echo echo
gum confirm "Relaunch Hyprland to use new terminal?" && uwsm stop gum confirm "Restart to use new terminal?" && systemctl reboot --no-wall

24
bin/omarchy-install-vscode Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/bash
echo "Installing VSCode..."
omarchy-pkg-add visual-studio-code-bin
mkdir -p ~/.vscode
cat > ~/.vscode/argv.json << 'EOF'
// This configuration file allows you to pass permanent command line arguments to VS Code.
// Only a subset of arguments is currently supported to reduce the likelihood of breaking
// the installation.
//
// PLEASE DO NOT CHANGE WITHOUT UNDERSTANDING THE IMPACT
//
// NOTE: Changing this file requires a restart of VS Code.
{
"password-store":"gnome-libsecret"
}
EOF
# Ensure VSC's own auto-update feature is turned off
printf '{\n "update.mode": "none"\n}\n' > ~/.config/Code/User/settings.json
setsid gtk-launch code

View File

@@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
exec setsid uwsm app -- alacritty --class=Omarchy -o font.size=9 -e bash -c 'fastfetch; read -n 1 -s' exec setsid uwsm-app -- alacritty --class=Omarchy -o font.size=9 -e bash -c 'fastfetch; read -n 1 -s'

View File

@@ -9,4 +9,4 @@ else
private_flag="--incognito" private_flag="--incognito"
fi fi
exec setsid uwsm app -- "$browser_exec" "${@/--private/$private_flag}" exec setsid uwsm-app -- "$browser_exec" "${@/--private/$private_flag}"

View File

@@ -1,10 +1,10 @@
#!/bin/bash #!/bin/bash
case "${EDITOR:-nvim}" in case "${EDITOR:-nvim}" in
nvim | vim | nano | micro | hx) nvim | vim | nano | micro | hx | helix)
exec setsid uwsm app -- "$TERMINAL" -e "$EDITOR" "$@" exec setsid uwsm-app -- "$TERMINAL" -e "$EDITOR" "$@"
;; ;;
*) *)
exec setsid uwsm app -- "$EDITOR" "$@" exec setsid uwsm-app -- "$EDITOR" "$@"
;; ;;
esac esac

View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
cmd="$*" cmd="$*"
exec setsid uwsm app -- alacritty --class=Omarchy --title=Omarchy -e bash -c "omarchy-show-logo; $cmd; omarchy-show-done" exec setsid uwsm-app -- alacritty -o font.size=9 --class=Omarchy --title=Omarchy -e bash -c "omarchy-show-logo; $cmd; omarchy-show-done"

View File

@@ -6,7 +6,7 @@ if (($# == 0)); then
fi fi
WINDOW_PATTERN="$1" WINDOW_PATTERN="$1"
LAUNCH_COMMAND="${2:-"uwsm app -- $WINDOW_PATTERN"}" LAUNCH_COMMAND="${2:-"uwsm-app -- $WINDOW_PATTERN"}"
WINDOW_ADDRESS=$(hyprctl clients -j | jq -r --arg p "$WINDOW_PATTERN" '.[]|select((.class|test("\\b" + $p + "\\b";"i")) or (.title|test("\\b" + $p + "\\b";"i")))|.address' | head -n1) WINDOW_ADDRESS=$(hyprctl clients -j | jq -r --arg p "$WINDOW_PATTERN" '.[]|select((.class|test("\\b" + $p + "\\b";"i")) or (.title|test("\\b" + $p + "\\b";"i")))|.address' | head -n1)
if [[ -n $WINDOW_ADDRESS ]]; then if [[ -n $WINDOW_ADDRESS ]]; then

View File

@@ -1,8 +1,12 @@
#!/bin/bash #!/bin/bash
if (($# == 0)); then if (($# == 0)); then
echo "Usage: omarchy-launch-or-focus-webapp [window-pattern] [url]" echo "Usage: omarchy-launch-or-focus-webapp [window-pattern] [url-and-flags...]"
exit 1 exit 1
fi fi
exec omarchy-launch-or-focus "$1" "omarchy-launch-webapp '$2'" WINDOW_PATTERN="$1"
shift
LAUNCH_COMMAND="omarchy-launch-webapp $@"
exec omarchy-launch-or-focus "$WINDOW_PATTERN" "$LAUNCH_COMMAND"

13
bin/omarchy-launch-walker Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
# Ensure elephant is running before launching walker
if ! pgrep -x elephant > /dev/null; then
setsid uwsm-app -- elephant &
fi
# Ensure walker service is running
if ! pgrep -f "walker --gapplication-service" > /dev/null; then
setsid uwsm-app -- walker --gapplication-service &
fi
exec walker --width 644 --maxheight 300 --minheight 300 "$@"

View File

@@ -7,4 +7,4 @@ google-chrome* | brave-browser* | microsoft-edge* | opera* | vivaldi* | helium-b
*) browser="chromium.desktop" ;; *) browser="chromium.desktop" ;;
esac esac
exec setsid uwsm app -- $(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$browser 2>/dev/null | head -1) --app="$1" "${@:2}" exec setsid uwsm-app -- $(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$browser 2>/dev/null | head -1) --app="$1" "${@:2}"

View File

@@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
exec setsid uwsm app -- "$TERMINAL" --class=Impala -e impala "$@" exec setsid uwsm-app -- "$TERMINAL" --class=Impala -e impala "$@"

View File

@@ -9,4 +9,4 @@ if pgrep -x "1password" >/dev/null; then
fi fi
# Avoid running screensaver when locked # Avoid running screensaver when locked
pkill -f "$TERMINAL --class Screensaver" pkill -f "alacritty --class Screensaver"

View File

@@ -29,11 +29,11 @@ menu() {
local index local index
index=$(echo -e "$options" | grep -nxF "$preselect" | cut -d: -f1) index=$(echo -e "$options" | grep -nxF "$preselect" | cut -d: -f1)
if [[ -n "$index" ]]; then if [[ -n "$index" ]]; then
args+=("-a" "$index") args+=("-c" "$index")
fi fi
fi fi
echo -e "$options" | walker --dmenu --theme dmenu_250 -p "$prompt…" "${args[@]}" echo -e "$options" | omarchy-launch-walker --dmenu --width 295 --minheight 1 --maxheight 600 -p "$prompt…" "${args[@]}" 2>/dev/null
} }
terminal() { terminal() {
@@ -104,21 +104,21 @@ show_capture_menu() {
} }
show_screenshot_menu() { show_screenshot_menu() {
case $(menu "Screenshot" " Region\n Window\n Display") in case $(menu "Screenshot" " Snap with Editing\n Straight to Clipboard") in
*Region*) omarchy-cmd-screenshot ;; *Editing*) omarchy-cmd-screenshot smart ;;
*Window*) omarchy-cmd-screenshot window ;; *Clipboard*) omarchy-cmd-screenshot smart clipboard ;;
*Display*) omarchy-cmd-screenshot output ;;
*) show_capture_menu ;; *) show_capture_menu ;;
esac esac
} }
show_screenrecord_menu() { show_screenrecord_menu() {
case $(menu "Screenrecord" " Region\n Region + Audio\n Display\n Display + Audio") in case $(menu "Screenrecord" " Region\n Region + Audio\n Display\n Display + Audio\n Display + Webcam") in
*"Region + Audio"*) omarchy-cmd-screenrecord region audio ;; *"Region + Audio"*) omarchy-cmd-screenrecord region --with-audio ;;
*Region*) omarchy-cmd-screenrecord ;; *Region*) omarchy-cmd-screenrecord ;;
*"Display + Audio"*) omarchy-cmd-screenrecord output audio ;; *"Display + Audio"*) omarchy-cmd-screenrecord output --with-audio ;;
*"Display + Webcam"*) omarchy-cmd-screenrecord output --with-audio --with-webcam ;;
*Display*) omarchy-cmd-screenrecord output ;; *Display*) omarchy-cmd-screenrecord output ;;
*) show_capture_menu ;; *) back_to show_capture_menu ;;
esac esac
} }
@@ -163,7 +163,7 @@ show_theme_menu() {
} }
show_font_menu() { show_font_menu() {
theme=$(menu "Font" "$(omarchy-font-list)" "-w 350" "$(omarchy-font-current)") theme=$(menu "Font" "$(omarchy-font-list)" "--width 350" "$(omarchy-font-current)")
if [[ "$theme" == "CNCLD" || -z "$theme" ]]; then if [[ "$theme" == "CNCLD" || -z "$theme" ]]; then
back_to show_style_menu back_to show_style_menu
else else
@@ -232,7 +232,7 @@ show_setup_security_menu() {
} }
show_install_menu() { show_install_menu() {
case $(menu "Install" "󰣇 Package\n󰣇 AUR\n Web App\n TUI\n Service\n Style\n󰵮 Development\n Editor\n Terminal\n󱚤 AI\n Gaming") in case $(menu "Install" "󰣇 Package\n󰣇 AUR\n Web App\n TUI\n Service\n Style\n󰵮 Development\n Editor\n Terminal\n󱚤 AI\n󰍲 Windows\n Gaming") in
*Package*) terminal omarchy-pkg-install ;; *Package*) terminal omarchy-pkg-install ;;
*AUR*) terminal omarchy-pkg-aur-install ;; *AUR*) terminal omarchy-pkg-aur-install ;;
*Web*) present_terminal omarchy-webapp-install ;; *Web*) present_terminal omarchy-webapp-install ;;
@@ -243,6 +243,7 @@ show_install_menu() {
*Editor*) show_install_editor_menu ;; *Editor*) show_install_editor_menu ;;
*Terminal*) show_install_terminal_menu ;; *Terminal*) show_install_terminal_menu ;;
*AI*) show_install_ai_menu ;; *AI*) show_install_ai_menu ;;
*Windows*) present_terminal "omarchy-windows-vm install" ;;
*Gaming*) show_install_gaming_menu ;; *Gaming*) show_install_gaming_menu ;;
*) show_main_menu ;; *) show_main_menu ;;
esac esac
@@ -260,7 +261,7 @@ show_install_service_menu() {
show_install_editor_menu() { show_install_editor_menu() {
case $(menu "Install" " VSCode\n Cursor\n Zed\n Sublime Text\n Helix\n Emacs") in case $(menu "Install" " VSCode\n Cursor\n Zed\n Sublime Text\n Helix\n Emacs") in
*VSCode*) install_and_launch "VSCode" "visual-studio-code-bin" "code" ;; *VSCode*) present_terminal omarchy-install-vscode ;;
*Cursor*) install_and_launch "Cursor" "cursor-bin" "cursor" ;; *Cursor*) install_and_launch "Cursor" "cursor-bin" "cursor" ;;
*Zed*) install_and_launch "Zed" "zed" "dev.zed.Zed" ;; *Zed*) install_and_launch "Zed" "zed" "dev.zed.Zed" ;;
*Sublime*) aur_install_and_launch "Sublime Text" "sublime-text-4" "sublime_text" ;; *Sublime*) aur_install_and_launch "Sublime Text" "sublime-text-4" "sublime_text" ;;
@@ -286,8 +287,9 @@ show_install_ai_menu() {
echo ollama echo ollama
) )
case $(menu "Install" "󱚤 Claude Code\n󱚤 Gemini [AUR]\n󱚤 OpenAI Codex [AUR]\n󱚤 LM Studio\n󱚤 Ollama\n󱚤 Crush\n󱚤 opencode") in case $(menu "Install" "󱚤 Claude Code\n󱚤 Cursor CLI [AUR]\n󱚤 Gemini [AUR]\n󱚤 OpenAI Codex [AUR]\n󱚤 LM Studio\n󱚤 Ollama\n󱚤 Crush\n󱚤 opencode") in
*Claude*) install "Claude Code" "claude-code" ;; *Claude*) install "Claude Code" "claude-code" ;;
*Cursor*) aur_install "Cursor CLI" "cursor-cli" ;;
*OpenAI*) aur_install "OpenAI Codex" "openai-codex-bin" ;; *OpenAI*) aur_install "OpenAI Codex" "openai-codex-bin" ;;
*Gemini*) aur_install "Gemini" "gemini-cli" ;; *Gemini*) aur_install "Gemini" "gemini-cli" ;;
*Studio*) install "LM Studio" "lmstudio" ;; *Studio*) install "LM Studio" "lmstudio" ;;
@@ -317,7 +319,7 @@ show_install_style_menu() {
} }
show_install_font_menu() { show_install_font_menu() {
case $(menu "Install" " Meslo LG Mono\n Fira Code\n Victor Code\n Bistream Vera Mono" "-w 350") in case $(menu "Install" " Meslo LG Mono\n Fira Code\n Victor Code\n Bistream Vera Mono" "--width 350") in
*Meslo*) install_font "Meslo LG Mono" "ttf-meslo-nerd" "MesloLGL Nerd Font" ;; *Meslo*) install_font "Meslo LG Mono" "ttf-meslo-nerd" "MesloLGL Nerd Font" ;;
*Fira*) install_font "Fira Code" "ttf-firacode-nerd" "FiraCode Nerd Font" ;; *Fira*) install_font "Fira Code" "ttf-firacode-nerd" "FiraCode Nerd Font" ;;
*Victor*) install_font "Victor Code" "ttf-victor-mono-nerd" "VictorMono Nerd Font" ;; *Victor*) install_font "Victor Code" "ttf-victor-mono-nerd" "VictorMono Nerd Font" ;;
@@ -372,11 +374,12 @@ show_install_elixir_menu() {
} }
show_remove_menu() { show_remove_menu() {
case $(menu "Remove" "󰣇 Package\n Web App\n TUI\n󰸌 Theme\n󰈷 Fingerprint\n Fido2") in case $(menu "Remove" "󰣇 Package\n Web App\n TUI\n󰸌 Theme\n󰍲 Windows\n󰈷 Fingerprint\n Fido2") in
*Package*) terminal omarchy-pkg-remove ;; *Package*) terminal omarchy-pkg-remove ;;
*Web*) present_terminal omarchy-webapp-remove ;; *Web*) present_terminal omarchy-webapp-remove ;;
*TUI*) present_terminal omarchy-tui-remove ;; *TUI*) present_terminal omarchy-tui-remove ;;
*Theme*) present_terminal omarchy-theme-remove ;; *Theme*) present_terminal omarchy-theme-remove ;;
*Windows*) present_terminal "omarchy-windows-vm remove" ;;
*Fingerprint*) present_terminal "omarchy-setup-fingerprint --remove" ;; *Fingerprint*) present_terminal "omarchy-setup-fingerprint --remove" ;;
*Fido2*) present_terminal "omarchy-setup-fido2 --remove" ;; *Fido2*) present_terminal "omarchy-setup-fido2 --remove" ;;
*) show_main_menu ;; *) show_main_menu ;;
@@ -384,14 +387,15 @@ show_remove_menu() {
} }
show_update_menu() { show_update_menu() {
case $(menu "Update" " Omarchy\n Branch\n Config\n󰸌 Extra Themes\n Process\n󰇅 Hardware\n Password\n Timezone") in case $(menu "Update" " Omarchy\n Branch\n Config\n󰸌 Extra Themes\n Process\n󰇅 Hardware\n Firmware\n Password\n Timezone") in
*Omarchy*) present_terminal omarchy-update ;; *Omarchy*) present_terminal omarchy-update ;;
*Branch*) show_update_branch_menu ;; *Branch*) show_update_branch_menu ;;
*Config*) show_update_config_menu ;; *Config*) show_update_config_menu ;;
*Themes*) present_terminal omarchy-theme-update ;; *Themes*) present_terminal omarchy-theme-update ;;
*Process*) show_update_process_menu ;; *Process*) show_update_process_menu ;;
*Hardware*) show_update_hardware_menu ;; *Hardware*) show_update_hardware_menu ;;
*Timezone*) omarchy-cmd-tzupdate ;; *Firmware*) present_terminal omarchy-update-firmware ;;
*Timezone*) present_terminal omarchy-tz-select ;;
*Password*) show_update_password_menu ;; *Password*) show_update_password_menu ;;
*) show_main_menu ;; *) show_main_menu ;;
esac esac
@@ -447,13 +451,12 @@ show_update_password_menu() {
} }
show_system_menu() { show_system_menu() {
case $(menu "System" " Lock\n󱄄 Screensaver\n󰤄 Suspend\n Relaunch\n󰜉 Restart\n󰐥 Shutdown") in case $(menu "System" " Lock\n󱄄 Screensaver\n󰤄 Suspend\n󰜉 Restart\n󰐥 Shutdown") in
*Lock*) omarchy-lock-screen ;; *Lock*) omarchy-lock-screen ;;
*Screensaver*) omarchy-launch-screensaver force ;; *Screensaver*) omarchy-launch-screensaver force ;;
*Suspend*) systemctl suspend ;; *Suspend*) systemctl suspend ;;
*Relaunch*) uwsm stop ;; *Restart*) omarchy-state clear re*-required && systemctl reboot --no-wall ;;
*Restart*) systemctl reboot ;; *Shutdown*) omarchy-state clear re*-required && systemctl poweroff --no-wall ;;
*Shutdown*) systemctl poweroff ;;
*) back_to show_main_menu ;; *) back_to show_main_menu ;;
esac esac
} }

View File

@@ -3,6 +3,69 @@
# A script to display Hyprland keybindings defined in your configuration # A script to display Hyprland keybindings defined in your configuration
# using walker for an interactive search menu. # using walker for an interactive search menu.
declare -A KEYCODE_SYM_MAP
build_keymap_cache() {
local keymap
keymap="$(xkbcli compile-keymap)" || {
echo "Failed to compile keymap" >&2
return 1
}
while IFS=, read -r code sym; do
[[ -z "$code" || -z "$sym" ]] && continue
KEYCODE_SYM_MAP["$code"]="$sym"
done < <(
awk '
BEGIN { sec = "" }
/xkb_keycodes/ { sec = "codes"; next }
/xkb_symbols/ { sec = "syms"; next }
sec == "codes" {
if (match($0, /<([A-Za-z0-9_]+)>\s*=\s*([0-9]+)\s*;/, m)) code_by_name[m[1]] = m[2]
}
sec == "syms" {
if (match($0, /key\s*<([A-Za-z0-9_]+)>\s*\{\s*\[\s*([^, \]]+)/, m)) sym_by_name[m[1]] = m[2]
}
END {
for (k in code_by_name) {
c = code_by_name[k]
s = sym_by_name[k]
if (c != "" && s != "" && s != "NoSymbol") print c "," s
}
}
' <<<"$keymap"
)
}
lookup_keycode_cached() {
printf '%s\n' "${KEYCODE_SYM_MAP[$1]}"
}
parse_keycodes() {
local start end elapsed
[[ "${DEBUG:-0}" == "1" ]] && start=$(date +%s.%N)
while IFS= read -r line; do
if [[ "$line" =~ code:([0-9]+) ]]; then
code="${BASH_REMATCH[1]}"
symbol=$(lookup_keycode_cached "$code" "$XKB_KEYMAP_CACHE")
echo "${line/code:${code}/$symbol}"
else
echo "$line"
fi
done
if [[ "$DEBUG" == "1" ]]; then
end=$(date +%s.%N)
# fall back to awk if bc is missing
if command -v bc >/dev/null 2>&1; then
elapsed=$(echo "$end - $start" | bc)
else
elapsed=$(awk -v s="$start" -v e="$end" 'BEGIN{printf "%.6f", (e - s)}')
fi
echo "[DEBUG] parse_keycodes elapsed: ${elapsed}s" >&2
fi
}
# Fetch dynamic keybindings from Hyprland # Fetch dynamic keybindings from Hyprland
# #
# Also do some pre-processing: # Also do some pre-processing:
@@ -11,30 +74,31 @@
# - Map numeric modifier key mask to a textual rendition # - Map numeric modifier key mask to a textual rendition
# - Output comma-separated values that the parser can understand # - Output comma-separated values that the parser can understand
dynamic_bindings() { dynamic_bindings() {
hyprctl -j binds | \ hyprctl -j binds |
jq -r '.[] | {modmask, key, keycode, description, dispatcher, arg} | "\(.modmask),\(.key)@\(.keycode),\(.description),\(.dispatcher),\(.arg)"' | \ jq -r '.[] | {modmask, key, keycode, description, dispatcher, arg} | "\(.modmask),\(.key)@\(.keycode),\(.description),\(.dispatcher),\(.arg)"' |
sed -r \ sed -r \
-e 's/null//' \ -e 's/null//' \
-e 's,~/.local/share/omarchy/bin/,,' \ -e 's,~/.local/share/omarchy/bin/,,' \
-e 's,uwsm app -- ,,' \ -e 's,uwsm app -- ,,' \
-e 's/@0//' \ -e 's,uwsm-app -- ,,' \
-e 's/,@/,code:/' \ -e 's/@0//' \
-e 's/^0,/,/' \ -e 's/,@/,code:/' \
-e 's/^1,/SHIFT,/' \ -e 's/^0,/,/' \
-e 's/^4,/CTRL,/' \ -e 's/^1,/SHIFT,/' \
-e 's/^5,/SHIFT CTRL,/' \ -e 's/^4,/CTRL,/' \
-e 's/^8,/ALT,/' \ -e 's/^5,/SHIFT CTRL,/' \
-e 's/^9,/SHIFT ALT,/' \ -e 's/^8,/ALT,/' \
-e 's/^12,/CTRL ALT,/' \ -e 's/^9,/SHIFT ALT,/' \
-e 's/^13,/SHIFT CTRL ALT,/' \ -e 's/^12,/CTRL ALT,/' \
-e 's/^64,/SUPER,/' \ -e 's/^13,/SHIFT CTRL ALT,/' \
-e 's/^65,/SUPER SHIFT,/' \ -e 's/^64,/SUPER,/' \
-e 's/^68,/SUPER CTRL,/' \ -e 's/^65,/SUPER SHIFT,/' \
-e 's/^69,/SUPER SHIFT CTRL,/' \ -e 's/^68,/SUPER CTRL,/' \
-e 's/^72,/SUPER ALT,/' \ -e 's/^69,/SUPER SHIFT CTRL,/' \
-e 's/^73,/SUPER SHIFT ALT,/' \ -e 's/^72,/SUPER ALT,/' \
-e 's/^76,/SUPER CTRL ALT,/' \ -e 's/^73,/SUPER SHIFT ALT,/' \
-e 's/^77,/SUPER SHIFT CTRL ALT,/' -e 's/^76,/SUPER CTRL ALT,/' \
-e 's/^77,/SUPER SHIFT CTRL ALT,/'
} }
# Parse and format keybindings # Parse and format keybindings
@@ -86,8 +150,10 @@ parse_bindings() {
monitor_height=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .height') monitor_height=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .height')
menu_height=$((monitor_height * 40 / 100)) menu_height=$((monitor_height * 40 / 100))
dynamic_bindings | \ build_keymap_cache
sort -u | \
parse_bindings | \
walker --dmenu --theme keybindings -p 'Keybindings' -w 800 -h "$menu_height"
dynamic_bindings |
sort -u |
parse_keycodes |
parse_bindings |
walker --dmenu -p 'Keybindings' --width 800 --height "$menu_height"

View File

@@ -1,8 +1,14 @@
#!/bin/bash #!/bin/bash
if omarchy-pkg-missing "$@"; then
sudo pacman -S --noconfirm --needed "$@" || exit 1
fi
for pkg in "$@"; do for pkg in "$@"; do
# Secondary check to handle states where pacman doesn't actually register an error
if ! pacman -Q "$pkg" &>/dev/null; then if ! pacman -Q "$pkg" &>/dev/null; then
sudo pacman -S --noconfirm "$pkg" || exit 1 echo -e "\033[31mError: Package '$pkg' did not install\033[0m" >&2
exit 1
fi fi
done done

View File

@@ -3,7 +3,7 @@
fzf_args=( fzf_args=(
--multi --multi
--preview 'yay -Siia {1}' --preview 'yay -Siia {1}'
--preview-label='alt-p: toggle description, alt-b/B: toggle PKGBUILD, alt-j/k: scroll, tab: multi-select, F11: maximize' --preview-label='alt-p: toggle description, alt-b/B: toggle PKGBUILD, alt-j/k: scroll, tab: multi-select'
--preview-label-pos='bottom' --preview-label-pos='bottom'
--preview-window 'down:65%:wrap' --preview-window 'down:65%:wrap'
--bind 'alt-p:toggle-preview' --bind 'alt-p:toggle-preview'

View File

@@ -3,7 +3,7 @@
fzf_args=( fzf_args=(
--multi --multi
--preview 'pacman -Sii {1}' --preview 'pacman -Sii {1}'
--preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select, F11: maximize' --preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select'
--preview-label-pos='bottom' --preview-label-pos='bottom'
--preview-window 'down:65%:wrap' --preview-window 'down:65%:wrap'
--bind 'alt-p:toggle-preview' --bind 'alt-p:toggle-preview'

View File

@@ -3,7 +3,7 @@
fzf_args=( fzf_args=(
--multi --multi
--preview 'yay -Qi {1}' --preview 'yay -Qi {1}'
--preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select, F11: maximize' --preview-label='alt-p: toggle description, alt-j/k: scroll, tab: multi-select'
--preview-label-pos='bottom' --preview-label-pos='bottom'
--preview-window 'down:65%:wrap' --preview-window 'down:65%:wrap'
--bind 'alt-p:toggle-preview' --bind 'alt-p:toggle-preview'

View File

@@ -1,4 +1,6 @@
#!/bin/bash #!/bin/bash
omarchy-refresh-config walker/config.toml omarchy-refresh-config walker/config.toml
omarchy-refresh-config elephant/calc.toml
omarchy-refresh-config elephant/desktopapplications.toml
omarchy-restart-walker omarchy-restart-walker

View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
pkill -x $1 pkill -x $1
setsid uwsm app -- $1 >/dev/null 2>&1 & setsid uwsm-app -- $1 >/dev/null 2>&1 &

View File

@@ -1,7 +1,21 @@
#!/bin/bash #!/bin/bash
pkill elephant
pkill walker pkill walker
# FIXME: Just deal with the memory leak for now.
# See https://github.com/basecamp/omarchy/issues/698 # Detect if we're running as root (from pacman hook)
setsid uwsm app -- walker --gapplication-service & if [[ $EUID -eq 0 ]]; then
echo # Always end in success so we don't terminate further running # Get the owner of this script to determine which user to run as
SCRIPT_OWNER=$(stat -c '%U' "$0")
USER_UID=$(id -u "$SCRIPT_OWNER")
# Restart services as the script owner
systemd-run --uid="$SCRIPT_OWNER" --setenv=XDG_RUNTIME_DIR="/run/user/$USER_UID" \
bash -c "
setsid uwsm-app -- elephant &
setsid uwsm-app -- walker --gapplication-service &
"
else
setsid uwsm-app -- elephant &
setsid uwsm-app -- walker --gapplication-service &
fi

View File

@@ -20,7 +20,7 @@ print_info() {
} }
check_fingerprint_hardware() { check_fingerprint_hardware() {
if ! lsusb | grep -Eiq 'fingerprint|synaptics|goodix|elan|validity'; then if ! lsusb | grep -Eiq 'fingerprint|synaptics|goodix|elan|validity|FPC'; then
print_error "\nNo fingerprint sensor detected." print_error "\nNo fingerprint sensor detected."
return 1 return 1
fi fi

View File

@@ -5,13 +5,13 @@
BACKGROUNDS_DIR="$HOME/.config/omarchy/current/theme/backgrounds/" BACKGROUNDS_DIR="$HOME/.config/omarchy/current/theme/backgrounds/"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background" CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
mapfile -d '' -t BACKGROUNDS < <(find "$BACKGROUNDS_DIR" -type f -print0 | sort -z) mapfile -d '' -t BACKGROUNDS < <(find -L "$BACKGROUNDS_DIR" -type f -print0 | sort -z)
TOTAL=${#BACKGROUNDS[@]} TOTAL=${#BACKGROUNDS[@]}
if [[ $TOTAL -eq 0 ]]; then if [[ $TOTAL -eq 0 ]]; then
notify-send "No background was found for theme" -t 2000 notify-send "No background was found for theme" -t 2000
pkill -x swaybg pkill -x swaybg
setsid uwsm app -- swaybg --color '#000000' >/dev/null 2>&1 & setsid uwsm-app -- swaybg --color '#000000' >/dev/null 2>&1 &
else else
# Get current background from symlink # Get current background from symlink
if [[ -L "$CURRENT_BACKGROUND_LINK" ]]; then if [[ -L "$CURRENT_BACKGROUND_LINK" ]]; then
@@ -44,5 +44,5 @@ else
# Relaunch swaybg # Relaunch swaybg
pkill -x swaybg pkill -x swaybg
setsid uwsm app -- swaybg -i "$CURRENT_BACKGROUND_LINK" -m fill >/dev/null 2>&1 & setsid uwsm-app -- swaybg -i "$CURRENT_BACKGROUND_LINK" -m fill >/dev/null 2>&1 &
fi fi

View File

@@ -24,15 +24,21 @@ ln -nsf "$THEME_PATH" "$CURRENT_THEME_DIR"
omarchy-theme-bg-next omarchy-theme-bg-next
# Restart components to apply new theme # Restart components to apply new theme
omarchy-restart-waybar if pgrep -x waybar >/dev/null; then
omarchy-restart-waybar
fi
omarchy-restart-swayosd omarchy-restart-swayosd
hyprctl reload hyprctl reload
pkill -SIGUSR2 btop pkill -SIGUSR2 btop
makoctl reload makoctl reload
# Change gnome, browser, vscode themes # Change gnome, browser, vscode, cursor themes
omarchy-theme-set-terminal omarchy-theme-set-terminal
omarchy-theme-set-gnome omarchy-theme-set-gnome
omarchy-theme-set-eza
omarchy-theme-set-browser omarchy-theme-set-browser
omarchy-theme-set-vscode omarchy-theme-set-vscode
omarchy-theme-set-cursor
omarchy-theme-set-obsidian
# Call hook on theme set
omarchy-hook theme-set "$THEME_NAME"

View File

@@ -2,18 +2,30 @@
CHROMIUM_THEME=~/.config/omarchy/current/theme/chromium.theme CHROMIUM_THEME=~/.config/omarchy/current/theme/chromium.theme
if omarchy-cmd-present chromium || omarchy-cmd-present brave; then if omarchy-cmd-present chromium || omarchy-cmd-present helium-browser || omarchy-cmd-present brave; then
if [[ -f $CHROMIUM_THEME ]]; then if [[ -f $CHROMIUM_THEME ]]; then
rgb=$(<$CHROMIUM_THEME) THEME_RGB_COLOR=$(<$CHROMIUM_THEME)
THEME_HEX_COLOR=$(printf '#%02x%02x%02x' ${rgb//,/ }) THEME_HEX_COLOR=$(printf '#%02x%02x%02x' ${THEME_RGB_COLOR//,/ })
else else
# Use a default, neutral grey if theme doesn't have a color # Use a default, neutral grey if theme doesn't have a color
THEME_RGB_COLOR="28,32,39"
THEME_HEX_COLOR="#1c2027" THEME_HEX_COLOR="#1c2027"
fi fi
if omarchy-cmd-present chromium; then if omarchy-cmd-present chromium; then
rm -f /etc/chromium/policies/managed/color.json
chromium --no-startup-window --set-theme-color="$THEME_RGB_COLOR"
if [[ -f ~/.config/omarchy/current/theme/light.mode ]]; then
chromium --no-startup-window --set-color-scheme="light"
else
chromium --no-startup-window --set-color-scheme="dark"
fi
fi
if omarchy-cmd-present helium-browser; then
echo "{\"BrowserThemeColor\": \"$THEME_HEX_COLOR\"}" | tee "/etc/chromium/policies/managed/color.json" >/dev/null echo "{\"BrowserThemeColor\": \"$THEME_HEX_COLOR\"}" | tee "/etc/chromium/policies/managed/color.json" >/dev/null
chromium --refresh-platform-policy --no-startup-window helium-browser --no-startup-window --refresh-platform-policy
fi fi
if omarchy-cmd-present brave; then if omarchy-cmd-present brave; then

4
bin/omarchy-theme-set-cursor Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
# Call the VSCode theme setter with Cursor-specific parameters
omarchy-theme-set-vscode cursor "$HOME/.config/Cursor/User/settings.json" "$HOME/.local/state/omarchy/toggles/skip-cursor-theme-changes" Cursor

View File

@@ -1,7 +0,0 @@
#!/bin/bash
if [ -f ~/.config/omarchy/current/theme/eza.yml ]; then
ln -snf ~/.config/omarchy/current/theme/eza.yml ~/.config/eza/theme.yml
else
rm -f ~/.config/eza/theme.yml
fi

659
bin/omarchy-theme-set-obsidian Executable file
View File

@@ -0,0 +1,659 @@
#!/bin/bash
# omarchy-theme-set-obsidian: Bootstrap and update Omarchy theme for Obsidian
#
# - Ensures registry at ~/.local/state/omarchy/obsidian-vaults
# - If missing/empty, bootstraps by scanning ~/Documents/*/.obsidian and ~/Dropbox/*/.obsidian
# - For each valid vault:
# - Ensures .obsidian/themes/Omarchy/{manifest.json, theme.css}
# - Updates theme.css (uses current themes obsidian.css if present; otherwise generates -- see below)
# Theme automagic generation logic:
#
# - Background/foreground: read from ~/.config/omarchy/current/theme/alacritty.toml [colors.primary]
# (background/foreground). Fallbacks: bg=#1a1b26, fg=#a9b1d6. Compute bg brightness for light/dark handling.
# - Palette extraction: collect colors from Alacritty (primary/normal/bright/dim/selection), Waybar (@define-color),
# and Hyprland (col.*_border; rgba->hex). Normalize, dedupe, and count frequencies.
# - Slot ordering: remove bg/fg, sort remaining colors by frequency, then fill 13 slots by cycling. Map slots to:
# h1h6, links, inline code, marks, interactive accent, blockquote border; muted/faint use border color.
# - Code colors: code background = closest color to bg (Euclidean RGB); if none, make a subtle bg variant (+/ RGB).
# code foreground = closest color to fg; fallback #e0e0e0.
# - Border color: from btop.theme theme[div_line]; else blended mix biased toward bg (≈ (bg+fg)/3).
# - Selection: from Alacritty [colors.selection] (background/text), honoring CellForeground/Background.
# If missing, background = 75% bg + 25% fg; text chosen for contrast vs selection background.
# - Fonts: monospace from Alacritty [font] or fontconfig monospace; UI font from fontconfig sans-serif.
VAULTS_FILE="$HOME/.local/state/omarchy/obsidian-vaults"
CURRENT_THEME_DIR="$HOME/.config/omarchy/current/theme"
# Ensure the vaults registry exists, or bootstrap from known locations
ensure_vaults_file() {
mkdir -p "$(dirname "$VAULTS_FILE")"
# If file exists (even empty), do not scan; treat as authoritative
if [ -f "$VAULTS_FILE" ]; then
return
fi
local tmpfile
tmpfile="$(mktemp)"
# Scan a couple of common locations for <base>/<vault>/.obsidian
for base in "$HOME/Documents" "$HOME/Dropbox"; do
[ -d "$base" ] || continue
for d in "$base"/*/.obsidian; do
[ -d "$d" ] || continue
vault_dir="${d%/.obsidian}"
printf "%s\n" "$vault_dir" >>"$tmpfile"
done
done
if [ -s "$tmpfile" ]; then
sort -u "$tmpfile" >"$VAULTS_FILE"
else
: >"$VAULTS_FILE"
fi
rm -f "$tmpfile"
}
# Ensure theme directory and minimal manifest exist in a vault
ensure_theme_scaffold() {
local vault_path="$1"
local theme_dir="$vault_path/.obsidian/themes/Omarchy"
mkdir -p "$theme_dir"
if [ ! -f "$theme_dir/manifest.json" ]; then
cat >"$theme_dir/manifest.json" <<'EOF'
{
"name": "Omarchy",
"version": "1.0.0",
"minAppVersion": "0.16.0",
"description": "Automatically syncs with your current Omarchy system theme colors and fonts",
"author": "Omarchy",
"authorUrl": "https://omarchy.org"
}
EOF
fi
[ -f "$theme_dir/theme.css" ] || : >"$theme_dir/theme.css"
}
# Function to extract hex color from string
extract_hex_color() {
echo "$1" | grep -oE '#[0-9a-fA-F]{6}' | head -1
}
# Function to convert RGB/RGBA to hex
rgb_to_hex() {
local rgb_string="$1"
if [[ $rgb_string =~ rgba?\(([0-9]+),\s*([0-9]+),\s*([0-9]+) ]]; then
printf "#%02x%02x%02x\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi
}
# Convert hex to RGB components
hex_to_rgb() {
local hex="${1#\#}"
printf "%d %d %d\n" "0x${hex:0:2}" "0x${hex:2:2}" "0x${hex:4:2}"
}
# Calculate perceived brightness (0-255)
calculate_brightness() {
local hex="$1"
read -r r g b <<<"$(hex_to_rgb "$hex")"
# Use perceived brightness formula
echo $(((r * 299 + g * 587 + b * 114) / 1000))
}
# Calculate color distance (euclidean in RGB space)
color_distance() {
local hex1="$1"
local hex2="$2"
read -r r1 g1 b1 <<<"$(hex_to_rgb "$hex1")"
read -r r2 g2 b2 <<<"$(hex_to_rgb "$hex2")"
echo $(((r1 - r2) * (r1 - r2) + (g1 - g2) * (g1 - g2) + (b1 - b2) * (b1 - b2)))
}
# Extract all colors with frequency count
extract_all_colors_with_count() {
local -A color_counts
local color
# Extract from Alacritty config
if [ -f "$CURRENT_THEME_DIR/alacritty.toml" ]; then
# Primary colors
while IFS= read -r color; do
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -E "(background|foreground|cursor|text)" "$CURRENT_THEME_DIR/alacritty.toml" | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | grep "^#")
# Normal colors
while IFS= read -r color; do
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -A 20 "\[colors.normal\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep -E "(black|red|green|yellow|blue|magenta|cyan|white)" | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | grep "^#")
# Bright colors
while IFS= read -r color; do
# Add # if missing
[[ "$color" =~ ^[0-9a-fA-F]{6}$ ]] && color="#$color"
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[[ "$color" =~ ^#[0-9a-f]{6}$ ]] && ((color_counts["$color"]++))
done < <(grep -A 20 "\[colors.bright\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep -E "(black|red|green|yellow|blue|magenta|cyan|white)" | sed "s/.*[\"']//;s/[\"'].*//")
# Dim colors if present
while IFS= read -r color; do
# Add # if missing
[[ "$color" =~ ^[0-9a-fA-F]{6}$ ]] && color="#$color"
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[[ "$color" =~ ^#[0-9a-f]{6}$ ]] && ((color_counts["$color"]++))
done < <(grep -A 20 "\[colors.dim\]" "$CURRENT_THEME_DIR/alacritty.toml" 2>/dev/null | grep -E "(black|red|green|yellow|blue|magenta|cyan|white)" | sed "s/.*[\"']//;s/[\"'].*//")
# Selection colors
while IFS= read -r color; do
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" 2>/dev/null | grep -E "(background|text)" | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | grep "^#")
fi
# Extract from Waybar CSS
if [ -f "$CURRENT_THEME_DIR/waybar.css" ]; then
while IFS= read -r color; do
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -oE '@define-color [a-z_-]+ #[0-9a-fA-F]{6}' "$CURRENT_THEME_DIR/waybar.css" | grep -oE '#[0-9a-fA-F]{6}')
fi
# Extract from Hyprland config
if [ -f "$CURRENT_THEME_DIR/hyprland.conf" ]; then
while IFS= read -r color; do
if [[ $color == rgba* ]] || [[ $color == rgb* ]]; then
color=$(rgb_to_hex "$color")
fi
color=$(echo "$color" | tr '[:upper:]' '[:lower:]') # Lowercase for consistency
[ -n "$color" ] && ((color_counts["$color"]++))
done < <(grep -E "col\.(active|inactive)_border" "$CURRENT_THEME_DIR/hyprland.conf" | grep -oE 'rgba?\([^)]+\)|#[0-9a-fA-F]{6,8}' | sed 's/ff$//')
fi
# Output colors with their counts
for color in "${!color_counts[@]}"; do
echo "${color_counts[$color]} $color"
done
}
# Sort colors by frequency
sort_colors_by_frequency() {
# Input is already "count color" format
sort -rn | cut -d' ' -f2
}
# Fill color slots with cycling if needed
fill_color_slots() {
local -a colors=("$@")
local -a slots
local num_colors=${#colors[@]}
# Need 13 slots total (code colors are handled separately)
local slots_needed=13
if [ $num_colors -eq 0 ]; then
# No colors available, use defaults
colors=("#3d3d3d" "#5d5d5d" "#7d7d7d" "#9d9d9d" "#bd93f9" "#50fa7b")
num_colors=6
fi
# Fill slots, cycling if necessary
for ((i = 0; i < slots_needed; i++)); do
slots[$i]="${colors[$((i % num_colors))]}"
done
echo "${slots[@]}"
}
# Main color extraction and theme generation
extract_theme_data() {
# Get primary colors from Alacritty
local bg_color="#1a1b26"
local fg_color="#a9b1d6"
if [ -f "$CURRENT_THEME_DIR/alacritty.toml" ]; then
local extracted_bg=$(grep -A 5 "\[colors.primary\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^background = " | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | head -1 | tr '[:upper:]' '[:lower:]')
local extracted_fg=$(grep -A 5 "\[colors.primary\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^foreground = " | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | head -1 | tr '[:upper:]' '[:lower:]')
[ -n "$extracted_bg" ] && bg_color="$extracted_bg"
[ -n "$extracted_fg" ] && fg_color="$extracted_fg"
fi
# Determine if light or dark theme
local bg_brightness=$(calculate_brightness "$bg_color")
local is_light_theme=false
[ $bg_brightness -gt 127 ] && is_light_theme=true
# Extract all colors with counts
local color_data=$(extract_all_colors_with_count)
# Filter out background and foreground colors for the main array
local filtered_data=$(echo "$color_data" | grep -v "$bg_color" | grep -v "$fg_color")
# Get all unique colors (including bg/fg) for distance calculations
local -a all_unique_colors
readarray -t all_unique_colors < <(echo "$color_data" | cut -d' ' -f2 | sort -u)
# Find the 3 closest colors to background for background variations
local -a bg_distances
for color in "${all_unique_colors[@]}"; do
if [ "$color" != "$bg_color" ]; then
distance=$(color_distance "$color" "$bg_color")
bg_distances+=("$distance:$color")
fi
done
# Sort by distance and get the closest color for code background
local -a closest_to_bg
readarray -t closest_to_bg < <(printf '%s\n' "${bg_distances[@]}" | sort -n | head -1 | cut -d: -f2)
# All background variations use the same as primary background
local bg_primary_alt="$bg_color"
local bg_secondary="$bg_color"
local bg_secondary_alt="$bg_color"
# Code block background uses the closest different color
local code_bg="${closest_to_bg[0]}"
# If no different color available, create a subtle variant for code blocks
if [ -z "$code_bg" ]; then
read -r r g b <<<"$(hex_to_rgb "$bg_color")"
if [ $bg_brightness -gt 127 ]; then
r=$((r - 10))
g=$((g - 10))
b=$((b - 10))
else
r=$((r + 15))
g=$((g + 15))
b=$((b + 15))
fi
[ $r -lt 0 ] && r=0
[ $r -gt 255 ] && r=255
[ $g -lt 0 ] && g=0
[ $g -gt 255 ] && g=255
[ $b -lt 0 ] && b=0
[ $b -gt 255 ] && b=255
code_bg=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
fi
# Find closest color to foreground for code block text
local code_fg=""
min_distance=999999999
for color in "${all_unique_colors[@]}"; do
if [ "$color" != "$fg_color" ]; then
distance=$(color_distance "$color" "$fg_color")
if [ $distance -lt $min_distance ]; then
min_distance=$distance
code_fg="$color"
fi
fi
done
[ -z "$code_fg" ] && code_fg="#e0e0e0" # Fallback
# Extract text selection colors from Alacritty
local selection_bg=""
local selection_fg=""
if [ -f "$CURRENT_THEME_DIR/alacritty.toml" ]; then
selection_bg=$(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^background = " | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | head -1 | tr '[:upper:]' '[:lower:]')
local selection_text=$(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^text = " | sed "s/.*[\"']0x/#/;s/.*[\"']#/#/;s/[\"'].*//;s/.*#\([0-9a-fA-F]\{6\}\).*/\#\1/" | head -1 | tr '[:upper:]' '[:lower:]')
# If text is set to CellForeground/CellBackground, use the appropriate color
if [ -z "$selection_text" ] || [[ "$(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^text = ")" == *"CellForeground"* ]]; then
selection_fg="$fg_color"
elif [[ "$(grep -A 5 "\[colors.selection\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep "^text = ")" == *"CellBackground"* ]]; then
selection_fg="$bg_color"
else
selection_fg="$selection_text"
fi
fi
# Fallback if no selection colors found
if [ -z "$selection_bg" ]; then
read -r r1 g1 b1 <<<"$(hex_to_rgb "$bg_color")"
read -r r2 g2 b2 <<<"$(hex_to_rgb "$fg_color")"
local r=$(((r1 * 3 + r2) / 4)) # 75% background, 25% foreground
local g=$(((g1 * 3 + g2) / 4))
local b=$(((b1 * 3 + b2) / 4))
selection_bg=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
fi
# Use contrasting color for selection text if not defined
if [ -z "$selection_fg" ]; then
# Calculate brightness of selection background
local sel_brightness=$(calculate_brightness "$selection_bg")
if [ $sel_brightness -gt 127 ]; then
selection_fg="$bg_color" # Dark text on light selection
else
selection_fg="$fg_color" # Light text on dark selection
fi
fi
# Extract border color from btop theme
local border_color=""
if [ -f "$CURRENT_THEME_DIR/btop.theme" ]; then
# Look for theme[div_line] in btop theme
local btop_divline=$(grep 'theme\[div_line\]' "$CURRENT_THEME_DIR/btop.theme" | head -1)
if [ -n "$btop_divline" ]; then
# Extract the color value after the = sign
local extracted=$(echo "$btop_divline" | sed 's/.*=//' | xargs)
# Check if it's a hex color and lowercase it
if [[ $extracted =~ ^#[0-9a-fA-F]{6}$ ]]; then
border_color=$(echo "$extracted" | tr '[:upper:]' '[:lower:]')
elif [[ $extracted =~ ^[0-9a-fA-F]{6}$ ]]; then
# Add # if missing and lowercase
border_color=$(echo "#$extracted" | tr '[:upper:]' '[:lower:]')
fi
fi
fi
# Fallback if no border color found
if [ -z "$border_color" ]; then
# Use a color between bg and fg
read -r r1 g1 b1 <<<"$(hex_to_rgb "$bg_color")"
read -r r2 g2 b2 <<<"$(hex_to_rgb "$fg_color")"
local r=$(((r1 + r2) / 3)) # Closer to background
local g=$(((g1 + g2) / 3))
local b=$(((b1 + b2) / 3))
border_color=$(printf "#%02x%02x%02x" "$r" "$g" "$b")
fi
# Get unique colors array (without bg/fg) sorted by frequency
local -a unique_colors
readarray -t unique_colors < <(echo "$filtered_data" | sort_colors_by_frequency)
# Fill the 13 color slots (code colors handled separately)
local -a color_slots
readarray -t color_slots < <(fill_color_slots "${unique_colors[@]}" | tr ' ' '\n')
# Extract fonts
local monospace_font="CaskaydiaMono Nerd Font"
local ui_font="Liberation Sans"
if [ -f "$CURRENT_THEME_DIR/alacritty.toml" ]; then
local alacritty_font=$(grep -A 5 "\[font\]" "$CURRENT_THEME_DIR/alacritty.toml" | grep 'family = ' | head -1 | cut -d'"' -f2)
[ -n "$alacritty_font" ] && monospace_font="$alacritty_font"
fi
if [ -f "$HOME/.config/fontconfig/fonts.conf" ]; then
local fontconfig_mono=$(xmlstarlet sel -t -v '//match[@target="pattern"][test/string="monospace"]/edit[@name="family"]/string' "$HOME/.config/fontconfig/fonts.conf" 2>/dev/null || true)
[ -n "$fontconfig_mono" ] && monospace_font="$fontconfig_mono"
local fontconfig_sans=$(xmlstarlet sel -t -v '//match[@target="pattern"][test/string="sans-serif"]/edit[@name="family"]/string' "$HOME/.config/fontconfig/fonts.conf" 2>/dev/null || true)
[ -n "$fontconfig_sans" ] && ui_font="$fontconfig_sans"
fi
# Generate CSS with 14-slot system
cat <<EOF
/* Omarchy Theme for Obsidian */
/* Generated on $(date) from theme: $(basename "$(readlink "$CURRENT_THEME_DIR" 2>/dev/null || echo "unknown")") */
/* Colors sorted by frequency, backgrounds by distance */
.theme-dark, .theme-light {
/* Core colors */
--background-primary: $bg_color;
--text-normal: $fg_color;
/* Background variations (always distance-based) */
--background-primary-alt: $bg_primary_alt;
--background-secondary: $bg_secondary;
--background-secondary-alt: $bg_secondary_alt;
/* Code block colors (always distance-based) */
--code-background: $code_bg;
--code-foreground: $code_fg;
/* Border color from btop theme */
--border-color: $border_color;
/* Selection colors from Alacritty */
--text-selection: $selection_bg;
--text-selection-fg: $selection_fg;
/* 13-slot color system for remaining elements */
--text-title-h1: ${color_slots[0]};
--text-title-h2: ${color_slots[1]};
--text-title-h3: ${color_slots[2]};
--text-title-h4: ${color_slots[3]};
--text-title-h5: ${color_slots[4]};
--text-title-h6: ${color_slots[4]}; /* Same as h5 */
--text-link: ${color_slots[5]};
--markup-code: ${color_slots[6]};
--text-mark: ${color_slots[7]};
--interactive-accent: ${color_slots[8]};
--blockquote-border: ${color_slots[9]};
--text-muted: $border_color; /* Use border color for muted text */
--text-faint: $border_color; /* Use border color for faint text */
/* Additional mappings */
--text-accent: var(--interactive-accent);
--text-accent-hover: var(--interactive-accent);
--text-error: var(--text-title-h1);
--text-error-hover: var(--text-title-h1);
--text-highlight-bg: $fg_color; /* Use text color as highlight background */
--text-on-accent: $bg_color;
--interactive-normal: var(--code-background);
--interactive-hover: var(--interactive-accent);
--interactive-accent-hover: var(--interactive-accent);
--interactive-success: var(--text-title-h2);
--scrollbar-bg: var(--background-primary);
--scrollbar-thumb-bg: var(--code-background);
--scrollbar-active-thumb-bg: var(--interactive-accent);
--background-modifier-border: var(--border-color);
--background-modifier-form-field: var(--code-background);
--background-modifier-form-field-highlighted: var(--code-background);
--background-modifier-box-shadow: rgba(0, 0, 0, 0.3);
--background-modifier-success: var(--interactive-success);
--background-modifier-error: var(--text-error);
--background-modifier-error-hover: var(--text-error);
--background-modifier-cover: rgba(0, 0, 0, 0.8);
--link-color: var(--text-link);
--link-color-hover: var(--text-link);
--link-unresolved-color: var(--text-muted);
--link-unresolved-opacity: 0.7;
--tag-color: var(--text-title-h3);
--tag-background: var(--code-background);
--graph-line: var(--text-muted);
--graph-node: var(--interactive-accent);
--graph-node-unresolved: var(--text-muted);
--graph-node-focused: var(--text-link);
--graph-node-tag: var(--text-title-h3);
--graph-node-attachment: var(--text-title-h2);
/* Fonts */
--font-interface-theme: "$ui_font";
--font-text-theme: "$ui_font";
--font-monospace-theme: "$monospace_font";
}
/* Headers */
.cm-header-1, .markdown-rendered h1 { color: var(--text-title-h1); }
.cm-header-2, .markdown-rendered h2 { color: var(--text-title-h2); }
.cm-header-3, .markdown-rendered h3 { color: var(--text-title-h3); }
.cm-header-4, .markdown-rendered h4 { color: var(--text-title-h4); }
.cm-header-5, .markdown-rendered h5 { color: var(--text-title-h5); }
.cm-header-6, .markdown-rendered h6 { color: var(--text-title-h6); }
/* Code blocks */
.markdown-rendered code {
font-family: var(--font-monospace-theme);
background-color: var(--code-background);
color: var(--markup-code);
padding: 2px 4px;
border-radius: 3px;
}
.markdown-rendered pre {
background-color: var(--code-background);
border: 1px solid var(--background-modifier-border);
border-radius: 5px;
}
.markdown-rendered pre code {
background-color: transparent;
color: var(--code-foreground);
}
/* Syntax highlighting */
.cm-s-obsidian span.cm-keyword { color: var(--text-title-h1); }
.cm-s-obsidian span.cm-string { color: var(--text-title-h2); }
.cm-s-obsidian span.cm-number { color: var(--text-title-h3); }
.cm-s-obsidian span.cm-comment { color: var(--text-muted); }
.cm-s-obsidian span.cm-operator { color: var(--text-link); }
.cm-s-obsidian span.cm-variable { color: var(--text-normal); }
.cm-s-obsidian span.cm-def { color: var(--text-link); }
/* Highlighted text */
.markdown-rendered mark,
.cm-s-obsidian span.cm-highlight,
mark {
background-color: var(--text-highlight-bg) !important;
color: var(--code-background) !important;
}
/* Links */
.markdown-rendered a {
color: var(--text-link);
}
/* Blockquotes */
.markdown-rendered blockquote {
border-left: 4px solid var(--blockquote-border);
padding-left: 1em;
}
/* Status bar */
.status-bar {
background-color: var(--code-background);
border-top: 1px solid var(--background-modifier-border);
}
/* Active file */
.workspace-leaf.mod-active .workspace-leaf-header-title {
color: var(--interactive-accent);
}
.nav-file-title.is-active {
background-color: var(--code-background);
color: var(--interactive-accent);
}
/* Text selection */
::selection {
background-color: var(--text-selection);
color: var(--text-selection-fg);
}
/* Search results */
.search-result-file-title {
color: var(--interactive-accent);
}
.search-result-file-match {
background-color: var(--code-background);
color: var(--text-normal);
border-left: 3px solid var(--interactive-accent);
}
.search-result-file-matched-text {
color: var(--code-background);
}
/* Tables */
.markdown-rendered table {
border: 1px solid var(--background-modifier-border);
}
.markdown-rendered th {
background-color: var(--code-background);
color: var(--text-accent);
}
.markdown-rendered td {
border: 1px solid var(--background-modifier-border);
}
/* Callouts */
.callout {
border-left: 4px solid var(--interactive-accent);
background-color: var(--code-background);
}
.callout * {
color: var(--text-normal);
}
/* Modal dialogs */
.modal {
background-color: var(--background-primary);
border: 2px solid var(--background-modifier-border);
}
/* Settings */
.vertical-tab-header-group-title {
color: var(--interactive-accent);
}
.vertical-tab-nav-item.is-active {
background-color: var(--code-background);
color: var(--interactive-accent);
}
EOF
}
# Option handling
if [ "${1:-}" = "--reset" ]; then
echo "♻️ Resetting Omarchy themes and registry..."
if [ -f "$VAULTS_FILE" ] && [ -s "$VAULTS_FILE" ]; then
while IFS= read -r vault_path || [ -n "$vault_path" ]; do
case "$vault_path" in ""|\#*) continue ;; esac
vault_path="${vault_path%/}"
vault_name=$(basename "$vault_path")
theme_dir="$vault_path/.obsidian/themes/Omarchy"
if [ -d "$theme_dir" ]; then
rm -rf "$theme_dir"
echo " ✅ $vault_name (theme removed)"
else
echo " $vault_name (no theme present)"
fi
done <"$VAULTS_FILE"
fi
rm -f "$VAULTS_FILE"
echo "✅ Registry removed"
exit 0
fi
# Main update logic
echo "🔄 Updating Obsidian vaults..."
# Step 1: ensure registry exists (bootstrap if needed)
ensure_vaults_file
while IFS= read -r vault_path || [ -n "$vault_path" ]; do
case "$vault_path" in "" | \#*) continue ;; esac
vault_path="${vault_path%/}"
vault_name=$(basename "$vault_path")
# Step 2: verify path exists; log/skip gracefully if invalid
if [ ! -d "$vault_path" ] || [ ! -d "$vault_path/.obsidian" ]; then
echo " ❌ $vault_name (invalid entry: missing directory or .obsidian)"
continue
fi
# Ensure theme files exist for this vault
ensure_theme_scaffold "$vault_path"
THEME_DIR="$vault_path/.obsidian/themes/Omarchy"
# Step 3: update theme.css
if [ -f "$CURRENT_THEME_DIR/obsidian.css" ]; then
cp "$CURRENT_THEME_DIR/obsidian.css" "$THEME_DIR/theme.css"
echo " ✅ $vault_name (custom theme)"
else
extract_theme_data >"$THEME_DIR/theme.css"
echo " ✅ $vault_name (generated theme)"
fi
done <"$VAULTS_FILE"

View File

@@ -1,7 +1,8 @@
#!/bin/bash #!/bin/bash
case "$TERMINAL" in if [[ -f ~/.config/alacritty/alacritty.toml ]]; then
"alacritty") touch ~/.config/alacritty/alacritty.toml ;; touch ~/.config/alacritty/alacritty.toml
"kitty") killall -SIGUSR1 kitty ;; fi
"ghostty") killall -SIGUSR2 ghostty ;;
esac killall -SIGUSR1 kitty
killall -SIGUSR2 ghostty

View File

@@ -3,44 +3,45 @@
# Note: We cannot use `jq` to update settings.json because its JSONC (allows comments), # Note: We cannot use `jq` to update settings.json because its JSONC (allows comments),
# which jq doesnt support. # which jq doesnt support.
VS_CODE_THEME="$HOME/.config/omarchy/current/theme/vscode.json" # Parameters: EDITOR_CMD SETTINGS_PATH SKIP_FLAG EDITOR_NAME
VS_CODE_SETTINGS="$HOME/.config/Code/User/settings.json" EDITOR_CMD="${1:-code}"
VS_CODE_SKIP_FLAG="$HOME/.local/state/omarchy/toggles/skip-vscode-theme-changes" SETTINGS_PATH="${2:-$HOME/.config/Code/User/settings.json}"
SKIP_FLAG="${3:-$HOME/.local/state/omarchy/toggles/skip-vscode-theme-changes}"
EDITOR_NAME="${4:-VS Code}"
if omarchy-cmd-present code && [[ ! -f "$VS_CODE_SKIP_FLAG" ]]; then VS_CODE_THEME="$HOME/.config/omarchy/current/theme/vscode.json"
if omarchy-cmd-present "$EDITOR_CMD" && [[ ! -f "$SKIP_FLAG" ]]; then
if [[ -f "$VS_CODE_THEME" ]]; then if [[ -f "$VS_CODE_THEME" ]]; then
theme_name=$(jq -r '.name' "$VS_CODE_THEME") theme_name=$(jq -r '.name' "$VS_CODE_THEME")
extension=$(jq -r '.extension' "$VS_CODE_THEME") extension=$(jq -r '.extension' "$VS_CODE_THEME")
# Install VS Code theme extension # Install $EDITOR_NAME theme extension
if [[ -n "$extension" ]] && ! code --list-extensions | grep -Fxq "$extension"; then if [[ -n "$extension" ]] && ! "$EDITOR_CMD" --list-extensions | grep -Fxq "$extension"; then
notify-send " Installing VS Code theme for $theme_name" "$EDITOR_CMD" --install-extension "$extension" >/dev/null
code --install-extension "$extension" >/dev/null
fi fi
# Create config file if there isn't already one # Create config file if there isn't already one
mkdir -p "$(dirname "$VS_CODE_SETTINGS")" mkdir -p "$(dirname "$SETTINGS_PATH")"
if [[ ! -f "$VS_CODE_SETTINGS" ]]; then if [[ ! -f "$SETTINGS_PATH" ]]; then
printf '{\n}\n' > "$VS_CODE_SETTINGS" printf '{\n}\n' >"$SETTINGS_PATH"
fi fi
# Create a `workbench.colorTheme` entry in settings. # Create a `workbench.colorTheme` entry in settings.
if ! grep -q '"workbench.colorTheme"' "$VS_CODE_SETTINGS"; then if ! grep -q '"workbench.colorTheme"' "$SETTINGS_PATH"; then
# Insert `"workbench.colorTheme": "",` immediately after the first `{` # Insert `"workbench.colorTheme": "",` immediately after the first `{`
# Use sed's first-match range (0,/{/) to only replace the first `{` # Use sed's first-match range (0,/{/) to only replace the first `{`
sed -i --follow-symlinks -E '0,/\{/{s/\{/{\ sed -i --follow-symlinks -E '0,/\{/{s/\{/{\ "workbench.colorTheme": "",/}' "$SETTINGS_PATH"
"workbench.colorTheme": "",/}' "$VS_CODE_SETTINGS"
fi fi
# Update theme # Update theme
sed -i --follow-symlinks -E \ sed -i --follow-symlinks -E \
"s/(\"workbench.colorTheme\"[[:space:]]*:[[:space:]]*\")[^\"]*(\")/\1$theme_name\2/" \ "s/(\"workbench.colorTheme\"[[:space:]]*:[[:space:]]*\")[^\"]*(\")/\1$theme_name\2/" \
"$VS_CODE_SETTINGS" "$SETTINGS_PATH"
else else
# Remove theme from settings.json when the theme doesn't have vscode support # Remove theme from settings.json when the theme doesn't have $EDITOR_NAME support
if [[ -f "$VS_CODE_SETTINGS" ]]; then if [[ -f "$SETTINGS_PATH" ]]; then
sed -i --follow-symlinks -E '/"workbench\.colorTheme"[[:space:]]*:[^,}]*,?/d' "$VS_CODE_SETTINGS" sed -i --follow-symlinks -E 's/\"workbench\.colorTheme\"[[:space:]]*:[^,}]*,?//' "$SETTINGS_PATH"
fi fi
fi fi
fi fi

View File

@@ -4,6 +4,6 @@ if pgrep -x hypridle >/dev/null; then
pkill -x hypridle pkill -x hypridle
notify-send "Stop locking computer when idle" notify-send "Stop locking computer when idle"
else else
uwsm app -- hypridle >/dev/null 2>&1 & uwsm-app -- hypridle >/dev/null 2>&1 &
notify-send "Now locking computer when idle" notify-send "Now locking computer when idle"
fi fi

View File

@@ -6,7 +6,7 @@ OFF_TEMP=6000
# Ensure hyprsunset is running # Ensure hyprsunset is running
if ! pgrep -x hyprsunset; then if ! pgrep -x hyprsunset; then
setsid uwsm app -- hyprsunset & setsid uwsm-app -- hyprsunset &
sleep 1 # Give it time to register sleep 1 # Give it time to register
fi fi

View File

@@ -3,5 +3,5 @@
if pgrep -x waybar >/dev/null; then if pgrep -x waybar >/dev/null; then
pkill -x waybar pkill -x waybar
else else
uwsm app -- waybar >/dev/null 2>&1 & uwsm-app -- waybar >/dev/null 2>&1 &
fi fi

6
bin/omarchy-tz-select Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
timezone=$(timedatectl list-timezones | gum filter --height 20 --header "Set timezone") || exit 1
sudo timedatectl set-timezone "$timezone"
echo "Timezone is now set to $timezone"
omarchy-restart-waybar

View File

@@ -3,7 +3,7 @@
set -e set -e
if (($# == 0)); then if (($# == 0)); then
echo "Usage: omarchy-verion-branch-set [master|dev]" echo "Usage: omarchy-update-branch [master|dev]"
exit 1 exit 1
fi fi

11
bin/omarchy-update-firmware Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
echo -e "\e[32mUpdate Firmware\e[0m"
if omarchy-cmd-missing fwupdmgr; then
omarchy-pkg-add fwupd
fi
fwupdmgr refresh
sudo fwupdmgr update

View File

@@ -5,4 +5,5 @@ set -e
omarchy-update-available-reset omarchy-update-available-reset
omarchy-update-system-pkgs omarchy-update-system-pkgs
omarchy-migrate omarchy-migrate
omarchy-hook post-update
omarchy-update-restart omarchy-update-restart

View File

@@ -5,9 +5,6 @@ if [ "$(uname -r | sed 's/-arch/\.arch/')" != "$(pacman -Q linux | awk '{print $
elif [ -f "$HOME/.local/state/omarchy/reboot-required" ]; then elif [ -f "$HOME/.local/state/omarchy/reboot-required" ]; then
gum confirm "Updates require reboot. Ready?" && omarchy-state clear re*-required && sudo reboot now gum confirm "Updates require reboot. Ready?" && omarchy-state clear re*-required && sudo reboot now
elif [ -f "$HOME/.local/state/omarchy/relaunch-required" ]; then
gum confirm "Updates require Hyprland relaunch. Ready?" && omarchy-state clear re*-required && uwsm stop
fi fi
for file in "$HOME"/.local/state/omarchy/restart-*-required; do for file in "$HOME"/.local/state/omarchy/restart-*-required; do

View File

@@ -1,3 +1,2 @@
#!/bin/bash #!/bin/bash
cat $OMARCHY_PATH/version
git -C "$OMARCHY_PATH" describe --tags $(git -C "$OMARCHY_PATH" rev-list --tags --max-count=1)

11
bin/omarchy-webapp-handler-hey Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
url="$1"
web_url="https://app.hey.com"
# Handle mailto: URLs
if [[ $url =~ ^mailto: ]]; then
email=$(echo "$url" | sed 's/mailto://')
web_url="https://app.hey.com/messages/new?to=$email"
fi
exec omarchy-launch-webapp "$web_url"

View File

@@ -6,7 +6,7 @@ DESKTOP_DIR="$HOME/.local/share/applications/"
if [ "$#" -eq 0 ]; then if [ "$#" -eq 0 ]; then
# Find all web apps # Find all web apps
while IFS= read -r -d '' file; do while IFS= read -r -d '' file; do
if grep -q '^Exec=.*omarchy-launch-webapp.*' "$file"; then if grep -q '^Exec=.*\(omarchy-launch-webapp\|omarchy-webapp-handler\).*' "$file"; then
WEB_APPS+=("$(basename "${file%.desktop}")") WEB_APPS+=("$(basename "${file%.desktop}")")
fi fi
done < <(find "$DESKTOP_DIR" -name '*.desktop' -print0) done < <(find "$DESKTOP_DIR" -name '*.desktop' -print0)

445
bin/omarchy-windows-vm Executable file
View File

@@ -0,0 +1,445 @@
#!/bin/bash
COMPOSE_FILE="$HOME/.config/windows/docker-compose.yml"
check_prerequisites() {
local DISK_SIZE_GB=${1:-64}
local REQUIRED_SPACE=$((DISK_SIZE_GB + 10)) # Add 10GB for Windows ISO and overhead
# Check for KVM support
if [ ! -e /dev/kvm ]; then
gum style \
--border normal \
--padding "1 2" \
--margin "1" \
"❌ KVM virtualization not available!" \
"" \
"Please enable virtualization in BIOS or run:" \
" sudo modprobe kvm-intel # for Intel CPUs" \
" sudo modprobe kvm-amd # for AMD CPUs"
exit 1
fi
# Check disk space
AVAILABLE_SPACE=$(df "$HOME" | awk 'NR==2 {print int($4/1024/1024)}')
if [ "$AVAILABLE_SPACE" -lt "$REQUIRED_SPACE" ]; then
echo "❌ Insufficient disk space!"
echo " Available: ${AVAILABLE_SPACE}GB"
echo " Required: ${REQUIRED_SPACE}GB (${DISK_SIZE_GB}GB disk + 10GB for Windows image)"
exit 1
fi
}
install_windows() {
# Set up trap to handle Ctrl+C
trap "echo ''; echo 'Installation cancelled by user'; exit 1" INT
check_prerequisites
omarchy-pkg-add freerdp openbsd-netcat gum
mkdir -p "$HOME/.windows"
mkdir -p "$HOME/.config/windows"
mkdir -p "$HOME/.local/share/applications/icons"
# Install Windows VM icon and desktop file
if [ -f "$OMARCHY_PATH/applications/icons/windows.png" ]; then
cp "$OMARCHY_PATH/applications/icons/windows.png" "$HOME/.local/share/applications/icons/windows.png"
fi
cat << EOF | tee "$HOME/.local/share/applications/windows-vm.desktop" > /dev/null
[Desktop Entry]
Name=Windows
Comment=Start Windows VM via Docker and connect with RDP
Exec=uwsm app -- omarchy-windows-vm launch
Icon=$HOME/.local/share/applications/icons/windows.png
Terminal=false
Type=Application
Categories=System;Virtualization;
EOF
# Get system resources
TOTAL_RAM=$(free -h | grep "^Mem:" | awk '{print $2}')
TOTAL_RAM_GB=$(free -g | grep "^Mem:" | awk '{print $2}')
TOTAL_CORES=$(nproc)
echo ""
echo "System Resources Detected:"
echo " Total RAM: $TOTAL_RAM"
echo " Total CPU Cores: $TOTAL_CORES"
echo ""
RAM_OPTIONS=""
for size in 2 4 8 16 32 64; do
if [ $size -le $TOTAL_RAM_GB ]; then
RAM_OPTIONS="$RAM_OPTIONS ${size}G"
fi
done
SELECTED_RAM=$(echo $RAM_OPTIONS | tr ' ' '\n' | gum choose --selected="4G" --header="How much RAM would you like to allocate to Windows VM?")
# Check if user cancelled
if [ -z "$SELECTED_RAM" ]; then
echo "Installation cancelled by user"
exit 1
fi
SELECTED_CORES=$(gum input --placeholder="Number of CPU cores (1-$TOTAL_CORES)" --value="2" --header="How many CPU cores would you like to allocate to Windows VM?" --char-limit=2)
# Check if user cancelled (Ctrl+C in gum input returns empty string)
if [ -z "$SELECTED_CORES" ]; then
echo "Installation cancelled by user"
exit 1
fi
if ! [[ "$SELECTED_CORES" =~ ^[0-9]+$ ]] || [ "$SELECTED_CORES" -lt 1 ] || [ "$SELECTED_CORES" -gt "$TOTAL_CORES" ]; then
echo "Invalid input. Using default: 2 cores"
SELECTED_CORES=2
fi
AVAILABLE_SPACE=$(df "$HOME" | awk 'NR==2 {print int($4/1024/1024)}')
MAX_DISK_GB=$((AVAILABLE_SPACE - 10)) # Leave 10GB for Windows image
# Check if we have enough space for minimum
if [ $MAX_DISK_GB -lt 32 ]; then
echo "❌ Insufficient disk space for Windows VM!"
echo " Available: ${AVAILABLE_SPACE}GB"
echo " Minimum required: 42GB (32GB disk + 10GB for Windows image)"
exit 1
fi
DISK_OPTIONS=""
for size in 32 64 128 256 512; do
if [ $size -le $MAX_DISK_GB ]; then
DISK_OPTIONS="$DISK_OPTIONS ${size}G"
fi
done
# Default to 64G if available, otherwise 32G
DEFAULT_DISK="64G"
if ! echo "$DISK_OPTIONS" | grep -q "64G"; then
DEFAULT_DISK="32G"
fi
SELECTED_DISK=$(echo $DISK_OPTIONS | tr ' ' '\n' | gum choose --selected="$DEFAULT_DISK" --header="How much disk space would you like to give Windows VM? (64GB+ recommended)")
# Check if user cancelled
if [ -z "$SELECTED_DISK" ]; then
echo "Installation cancelled by user"
exit 1
fi
# Extract just the number for prerequisite check
DISK_SIZE_NUM=$(echo "$SELECTED_DISK" | sed 's/G//')
# Re-check prerequisites with selected disk size
check_prerequisites "$DISK_SIZE_NUM"
# Prompt for username and password
USERNAME=$(gum input --placeholder="Username (Press enter to use default: docker)" --header="Enter Windows username:")
if [ -z "$USERNAME" ]; then
USERNAME="docker"
fi
PASSWORD=$(gum input --placeholder="Password (Press enter to use default: admin)" --password --header="Enter Windows password:")
if [ -z "$PASSWORD" ]; then
PASSWORD="admin"
PASSWORD_DISPLAY="(default)"
else
PASSWORD_DISPLAY="(user-defined)"
fi
# Display configuration summary
gum style \
--border normal \
--padding "1 2" \
--margin "1" \
--align left \
--bold \
"Windows VM Configuration" \
"" \
"RAM: $SELECTED_RAM" \
"CPU: $SELECTED_CORES cores" \
"Disk: $SELECTED_DISK" \
"Username: $USERNAME" \
"Password: $PASSWORD_DISPLAY"
# Ask for confirmation
echo ""
if ! gum confirm "Proceed with this configuration?"; then
echo "Installation cancelled by user"
exit 1
fi
mkdir -p $HOME/Windows
# Create docker-compose.yml in user config directory
cat << EOF | tee "$COMPOSE_FILE" > /dev/null
services:
windows:
image: dockurr/windows
container_name: omarchy-windows
environment:
VERSION: "11"
RAM_SIZE: "$SELECTED_RAM"
CPU_CORES: "$SELECTED_CORES"
DISK_SIZE: "$SELECTED_DISK"
USERNAME: "$USERNAME"
PASSWORD: "$PASSWORD"
devices:
- /dev/kvm
- /dev/net/tun
cap_add:
- NET_ADMIN
ports:
- 8006:8006
- 3389:3389/tcp
- 3389:3389/udp
volumes:
- $HOME/.windows:/storage
- $HOME/Windows:/shared
restart: always
stop_grace_period: 2m
EOF
echo ""
echo "Starting Windows VM installation..."
echo "This will download a Windows 11 image (may take 10-15 minutes)."
echo ""
echo "Monitor installation progress at: http://127.0.0.1:8006"
echo ""
# Start docker-compose with user's config
echo "Starting Windows VM with docker-compose..."
if ! docker-compose -f "$COMPOSE_FILE" up -d 2>&1; then
echo "❌ Failed to start Windows VM!"
echo " Common issues:"
echo " - Docker daemon not running: sudo systemctl start docker"
echo " - Port already in use: check if another VM is running"
echo " - Permission issues: make sure you're in the docker group"
exit 1
fi
echo ""
echo "Windows VM is starting up!"
echo ""
echo "Opening browser to monitor installation..."
# Open browser to monitor installation
sleep 3
xdg-open "http://127.0.0.1:8006"
echo ""
echo "Installation is running in the background."
echo "You can monitor progress at: http://127.0.0.1:8006"
echo ""
echo "Once finished, launch 'Windows' via Super + Space"
echo ""
echo "To stop the VM: omarchy-windows-vm stop"
echo "To change resources: ~/.config/windows/docker-compose.yml"
echo ""
}
remove_windows() {
echo "Removing Windows VM..."
docker-compose -f "$COMPOSE_FILE" down 2>/dev/null || true
docker rmi dockurr/windows 2>/dev/null || echo "Image already removed or not found"
rm "$HOME/.local/share/applications/windows-vm.desktop"
rm -rf "$HOME/.config/windows"
rm -rf "$HOME/.windows"
echo ""
echo "Windows VM removal completed!"
}
launch_windows() {
KEEP_ALIVE=false
if [ "$1" = "--keep-alive" ] || [ "$1" = "-k" ]; then
KEEP_ALIVE=true
fi
# Check if config exists
if [ ! -f "$COMPOSE_FILE" ]; then
echo "Windows VM not configured. Please run: omarchy-windows-vm install"
exit 1
fi
# Check if container is already running
CONTAINER_STATUS=$(docker inspect --format='{{.State.Status}}' omarchy-windows 2>/dev/null)
if [ "$CONTAINER_STATUS" != "running" ]; then
echo "Starting Windows VM..."
# Send desktop notification
notify-send "Windows VM" "Starting Windows VM, this may take a moment..."
if ! docker-compose -f "$COMPOSE_FILE" up -d 2>&1; then
echo "❌ Failed to start Windows VM!"
echo " Try checking: omarchy-windows-vm status"
echo " View logs: docker logs omarchy-windows"
notify-send -u critical "Windows VM" "Failed to start Windows VM"
exit 1
fi
# Wait for RDP to be ready
echo "Waiting for Windows VM to be ready..."
WAIT_COUNT=0
while ! nc -z 127.0.0.1 3389 2>/dev/null; do
sleep 2
WAIT_COUNT=$((WAIT_COUNT + 1))
if [ $WAIT_COUNT -gt 60 ]; then # 2 minutes timeout
echo "❌ Timeout waiting for RDP!"
echo " The VM might still be installing Windows."
echo " Check progress at: http://127.0.0.1:8006"
exit 1
fi
done
# Give it a moment more to fully initialize
sleep 3
fi
# Extract credentials from compose file
WIN_USER=$(grep "USERNAME:" "$COMPOSE_FILE" | sed 's/.*USERNAME: "\(.*\)"/\1/')
WIN_PASS=$(grep "PASSWORD:" "$COMPOSE_FILE" | sed 's/.*PASSWORD: "\(.*\)"/\1/')
# Use defaults if not found
[ -z "$WIN_USER" ] && WIN_USER="docker"
[ -z "$WIN_PASS" ] && WIN_PASS="admin"
# Build the connection info
if [ "$KEEP_ALIVE" = true ]; then
LIFECYCLE="VM will keep running after RDP closes
To stop: omarchy-windows-vm stop"
else
LIFECYCLE="VM will auto-stop when RDP closes"
fi
gum style \
--border normal \
--padding "1 2" \
--margin "1" \
--align center \
"Connecting to Windows VM" \
"" \
"$LIFECYCLE"
# Detect display scale from Hyprland
HYPR_SCALE=$(hyprctl monitors -j | jq -r '.[0].scale')
SCALE_PERCENT=$(echo "$HYPR_SCALE" | awk '{print int($1 * 100)}')
RDP_SCALE=""
if [ "$SCALE_PERCENT" -ge 170 ]; then
RDP_SCALE="/scale:180"
elif [ "$SCALE_PERCENT" -ge 130 ]; then
RDP_SCALE="/scale:140"
fi
# If scale is less than 130%, don't set any scale (use default 100)
# Connect with RDP in fullscreen (auto-detects resolution)
xfreerdp3 /u:"$WIN_USER" /p:"$WIN_PASS" /v:127.0.0.1:3389 +f -grab-keyboard /cert:ignore /title:"Windows VM - Omarchy" /floatbar:sticky:off,default:visible,show:fullscreen $RDP_SCALE
# After RDP closes, stop the container unless --keep-alive was specified
if [ "$KEEP_ALIVE" = false ]; then
echo ""
echo "RDP session closed. Stopping Windows VM..."
docker-compose -f "$COMPOSE_FILE" down
echo "Windows VM stopped."
else
echo ""
echo "RDP session closed. Windows VM is still running."
echo "To stop it: omarchy-windows-vm stop"
fi
}
stop_windows() {
if [ ! -f "$COMPOSE_FILE" ]; then
echo "Windows VM not configured."
exit 1
fi
echo "Stopping Windows VM..."
docker-compose -f "$COMPOSE_FILE" down
echo "Windows VM stopped."
}
status_windows() {
if [ ! -f "$COMPOSE_FILE" ]; then
echo "Windows VM not configured."
echo "To set up: omarchy-windows-vm install"
exit 1
fi
CONTAINER_STATUS=$(docker inspect --format='{{.State.Status}}' omarchy-windows 2>/dev/null)
if [ -z "$CONTAINER_STATUS" ]; then
echo "Windows VM container not found."
echo "To start: omarchy-windows-vm launch"
elif [ "$CONTAINER_STATUS" = "running" ]; then
gum style \
--border normal \
--padding "1 2" \
--margin "1" \
--align left \
"Windows VM Status: RUNNING" \
"" \
"Web interface: http://127.0.0.1:8006" \
"RDP available: port 3389" \
"" \
"To connect: omarchy-windows-vm launch" \
"To stop: omarchy-windows-vm stop"
else
echo "Windows VM is stopped (status: $CONTAINER_STATUS)"
echo "To start: omarchy-windows-vm launch"
fi
}
show_usage() {
echo "Usage: omarchy-windows-vm [command] [options]"
echo ""
echo "Commands:"
echo " install Install and configure Windows VM"
echo " remove Remove Windows VM and optionally its data"
echo " launch [options] Start Windows VM (if needed) and connect via RDP"
echo " Options:"
echo " --keep-alive, -k Keep VM running after RDP closes"
echo " stop Stop the running Windows VM"
echo " status Show current VM status"
echo " help Show this help message"
echo ""
echo "Examples:"
echo " omarchy-windows-vm install # Set up Windows VM for first time"
echo " omarchy-windows-vm launch # Connect to VM (auto-stop on exit)"
echo " omarchy-windows-vm launch -k # Connect to VM (keep running)"
echo " omarchy-windows-vm stop # Shut down the VM"
}
# Main command dispatcher
case "$1" in
install)
install_windows
;;
remove)
remove_windows
;;
launch|start)
launch_windows "$2"
;;
stop|down)
stop_windows
;;
status)
status_windows
;;
help|--help|-h|"")
show_usage
;;
*)
echo "Unknown command: $1" >&2
echo "" >&2
show_usage >&2
exit 1
;;
esac

View File

@@ -16,5 +16,6 @@ decorations = "None"
[keyboard] [keyboard]
bindings = [ bindings = [
{ key = "F11", action = "ToggleFullscreen" } { key = "Insert", mods = "Shift", action = "Paste" },
{ key = "Insert", mods = "Control", action = "Copy" }
] ]

View File

@@ -1,3 +1,5 @@
--ozone-platform=wayland --ozone-platform=wayland
--ozone-platform-hint=wayland --ozone-platform-hint=wayland
--enable-features=TouchpadOverscrollHistoryNavigation --enable-features=TouchpadOverscrollHistoryNavigation
# Chromium crash workaround for Wayland color management on Hyprland - see https://github.com/hyprwm/Hyprland/issues/11957
--disable-features=WaylandWpColorManagerV1

View File

@@ -22,7 +22,7 @@ presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:defaul
#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists. #* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists.
#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift. #* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift.
vim_keys = False vim_keys = True
#* Rounded corners on boxes, is ignored if TTY mode is ON. #* Rounded corners on boxes, is ignored if TTY mode is ON.
rounded_corners = True rounded_corners = True

View File

@@ -2,3 +2,5 @@
--ozone-platform-hint=wayland --ozone-platform-hint=wayland
--enable-features=TouchpadOverscrollHistoryNavigation --enable-features=TouchpadOverscrollHistoryNavigation
--load-extension=~/.local/share/omarchy/default/chromium/extensions/copy-url --load-extension=~/.local/share/omarchy/default/chromium/extensions/copy-url
# Chromium crash workaround for Wayland color management on Hyprland - see https://github.com/hyprwm/Hyprland/issues/11957
--disable-features=WaylandWpColorManagerV1

View File

@@ -0,0 +1 @@
async = false

View File

@@ -0,0 +1,3 @@
show_actions = false
only_search_title = true
history = false

View File

@@ -7,10 +7,12 @@ font-style = Regular
font-size = 9 font-size = 9
# Window # Window
window-theme = ghostty
window-padding-x = 14 window-padding-x = 14
window-padding-y = 14 window-padding-y = 14
confirm-close-surface=false confirm-close-surface=false
resize-overlay = never resize-overlay = never
gtk-toolbar-style = flat
# Cursor styling # Cursor styling
cursor-style = "block" cursor-style = "block"
@@ -18,4 +20,8 @@ cursor-style-blink = false
shell-integration-features = no-cursor shell-integration-features = no-cursor
# Keyboard bindings # Keyboard bindings
keybind = f11=toggle_fullscreen keybind = shift+insert=paste_from_clipboard
keybind = control+insert=copy_to_clipboard
# SSH session terminfo
shell-integration-features = ssh-env

View File

@@ -1,2 +1,2 @@
# Extra autostart processes # Extra autostart processes
# exec-once = uwsm app -- my-service # exec-once = uwsm-app -- my-service

View File

@@ -1,29 +1,29 @@
# Application bindings # Application bindings
$terminal = uwsm app -- $TERMINAL $terminal = uwsm-app -- $TERMINAL
$browser = omarchy-launch-browser $browser = omarchy-launch-browser
bindd = SUPER, return, Terminal, exec, $terminal --working-directory="$(omarchy-cmd-terminal-cwd)" bindd = SUPER, RETURN, Terminal, exec, $terminal --working-directory="$(omarchy-cmd-terminal-cwd)"
bindd = SUPER, F, File manager, exec, uwsm app -- nautilus --new-window bindd = SUPER SHIFT, F, File manager, exec, uwsm-app -- nautilus --new-window
bindd = SUPER, B, Browser, exec, $browser bindd = SUPER SHIFT, B, Browser, exec, $browser
bindd = SUPER SHIFT, B, Browser (private), exec, $browser --private bindd = SUPER SHIFT ALT, B, Browser (private), exec, $browser --private
bindd = SUPER, M, Music, exec, omarchy-launch-or-focus spotify bindd = SUPER SHIFT, M, Music, exec, omarchy-launch-or-focus spotify
bindd = SUPER, N, Editor, exec, omarchy-launch-editor bindd = SUPER SHIFT, N, Editor, exec, omarchy-launch-editor
bindd = SUPER, T, Activity, exec, $terminal -e btop bindd = SUPER SHIFT, T, Activity, exec, $terminal -e btop
bindd = SUPER, D, Docker, exec, $terminal -e lazydocker bindd = SUPER SHIFT, D, Docker, exec, $terminal -e lazydocker
bindd = SUPER, G, Signal, exec, omarchy-launch-or-focus signal "uwsm app -- signal-desktop" bindd = SUPER SHIFT, G, Signal, exec, omarchy-launch-or-focus signal "uwsm-app -- signal-desktop"
bindd = SUPER, O, Obsidian, exec, omarchy-launch-or-focus obsidian "uwsm app -- obsidian -disable-gpu --enable-wayland-ime" bindd = SUPER SHIFT, O, Obsidian, exec, omarchy-launch-or-focus "^obsidian$" "uwsm-app -- obsidian -disable-gpu --enable-wayland-ime"
bindd = SUPER, slash, Passwords, exec, uwsm app -- 1password bindd = SUPER SHIFT, SLASH, Passwords, exec, uwsm-app -- 1password
# If your web app url contains #, type it as ## to prevent hyperland treat it as comments # If your web app url contains #, type it as ## to prevent hyperland treat it as comments
bindd = SUPER, A, ChatGPT, exec, omarchy-launch-webapp "https://chatgpt.com" bindd = SUPER SHIFT, A, ChatGPT, exec, omarchy-launch-webapp "https://chatgpt.com"
bindd = SUPER SHIFT, A, Grok, exec, omarchy-launch-webapp "https://grok.com" bindd = SUPER SHIFT ALT, A, Grok, exec, omarchy-launch-webapp "https://grok.com"
bindd = SUPER, C, Calendar, exec, omarchy-launch-webapp "https://app.hey.com/calendar/weeks/" bindd = SUPER SHIFT, C, Calendar, exec, omarchy-launch-webapp "https://app.hey.com/calendar/weeks/"
bindd = SUPER, E, Email, exec, omarchy-launch-webapp "https://app.hey.com" bindd = SUPER SHIFT, E, Email, exec, omarchy-launch-webapp "https://app.hey.com"
bindd = SUPER, Y, YouTube, exec, omarchy-launch-or-focus-webapp YouTube "https://youtube.com/" bindd = SUPER SHIFT, Y, YouTube, exec, omarchy-launch-webapp "https://youtube.com/"
bindd = SUPER SHIFT, G, WhatsApp, exec, omarchy-launch-or-focus-webapp WhatsApp "https://web.whatsapp.com/" bindd = SUPER SHIFT ALT, G, WhatsApp, exec, omarchy-launch-or-focus-webapp WhatsApp "https://web.whatsapp.com/"
bindd = SUPER ALT, G, Google Messages, exec, omarchy-launch-or-focus-webapp "Google Messages" "https://messages.google.com/web/conversations" bindd = SUPER SHIFT CTRL, G, Google Messages, exec, omarchy-launch-or-focus-webapp "Google Messages" "https://messages.google.com/web/conversations"
bindd = SUPER, X, X, exec, omarchy-launch-webapp "https://x.com/" bindd = SUPER SHIFT, X, X, exec, omarchy-launch-webapp "https://x.com/"
bindd = SUPER SHIFT, X, X Post, exec, omarchy-launch-webapp "https://x.com/compose/post" bindd = SUPER SHIFT ALT, X, X Post, exec, omarchy-launch-webapp "https://x.com/compose/post"
# Overwrite existing bindings, like putting Omarchy Menu on Super + Space # Overwrite existing bindings, like putting Omarchy Menu on Super + Space
# unbind = SUPER, SPACE # unbind = SUPER, SPACE

View File

@@ -3,7 +3,8 @@
# Use defaults Omarchy defaults (but don't edit these directly!) # Use defaults Omarchy defaults (but don't edit these directly!)
source = ~/.local/share/omarchy/default/hypr/autostart.conf source = ~/.local/share/omarchy/default/hypr/autostart.conf
source = ~/.local/share/omarchy/default/hypr/bindings/media.conf source = ~/.local/share/omarchy/default/hypr/bindings/media.conf
source = ~/.local/share/omarchy/default/hypr/bindings/tiling.conf source = ~/.local/share/omarchy/default/hypr/bindings/clipboard.conf
source = ~/.local/share/omarchy/default/hypr/bindings/tiling-v2.conf
source = ~/.local/share/omarchy/default/hypr/bindings/utilities.conf source = ~/.local/share/omarchy/default/hypr/bindings/utilities.conf
source = ~/.local/share/omarchy/default/hypr/envs.conf source = ~/.local/share/omarchy/default/hypr/envs.conf
source = ~/.local/share/omarchy/default/hypr/looknfeel.conf source = ~/.local/share/omarchy/default/hypr/looknfeel.conf
@@ -18,3 +19,6 @@ source = ~/.config/hypr/bindings.conf
source = ~/.config/hypr/envs.conf source = ~/.config/hypr/envs.conf
source = ~/.config/hypr/looknfeel.conf source = ~/.config/hypr/looknfeel.conf
source = ~/.config/hypr/autostart.conf source = ~/.config/hypr/autostart.conf
# Add any other personal Hyprland configuration below
# windowrule = workspace 5, class:qemu

View File

@@ -13,7 +13,7 @@ animations {
input-field { input-field {
monitor = monitor =
size = 600, 100 size = 650, 100
position = 0, 0 position = 0, 0
halign = center halign = center
valign = center valign = center
@@ -22,12 +22,12 @@ input-field {
outer_color = $outer_color outer_color = $outer_color
outline_thickness = 4 outline_thickness = 4
font_family = CaskaydiaMono Nerd Font font_family = CaskaydiaMono Nerd Font Propo
font_color = $font_color font_color = $font_color
placeholder_text = Enter Password 󰈷 placeholder_text = Enter Password 󰈷
check_color = $check_color check_color = $check_color
fail_text = <i>$PAMFAIL ($ATTEMPTS)</i> fail_text = <i>$FAIL ($ATTEMPTS)</i>
rounding = 0 rounding = 0
shadow_passes = 0 shadow_passes = 0

View File

@@ -4,3 +4,9 @@ profile {
time = 07:00 time = 07:00
identity = true identity = true
} }
# Enable auto switch to nightlight:
# profile {
# time = 20:00
# temperature = 4000
# }

View File

@@ -3,7 +3,7 @@
input { input {
# Use multiple keyboard layouts and switch between them with Left Alt + Right Alt # Use multiple keyboard layouts and switch between them with Left Alt + Right Alt
# kb_layout = us,dk,eu # kb_layout = us,dk,eu
kb_options = compose:caps # ,grp:alts_toggle kb_options = compose:caps # ,grp:shifts_toggle
# Change speed of keyboard repeat # Change speed of keyboard repeat
repeat_rate = 40 repeat_rate = 40
@@ -12,7 +12,7 @@ input {
# Start with numlock on by default # Start with numlock on by default
numlock_by_default = true numlock_by_default = true
# Increase sensitity for mouse/trackpack (default: 0) # Increase sensitivity for mouse/trackpad (default: 0)
# sensitivity = 0.35 # sensitivity = 0.35
touchpad { touchpad {

View File

@@ -1,7 +1,6 @@
# See https://wiki.hyprland.org/Configuring/Monitors/ # See https://wiki.hyprland.org/Configuring/Monitors/
# List current monitors and resolutions possible: hyprctl monitors # List current monitors and resolutions possible: hyprctl monitors
# Format: monitor = [port], resolution, position, scale # Format: monitor = [port], resolution, position, scale
# You must relaunch Hyprland after changing any envs (use Super+Esc, then Relaunch)
# Optimized for retina-class 2x displays, like 13" 2.8K, 27" 5K, 32" 6K. # Optimized for retina-class 2x displays, like 13" 2.8K, 27" 5K, 32" 6K.
env = GDK_SCALE,2 env = GDK_SCALE,2

View File

@@ -13,7 +13,8 @@ show_window_resize_notification no
confirm_os_window_close 0 confirm_os_window_close 0
# Keybindings # Keybindings
map F11 toggle_fullscreen map ctrl+insert copy_to_clipboard
map shift+insert paste_from_clipboard
# Allow remote access # Allow remote access
single_instance yes single_instance yes

View File

@@ -1,10 +0,0 @@
{
"extras": [
"lazyvim.plugins.extras.editor.neo-tree"
],
"install_version": 8,
"news": {
"NEWS.md": "10960"
},
"version": 8
}

View File

@@ -1,8 +0,0 @@
return {
"folke/snacks.nvim",
opts = {
scroll = {
enabled = false, -- Disable scrolling animations
},
},
}

View File

@@ -1,8 +0,0 @@
return {
{
"LazyVim/LazyVim",
opts = {
colorscheme = "tokyonight",
},
},
}

View File

@@ -1,45 +0,0 @@
-- transparent background
vim.api.nvim_set_hl(0, "Normal", { bg = "none" })
vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" })
vim.api.nvim_set_hl(0, "FloatBorder", { bg = "none" })
vim.api.nvim_set_hl(0, "Pmenu", { bg = "none" })
vim.api.nvim_set_hl(0, "Terminal", { bg = "none" })
vim.api.nvim_set_hl(0, "EndOfBuffer", { bg = "none" })
vim.api.nvim_set_hl(0, "FoldColumn", { bg = "none" })
vim.api.nvim_set_hl(0, "Folded", { bg = "none" })
vim.api.nvim_set_hl(0, "SignColumn", { bg = "none" })
vim.api.nvim_set_hl(0, "NormalNC", { bg = "none" })
vim.api.nvim_set_hl(0, "WhichKeyFloat", { bg = "none" })
vim.api.nvim_set_hl(0, "TelescopeBorder", { bg = "none" })
vim.api.nvim_set_hl(0, "TelescopeNormal", { bg = "none" })
vim.api.nvim_set_hl(0, "TelescopePromptBorder", { bg = "none" })
vim.api.nvim_set_hl(0, "TelescopePromptTitle", { bg = "none" })
-- transparent background for neotree
vim.api.nvim_set_hl(0, "NeoTreeNormal", { bg = "none" })
vim.api.nvim_set_hl(0, "NeoTreeNormalNC", { bg = "none" })
vim.api.nvim_set_hl(0, "NeoTreeVertSplit", { bg = "none" })
vim.api.nvim_set_hl(0, "NeoTreeWinSeparator", { bg = "none" })
vim.api.nvim_set_hl(0, "NeoTreeEndOfBuffer", { bg = "none" })
-- transparent background for nvim-tree
vim.api.nvim_set_hl(0, "NvimTreeNormal", { bg = "none" })
vim.api.nvim_set_hl(0, "NvimTreeVertSplit", { bg = "none" })
vim.api.nvim_set_hl(0, "NvimTreeEndOfBuffer", { bg = "none" })
-- transparent notify background
vim.api.nvim_set_hl(0, "NotifyINFOBody", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyERRORBody", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyWARNBody", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyTRACEBody", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyDEBUGBody", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyINFOTitle", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyERRORTitle", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyWARNTitle", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyTRACETitle", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyDEBUGTitle", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyINFOBorder", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyERRORBorder", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyWARNBorder", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyTRACEBorder", { bg = "none" })
vim.api.nvim_set_hl(0, "NotifyDEBUGBorder", { bg = "none" })

View File

@@ -0,0 +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.
# Example: Show the name of the theme that was just set.
# notify-send "New font" "Your new font is $1"

View File

@@ -0,0 +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.
# Example: Show notification after the system has been updated.
# notify-send "Update Performed" "Your system is now up to date"

View File

@@ -0,0 +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.
# Example: Show the name of the theme that was just set.
# notify-send "New theme" "Your new theme is $1"

View File

@@ -6,3 +6,4 @@ After=graphical-session.target
Type=oneshot Type=oneshot
ExecStart=%h/.local/share/omarchy/bin/omarchy-battery-monitor ExecStart=%h/.local/share/omarchy/bin/omarchy-battery-monitor
Environment=DISPLAY=:0 Environment=DISPLAY=:0
LogLevelMax=warning

View File

@@ -1,4 +1,4 @@
# Changes require a relaunch of Hyprland to take effect. # Changes require a restart to take effect.
export TERMINAL=alacritty export TERMINAL=alacritty
export EDITOR=nvim export EDITOR=nvim

View File

@@ -1,4 +1,4 @@
# Changes require a relaunch of Hyprland to take effect. # Changes require a restart to take effect.
# Ensure Omarchy bins are in the path # Ensure Omarchy bins are in the path
export OMARCHY_PATH=$HOME/.local/share/omarchy export OMARCHY_PATH=$HOME/.local/share/omarchy

View File

@@ -1,100 +1,145 @@
close_when_open = true force_keyboard_focus = true # forces keyboard forcus to stay in Walker
theme = "omarchy-default" close_when_open = true # close walker when invoking while already opened
theme_base = [] selection_wrap = true # wrap list if at bottom or top
theme_location = ["~/.local/share/omarchy/default/walker/themes/"] click_to_close = true # closes walker if clicking outside of the main content area
hotreload_theme = true global_argument_delimiter = "#" # query: firefox#https://benz.dev => part after delimiter will be ignored when querying. this should be the same as in the elephant config
force_keyboard_focus = true exact_search_prefix = "'" # disable fuzzy searching
timeout = 60 theme = "omarchy-default" # theme to use
disable_mouse = false # disable mouse (on input and list only)
additional_theme_location = "~/.local/share/omarchy/default/walker/themes/"
[keys.ai] [shell]
run_last_response = ["ctrl e"] anchor_top = true
anchor_bottom = true
anchor_left = true
anchor_right = true
[list] [placeholders]
max_entries = 200 "default" = { input = " Search...", list = "No Results" } # placeholders for input and empty list, key is the providers name, so f.e. "desktopapplications" or "menus:other"
cycle = true
[search] [keybinds]
placeholder = " Search..." close = ["Escape"]
next = ["Down"]
previous = ["Up"]
toggle_exact = ["ctrl e"]
resume_last_query = ["ctrl r"]
quick_activate = []
[builtins.hyprland_keybinds] [providers]
path = "~/.config/hypr/hyprland.conf" default = [
hidden = true "desktopapplications",
"menus",
"websearch",
] # providers to be queried by default
empty = ["desktopapplications"] # providers to be queried when query is empty
max_results = 50 # global max results
[builtins.applications] [providers.sets] # define your own defaults/empty sets of providers
launch_prefix = "uwsm app -- " [providers.max_results_provider] # define max results per provider in here
placeholder = " Search..."
prioritize_new = false
context_aware = false
show_sub_when_single = false
history = false
icon = ""
hidden = true
[builtins.applications.actions] [[providers.prefixes]]
enabled = false prefix = "/"
hide_category = true provider = "providerlist"
[builtins.bookmarks] [[providers.prefixes]]
hidden = true
[[builtins.bookmarks.entries]]
label = "Omarchy - Github"
url = "https://github.com/basecamp/omarchy"
keywords = ["omarchy", "github"]
[[builtins.bookmarks.entries]]
label = "Omarchy Manual"
url = "https://manuals.omamix.org/2/the-omarchy-manual"
keywords = ["omarchy"]
[builtins.calc]
name = "Calculator"
icon = ""
min_chars = 3
prefix = "="
[builtins.windows]
switcher_only = true
hidden = true
[builtins.clipboard]
hidden = true
[builtins.commands]
hidden = true
[builtins.custom_commands]
hidden = true
[builtins.emojis]
name = "Emojis"
icon = ""
prefix = ":"
[builtins.symbols]
after_copy = ""
hidden = true
[builtins.finder]
use_fd = true
cmd_alt = "xdg-open $(dirname ~/%RESULT%)"
icon = "file"
name = "Finder"
preview_images = true
hidden = false
prefix = "." prefix = "."
provider = "files"
[builtins.runner] [[providers.prefixes]]
shell_config = "" prefix = ":"
switcher_only = true provider = "symbols"
hidden = true
[builtins.ssh] [[providers.prefixes]]
hidden = true prefix = "="
provider = "calc"
[builtins.websearch] [[providers.prefixes]]
switcher_only = true prefix = "@"
hidden = true provider = "websearch"
[builtins.translation] [[providers.prefixes]]
hidden = true prefix = "$"
provider = "clipboard"
[providers.actions] # This will be MERGED/OVEWRITTEN with what the user specifies
dmenu = [{ action = "select", default = true, bind = "Return" }]
providerlist = [
{ action = "activate", default = true, bind = "Return", after = "ClearReload" },
]
bluetooth = [
{ action = "find", global = true, bind = "ctrl f", after = "AsyncClearReload" },
{ action = "trust", bind = "ctrl t", after = "AsyncReload" },
{ action = "untrust", bind = "ctrl t", after = "AsyncReload" },
{ action = "pair", bind = "Return", after = "AsyncReload" },
{ action = "remove", bind = "ctrl d", after = "AsyncReload" },
{ action = "connect", bind = "Return", after = "AsyncReload" },
{ action = "disconnect", bind = "Return", after = "AsyncReload" },
]
archlinuxpkgs = [
{ action = "install", bind = "Return", default = true },
{ action = "remove", bind = "Return" },
]
calc = [
{ action = "copy", default = true, bind = "Return" },
{ action = "delete", bind = "ctrl d", after = "AsyncReload" },
{ action = "save", bind = "ctrl s", after = "AsyncClearReload" },
]
websearch = [
{ action = "search", default = true, bind = "Return" },
{ action = "erase_history", label = "clear hist", bind = "ctrl h", after = "Reload" },
]
desktopapplications = [
{ action = "start", default = true, bind = "Return" },
{ action = "start:keep", label = "open+next", bind = "shift Return", after = "KeepOpen" },
{ action = "erase_history", label = "clear hist", bind = "ctrl h", after = "AsyncReload" },
{ action = "pin", bind = "ctrl p", after = "AsyncReload" },
{ action = "unpin", bind = "ctrl p", after = "AsyncReload" },
{ action = "pinup", bind = "ctrl n", after = "AsyncReload" },
{ action = "pindown", bind = "ctrl m", after = "AsyncReload" },
]
files = [
{ action = "open", default = true, bind = "Return" },
{ action = "opendir", label = "open dir", bind = "ctrl Return" },
{ action = "copypath", label = "copy path", bind = "ctrl shift c" },
{ action = "copyfile", label = "copy file", bind = "ctrl c" },
]
todo = [
{ action = "save", default = true, bind = "Return", after = "ClearReload" },
{ action = "delete", bind = "ctrl d", after = "ClearReload" },
{ action = "active", bind = "Return", after = "ClearReload" },
{ action = "inactive", bind = "Return", after = "ClearReload" },
{ action = "done", bind = "ctrl f", after = "ClearReload" },
{ action = "clear", bind = "ctrl x", after = "ClearReload", global = true },
]
runner = [
{ action = "run", default = true, bind = "Return" },
{ action = "runterminal", label = "run in terminal", bind = "shift Return" },
{ action = "erase_history", label = "clear hist", bind = "ctrl h", after = "Reload" },
]
symbols = [
{ action = "run_cmd", label = "select", default = true, bind = "Return" },
{ action = "erase_history", label = "clear hist", bind = "ctrl h", after = "Reload" },
]
unicode = [
{ action = "run_cmd", label = "select", default = true, bind = "Return" },
{ action = "erase_history", label = "clear hist", bind = "ctrl h", after = "Reload" },
]
clipboard = [
{ action = "copy", default = true, bind = "Return" },
{ action = "remove", bind = "ctrl d", after = "ClearReload" },
{ action = "remove_all", global = true, label = "clear", bind = "ctrl shift d", after = "ClearReload" },
{ action = "toggle_images", global = true, label = "toggle images", bind = "ctrl i", after = "ClearReload" },
{ action = "edit", bind = "ctrl o" },
]

View File

@@ -61,7 +61,7 @@
"format": "{:L%A %H:%M}", "format": "{:L%A %H:%M}",
"format-alt": "{:L%d %B W%V %Y}", "format-alt": "{:L%d %B W%V %Y}",
"tooltip": false, "tooltip": false,
"on-click-right": "omarchy-cmd-tzupdate" "on-click-right": "omarchy-launch-floating-terminal-with-presentation omarchy-tz-select"
}, },
"network": { "network": {
"format-icons": ["󰤯", "󰤟", "󰤢", "󰤥", "󰤨"], "format-icons": ["󰤯", "󰤟", "󰤢", "󰤥", "󰤨"],
@@ -122,7 +122,7 @@
"modules": ["custom/expand-icon", "tray"] "modules": ["custom/expand-icon", "tray"]
}, },
"custom/expand-icon": { "custom/expand-icon": {
"format": " ", "format": "",
"tooltip": false "tooltip": false
}, },
"custom/screenrecording-indicator": { "custom/screenrecording-indicator": {
@@ -133,6 +133,6 @@
}, },
"tray": { "tray": {
"icon-size": 12, "icon-size": 12,
"spacing": 12 "spacing": 17
} }
} }

View File

@@ -7,7 +7,7 @@
border: none; border: none;
border-radius: 0; border-radius: 0;
min-height: 0; min-height: 0;
font-family: CaskaydiaMono Nerd Font; font-family: 'CaskaydiaMono Nerd Font';
font-size: 12px; font-size: 12px;
} }
@@ -30,11 +30,8 @@
opacity: 0.5; opacity: 0.5;
} }
#tray,
#cpu, #cpu,
#battery, #battery,
#network,
#bluetooth,
#pulseaudio, #pulseaudio,
#custom-omarchy, #custom-omarchy,
#custom-screenrecording-indicator, #custom-screenrecording-indicator,
@@ -43,8 +40,20 @@
margin: 0 7.5px; margin: 0 7.5px;
} }
#tray {
margin-right: 16px;
}
#bluetooth {
margin-right: 17px;
}
#network {
margin-right: 13px;
}
#custom-expand-icon { #custom-expand-icon {
margin-right: 7px; margin-right: 20px;
} }
tooltip { tooltip {

View File

@@ -12,3 +12,4 @@ source = ~/.local/share/omarchy/default/hypr/apps/steam.conf
source = ~/.local/share/omarchy/default/hypr/apps/system.conf source = ~/.local/share/omarchy/default/hypr/apps/system.conf
source = ~/.local/share/omarchy/default/hypr/apps/terminals.conf source = ~/.local/share/omarchy/default/hypr/apps/terminals.conf
source = ~/.local/share/omarchy/default/hypr/apps/walker.conf source = ~/.local/share/omarchy/default/hypr/apps/walker.conf
source = ~/.local/share/omarchy/default/hypr/apps/webcam-overlay.conf

View File

@@ -1,5 +1,5 @@
# Browser types # Browser types
windowrule = tag +chromium-based-browser, class:([cC]hrom(e|ium)|[bB]rave-browser|Microsoft-edge|Vivaldi-stable) windowrule = tag +chromium-based-browser, class:((google-)?[cC]hrom(e|ium)|[bB]rave-browser|Microsoft-edge|Vivaldi-stable|helium)
windowrule = tag +firefox-based-browser, class:([fF]irefox|zen|librewolf) windowrule = tag +firefox-based-browser, class:([fF]irefox|zen|librewolf)
# Force chromium-based browsers into a tile to deal with --app bug # Force chromium-based browsers into a tile to deal with --app bug

View File

@@ -5,6 +5,7 @@ windowrule = size 800 600, tag:floating-window
windowrule = tag +floating-window, class:(blueberry.py|Impala|Wiremix|org.gnome.NautilusPreviewer|com.gabm.satty|Omarchy|About|TUI.float) windowrule = tag +floating-window, class:(blueberry.py|Impala|Wiremix|org.gnome.NautilusPreviewer|com.gabm.satty|Omarchy|About|TUI.float)
windowrule = tag +floating-window, class:(xdg-desktop-portal-gtk|sublime_text|DesktopEditors|org.gnome.Nautilus), title:^(Open.*Files?|Open [F|f]older.*|Save.*Files?|Save.*As|Save|All Files) windowrule = tag +floating-window, class:(xdg-desktop-portal-gtk|sublime_text|DesktopEditors|org.gnome.Nautilus), title:^(Open.*Files?|Open [F|f]older.*|Save.*Files?|Save.*As|Save|All Files)
windowrule = float, class:org.gnome.Calculator
# Fullscreen screensaver # Fullscreen screensaver
windowrule = fullscreen, class:Screensaver windowrule = fullscreen, class:Screensaver

View File

@@ -0,0 +1,6 @@
# Webcam overlay for screen recording
windowrule = float, title:WebcamOverlay
windowrule = pin, title:WebcamOverlay
windowrule = noinitialfocus, title:WebcamOverlay
windowrule = nodim, title:WebcamOverlay
windowrule = move 100%-w-40 100%-w-40, title:WebcamOverlay # There's a typo in the hyprland rule so 100%-w on the height param is actually correct here

View File

@@ -1,10 +1,10 @@
exec-once = uwsm app -- hypridle exec-once = uwsm-app -- hypridle
exec-once = uwsm app -- mako exec-once = uwsm-app -- mako
exec-once = uwsm app -- waybar exec-once = uwsm-app -- waybar
exec-once = uwsm app -- fcitx5 exec-once = uwsm-app -- fcitx5
exec-once = uwsm app -- swaybg -i ~/.config/omarchy/current/background -m fill exec-once = uwsm-app -- swaybg -i ~/.config/omarchy/current/background -m fill
exec-once = uwsm app -- swayosd-server exec-once = uwsm-app -- swayosd-server
exec-once = uwsm app -- walker --gapplication-service &
exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
exec-once = wl-clip-persist --clipboard regular --all-mime-type-regex '^(?!x-kde-passwordManagerHint).+'
exec-once = omarchy-cmd-first-run exec-once = omarchy-cmd-first-run
exec-once = uwsm-app -- elephant
exec-once = uwsm-app -- walker --gapplication-service

View File

@@ -1,6 +1,6 @@
# Deprecated bindings file. New installations include everything directly. # Deprecated bindings file. New installations include everything directly.
bindd = SUPER, return, Terminal, exec, $terminal bindd = SUPER, RETURN, Terminal, exec, $terminal
bindd = SUPER, F, File manager, exec, $fileManager bindd = SUPER, F, File manager, exec, $fileManager
bindd = SUPER, B, Web browser, exec, $browser bindd = SUPER, B, Web browser, exec, $browser
bindd = SUPER, M, Music player, exec, $music bindd = SUPER, M, Music player, exec, $music
@@ -9,7 +9,7 @@ bindd = SUPER, T, Top, exec, $terminal -e btop
bindd = SUPER, D, Lazy Docker, exec, $terminal -e lazydocker bindd = SUPER, D, Lazy Docker, exec, $terminal -e lazydocker
bindd = SUPER, G, Messenger, exec, $messenger bindd = SUPER, G, Messenger, exec, $messenger
bindd = SUPER, O, Obsidian, exec, obsidian -disable-gpu bindd = SUPER, O, Obsidian, exec, obsidian -disable-gpu
bindd = SUPER, slash, Password manager, exec, $passwordManager bindd = SUPER, SLASH, Password manager, exec, $passwordManager
source = ~/.local/share/omarchy/default/hypr/bindings/media.conf source = ~/.local/share/omarchy/default/hypr/bindings/media.conf
source = ~/.local/share/omarchy/default/hypr/bindings/tiling.conf source = ~/.local/share/omarchy/default/hypr/bindings/tiling.conf

Some files were not shown because too many files have changed in this diff Show More