From 1eab0cffc9f6b0619a49cf15ca8413795814cefa Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 16 May 2026 20:34:09 +0200 Subject: [PATCH] Integrate swaybg and swayosd into the new shell --- AGENTS.md | 6 +- bin/omarchy | 3 +- bin/omarchy-audio-input-mute | 18 +- bin/omarchy-audio-output-switch | 44 +-- bin/omarchy-audio-output-volume | 63 +++++ bin/omarchy-audio-player | 28 ++ bin/omarchy-brightness-display | 6 +- bin/omarchy-brightness-display-apple | 2 +- bin/omarchy-brightness-keyboard | 5 +- bin/omarchy-first-run | 1 - bin/omarchy-font-set | 3 +- bin/omarchy-osd | 37 +++ bin/omarchy-refresh-swayosd | 7 - bin/omarchy-restart-swayosd | 9 - bin/omarchy-shell-ipc | 2 +- bin/omarchy-swayosd-brightness | 15 - bin/omarchy-swayosd-client | 6 - bin/omarchy-swayosd-kbd-brightness | 15 - bin/omarchy-theme-bg-set | 4 - bin/omarchy-theme-set | 2 +- bin/omarchy-toggle-touchpad | 4 +- bin/omarchy-toggle-touchscreen | 4 +- config/swayosd/config.toml | 4 - config/swayosd/style.css | 28 -- config/systemd/user/swayosd-server.service | 13 - default/hypr/autostart.lua | 3 +- default/hypr/bindings/media.lua | 20 +- default/omarchy-skill/SKILL.md | 8 +- default/omarchy/omarchy-menu.jsonc | 6 +- default/quickshell/omarchy-shell/README.md | 2 +- .../plugins/background/Background.qml | 259 ++++++++++++++++++ .../plugins/background/manifest.json | 11 + .../omarchy-shell/plugins/osd/Osd.qml | 140 ++++++++++ .../omarchy-shell/plugins/osd/manifest.json | 11 + .../omarchy-shell/shell-defaults.json | 73 +++-- default/quickshell/omarchy-shell/shell.qml | 3 +- default/themed/swayosd.css.tpl | 5 - install/first-run/swayosd.sh | 2 - install/omarchy-base.packages | 2 - migrations/1753138691.sh | 6 - migrations/1753224615.sh | 9 - migrations/1754390772.sh | 6 - migrations/1778171768.sh | 8 - migrations/1778743515.sh | 6 +- themes/last-horizon/swayosd.css | 30 -- themes/lumon/swayosd.css | 44 --- themes/retro-82/swayosd.css | 5 - themes/solitude/swayosd.css | 30 -- 48 files changed, 665 insertions(+), 353 deletions(-) create mode 100755 bin/omarchy-audio-output-volume create mode 100755 bin/omarchy-audio-player create mode 100755 bin/omarchy-osd delete mode 100755 bin/omarchy-refresh-swayosd delete mode 100755 bin/omarchy-restart-swayosd delete mode 100755 bin/omarchy-swayosd-brightness delete mode 100755 bin/omarchy-swayosd-client delete mode 100755 bin/omarchy-swayosd-kbd-brightness delete mode 100644 config/swayosd/config.toml delete mode 100644 config/swayosd/style.css delete mode 100644 config/systemd/user/swayosd-server.service create mode 100644 default/quickshell/omarchy-shell/plugins/background/Background.qml create mode 100644 default/quickshell/omarchy-shell/plugins/background/manifest.json create mode 100644 default/quickshell/omarchy-shell/plugins/osd/Osd.qml create mode 100644 default/quickshell/omarchy-shell/plugins/osd/manifest.json delete mode 100644 default/themed/swayosd.css.tpl delete mode 100644 install/first-run/swayosd.sh delete mode 100644 migrations/1753138691.sh delete mode 100644 migrations/1753224615.sh delete mode 100644 migrations/1754390772.sh delete mode 100644 migrations/1778171768.sh delete mode 100644 themes/last-horizon/swayosd.css delete mode 100644 themes/lumon/swayosd.css delete mode 100644 themes/retro-82/swayosd.css delete mode 100644 themes/solitude/swayosd.css diff --git a/AGENTS.md b/AGENTS.md index 89b16428..591d9a02 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,7 +31,7 @@ Common prefixes include: Other current prefixes include: -- `ac-`, `audio-`, `battery-`, `branch-`, `brightness-`, `channel-`, `config-`, `debug-`, `dev-`, `drive-`, `first-`, `font-`, `haptic-`, `hibernation-`, `hook-`, `hyprland-`, `menu-`, `migrate-`, `notification-`, `npx-`, `plymouth-`, `powerprofiles-`, `reinstall-`, `remove-`, `screensaver-`, `show-`, `snapshot-`, `state-`, `sudo-`, `swayosd-`, `system-`, `transcode-`, `tui-`, `tz-`, `upload-`, `version-`, `voxtype-`, `webapp-`, `wifi-`, `windows-` +- `ac-`, `audio-`, `battery-`, `branch-`, `brightness-`, `channel-`, `config-`, `debug-`, `dev-`, `drive-`, `first-`, `font-`, `haptic-`, `hibernation-`, `hook-`, `hyprland-`, `menu-`, `migrate-`, `notification-`, `npx-`, `plymouth-`, `powerprofiles-`, `reinstall-`, `remove-`, `screensaver-`, `show-`, `snapshot-`, `state-`, `sudo-`, `system-`, `transcode-`, `tui-`, `tz-`, `upload-`, `version-`, `voxtype-`, `webapp-`, `wifi-`, `windows-` # Command Metadata @@ -40,8 +40,6 @@ Commands in `bin/` can declare CLI metadata in comments near the top of the file Supported metadata keys: - `# omarchy:summary=...` - short help text -- `# omarchy:group=...` - command group when it differs from the filename-derived prefix -- `# omarchy:name=...` - command name within the group - `# omarchy:args=...` - usage arguments - `# omarchy:examples=...` - examples separated with ` | ` - `# omarchy:alias=...` / `# omarchy:aliases=...` - alternate routes @@ -109,7 +107,7 @@ The Quickshell desktop runs as a single long-running process out of not start additional standalone `quickshell -p` instances for individual components. -Run `omarchy restart shell` after making changes to QML files. +Run `omarchy-restart-shell` after making changes to QML files. Plugin contract: diff --git a/bin/omarchy b/bin/omarchy index f27c9630..4e801c38 100755 --- a/bin/omarchy +++ b/bin/omarchy @@ -27,6 +27,7 @@ declare -A BINARY_TO_KEY declare -A GROUP_DESCRIPTIONS GROUP_DESCRIPTIONS[ac]="AC power detection" +GROUP_DESCRIPTIONS[audio]="Audio input and output controls" GROUP_DESCRIPTIONS[battery]="Battery status helpers" GROUP_DESCRIPTIONS[branch]="Omarchy git branch management" GROUP_DESCRIPTIONS[branding]="About and screensaver branding" @@ -51,6 +52,7 @@ GROUP_DESCRIPTIONS[menu]="Omarchy menu commands" GROUP_DESCRIPTIONS[migrate]="Migration runner" GROUP_DESCRIPTIONS[notification]="Notification helpers" GROUP_DESCRIPTIONS[npx]="NPX package wrappers" +GROUP_DESCRIPTIONS[osd]="On-screen display status helpers" GROUP_DESCRIPTIONS[pkg]="Package management helpers" GROUP_DESCRIPTIONS[plymouth]="Plymouth boot theme management" GROUP_DESCRIPTIONS[powerprofiles]="Power profile management" @@ -64,7 +66,6 @@ GROUP_DESCRIPTIONS[screensaver]="Screensaver branding and animation" GROUP_DESCRIPTIONS[snapshot]="System snapshots" GROUP_DESCRIPTIONS[style]="Global UI style controls" GROUP_DESCRIPTIONS[sudo]="Sudo configuration helpers" -GROUP_DESCRIPTIONS[swayosd]="SwayOSD status display helpers" GROUP_DESCRIPTIONS[system]="Reboot, shutdown, logout, and lock" GROUP_DESCRIPTIONS[theme]="Theme management" GROUP_DESCRIPTIONS[toggle]="Toggle Omarchy features" diff --git a/bin/omarchy-audio-input-mute b/bin/omarchy-audio-input-mute index 19e12f23..554eae44 100755 --- a/bin/omarchy-audio-input-mute +++ b/bin/omarchy-audio-input-mute @@ -4,18 +4,10 @@ wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle >/dev/null -if pactl get-source-mute @DEFAULT_SOURCE@ | rg -q 'yes'; then - led=on - osd_message='Microphone muted' - osd_icon='microphone-sensitivity-muted-symbolic' +if wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | grep -q MUTED; then + omarchy-brightness-keyboard-mute on + omarchy-osd -i microphone-muted -m "Microphone muted" else - led=off - osd_message='Microphone on' - osd_icon='audio-input-microphone-symbolic' + omarchy-brightness-keyboard-mute off + omarchy-osd -i microphone -m "Microphone on" fi - -omarchy-brightness-keyboard-mute "$led" - -omarchy-swayosd-client \ - --custom-message "$osd_message" \ - --custom-icon "$osd_icon" diff --git a/bin/omarchy-audio-output-switch b/bin/omarchy-audio-output-switch index f5f94d44..d1ddf75f 100755 --- a/bin/omarchy-audio-output-switch +++ b/bin/omarchy-audio-output-switch @@ -2,16 +2,18 @@ # omarchy:summary=Switch between audio outputs while preserving the mute status. By default mapped to Super + Mute. +set -euo pipefail + sinks=$(pactl -f json list sinks | jq '[.[] | select((.ports | length == 0) or ([.ports[]? | .availability != "not available"] | any))]') -sinks_count=$(echo "$sinks" | jq '. | length') +sinks_count=$(jq 'length' <<<"$sinks") if (( sinks_count == 0 )); then - omarchy-swayosd-client --custom-message "No audio devices found" + omarchy-osd -m "No audio devices found" exit 1 fi current_sink_name=$(pactl get-default-sink) -current_sink_index=$(echo "$sinks" | jq -r --arg name "$current_sink_name" 'map(.name) | index($name)') +current_sink_index=$(jq -r --arg name "$current_sink_name" 'map(.name) | index($name)' <<<"$sinks") if [[ $current_sink_index != "null" ]]; then next_sink_index=$(((current_sink_index + 1) % sinks_count)) @@ -19,28 +21,13 @@ else next_sink_index=0 fi -next_sink=$(echo "$sinks" | jq -r ".[$next_sink_index]") -next_sink_name=$(echo "$next_sink" | jq -r '.name') +next_sink=$(jq -c ".[$next_sink_index]" <<<"$sinks") +next_sink_name=$(jq -r '.name' <<<"$next_sink") +next_sink_description=$(jq -r '.description // .properties."device.description" // .name' <<<"$next_sink") +next_sink_volume=$(jq -r '.volume | to_entries[0].value.value_percent | sub("%"; "") | tonumber' <<<"$next_sink") +next_sink_is_muted=$(jq -r '.mute' <<<"$next_sink") -next_sink_description=$(echo "$next_sink" | jq -r '.description') -if [[ $next_sink_description == "(null)" ]] || [[ $next_sink_description == "null" ]] || [[ -z $next_sink_description ]]; then - # For Bluetooth devices, the friendly name is on the Device entry (device.id), not the Sink entry (object.id) - device_id=$(echo "$next_sink" | jq -r '.properties."device.id"') - if [[ $device_id != "null" ]] && [[ -n $device_id ]]; then - next_sink_description=$(wpctl status | grep -E "^\s*│?\s+${device_id}\." | sed -E 's/^.*[0-9]+\.\s+//' | sed -E 's/\s+\[.*$//') - fi - # Fall back to object.id lookup if device.id didn't yield a result - if [[ -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 -fi - -next_sink_volume=$(echo "$next_sink" | jq -r \ - '.volume | to_entries[0].value.value_percent | sub("%"; "")') -next_sink_is_muted=$(echo "$next_sink" | jq -r '.mute') - -if [[ $next_sink_is_muted = "true" ]] || (( next_sink_volume == 0 )); then +if [[ $next_sink_is_muted == "true" ]] || (( next_sink_volume == 0 )); then icon_state="muted" elif (( next_sink_volume <= 33 )); then icon_state="low" @@ -50,13 +37,8 @@ else icon_state="high" fi -next_sink_volume_icon="sink-volume-${icon_state}-symbolic" - if [[ $next_sink_name != $current_sink_name ]]; then - next_sink_wpid=$(echo "$next_sink" | jq -r '.properties."object.id"') - wpctl set-default "$next_sink_wpid" + pactl set-default-sink "$next_sink_name" fi -omarchy-swayosd-client \ - --custom-message "$next_sink_description" \ - --custom-icon "$next_sink_volume_icon" +omarchy-osd -i "volume-${icon_state}" -m "$next_sink_description" diff --git a/bin/omarchy-audio-output-volume b/bin/omarchy-audio-output-volume new file mode 100755 index 00000000..92725c92 --- /dev/null +++ b/bin/omarchy-audio-output-volume @@ -0,0 +1,63 @@ +#!/bin/bash + +# omarchy:summary=Adjust output volume and show the Omarchy OSD +# omarchy:args= +# omarchy:examples=omarchy audio output volume raise | omarchy audio output volume lower | omarchy audio output volume mute-toggle | omarchy audio output volume +1 + +set -euo pipefail + +action="${1:-}" + +if [[ -z $action ]]; then + echo "Usage: omarchy-audio-output-volume " + exit 1 +fi + +volume_state() { + wpctl get-volume @DEFAULT_AUDIO_SINK@ +} + +volume_percent() { + volume_state | awk '{ for (i=1; i<=NF; i++) if ($i ~ /^[0-9.]+$/) print int($i * 100) }' +} + +volume_muted() { + volume_state | grep -q MUTED +} + +case "$action" in + raise) action="+5" ;; + lower) action="-5" ;; +esac + +if [[ $action == "mute-toggle" ]]; then + runtime_dir="${XDG_RUNTIME_DIR:-/tmp}" + debounce_file="$runtime_dir/omarchy-audio-output-volume-mute-toggle.last" + now=$(date +%s%3N) + last=0 + [[ -r $debounce_file ]] && read -r last < "$debounce_file" || true + if (( now - last < 250 )); then + exit 0 + fi + printf '%s\n' "$now" > "$debounce_file" + + wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle >/dev/null +elif [[ $action == +* ]]; then + step="${action#+}" + wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ "${step}%+" +elif [[ $action == -* ]]; then + step="${action#-}" + wpctl set-volume @DEFAULT_AUDIO_SINK@ "${step}%-" +else + echo "Unknown volume action: $action" + exit 1 +fi + +percent=$(volume_percent) +if volume_muted || (( percent == 0 )); then + icon="volume-muted" +else + icon="volume-high" +fi + +omarchy-osd -i "$icon" -p "$percent" diff --git a/bin/omarchy-audio-player b/bin/omarchy-audio-player new file mode 100755 index 00000000..9766c4fa --- /dev/null +++ b/bin/omarchy-audio-player @@ -0,0 +1,28 @@ +#!/bin/bash + +# omarchy:summary=Control media playback and show the Omarchy OSD +# omarchy:args= +# omarchy:examples=omarchy audio player next | omarchy audio player play-pause + +set -euo pipefail + +action="${1:-play-pause}" + +playerctl "$action" >/dev/null 2>&1 || true +sleep 0.05 + +message=$(playerctl metadata --format '{{title}}' 2>/dev/null || true) +if [[ -z $message ]]; then + message=$(playerctl metadata --format '{{playerName}}' 2>/dev/null || true) +fi +if [[ -z $message ]]; then + case "$action" in + next) message="Next track" ;; + previous) message="Previous track" ;; + play) message="Playing" ;; + pause) message="Paused" ;; + *) message="Play/pause" ;; + esac +fi + +omarchy-osd -i media -m "$message" diff --git a/bin/omarchy-brightness-display b/bin/omarchy-brightness-display index ffeb3caa..fc6a8a4f 100755 --- a/bin/omarchy-brightness-display +++ b/bin/omarchy-brightness-display @@ -17,7 +17,7 @@ fi runtime_dir="${XDG_RUNTIME_DIR:-/tmp}" # Drop overlapping brightness key events so concurrent invocations do not race. -# Hardware key repeat present on some devices can otherwise glitch SwayOSD rendering. +# Hardware key repeat present on some devices can otherwise glitch OSD rendering. exec 9>"$runtime_dir/omarchy-brightness-display.lock" flock -n 9 || exit 0 @@ -64,5 +64,5 @@ fi # Set the actual brightness of the display device. brightnessctl -d "$device" set "$step" >/dev/null -# Use SwayOSD to display the new brightness setting. -omarchy-swayosd-brightness "$(brightnessctl -d "$device" -m | cut -d',' -f4 | tr -d '%')" +# Use the OSD to display the new brightness setting. +omarchy-osd -i brightness -p "$(brightnessctl -d "$device" -m | cut -d',' -f4 | tr -d '%')" diff --git a/bin/omarchy-brightness-display-apple b/bin/omarchy-brightness-display-apple index 480b9fe7..912538b6 100755 --- a/bin/omarchy-brightness-display-apple +++ b/bin/omarchy-brightness-display-apple @@ -30,5 +30,5 @@ else sudo asdcontrol "$device" -- "$step" >/dev/null value="$(sudo asdcontrol "$device" | awk -F= '/BRIGHTNESS=/{print $2+0}')" - omarchy-swayosd-brightness "$(( value * 100 / 60000 ))" + omarchy-osd -i brightness -p "$(( value * 100 / 60000 ))" fi diff --git a/bin/omarchy-brightness-keyboard b/bin/omarchy-brightness-keyboard index 7e5febe6..e680530f 100755 --- a/bin/omarchy-brightness-keyboard +++ b/bin/omarchy-brightness-keyboard @@ -49,7 +49,4 @@ fi # Set the new brightness. brightnessctl -d "$device" set "$new_brightness" >/dev/null - -# Use SwayOSD to display the new brightness setting. -percent=$((new_brightness * 100 / max_brightness)) -omarchy-swayosd-kbd-brightness "$percent" +omarchy-osd -i keyboard -p "$(( new_brightness * 100 / max_brightness ))" diff --git a/bin/omarchy-first-run b/bin/omarchy-first-run index 97b41f80..9f48eb3d 100755 --- a/bin/omarchy-first-run +++ b/bin/omarchy-first-run @@ -17,7 +17,6 @@ if [[ -f $FIRST_RUN_MODE ]]; then bash "$OMARCHY_PATH/install/first-run/dns-resolver.sh" bash "$OMARCHY_PATH/install/first-run/gnome-theme.sh" bash "$OMARCHY_PATH/install/first-run/gdk-scale.sh" - bash "$OMARCHY_PATH/install/first-run/swayosd.sh" bash "$OMARCHY_PATH/install/first-run/gtk-primary-paste.sh" bash "$OMARCHY_PATH/install/first-run/elephant.sh" omarchy-hook-install post-update "$OMARCHY_PATH/install/first-run/install-voxtype.hook" diff --git a/bin/omarchy-font-set b/bin/omarchy-font-set index 36a2babd..920625d7 100755 --- a/bin/omarchy-font-set +++ b/bin/omarchy-font-set @@ -27,7 +27,6 @@ if [[ -n $font_name ]]; then fi sed -i "s/font_family = .*/font_family = $font_name/g" ~/.config/hypr/hyprlock.conf - sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/swayosd/style.css # fontconfig is the canonical source of truth — the omarchy shell, Qt # apps, and anything else that resolves "monospace" all read from here. @@ -36,7 +35,7 @@ if [[ -n $font_name ]]; then -v "$font_name" \ ~/.config/fontconfig/fonts.conf - omarchy-restart-swayosd + omarchy-restart-shell if pgrep -x ghostty; then notify-send -a omarchy-action -u low " You must restart Ghostty to see font change" diff --git a/bin/omarchy-osd b/bin/omarchy-osd new file mode 100755 index 00000000..3090bd87 --- /dev/null +++ b/bin/omarchy-osd @@ -0,0 +1,37 @@ +#!/bin/bash + +# omarchy:summary=Show the Omarchy Quickshell on-screen display +# omarchy:args=[-i|--icon ] [-m|--message ] [-p|--progress <0-100>] +# omarchy:examples=omarchy osd -i brightness -p 50 | omarchy osd -m "Hello" + +set -euo pipefail + +icon="" +message="" +progress="" +progress_text="" +max="100" + +while (($#)); do + case $1 in + -i|--icon) icon="${2:-}"; shift 2 ;; + -m|--message) message="${2:-}"; shift 2 ;; + -p|--progress) progress="${2:-}"; shift 2 ;; + -h|--help) omarchy osd --help; exit 0 ;; + *) echo "Unknown OSD option: $1" >&2; exit 1 ;; + esac +done + +if [[ -n $progress ]]; then + progress_text="${progress}%" +fi + +payload=$(jq -cn \ + --arg icon "$icon" \ + --arg message "$message" \ + --arg value "$progress" \ + --arg progressText "$progress_text" \ + --arg max "$max" \ + '{icon:$icon,message:$message,value:$value,progressText:$progressText,max:$max}') + +omarchy-shell-ipc osd show "$payload" >/dev/null 2>&1 || true diff --git a/bin/omarchy-refresh-swayosd b/bin/omarchy-refresh-swayosd deleted file mode 100755 index 65820784..00000000 --- a/bin/omarchy-refresh-swayosd +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# omarchy:summary=Overwrite the user configs for swayosd (controls on-screen feedback for changing volume/songs etc) with the Omarchy defaults and restart the service. - -omarchy-refresh-config swayosd/config.toml -omarchy-refresh-config swayosd/style.css -omarchy-restart-swayosd diff --git a/bin/omarchy-restart-swayosd b/bin/omarchy-restart-swayosd deleted file mode 100755 index 06b3204f..00000000 --- a/bin/omarchy-restart-swayosd +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# omarchy:summary=Restart the SwayOSD server - -systemctl --user daemon-reload -systemctl --user stop swayosd-server.service || true -pkill -x swayosd-server || true -systemctl --user reset-failed swayosd-server.service || true -systemctl --user enable --now swayosd-server.service diff --git a/bin/omarchy-shell-ipc b/bin/omarchy-shell-ipc index d6d60de9..0de6af33 100755 --- a/bin/omarchy-shell-ipc +++ b/bin/omarchy-shell-ipc @@ -59,4 +59,4 @@ else } 9>"$lockfile" fi -exec quickshell ipc -p "$SHELL_DIR" call "$@" +exec quickshell ipc -p "$SHELL_DIR" call -- "$@" diff --git a/bin/omarchy-swayosd-brightness b/bin/omarchy-swayosd-brightness deleted file mode 100755 index 3a533085..00000000 --- a/bin/omarchy-swayosd-brightness +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# omarchy:summary=Display brightness level using SwayOSD on the current monitor. -# omarchy:args=<0-100> -# omarchy:examples=omarchy swayosd brightness 0 | omarchy swayosd brightness 50 | omarchy swayosd brightness 100 - -percent="$1" - -progress="$(awk -v p="$percent" 'BEGIN{printf "%.2f", p/100}')" -[[ $progress == "0.00" ]] && progress="0.01" - -omarchy-swayosd-client \ - --custom-icon display-brightness-symbolic \ - --custom-progress "$progress" \ - --custom-progress-text "$(printf '%3d%%' "$percent")" diff --git a/bin/omarchy-swayosd-client b/bin/omarchy-swayosd-client deleted file mode 100755 index e8343aaa..00000000 --- a/bin/omarchy-swayosd-client +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -# omarchy:summary=Wrapper for swayosd-client that targets the currently focused monitor. -# omarchy:args= - -exec swayosd-client --monitor "$(omarchy-hyprland-monitor-focused)" "$@" diff --git a/bin/omarchy-swayosd-kbd-brightness b/bin/omarchy-swayosd-kbd-brightness deleted file mode 100755 index 52e7959a..00000000 --- a/bin/omarchy-swayosd-kbd-brightness +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# omarchy:summary=Display keyboard brightness level using SwayOSD on the current monitor. -# omarchy:args=<0-100> -# omarchy:examples=omarchy swayosd kbd brightness 0 | omarchy swayosd kbd brightness 50 | omarchy swayosd kbd brightness 100 - -percent="$1" - -progress="$(awk -v p="$percent" 'BEGIN{printf "%.2f", p/100}')" -[[ $progress == "0.00" ]] && progress="0.01" - -omarchy-swayosd-client \ - --custom-icon keyboard-brightness-symbolic \ - --custom-progress "$progress" \ - --custom-progress-text "${percent}%" diff --git a/bin/omarchy-theme-bg-set b/bin/omarchy-theme-bg-set index 803bea36..6eb03b98 100755 --- a/bin/omarchy-theme-bg-set +++ b/bin/omarchy-theme-bg-set @@ -19,7 +19,3 @@ fi # Create symlink to the new background ln -nsf "$BACKGROUND" "$CURRENT_BACKGROUND_LINK" - -# Kill existing swaybg and start new one -pkill -x swaybg -setsid uwsm-app -- swaybg -i "$CURRENT_BACKGROUND_LINK" -m fill >/dev/null 2>&1 & diff --git a/bin/omarchy-theme-set b/bin/omarchy-theme-set index 4b61fc43..64cc1e6a 100755 --- a/bin/omarchy-theme-set +++ b/bin/omarchy-theme-set @@ -59,7 +59,7 @@ mv "$NEXT_THEME_PATH" "$CURRENT_THEME_PATH" echo "$THEME_NAME" >"$HOME/.config/omarchy/current/theme.name" post_theme_commands=( - omarchy-restart-swayosd + omarchy-restart-shell omarchy-restart-terminal omarchy-restart-hyprctl omarchy-restart-btop diff --git a/bin/omarchy-toggle-touchpad b/bin/omarchy-toggle-touchpad index 15ad4ca5..3ab72616 100755 --- a/bin/omarchy-toggle-touchpad +++ b/bin/omarchy-toggle-touchpad @@ -15,14 +15,14 @@ fi enable() { hyprctl eval "hl.device({ name = \"$device\", enabled = true })" >/dev/null rm -f "$STATE_FILE" - omarchy-swayosd-client --custom-icon input-touchpad-symbolic --custom-message "Touchpad enabled" + omarchy-osd -i touchpad -m "Touchpad enabled" } disable() { hyprctl eval "hl.device({ name = \"$device\", enabled = false })" >/dev/null mkdir -p "$(dirname "$STATE_FILE")" printf 'hl.device({ name = "%s", enabled = false })\n' "$device" >"$STATE_FILE" - omarchy-swayosd-client --custom-icon touchpad-disabled-symbolic --custom-message "Touchpad disabled" + omarchy-osd -i touchpad -m "Touchpad disabled" } case "${1:-toggle}" in diff --git a/bin/omarchy-toggle-touchscreen b/bin/omarchy-toggle-touchscreen index 7225c793..45b1284f 100755 --- a/bin/omarchy-toggle-touchscreen +++ b/bin/omarchy-toggle-touchscreen @@ -15,14 +15,14 @@ fi enable() { hyprctl eval "hl.device({ name = \"$device\", enabled = true })" >/dev/null rm -f "$STATE_FILE" - omarchy-swayosd-client --custom-icon device-support-touch-symbolic --custom-message "Touchscreen enabled" + omarchy-osd -i touch -m "Touchscreen enabled" } disable() { hyprctl eval "hl.device({ name = \"$device\", enabled = false })" >/dev/null mkdir -p "$(dirname "$STATE_FILE")" printf 'hl.device({ name = "%s", enabled = false })\n' "$device" >"$STATE_FILE" - omarchy-swayosd-client --custom-icon touch-disabled-symbolic --custom-message "Touchscreen disabled" + omarchy-osd -i touch -m "Touchscreen disabled" } case "${1:-toggle}" in diff --git a/config/swayosd/config.toml b/config/swayosd/config.toml deleted file mode 100644 index 759cbe1f..00000000 --- a/config/swayosd/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[server] -show_percentage = true -max_volume = 100 -style = "~/.config/swayosd/style.css" diff --git a/config/swayosd/style.css b/config/swayosd/style.css deleted file mode 100644 index b95ab9f3..00000000 --- a/config/swayosd/style.css +++ /dev/null @@ -1,28 +0,0 @@ -@import "../omarchy/current/theme/swayosd.css"; - -window { - border-radius: 0; - opacity: 0.97; - border: 2px solid @border-color; - - background-color: @background-color; -} - -label { - font-family: 'JetBrainsMono Nerd Font'; - font-size: 11pt; - - color: @label; -} - -image { - color: @image; -} - -progressbar { - border-radius: 0; -} - -progress { - background-color: @progress; -} diff --git a/config/systemd/user/swayosd-server.service b/config/systemd/user/swayosd-server.service deleted file mode 100644 index 55c7f9c2..00000000 --- a/config/systemd/user/swayosd-server.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=SwayOSD server -PartOf=graphical-session.target -After=graphical-session.target - -[Service] -Type=simple -ExecStart=/usr/bin/swayosd-server -Restart=always -RestartSec=2 - -[Install] -WantedBy=graphical-session.target diff --git a/default/hypr/autostart.lua b/default/hypr/autostart.lua index dab4d2da..5d241cd7 100644 --- a/default/hypr/autostart.lua +++ b/default/hypr/autostart.lua @@ -1,8 +1,7 @@ hl.on("hyprland.start", function() - hl.exec_cmd("uwsm-app -- hypridle") hl.exec_cmd("omarchy-restart-shell") + hl.exec_cmd("uwsm-app -- hypridle") hl.exec_cmd("uwsm-app -- fcitx5 --disable notificationitem") - hl.exec_cmd("uwsm-app -- swaybg -i ~/.config/omarchy/current/background -m fill") hl.exec_cmd("/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1") hl.exec_cmd("omarchy-first-run") hl.exec_cmd("omarchy-powerprofiles-init") diff --git a/default/hypr/bindings/media.lua b/default/hypr/bindings/media.lua index 5c2b3ccd..71e92a4d 100644 --- a/default/hypr/bindings/media.lua +++ b/default/hypr/bindings/media.lua @@ -1,8 +1,8 @@ -- Volume, brightness, keyboard backlight, and touchpad controls. -o.bind("XF86AudioRaiseVolume", "Volume up", "omarchy-swayosd-client --output-volume raise", { locked = true, repeating = true }) -o.bind("XF86AudioLowerVolume", "Volume down", "omarchy-swayosd-client --output-volume lower", { locked = true, repeating = true }) -o.bind("XF86AudioMute", "Mute", "omarchy-swayosd-client --output-volume mute-toggle", { locked = true, repeating = true }) -o.bind("XF86AudioMicMute", "Mute microphone", "omarchy-audio-input-mute", { locked = true, repeating = true }) +o.bind("XF86AudioRaiseVolume", "Volume up", "omarchy-audio-output-volume raise", { locked = true, repeating = true }) +o.bind("XF86AudioLowerVolume", "Volume down", "omarchy-audio-output-volume lower", { locked = true, repeating = true }) +o.bind("XF86AudioMute", "Mute", "omarchy-audio-output-volume mute-toggle", { locked = true }) +o.bind("XF86AudioMicMute", "Mute microphone", "omarchy-audio-input-mute", { locked = true }) o.bind("XF86MonBrightnessUp", "Brightness up", "omarchy-brightness-display +5%", { locked = true, repeating = true }) o.bind("XF86MonBrightnessDown", "Brightness down", "omarchy-brightness-display 5%-", { locked = true, repeating = true }) o.bind("SHIFT + XF86MonBrightnessUp", "Brightness maximum", "omarchy-brightness-display 100%", { locked = true, repeating = true }) @@ -15,15 +15,15 @@ o.bind("XF86TouchpadOn", "Enable touchpad", "omarchy-toggle-touchpad on", { lock o.bind("XF86TouchpadOff", "Disable touchpad", "omarchy-toggle-touchpad off", { locked = true }) -- Precise volume and brightness controls. -o.bind("ALT + XF86AudioRaiseVolume", "Volume up precise", "omarchy-swayosd-client --output-volume +1", { locked = true, repeating = true }) -o.bind("ALT + XF86AudioLowerVolume", "Volume down precise", "omarchy-swayosd-client --output-volume -1", { locked = true, repeating = true }) +o.bind("ALT + XF86AudioRaiseVolume", "Volume up precise", "omarchy-audio-output-volume +1", { locked = true, repeating = true }) +o.bind("ALT + XF86AudioLowerVolume", "Volume down precise", "omarchy-audio-output-volume -1", { locked = true, repeating = true }) o.bind("ALT + XF86MonBrightnessUp", "Brightness up precise", "omarchy-brightness-display +1%", { locked = true, repeating = true }) o.bind("ALT + XF86MonBrightnessDown", "Brightness down precise", "omarchy-brightness-display 1%-", { locked = true, repeating = true }) -- Media controls. -o.bind("XF86AudioNext", "Next track", "omarchy-swayosd-client --playerctl next", { locked = true }) -o.bind("XF86AudioPause", "Pause", "omarchy-swayosd-client --playerctl play-pause", { locked = true }) -o.bind("XF86AudioPlay", "Play", "omarchy-swayosd-client --playerctl play-pause", { locked = true }) -o.bind("XF86AudioPrev", "Previous track", "omarchy-swayosd-client --playerctl previous", { locked = true }) +o.bind("XF86AudioNext", "Next track", "omarchy-audio-player next", { locked = true }) +o.bind("XF86AudioPause", "Pause", "omarchy-audio-player play-pause", { locked = true }) +o.bind("XF86AudioPlay", "Play", "omarchy-audio-player play-pause", { locked = true }) +o.bind("XF86AudioPrev", "Previous track", "omarchy-audio-player previous", { locked = true }) o.bind("SUPER + XF86AudioMute", "Switch audio output", "omarchy-audio-output-switch", { locked = true }) diff --git a/default/omarchy-skill/SKILL.md b/default/omarchy-skill/SKILL.md index 9bb1ea03..422871c0 100644 --- a/default/omarchy-skill/SKILL.md +++ b/default/omarchy-skill/SKILL.md @@ -79,7 +79,7 @@ Omarchy is built on: | **Omarchy shell** | Status bar + notifications (Quickshell) | `~/.config/omarchy/shell.json` | | **Walker** | App launcher | `~/.config/walker/` | | **Alacritty/Foot/Kitty/Ghostty** | Terminals | `~/.config//` | -| **SwayOSD** | On-screen display | `~/.config/swayosd/` | +| **Omarchy OSD** | On-screen display | Quickshell plugin | ## Command Discovery @@ -111,7 +111,7 @@ Run `omarchy --help` for the full list. The most common groups: | Group | Purpose | Example | |-------|---------|---------| | `omarchy refresh` | Reset config to defaults (backs up first) | `omarchy refresh shell` | -| `omarchy restart` | Restart a service/app | `omarchy restart shell` | +| `omarchy restart` | Restart a service/app | `omarchy-restart-shell` | | `omarchy toggle` | Toggle feature on/off | `omarchy toggle nightlight` | | `omarchy theme` | Theme management | `omarchy theme set ` | | `omarchy install` | Install optional software / packages | `omarchy install docker dbs` | @@ -160,7 +160,7 @@ inside a single long-running Quickshell process (`omarchy-shell`). The shell hot-reloads `shell.json` on save — no restart needed for layout changes. For more invasive changes (new plugin, packaged update): -**Commands:** `omarchy restart shell`, `omarchy refresh shell`, `omarchy launch settings` +**Commands:** `omarchy-restart-shell`, `omarchy refresh shell`, `omarchy launch settings` ### Terminals @@ -201,7 +201,7 @@ cp ~/.config/hypr/bindings.conf ~/.config/hypr/bindings.conf.bak.$(date +%s) # 4. Apply changes # - Hyprland: auto-reloads on save, but MUST validate with `hyprctl reload` and `hyprctl configerrors` -# - Omarchy shell: shell.json hot-reloads; use `omarchy restart shell` for plugin/widget code changes +# - Omarchy shell: shell.json hot-reloads; use `omarchy-restart-shell` for plugin/widget code changes # - Walker: MUST restart with `omarchy restart walker` # - Terminals: MUST restart with `omarchy restart terminal` ``` diff --git a/default/omarchy/omarchy-menu.jsonc b/default/omarchy/omarchy-menu.jsonc index fbe24ae9..cae68e52 100644 --- a/default/omarchy/omarchy-menu.jsonc +++ b/default/omarchy/omarchy-menu.jsonc @@ -164,7 +164,7 @@ "setup.config.hypridle": {"icon":"","label":"Hypridle","keywords":"idle","action":"omarchy-launch-config-editor ~/.config/hypr/hypridle.conf && omarchy-restart-hypridle"}, "setup.config.hyprlock": {"icon":"","label":"Hyprlock","keywords":"lock","action":"omarchy-launch-config-editor ~/.config/hypr/hyprlock.conf"}, "setup.config.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"night light","action":"omarchy-launch-config-editor ~/.config/hypr/hyprsunset.conf && omarchy-restart-hyprsunset"}, - "setup.config.swayosd": {"icon":"","label":"Swayosd","action":"omarchy-launch-config-editor ~/.config/swayosd/config.toml && omarchy-restart-swayosd"}, + "setup.config.osd": {"icon":"","label":"OSD","action":"omarchy launch settings"}, "setup.config.walker": {"icon":"󰌧","label":"Walker","keywords":"launcher","action":"omarchy-launch-config-editor ~/.config/walker/config.toml && omarchy-restart-walker"}, "setup.config.bar": {"icon":"󰍜","label":"Bar","keywords":"quickshell shell config","action":"omarchy-launch-settings bar"}, "setup.config.xcompose": {"icon":"󰞅","label":"XCompose","keywords":"compose key","action":"omarchy-launch-config-editor ~/.XCompose && omarchy-restart-xcompose"}, @@ -311,7 +311,7 @@ "update.channel.dev": {"icon":"🔴","label":"Dev","keywords":"development","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set dev'"}, "update.process.hypridle": {"icon":"","label":"Hypridle","keywords":"restart","action":"omarchy-restart-hypridle"}, "update.process.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"restart","action":"omarchy-restart-hyprsunset"}, - "update.process.swayosd": {"icon":"","label":"Swayosd","keywords":"restart","action":"omarchy-restart-swayosd"}, + "update.process.osd": {"icon":"","label":"OSD","keywords":"restart","action":"omarchy-restart-shell"}, "update.process.walker": {"icon":"󰌧","label":"Walker","keywords":"restart launcher","action":"omarchy-restart-walker"}, "update.process.shell": {"icon":"󰍜","label":"Shell","keywords":"restart bar quickshell omarchy-shell","action":"omarchy-restart-shell"}, "update.config.hyprland": {"icon":"","label":"Hyprland","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-hyprland"}, @@ -319,7 +319,7 @@ "update.config.hyprlock": {"icon":"","label":"Hyprlock","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-hyprlock"}, "update.config.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-hyprsunset"}, "update.config.plymouth": {"icon":"󱣴","label":"Plymouth","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-plymouth"}, - "update.config.swayosd": {"icon":"","label":"Swayosd","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-swayosd"}, + "update.config.osd": {"icon":"","label":"OSD","keywords":"refresh","action":"omarchy-restart-shell"}, "update.config.tmux": {"icon":"","label":"Tmux","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-tmux"}, "update.config.walker": {"icon":"󰌧","label":"Walker","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-walker"}, "update.config.shell": {"icon":"󰍜","label":"Shell","keywords":"refresh bar quickshell","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-shell"}, diff --git a/default/quickshell/omarchy-shell/README.md b/default/quickshell/omarchy-shell/README.md index a3115af9..3890285d 100644 --- a/default/quickshell/omarchy-shell/README.md +++ b/default/quickshell/omarchy-shell/README.md @@ -121,7 +121,7 @@ quickshell ipc -p $OMARCHY_PATH/default/quickshell/omarchy-shell call shell ping ``` Hyprland starts the shell through `omarchy-restart-shell` on boot. -Use `omarchy restart shell` to reload the long-running shell process. +Use `omarchy-restart-shell` to reload the long-running shell process. A convenience wrapper, [`omarchy-shell-ipc`](../../../bin/omarchy-shell-ipc), starts the shell if it is not already running, then forwards a `call`. It diff --git a/default/quickshell/omarchy-shell/plugins/background/Background.qml b/default/quickshell/omarchy-shell/plugins/background/Background.qml new file mode 100644 index 00000000..40edefe0 --- /dev/null +++ b/default/quickshell/omarchy-shell/plugins/background/Background.qml @@ -0,0 +1,259 @@ +import Quickshell +import Quickshell.Io +import Quickshell.Wayland +import QtQuick + +Item { + id: root + + property string omarchyPath: "" + property var shell: null + property var manifest: null + + readonly property string home: Quickshell.env("HOME") + readonly property string currentBackgroundLink: home + "/.config/omarchy/current/background" + + property string currentBackground: "" + property string displayedBackground: "" + property string incomingBackground: "" + property string oldBackground: "" + property bool finishingTransition: false + property int backgroundVersion: 0 + property real revealProgress: 1 + + function imageUrl(path) { + if (!path) return "" + return "file://" + path + } + + function refreshBackground() { + if (!readlinkProc.running) readlinkProc.running = true + } + + function setBackground(path) { + path = String(path || "").trim() + if (!path || path === currentBackground) return + currentBackground = path + backgroundVersion += 1 + + if (!displayedBackground) { + displayedBackground = path + revealProgress = 1 + return + } + + revealAnimation.stop() + finishingTransition = false + oldBackground = displayedBackground + incomingBackground = path + revealProgress = 0 + } + + function openSelector() { + if (!bgSwitchProc.running) bgSwitchProc.running = true + } + + Process { + id: bgSwitchProc + command: ["bash", "-lc", "background=$(omarchy-theme-bg-switcher); [[ -n $background ]] && omarchy-theme-bg-set \"$background\""] + onExited: root.refreshBackground() + } + + Process { + id: readlinkProc + command: ["readlink", "-f", root.currentBackgroundLink] + stdout: StdioCollector { + onStreamFinished: root.setBackground(String(text || "").trim()) + } + } + + Timer { + interval: 100 + running: true + repeat: true + onTriggered: root.refreshBackground() + } + + NumberAnimation { + id: revealAnimation + target: root + property: "revealProgress" + from: 0 + to: 1 + duration: 420 + easing.type: Easing.InOutCubic + onFinished: { + if (root.incomingBackground) { + root.displayedBackground = root.incomingBackground + root.finishingTransition = true + } + root.revealProgress = 1 + } + } + + Component.onCompleted: refreshBackground() + + Variants { + model: Quickshell.screens + + PanelWindow { + id: panel + required property var modelData + + screen: modelData + visible: true + anchors { top: true; bottom: true; left: true; right: true } + color: "transparent" + property bool maskReady: false + WlrLayershell.namespace: "omarchy-background" + WlrLayershell.layer: WlrLayer.Background + WlrLayershell.keyboardFocus: WlrKeyboardFocus.None + exclusionMode: ExclusionMode.Ignore + + Image { + id: base + anchors.fill: parent + source: root.imageUrl(root.displayedBackground) + fillMode: Image.PreserveAspectCrop + asynchronous: true + cache: false + onStatusChanged: { + if (status === Image.Ready && root.finishingTransition) { + root.incomingBackground = "" + root.oldBackground = "" + root.finishingTransition = false + } + } + } + + Image { + id: incomingFrame + anchors.fill: parent + source: root.imageUrl(root.incomingBackground) + fillMode: Image.PreserveAspectCrop + asynchronous: true + cache: false + visible: root.incomingBackground !== "" && status === Image.Ready + opacity: root.revealProgress >= 1 ? 1 : 0.001 + onStatusChanged: if (status === Image.Ready && root.incomingBackground) revealCanvas.prepareImage() + } + + Image { + id: oldFrame + anchors.fill: parent + source: root.imageUrl(root.oldBackground) + fillMode: Image.PreserveAspectCrop + asynchronous: true + cache: false + visible: root.oldBackground !== "" && root.revealProgress < 1 + onStatusChanged: if (status === Image.Ready && root.incomingBackground) revealCanvas.requestPaint() + } + + Canvas { + id: revealCanvas + anchors.fill: parent + visible: root.incomingBackground !== "" && root.revealProgress < 1 && incomingFrame.status === Image.Ready && oldFrame.status === Image.Ready + opacity: panel.maskReady ? 1 : 0 + renderTarget: Canvas.FramebufferObject + renderStrategy: Canvas.Immediate + + readonly property real slant: -0.18 + + function prepareImage() { + var src = root.imageUrl(root.incomingBackground) + if (!src) return + if (isImageLoaded(src)) { + requestPaint() + } else if (!isImageLoading(src)) { + loadImage(src) + } + } + + onImageLoaded: function(url) { + if (url === root.imageUrl(root.incomingBackground)) requestPaint() + } + + onPaint: { + var ctx = getContext("2d") + ctx.reset() + ctx.clearRect(0, 0, width, height) + + var src = root.imageUrl(root.incomingBackground) + if (!src || incomingFrame.status !== Image.Ready || root.revealProgress >= 1) return + if (!isImageLoaded(src)) { + prepareImage() + return + } + + var iw = incomingFrame.sourceSize.width + var ih = incomingFrame.sourceSize.height + if (iw <= 0 || ih <= 0 || width <= 0 || height <= 0) return + + var sx = 0 + var sy = 0 + var sw = iw + var sh = ih + if (iw / ih > width / height) { + sw = ih * width / height + sx = (iw - sw) / 2 + } else { + sh = iw * height / width + sy = (ih - sh) / 2 + } + + var center = width / 2 + var reach = width / 2 + Math.abs(slant) * height + 4 + var spread = reach * root.revealProgress + var leftTop = center - spread + var leftBottom = center - spread + slant * height + var rightTop = center + spread + var rightBottom = center + spread + slant * height + + ctx.save() + ctx.beginPath() + ctx.moveTo(center, 0) + ctx.lineTo(leftTop, 0) + ctx.lineTo(leftBottom, height) + ctx.lineTo(center, height) + ctx.closePath() + ctx.clip() + ctx.drawImage(src, sx, sy, sw, sh, 0, 0, width, height) + ctx.restore() + + ctx.save() + ctx.beginPath() + ctx.moveTo(center, 0) + ctx.lineTo(rightTop, 0) + ctx.lineTo(rightBottom, height) + ctx.lineTo(center, height) + ctx.closePath() + ctx.clip() + ctx.drawImage(src, sx, sy, sw, sh, 0, 0, width, height) + ctx.restore() + + if (!panel.maskReady && root.incomingBackground && root.revealProgress === 0) { + Qt.callLater(function() { + panel.maskReady = true + revealAnimation.restart() + }) + } + } + + Connections { + target: root + function onRevealProgressChanged() { revealCanvas.requestPaint() } + function onIncomingBackgroundChanged() { + panel.maskReady = false + revealCanvas.prepareImage() + } + } + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton + onDoubleClicked: root.openSelector() + } + } + } +} diff --git a/default/quickshell/omarchy-shell/plugins/background/manifest.json b/default/quickshell/omarchy-shell/plugins/background/manifest.json new file mode 100644 index 00000000..5ba0c4e5 --- /dev/null +++ b/default/quickshell/omarchy-shell/plugins/background/manifest.json @@ -0,0 +1,11 @@ +{ + "schemaVersion": 1, + "id": "omarchy.background", + "name": "Background", + "version": "1.0.0", + "author": "Omarchy", + "description": "Desktop background renderer with click handling and transitions", + "kinds": ["service"], + "activation": "startup", + "entryPoints": { "service": "Background.qml" } +} diff --git a/default/quickshell/omarchy-shell/plugins/osd/Osd.qml b/default/quickshell/omarchy-shell/plugins/osd/Osd.qml new file mode 100644 index 00000000..f5e67c99 --- /dev/null +++ b/default/quickshell/omarchy-shell/plugins/osd/Osd.qml @@ -0,0 +1,140 @@ +import QtQuick +import Quickshell +import Quickshell.Io +import Quickshell.Wayland +import qs.Commons + +Item { + id: root + + property string omarchyPath: "" + property var shell: null + property var manifest: null + + property bool opened: false + property string icon: "" + property string message: "" + property int value: 0 + property int maxValue: 100 + property bool hasProgress: true + + function clamp(v, min, max) { return Math.max(min, Math.min(max, v)) } + + function iconFor(name, percent) { + var n = String(name || "").toLowerCase() + if (n === "volume-muted" || n === "volume-mute" || n === "muted" || n === "mute") return "󰝟" + if (n === "volume-low") return "" + if (n === "volume-medium") return "" + if (n === "volume-high" || n === "volume") return "" + if (n === "microphone-muted" || n === "microphone-off" || n === "mic-muted" || n === "mic-off") return "󰍭" + if (n === "microphone" || n === "mic") return "󰍬" + if (n === "keyboard") return "󰌌" + if (n === "brightness" || n === "display") return "󰃠" + if (n === "touchpad") return "󰟸" + if (n === "touch" || n === "touchscreen") return "󰜉" + if (n === "media" || n === "player") return "󰝚" + if (percent <= 0) return "󰝟" + if (percent <= 33) return "" + if (percent <= 66) return "" + return "" + } + + function show(iconName, rawMessage, rawValue, rawMax, rawProgressText) { + maxValue = Math.max(1, parseInt(rawMax || "100", 10)) + var parsed = parseInt(rawValue || "0", 10) + hasProgress = rawValue !== "" && !isNaN(parsed) && rawMessage === "" + value = hasProgress ? clamp(parsed, 0, maxValue) : 0 + message = String(rawMessage || (hasProgress ? (rawProgressText || Math.round(value * 100 / maxValue) + "%") : "")) + icon = iconFor(iconName, hasProgress ? Math.round(value * 100 / maxValue) : -1) + opened = true + hideTimer.restart() + } + + function open(payloadJson) { + try { + var p = JSON.parse(payloadJson || "{}") + show(p.icon || "", p.message || "", p.value === undefined ? "" : String(p.value), p.max === undefined ? "100" : String(p.max), p.progressText || "") + } catch (e) {} + } + + function close() { opened = false } + + Timer { + id: hideTimer + interval: 1200 + onTriggered: root.opened = false + } + + IpcHandler { + target: "osd" + function show(payloadJson: string): string { + root.open(payloadJson) + return "ok" + } + function close(): string { root.close(); return "ok" } + function state(): string { return root.opened ? "open" : "closed" } + function ping(): string { return "ok" } + } + + PanelWindow { + id: panel + visible: root.opened + anchors { top: true; bottom: true; left: true; right: true } + color: "transparent" + WlrLayershell.namespace: "omarchy-osd" + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.keyboardFocus: WlrKeyboardFocus.None + exclusionMode: ExclusionMode.Ignore + + Rectangle { + id: card + width: 269 + height: 68 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: 67 + color: Color.alpha(Color.background, 0.97) + border.color: Color.foreground + border.width: 2 + radius: 0 + opacity: root.opened ? 1 : 0 + + Row { + anchors.fill: parent + anchors.leftMargin: 16 + anchors.rightMargin: 16 + spacing: 16 + Text { + width: 28 + anchors.verticalCenter: parent.verticalCenter + horizontalAlignment: Text.AlignHCenter + text: root.icon + font.family: "JetBrainsMono Nerd Font" + font.pixelSize: 27 + color: Color.foreground + } + Rectangle { + visible: root.hasProgress + width: visible ? 142 : 0 + height: 6 + anchors.verticalCenter: parent.verticalCenter + color: Color.alpha(Color.foreground, 0.45) + Rectangle { + height: parent.height + width: parent.width * (root.hasProgress ? root.value / root.maxValue : 0) + color: Color.accent + } + } + Text { + width: root.hasProgress ? 41 : 190 + anchors.verticalCenter: parent.verticalCenter + text: root.message + font.family: "JetBrainsMono Nerd Font" + font.bold: true + font.pixelSize: 14 + color: Color.foreground + } + } + } + } +} diff --git a/default/quickshell/omarchy-shell/plugins/osd/manifest.json b/default/quickshell/omarchy-shell/plugins/osd/manifest.json new file mode 100644 index 00000000..83bf5c67 --- /dev/null +++ b/default/quickshell/omarchy-shell/plugins/osd/manifest.json @@ -0,0 +1,11 @@ +{ + "schemaVersion": 1, + "id": "omarchy.osd", + "name": "On-screen display", + "version": "1.0.0", + "description": "Quickshell volume, brightness, and status overlays.", + "kinds": ["panel"], + "activation": "persistent", + "keepLoaded": true, + "entryPoints": { "panel": "Osd.qml" } +} diff --git a/default/quickshell/omarchy-shell/shell-defaults.json b/default/quickshell/omarchy-shell/shell-defaults.json index 569fc4d4..11e1d3dc 100644 --- a/default/quickshell/omarchy-shell/shell-defaults.json +++ b/default/quickshell/omarchy-shell/shell-defaults.json @@ -5,28 +5,67 @@ "centerAnchor": "calendar", "layout": { "left": [ - { "id": "omarchy" }, - { "id": "workspaces" } + { + "id": "omarchy" + }, + { + "id": "workspaces" + } ], "center": [ - { "id": "calendar", "format": "dddd HH:mm", "formatAlt": "dd MMMM 'W'ww yyyy", "verticalFormat": "HH\n—\nmm" }, - { "id": "weatherFlyout" }, - { "id": "update" }, - { "id": "voxtype" }, - { "id": "screenRecording" }, - { "id": "idle" }, - { "id": "notifications" } + { + "id": "calendar", + "format": "dddd HH:mm", + "formatAlt": "dd MMMM 'W'ww yyyy", + "verticalFormat": "HH\n\u2014\nmm" + }, + { + "id": "weatherFlyout" + }, + { + "id": "update" + }, + { + "id": "voxtype" + }, + { + "id": "screenRecording" + }, + { + "id": "idle" + }, + { + "id": "notifications" + } ], "right": [ - { "id": "tray" }, - { "id": "bluetoothPanel" }, - { "id": "networkPanel" }, - { "id": "audioPanel" }, - { "id": "battery" }, - { "id": "systemStats" }, - { "id": "controlCenter" } + { + "id": "tray" + }, + { + "id": "bluetoothPanel" + }, + { + "id": "networkPanel" + }, + { + "id": "audioPanel" + }, + { + "id": "battery" + }, + { + "id": "systemStats" + }, + { + "id": "controlCenter" + } ] } }, - "plugins": [] + "plugins": [ + { + "id": "omarchy.osd" + } + ] } diff --git a/default/quickshell/omarchy-shell/shell.qml b/default/quickshell/omarchy-shell/shell.qml index c5d93c1b..4b839435 100644 --- a/default/quickshell/omarchy-shell/shell.qml +++ b/default/quickshell/omarchy-shell/shell.qml @@ -55,7 +55,8 @@ ShellRoot { }, plugins: [ { id: "omarchy.settings" }, - { id: "omarchy.image-picker" } + { id: "omarchy.image-picker" }, + { id: "omarchy.osd" } ] }) diff --git a/default/themed/swayosd.css.tpl b/default/themed/swayosd.css.tpl deleted file mode 100644 index e06402c4..00000000 --- a/default/themed/swayosd.css.tpl +++ /dev/null @@ -1,5 +0,0 @@ -@define-color background-color {{ background }}; -@define-color border-color {{ foreground }}; -@define-color label {{ foreground }}; -@define-color image {{ foreground }}; -@define-color progress {{ accent }}; diff --git a/install/first-run/swayosd.sh b/install/first-run/swayosd.sh deleted file mode 100644 index 49db63f3..00000000 --- a/install/first-run/swayosd.sh +++ /dev/null @@ -1,2 +0,0 @@ -systemctl --user daemon-reload -systemctl --user enable --now swayosd-server.service diff --git a/install/omarchy-base.packages b/install/omarchy-base.packages index 79b875dc..63e4bac8 100644 --- a/install/omarchy-base.packages +++ b/install/omarchy-base.packages @@ -117,8 +117,6 @@ spotify socat starship sushi -swaybg -swayosd system-config-printer tesseract tesseract-data-eng diff --git a/migrations/1753138691.sh b/migrations/1753138691.sh deleted file mode 100644 index ef55a91f..00000000 --- a/migrations/1753138691.sh +++ /dev/null @@ -1,6 +0,0 @@ -echo "Install swayOSD to show volume status" - -if omarchy-cmd-missing swayosd-server; then - omarchy-pkg-add swayosd - setsid uwsm-app -- swayosd-server &>/dev/null & -fi diff --git a/migrations/1753224615.sh b/migrations/1753224615.sh deleted file mode 100644 index 6f9dcfb5..00000000 --- a/migrations/1753224615.sh +++ /dev/null @@ -1,9 +0,0 @@ -echo "Adding SwayOSD theming" - -if [[ ! -d ~/.config/swayosd ]]; then - mkdir -p ~/.config/swayosd - cp -r ~/.local/share/omarchy/config/swayosd/* ~/.config/swayosd/ - - pkill swayosd-server - setsid uwsm-app -- swayosd-server &>/dev/null & -fi diff --git a/migrations/1754390772.sh b/migrations/1754390772.sh deleted file mode 100644 index 86c95d65..00000000 --- a/migrations/1754390772.sh +++ /dev/null @@ -1,6 +0,0 @@ -echo "Set SwayOSD max volume back to 100" - -if ! grep -q "max_volume = 100" ~/.config/swayosd/config.toml; then - sed -i 's/max_volume = 150/max_volume = 100/' ~/.config/swayosd/config.toml - omarchy-restart-swayosd -fi diff --git a/migrations/1778171768.sh b/migrations/1778171768.sh deleted file mode 100644 index c69ece32..00000000 --- a/migrations/1778171768.sh +++ /dev/null @@ -1,8 +0,0 @@ -echo "Run SwayOSD as a supervised session service" - -mkdir -p ~/.config/systemd/user -cp "$OMARCHY_PATH/config/systemd/user/swayosd-server.service" ~/.config/systemd/user/swayosd-server.service - -pkill -x swayosd-server || true - -bash "$OMARCHY_PATH/install/first-run/swayosd.sh" diff --git a/migrations/1778743515.sh b/migrations/1778743515.sh index fe0b7516..22d26493 100644 --- a/migrations/1778743515.sh +++ b/migrations/1778743515.sh @@ -1,4 +1,4 @@ -echo "Flip from waybar + mako to omarchy-shell (quickshell-backed bar and notifications)" +echo "Flip from waybar + mako + swaybg to omarchy-shell (quickshell-backed bar and notifications)" omarchy-pkg-add quickshell @@ -17,4 +17,8 @@ if [[ -d ~/.config/waybar ]]; then fi rm -f ~/.local/state/omarchy/toggles/waybar-off +# swaybg is replaced with integrated background in shell +pkill -x swaybg 2>/dev/null || true +omarchy-pkg-drop swaybg + omarchy-restart-shell diff --git a/themes/last-horizon/swayosd.css b/themes/last-horizon/swayosd.css deleted file mode 100644 index b675ae06..00000000 --- a/themes/last-horizon/swayosd.css +++ /dev/null @@ -1,30 +0,0 @@ -@define-color background-color #0c0b0c; -@define-color border-color #b59790; -@define-color label #e2dddc; -@define-color image #b59790; -@define-color progress #e2dddc; - - -/* Cancel out Omarchy settings */ -window:not(:backdrop), -window:backdrop { - border: none; - border-width: 0; - border-radius: 4px; - background-color: transparent; - box-shadow: none; - padding: 12px; -} - - -/* Draw a new background */ -window:not(:backdrop) #container, -window:backdrop #container { - border: 2px solid @border-color; - border-radius: 4px; - background-color: @background-color; - padding: 12px; - background-clip: padding-box; - box-shadow: 2px 2px 9px 0px rgba(22, 22, 22, 1); - -} diff --git a/themes/lumon/swayosd.css b/themes/lumon/swayosd.css deleted file mode 100644 index 53c3f054..00000000 --- a/themes/lumon/swayosd.css +++ /dev/null @@ -1,44 +0,0 @@ -@define-color background-color #1b2d40; -@define-color border-color #304860; -@define-color label #d6e2ee; -@define-color image #d6e2ee; -@define-color progress #6fb8e3; -@define-color edge-light #f2fcff; - -/* Cancel out Omarchy defaults */ -window:not(:backdrop), -window:backdrop { - border: none; - border-width: 0; - background-color: transparent; - box-shadow: none; - padding: 12px; -} - -/* Draw the Lumon OSD shell */ -window:not(:backdrop) #container, -window:backdrop #container { - border: 2px solid alpha(@border-color, 0.92); - background-color: alpha(@background-color, 0.95); - padding: 12px 16px; - background-clip: padding-box; -} - -image, -label { - color: @label; -} - -progressbar { - min-height: 8px; -} - -progressbar trough { - background: alpha(@border-color, 0.24); - box-shadow: inset 0 1px rgba(242, 252, 255, 0.03); -} - -progressbar progress { - background: linear-gradient(90deg, @progress, @edge-light); - box-shadow: 0 0 10px rgba(111, 184, 227, 0.18); -} diff --git a/themes/retro-82/swayosd.css b/themes/retro-82/swayosd.css deleted file mode 100644 index b3e23641..00000000 --- a/themes/retro-82/swayosd.css +++ /dev/null @@ -1,5 +0,0 @@ -@define-color background-color #00172e; -@define-color border-color #134e5a; -@define-color label #f6dcac; -@define-color image #f6dcac; -@define-color progress #e97b3c; diff --git a/themes/solitude/swayosd.css b/themes/solitude/swayosd.css deleted file mode 100644 index 8abdbd77..00000000 --- a/themes/solitude/swayosd.css +++ /dev/null @@ -1,30 +0,0 @@ -@define-color background-color #101315; -@define-color border-color #2f353b; -@define-color label #cacccc; -@define-color image #cacccc; -@define-color progress #d9dbdc; - - -/* Cancel out Omarchy settings */ -window:not(:backdrop), -window:backdrop { - border: none; - border-width: 0; - border-radius: 4px; - background-color: transparent; - box-shadow: none; - padding: 12px; -} - - -/* Draw a new background */ -window:not(:backdrop) #container, -window:backdrop #container { - border: 2px solid @border-color; - border-radius: 6px; - background-color: @background-color; - padding: 12px; - background-clip: padding-box; - box-shadow: 2px 2px 9px 0px rgba(22, 22, 22, 1); - -}