mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-02 20:28:19 +02:00
Compare commits
71
Commits
+2
-4
@@ -55,7 +55,7 @@ GROUP_DESCRIPTIONS[reinstall]="Reinstall and reset workflows"
|
||||
GROUP_DESCRIPTIONS[remove]="Removal workflows"
|
||||
GROUP_DESCRIPTIONS[restart]="Restart Omarchy components"
|
||||
GROUP_DESCRIPTIONS[setup]="Interactive setup wizards"
|
||||
GROUP_DESCRIPTIONS[share]="Share clipboard, files, and folders"
|
||||
GROUP_DESCRIPTIONS[screensaver]="Screensaver branding and animation"
|
||||
GROUP_DESCRIPTIONS[snapshot]="System snapshots"
|
||||
GROUP_DESCRIPTIONS[state]="Persistent Omarchy state"
|
||||
GROUP_DESCRIPTIONS[sudo]="Sudo configuration helpers"
|
||||
@@ -63,6 +63,7 @@ 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"
|
||||
GROUP_DESCRIPTIONS[transcode]="Image and video transcoding"
|
||||
GROUP_DESCRIPTIONS[tui]="Terminal UI launchers"
|
||||
GROUP_DESCRIPTIONS[tz]="Timezone selection"
|
||||
GROUP_DESCRIPTIONS[update]="Omarchy and system updates"
|
||||
@@ -327,9 +328,6 @@ load_group_extra_commands() {
|
||||
install)
|
||||
load_command_by_binary omarchy-pkg-add
|
||||
;;
|
||||
system)
|
||||
load_command_by_binary omarchy-lock-screen
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,18 @@
|
||||
# omarchy:args=[--with-desktop-audio] [--with-microphone-audio] [--with-webcam] [--webcam-device=<device>] [--resolution=<size>] [--stop-recording]
|
||||
# omarchy:examples=omarchy screenrecord | omarchy capture screenrecord --with-desktop-audio
|
||||
# omarchy:aliases=omarchy screenrecord
|
||||
#
|
||||
# Env: OMARCHY_SCREENRECORD_USE_PORTAL=true skips the built-in slurp picker and
|
||||
# uses gpu-screen-recorder's xdg-desktop-portal capture backend instead. The
|
||||
# portal backend was originally added (PR #3401) for HDR-aware capture, support
|
||||
# for monitors driven by external GPUs, and window capture — enable it if any
|
||||
# of those matter to you. Off by default because the portal path can fail EGL
|
||||
# DMA-BUF modifier import on some configurations, leaving recording unable to
|
||||
# start.
|
||||
#
|
||||
# Env: OMARCHY_SCREENRECORD_DEBUG=true appends gpu-screen-recorder's stderr (and
|
||||
# the picker target it was launched with) to /tmp/omarchy-screenrecord.log so
|
||||
# users can attach a log when reporting capture failures.
|
||||
|
||||
[[ -f ~/.config/user-dirs.dirs ]] && source ~/.config/user-dirs.dirs
|
||||
OUTPUT_DIR="${OMARCHY_SCREENRECORD_DIR:-${XDG_VIDEOS_DIR:-$HOME/Videos}}"
|
||||
@@ -21,6 +33,7 @@ WEBCAM_DEVICE=""
|
||||
RESOLUTION=""
|
||||
STOP_RECORDING="false"
|
||||
RECORDING_FILE="/tmp/omarchy-screenrecord-filename"
|
||||
LOG_FILE=$([[ ${OMARCHY_SCREENRECORD_DEBUG:-false} == "true" ]] && echo "/tmp/omarchy-screenrecord.log" || echo "/dev/null")
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
@@ -87,7 +100,92 @@ default_resolution() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Monitor + window rectangles on the focused workspace, in slurp's "X,Y WxH" format.
|
||||
# Mirrors omarchy-capture-screenshot so the picker UX is identical.
|
||||
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])"'
|
||||
}
|
||||
|
||||
# Echoes "monitor:NAME" when the selection matches an entire monitor, otherwise
|
||||
# "region:WxH+X+Y" with physical-pixel coordinates ready for gpu-screen-recorder.
|
||||
# Returns non-zero if the user cancelled the picker.
|
||||
select_capture_target() {
|
||||
local rects=$(get_rectangles)
|
||||
hyprpicker -r -z >/dev/null 2>&1 &
|
||||
local picker_pid=$!
|
||||
sleep .1
|
||||
local selection=$(echo "$rects" | slurp 2>/dev/null)
|
||||
kill $picker_pid 2>/dev/null
|
||||
|
||||
# X and Y can be negative (Hyprland monitor positions in multi-display layouts);
|
||||
# widths and heights are always positive.
|
||||
[[ $selection =~ ^(-?[0-9]+),(-?[0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]] || return 1
|
||||
local sx=${BASH_REMATCH[1]} sy=${BASH_REMATCH[2]}
|
||||
local sw=${BASH_REMATCH[3]} sh=${BASH_REMATCH[4]}
|
||||
|
||||
# A bare click (area < 20px²) snaps to whichever rectangle the click landed
|
||||
# inside, so users don't end up with accidental 2px recordings.
|
||||
if ((sw * sh < 20)); then
|
||||
while IFS= read -r rect; do
|
||||
[[ $rect =~ ^(-?[0-9]+),(-?[0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]] || continue
|
||||
local rx=${BASH_REMATCH[1]} ry=${BASH_REMATCH[2]}
|
||||
local rw=${BASH_REMATCH[3]} rh=${BASH_REMATCH[4]}
|
||||
if ((sx >= rx && sx < rx + rw && sy >= ry && sy < ry + rh)); then
|
||||
sx=$rx sy=$ry sw=$rw sh=$rh
|
||||
break
|
||||
fi
|
||||
done <<<"$rects"
|
||||
fi
|
||||
|
||||
# When the selection exactly matches a monitor, prefer -w <monitor> over a
|
||||
# region capture — same kms backend, but no scaling math and full native res.
|
||||
local monitor=$(hyprctl monitors -j | jq -r --argjson x "$sx" --argjson y "$sy" --argjson w "$sw" --argjson h "$sh" '
|
||||
.[] | select(.x == $x and .y == $y and (.width / .scale | floor) == $w and (.height / .scale | floor) == $h) | .name' | head -1)
|
||||
|
||||
if [[ -n $monitor ]]; then
|
||||
echo "monitor:$monitor"
|
||||
return
|
||||
fi
|
||||
|
||||
# gpu-screen-recorder wants region geometry in the compositor's logical
|
||||
# coordinate space — same space slurp returns — so pass the values through
|
||||
# untouched. (gsr scales to physical pixels itself based on the monitor.)
|
||||
echo "region:${sw}x${sh}+${sx}+${sy}"
|
||||
}
|
||||
|
||||
start_screenrecording() {
|
||||
local capture_args=()
|
||||
local target
|
||||
|
||||
# Opt-in path for HDR, external-GPU monitors, and window capture (all things
|
||||
# the portal backend supports and the kms backend doesn't). Default flow uses
|
||||
# slurp + the kms backend, which avoids the EGL DMA-BUF modifier import
|
||||
# failures the portal path can hit on some configurations.
|
||||
if [[ ${OMARCHY_SCREENRECORD_USE_PORTAL:-false} == "true" ]]; then
|
||||
target="portal"
|
||||
capture_args=(-w portal -s "${RESOLUTION:-$(default_resolution)}")
|
||||
else
|
||||
target=$(select_capture_target) || return 1
|
||||
|
||||
case $target in
|
||||
monitor:*)
|
||||
capture_args=(-w "${target#monitor:}" -s "${RESOLUTION:-$(default_resolution)}")
|
||||
;;
|
||||
region:*)
|
||||
capture_args=(-w "${target#region:}")
|
||||
[[ -n $RESOLUTION ]] && capture_args+=(-s "$RESOLUTION")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
[[ $WEBCAM == "true" ]] && start_webcam_overlay
|
||||
|
||||
local filename="$OUTPUT_DIR/screenrecording-$(date +'%Y-%m-%d_%H-%M-%S').mp4"
|
||||
local audio_devices=""
|
||||
local audio_args=()
|
||||
@@ -102,12 +200,10 @@ start_screenrecording() {
|
||||
|
||||
[[ -n $audio_devices ]] && audio_args+=(-a "$audio_devices" -ac aac)
|
||||
|
||||
local resolution="${RESOLUTION:-$(default_resolution)}"
|
||||
|
||||
gpu-screen-recorder -w portal -k auto -s "$resolution" -f 60 -fm cfr -fallback-cpu-encoding yes -o "$filename" "${audio_args[@]}" &
|
||||
echo "===== $(date '+%F %T') args: $* target: $target =====" >>"$LOG_FILE"
|
||||
gpu-screen-recorder "${capture_args[@]}" -k auto -f 60 -fm cfr -fallback-cpu-encoding yes -o "$filename" "${audio_args[@]}" 2>>"$LOG_FILE" &
|
||||
local pid=$!
|
||||
|
||||
# Wait for recording to actually start (file appears after portal selection)
|
||||
while kill -0 $pid 2>/dev/null && [[ ! -f $filename ]]; do
|
||||
sleep 0.2
|
||||
done
|
||||
@@ -175,7 +271,10 @@ finalize_recording() {
|
||||
# Trim the first frame, and normalize audio to -14 LUFS if present, in a single pass
|
||||
local args=(-y -ss 0.1 -i "$latest" "${video_codec[@]}")
|
||||
if ffprobe -v error -select_streams a -show_entries stream=codec_type -of csv=p=0 "$latest" 2>/dev/null | grep -q audio; then
|
||||
args+=(-af loudnorm=I=-14:TP=-1.5:LRA=11)
|
||||
# Hard-mute the first 400ms to drop the PipeWire capture-open pop (a near-clipping
|
||||
# transient around 130-200ms that a gentle fade-in can't attenuate enough), then a
|
||||
# 50ms fade avoids a click at the boundary before loudnorm normalizes the rest.
|
||||
args+=(-af "volume=enable='lt(t,0.4)':volume=0,afade=t=in:st=0.4:d=0.05,loudnorm=I=-14:TP=-1.5:LRA=11")
|
||||
fi
|
||||
|
||||
local processed="${latest%.mp4}-processed.mp4"
|
||||
@@ -191,7 +290,5 @@ if screenrecording_active; then
|
||||
elif [[ $STOP_RECORDING == "true" ]]; then
|
||||
exit 1
|
||||
else
|
||||
[[ $WEBCAM == "true" ]] && start_webcam_overlay
|
||||
|
||||
start_screenrecording || cleanup_webcam
|
||||
fi
|
||||
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Extract text from a screenshot region with OCR
|
||||
# omarchy:group=capture
|
||||
# omarchy:examples=omarchy capture ocr
|
||||
|
||||
# Keep hyprpicker alive until after grim captures so the screenshot sees the
|
||||
# frozen overlay rather than live content shifting during teardown.
|
||||
cleanup_freeze() {
|
||||
[[ -n $PID ]] && kill $PID 2>/dev/null
|
||||
}
|
||||
trap cleanup_freeze EXIT
|
||||
|
||||
hyprpicker -r -z >/dev/null 2>&1 &
|
||||
PID=$!
|
||||
sleep .1
|
||||
SELECTION=$(slurp 2>/dev/null)
|
||||
|
||||
[[ -z $SELECTION ]] && exit 0
|
||||
|
||||
TEXT=$(grim -g "$SELECTION" - | tesseract stdin stdout --oem 1 --psm 6 -l eng --dpi 300 -c preserve_interword_spaces=1 2>/dev/null) || exit 1
|
||||
|
||||
[[ -z $TEXT ]] && exit 1
|
||||
|
||||
printf "%s" "$TEXT" | wl-copy
|
||||
notify-send " Copied text from selection to clipboard"
|
||||
@@ -16,6 +16,7 @@ if [[ -f $FIRST_RUN_MODE ]]; then
|
||||
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/gtk-primary-paste.sh"
|
||||
bash "$OMARCHY_PATH/install/first-run/elephant.sh"
|
||||
sudo rm -f /etc/sudoers.d/first-run
|
||||
|
||||
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Detect whether the computer has an NVIDIA GPU with GSP firmware (Turing or newer).
|
||||
|
||||
# GTX 16xx, RTX 20xx-50xx, RTX Pro, Quadro RTX, datacenter A/H/T/L series.
|
||||
lspci | grep -i 'nvidia' | grep -qE "GTX 16[0-9]{2}|RTX [2-5][0-9]{3}|RTX PRO [0-9]{4}|Quadro RTX|RTX A[0-9]{4}|A[1-9][0-9]{2}|H[1-9][0-9]{2}|T4|L[0-9]+"
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Detect whether the computer has an NVIDIA GPU without GSP firmware (Maxwell/Pascal/Volta).
|
||||
|
||||
# GTX 9xx/10xx, GT 10xx, Quadro P/M/GV, MX series, Titan X/Xp/V, Tesla V100.
|
||||
lspci | grep -i 'nvidia' | grep -qE "GTX (9[0-9]{2}|10[0-9]{2})|GT 10[0-9]{2}|Quadro [PM][0-9]{3,4}|Quadro GV100|MX *[0-9]+|Titan (X|Xp|V)|Tesla V100"
|
||||
@@ -3,6 +3,7 @@
|
||||
# omarchy:summary=Allow Chromium to sign in to Google accounts by adding the required OAuth credentials
|
||||
|
||||
if [[ -f ~/.config/chromium-flags.conf ]]; then
|
||||
echo "Installing Chromium Google account support..."
|
||||
CONF=~/.config/chromium-flags.conf
|
||||
|
||||
grep -qxF -- "--oauth2-client-id=77185425430.apps.googleusercontent.com" "$CONF" ||
|
||||
|
||||
@@ -13,6 +13,7 @@ fi
|
||||
|
||||
if [[ -n $choices ]]; then
|
||||
for db in $choices; do
|
||||
echo "Installing $db..."
|
||||
case $db in
|
||||
MySQL) sudo docker run -d --restart unless-stopped -p "127.0.0.1:3306:3306" --name=mysql8 -e MYSQL_ROOT_PASSWORD= -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:8.4 ;;
|
||||
PostgreSQL) sudo docker run -d --restart unless-stopped -p "127.0.0.1:5432:5432" --name=postgres18 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:18 ;;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
echo "Installing GeForce NOW..."
|
||||
omarchy-pkg-add flatpak
|
||||
cd /tmp
|
||||
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install lib32 graphics drivers (Vulkan + NVIDIA) for any detected GPUs.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
echo "Installing lib32 graphics drivers..."
|
||||
|
||||
PACKAGES=()
|
||||
|
||||
declare -A VULKAN_DRIVERS=(
|
||||
[Intel]=lib32-vulkan-intel
|
||||
[AMD]=lib32-vulkan-radeon
|
||||
)
|
||||
for vendor in "${!VULKAN_DRIVERS[@]}"; do
|
||||
if lspci | grep -iE "(VGA|Display).*$vendor" >/dev/null; then
|
||||
PACKAGES+=("${VULKAN_DRIVERS[$vendor]}")
|
||||
fi
|
||||
done
|
||||
|
||||
if omarchy-hw-nvidia-gsp; then
|
||||
PACKAGES+=(lib32-nvidia-utils)
|
||||
elif omarchy-hw-nvidia-without-gsp; then
|
||||
PACKAGES+=(lib32-nvidia-580xx-utils)
|
||||
fi
|
||||
|
||||
[[ ${#PACKAGES[@]} -gt 0 ]] && omarchy-pkg-add "${PACKAGES[@]}"
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install Heroic Games Launcher (Epic, GOG, Amazon Prime Gaming) with graphics drivers.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
echo "Installing Heroic Games Launcher..."
|
||||
omarchy-pkg-add heroic-games-launcher-bin
|
||||
omarchy-install-gaming-gpu-lib32
|
||||
|
||||
setsid gtk-launch heroic >/dev/null 2>&1 &
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install Lutris with Wine + DXVK for running Windows games (Battle.net, EA, Ubisoft Connect, etc.)
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
echo "Installing Lutris..."
|
||||
omarchy-pkg-add lutris umu-launcher wine-staging wine-mono wine-gecko winetricks python-protobuf
|
||||
omarchy-install-gaming-gpu-lib32
|
||||
|
||||
# Lutris ships with `#!/usr/bin/env python3`, which resolves to mise's Python and
|
||||
# fails to import the lutris module. Pin the shebang to the system Python.
|
||||
sudo sed -i '/env python3/ c\#!/bin/python3' /usr/bin/lutris
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
Lutris will open and auto-fetch its DXVK and VKD3D runtimes in the background
|
||||
(watch the bottom status bar). Once that finishes, click the + to add or install games.
|
||||
|
||||
EOF
|
||||
|
||||
setsid lutris >/dev/null 2>&1 &
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install Moonlight (NVIDIA GameStream / Sunshine client) for streaming games to this PC.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
echo "Installing Moonlight..."
|
||||
omarchy-pkg-add moonlight-qt
|
||||
|
||||
setsid gtk-launch com.moonlight_stream.Moonlight.desktop >/dev/null 2>&1 &
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install RetroArch with the full libretro core set plus FBNeo and a ~/Games ROM directory.
|
||||
|
||||
set -e
|
||||
|
||||
echo "Installing RetroArch..."
|
||||
omarchy-pkg-add \
|
||||
retroarch \
|
||||
retroarch-assets-glui retroarch-assets-ozone retroarch-assets-xmb \
|
||||
libretro-beetle-pce libretro-beetle-pce-fast libretro-beetle-psx libretro-beetle-psx-hw libretro-beetle-supergrafx \
|
||||
libretro-blastem \
|
||||
libretro-bsnes libretro-bsnes-hd libretro-bsnes2014 \
|
||||
libretro-core-info \
|
||||
libretro-desmume libretro-dolphin libretro-flycast \
|
||||
libretro-gambatte libretro-genesis-plus-gx \
|
||||
libretro-kronos \
|
||||
libretro-mame libretro-mame2016 libretro-melonds libretro-mesen libretro-mesen-s libretro-mgba libretro-mupen64plus-next \
|
||||
libretro-nestopia \
|
||||
libretro-overlays \
|
||||
libretro-parallel-n64 libretro-picodrive libretro-play libretro-ppsspp \
|
||||
libretro-sameboy libretro-scummvm libretro-shaders-slang libretro-snes9x \
|
||||
libretro-yabause \
|
||||
libretro-fbneo-git \
|
||||
libretro-database-git \
|
||||
retroarch-joypad-autoconfig-git
|
||||
|
||||
# Set up ~/Games for BIOS files and ROMs
|
||||
mkdir -p "$HOME/Games/bios" "$HOME/Games/roms"
|
||||
|
||||
CFG="$HOME/.config/retroarch/retroarch.cfg"
|
||||
mkdir -p "$(dirname "$CFG")"
|
||||
touch "$CFG"
|
||||
|
||||
set_cfg() {
|
||||
local key=$1 value=$2
|
||||
if grep -q "^$key = " "$CFG"; then
|
||||
sed -i "s|^$key = .*|$key = \"$value\"|" "$CFG"
|
||||
else
|
||||
echo "$key = \"$value\"" >>"$CFG"
|
||||
fi
|
||||
}
|
||||
|
||||
set_cfg rgui_browser_directory "$HOME/Games/roms"
|
||||
set_cfg system_directory "$HOME/Games/bios"
|
||||
|
||||
# Point at the cores and assets installed by pacman
|
||||
set_cfg libretro_directory "/usr/lib/libretro"
|
||||
set_cfg libretro_info_path "/usr/share/libretro/info"
|
||||
set_cfg overlay_directory "/usr/share/libretro/overlays"
|
||||
set_cfg osk_overlay_directory "/usr/share/libretro/overlays/keyboards"
|
||||
set_cfg video_shader_dir "/usr/share/libretro/shaders/shaders_slang"
|
||||
set_cfg joypad_autoconfig_dir "/usr/share/libretro/autoconfig"
|
||||
|
||||
# Point at the database, cheats, and cursors from libretro-database-git
|
||||
set_cfg content_database_path "/usr/share/libretro/database/rdb"
|
||||
set_cfg cheat_database_path "/usr/share/libretro/database/cht"
|
||||
set_cfg cursor_directory "/usr/share/libretro/database/cursors"
|
||||
|
||||
# Vulkan is required for slang shaders and unlocks hardware renderers in beetle-psx-hw, parallel-n64, dolphin
|
||||
set_cfg video_driver "vulkan"
|
||||
|
||||
# XMB is the classic PS3-style menu (vs. ozone/rgui/glui)
|
||||
set_cfg menu_driver "xmb"
|
||||
|
||||
# Default to crt-royale shader for that classic CRT look. The global preset is
|
||||
# auto-loaded by RetroArch when auto_shaders_enable is true and no per-core/per-game
|
||||
# preset takes precedence — setting video_shader alone in retroarch.cfg is not enough.
|
||||
set_cfg video_shader_enable "true"
|
||||
set_cfg auto_shaders_enable "true"
|
||||
mkdir -p ~/.config/retroarch/config
|
||||
echo '#reference "/usr/share/libretro/shaders/shaders_slang/crt/crt-royale.slangp"' \
|
||||
> ~/.config/retroarch/config/global.slangp
|
||||
|
||||
# Hide Images and Video tabs in the main menu sidebar
|
||||
set_cfg content_show_images "false"
|
||||
set_cfg content_show_video "false"
|
||||
|
||||
echo ""
|
||||
echo "Put your roms and bios files in ~/Games. Then start RetroArch from the app launcher (Super + Space)."
|
||||
|
||||
setsid nautilus "$HOME/Games" >/dev/null 2>&1 &
|
||||
@@ -5,6 +5,11 @@
|
||||
|
||||
set -e
|
||||
|
||||
echo "Now pick dependencies matching your graphics card"
|
||||
sudo pacman -S steam
|
||||
echo "Installing Steam..."
|
||||
omarchy-pkg-add steam
|
||||
omarchy-install-gaming-gpu-lib32
|
||||
|
||||
echo ""
|
||||
echo "Steam will start automatically now. This might take a while..."
|
||||
|
||||
setsid gtk-launch steam >/dev/null 2>&1 &
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install Xbox Cloud Gaming as a web app and launch it.
|
||||
|
||||
set -e
|
||||
|
||||
echo "Installing Xbox Cloud Gaming..."
|
||||
omarchy-webapp-install "Xbox Cloud Gaming" "https://www.xbox.com/en-US/play" "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/xbox.png"
|
||||
|
||||
setsid omarchy-launch-webapp "https://www.xbox.com/en-US/play" >/dev/null 2>&1 &
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install support for using Xbox controllers with Steam/RetroArch/etc.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
echo "Installing Xbox controller Bluetooth support..."
|
||||
|
||||
# Install xpadneo to ensure controllers work out of the box
|
||||
omarchy-pkg-add linux-headers xpadneo-dkms
|
||||
|
||||
# Prevent xpad/xpadneo driver conflict
|
||||
echo blacklist xpad | sudo tee /etc/modprobe.d/blacklist-xpad.conf >/dev/null
|
||||
echo hid_xpadneo | sudo tee /etc/modules-load.d/xpadneo.conf >/dev/null
|
||||
|
||||
# Ensure user is in the input group (controllers need it)
|
||||
needs_reboot=false
|
||||
if ! id -nG "$USER" | grep -qw input; then
|
||||
sudo usermod -aG input "$USER"
|
||||
needs_reboot=true
|
||||
fi
|
||||
|
||||
# Swap drivers in the running kernel so a reboot isn't needed otherwise
|
||||
if lsmod | grep -q '^xpad '; then
|
||||
sudo modprobe -r xpad 2>/dev/null || needs_reboot=true
|
||||
fi
|
||||
|
||||
if $needs_reboot; then
|
||||
gum confirm "Reboot needed to finish setup. Reboot now?" && sudo reboot now
|
||||
exit 0
|
||||
fi
|
||||
|
||||
sudo modprobe hid_xpadneo
|
||||
|
||||
echo ""
|
||||
echo "Now you can pair your Xbox controller with Bluetooth using Super + Ctrl + B."
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install Helix and configure it to use the current Omarchy theme.
|
||||
# omarchy:summary=Install Helix and configure it to use the current Omarchy theme
|
||||
|
||||
echo "Installing Helix..."
|
||||
omarchy-pkg-add helix
|
||||
|
||||
@@ -22,6 +22,8 @@ kitty) desktop_id="kitty.desktop" ;;
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Installing $package..."
|
||||
|
||||
# Install package
|
||||
if omarchy-pkg-add $package; then
|
||||
# Copy custom desktop entry for alacritty with X-TerminalArg* keys
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install support for using Xbox controllers with Steam/RetroArch/etc.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
# Install xpadneo to ensure controllers work out of the box
|
||||
omarchy-pkg-add linux-headers
|
||||
omarchy-pkg-aur-add xpadneo-dkms
|
||||
|
||||
# Prevent xpad/xpadneo driver conflict
|
||||
echo blacklist xpad | sudo tee /etc/modprobe.d/blacklist-xpad.conf >/dev/null
|
||||
echo hid_xpadneo | sudo tee /etc/modules-load.d/xpadneo.conf >/dev/null
|
||||
|
||||
# Give user access to game controllers
|
||||
sudo usermod -a -G input $USER
|
||||
|
||||
# Modules need to be loaded
|
||||
gum confirm "Install requires reboot. Ready?" && sudo reboot now
|
||||
+78
-12
@@ -93,19 +93,22 @@ show_learn_menu() {
|
||||
}
|
||||
|
||||
show_trigger_menu() {
|
||||
case $(menu "Trigger" " Capture\n Share\n Toggle\n Hardware") in
|
||||
case $(menu "Trigger" " Capture\n Transcode\n Share\n Toggle\n Workspace\n Hardware") in
|
||||
*Capture*) show_capture_menu ;;
|
||||
*Transcode*) show_transcode_menu ;;
|
||||
*Share*) show_share_menu ;;
|
||||
*Toggle*) show_toggle_menu ;;
|
||||
*Workspace*) show_workspace_menu ;;
|
||||
*Hardware*) show_hardware_menu ;;
|
||||
*) show_main_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_capture_menu() {
|
||||
case $(menu "Capture" " Screenshot\n Screenrecord\n Color") in
|
||||
case $(menu "Capture" " Screenshot\n Screenrecord\n Text Extraction\n Color") in
|
||||
*Screenshot*) omarchy-capture-screenshot ;;
|
||||
*Screenrecord*) show_screenrecord_menu ;;
|
||||
*Text*) omarchy-capture-text-extraction ;;
|
||||
*Color*) pkill hyprpicker || hyprpicker -a ;;
|
||||
*) back_to show_trigger_menu ;;
|
||||
esac
|
||||
@@ -165,13 +168,30 @@ show_share_menu() {
|
||||
esac
|
||||
}
|
||||
|
||||
show_transcode_menu() {
|
||||
case $(menu "Transcode" " Picture\n Video") in
|
||||
*Picture*) present_terminal "omarchy-transcode --path '$HOME/Pictures'" ;;
|
||||
*Video*) present_terminal "omarchy-transcode --path '$HOME/Videos'" ;;
|
||||
*) back_to show_trigger_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_workspace_menu() {
|
||||
case $(menu "Workspace" " Restore\n Save") in
|
||||
*Restore*) omarchy-workspace-restore ;;
|
||||
*Save*) omarchy-workspace-save ;;
|
||||
*) back_to show_trigger_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_toggle_menu() {
|
||||
local options=" Screensaver\n Nightlight\n Idle Lock\n Top Bar\n Workspace Layout\n Window Gaps\n 1-Window Ratio\n Monitor Scaling\n Direct Boot\n Passwordless Sudo"
|
||||
local options=" Screensaver\n Nightlight\n Idle Lock\n Notifications\n Top Bar\n Workspace Layout\n Window Gaps\n 1-Window Ratio\n Monitor Scaling\n Direct Boot\n Passwordless Sudo"
|
||||
|
||||
case $(menu "Toggle" "$options") in
|
||||
*Screensaver*) omarchy-toggle-screensaver ;;
|
||||
*Nightlight*) omarchy-toggle-nightlight ;;
|
||||
*Idle*) omarchy-toggle-idle ;;
|
||||
*Notifications*) omarchy-toggle-notification-silencing ;;
|
||||
*Bar*) omarchy-toggle-waybar ;;
|
||||
*Layout*) omarchy-hyprland-workspace-layout-toggle ;;
|
||||
*Ratio*) omarchy-hyprland-window-single-square-aspect-toggle ;;
|
||||
@@ -215,12 +235,36 @@ show_style_menu() {
|
||||
*Font*) show_font_menu ;;
|
||||
*Background*) show_background_menu ;;
|
||||
*Hyprland*) open_in_editor ~/.config/hypr/looknfeel.conf ;;
|
||||
*Screensaver*) open_in_editor ~/.config/omarchy/branding/screensaver.txt ;;
|
||||
*Screensaver*) show_screensaver_menu ;;
|
||||
*About*) open_in_editor ~/.config/omarchy/branding/about.txt ;;
|
||||
*) show_main_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_screensaver_menu() {
|
||||
case $(menu "Screensaver" " Set From Image\n Restore Default\n Edit Text\n Preview") in
|
||||
*Image*) set_screensaver_from_image ;;
|
||||
*Default*) terminal bash -lc 'omarchy-screensaver-set-logo default; echo; read -n 1 -s -r -p "Press any key to close..."' ;;
|
||||
*Text*) open_in_editor ~/.config/omarchy/branding/screensaver.txt ;;
|
||||
*Preview*) omarchy-launch-screensaver force ;;
|
||||
*) show_style_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
set_screensaver_from_image() {
|
||||
terminal bash -lc '
|
||||
image=$(fd --type file --ignore-case --extension svg --extension png . "$HOME" 2>/dev/null | fzf --prompt "Logo image> ")
|
||||
if [[ -n $image ]]; then
|
||||
if omarchy-screensaver-set-logo "$image"; then
|
||||
echo
|
||||
echo "Preview with: omarchy-launch-screensaver force"
|
||||
fi
|
||||
echo
|
||||
read -n 1 -s -r -p "Press any key to close..."
|
||||
fi
|
||||
'
|
||||
}
|
||||
|
||||
show_theme_menu() {
|
||||
omarchy-launch-walker -m menus:omarchythemes --width 800 --minheight 400
|
||||
}
|
||||
@@ -384,12 +428,16 @@ show_install_ai_menu() {
|
||||
}
|
||||
|
||||
show_install_gaming_menu() {
|
||||
case $(menu "Install" " Steam\n NVIDIA GeForce NOW\n RetroArch [AUR]\n Minecraft\n Xbox Controller [AUR]") in
|
||||
*Steam*) present_terminal omarchy-install-steam ;;
|
||||
*GeForce*) present_terminal omarchy-install-geforce-now ;;
|
||||
*RetroArch*) aur_install_and_launch "RetroArch" "retroarch retroarch-assets libretro libretro-fbneo" "com.libretro.RetroArch.desktop" ;;
|
||||
case $(menu "Install" " Steam\n RetroArch\n Minecraft\n NVIDIA GeForce NOW\n Xbox Cloud Gaming\n Xbox Controller ()\n Moonlight (GameStream)\n Lutris (Battle.net)\n Heroic (Epic Games)") in
|
||||
*Steam*) present_terminal omarchy-install-gaming-steam ;;
|
||||
*RetroArch*) present_terminal omarchy-install-gaming-retroarch ;;
|
||||
*Minecraft*) install_and_launch "Minecraft" "minecraft-launcher" "minecraft-launcher" ;;
|
||||
*Xbox*) present_terminal omarchy-install-xbox-controllers ;;
|
||||
*GeForce*) present_terminal omarchy-install-gaming-geforce-now ;;
|
||||
*"Xbox Cloud"*) present_terminal omarchy-install-gaming-xbox-cloud ;;
|
||||
*Xbox*) present_terminal omarchy-install-gaming-xbox-controllers ;;
|
||||
*Lutris*) present_terminal omarchy-install-gaming-lutris ;;
|
||||
*Heroic*) present_terminal omarchy-install-gaming-heroic ;;
|
||||
*Moonlight*) present_terminal omarchy-install-gaming-moonlight ;;
|
||||
*) show_install_menu ;;
|
||||
esac
|
||||
}
|
||||
@@ -404,12 +452,12 @@ show_install_style_menu() {
|
||||
}
|
||||
|
||||
show_install_font_menu() {
|
||||
case $(menu "Install" " Cascadia Mono\n Meslo LG Mono\n Fira Code\n Victor Code\n Bistream Vera Mono\n Iosevka" "--width 350") in
|
||||
case $(menu "Install" " Cascadia Mono\n Meslo LG Mono\n Fira Code\n Victor Code\n Bitstream Vera Mono\n Iosevka" "--width 350") in
|
||||
*Cascadia*) install_font "Cascadia Mono" "ttf-cascadia-mono-nerd" "CaskaydiaMono 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" ;;
|
||||
*Victor*) install_font "Victor Code" "ttf-victor-mono-nerd" "VictorMono Nerd Font" ;;
|
||||
*Bistream*) install_font "Bistream Vera Code" "ttf-bitstream-vera-mono-nerd" "BitstromWera Nerd Font" ;;
|
||||
*Bitstream*) install_font "Bitstream Vera Code" "ttf-bitstream-vera-mono-nerd" "BitstromWera Nerd Font" ;;
|
||||
*Iosevka*) install_font "Iosevka" "ttf-iosevka-nerd" "Iosevka Nerd Font Mono" ;;
|
||||
*) show_install_menu ;;
|
||||
esac
|
||||
@@ -462,11 +510,12 @@ show_install_elixir_menu() {
|
||||
}
|
||||
|
||||
show_remove_menu() {
|
||||
case $(menu "Remove" " Package\n Web App\n TUI\n Development\n Preinstalls\n Dictation\n Theme\n Windows\n Fingerprint\n Fido2") in
|
||||
case $(menu "Remove" " Package\n Web App\n TUI\n Development\n Gaming\n Preinstalls\n Dictation\n Theme\n Windows\n Fingerprint\n Fido2") in
|
||||
*Package*) terminal omarchy-pkg-remove ;;
|
||||
*Web*) present_terminal omarchy-webapp-remove ;;
|
||||
*TUI*) present_terminal omarchy-tui-remove ;;
|
||||
*Development*) show_remove_development_menu ;;
|
||||
*Gaming*) show_remove_gaming_menu ;;
|
||||
*Preinstalls*) present_terminal omarchy-remove-preinstalls ;;
|
||||
*Dictation*) present_terminal omarchy-voxtype-remove ;;
|
||||
*Theme*) present_terminal omarchy-theme-remove ;;
|
||||
@@ -477,6 +526,21 @@ show_remove_menu() {
|
||||
esac
|
||||
}
|
||||
|
||||
show_remove_gaming_menu() {
|
||||
case $(menu "Remove" " Steam\n RetroArch\n Minecraft\n NVIDIA GeForce NOW\n Xbox Cloud Gaming\n Xbox Controller ()\n Moonlight (GameStream)\n Lutris (Battle.net)\n Heroic (Epic Games)") in
|
||||
*Steam*) present_terminal omarchy-remove-gaming-steam ;;
|
||||
*RetroArch*) present_terminal omarchy-remove-gaming-retroarch ;;
|
||||
*Minecraft*) present_terminal omarchy-remove-gaming-minecraft ;;
|
||||
*GeForce*) present_terminal omarchy-remove-gaming-geforce-now ;;
|
||||
*"Xbox Cloud"*) present_terminal omarchy-remove-gaming-xbox-cloud ;;
|
||||
*Xbox*) present_terminal omarchy-remove-gaming-xbox-controllers ;;
|
||||
*Moonlight*) present_terminal omarchy-remove-gaming-moonlight ;;
|
||||
*Lutris*) present_terminal omarchy-remove-gaming-lutris ;;
|
||||
*Heroic*) present_terminal omarchy-remove-gaming-heroic ;;
|
||||
*) show_remove_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_remove_development_menu() {
|
||||
case $(menu "Remove" " Ruby on Rails\n JavaScript\n Go\n PHP\n Python\n Elixir\n Zig\n Rust\n Java\n .NET\n OCaml\n Clojure\n Scala") in
|
||||
*Rails*) present_terminal "omarchy-remove-dev-env ruby" ;;
|
||||
@@ -625,7 +689,9 @@ go_to_menu() {
|
||||
*trigger*) show_trigger_menu ;;
|
||||
*toggle*) show_toggle_menu ;;
|
||||
*hardware*) show_hardware_menu ;;
|
||||
*workspace*) show_workspace_menu ;;
|
||||
*share*) show_share_menu ;;
|
||||
*transcode*) show_transcode_menu ;;
|
||||
*background*) show_background_menu ;;
|
||||
*capture*) show_capture_menu ;;
|
||||
*style*) show_style_menu ;;
|
||||
|
||||
@@ -4,8 +4,13 @@
|
||||
# omarchy:args=<packages...>
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
installed=()
|
||||
for pkg in "$@"; do
|
||||
if pacman -Q "$pkg" &>/dev/null; then
|
||||
sudo pacman -Rns --noconfirm "$pkg"
|
||||
installed+=("$pkg")
|
||||
fi
|
||||
done
|
||||
|
||||
if (( ${#installed[@]} > 0 )); then
|
||||
sudo pacman -Rns --noconfirm "${installed[@]}"
|
||||
fi
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# omarchy:summary=Overwrite the user config for the Plymouth drive decryption and boot sequence with the Omarchy default and rebuild it.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
sudo cp ~/.local/share/omarchy/default/plymouth/* /usr/share/plymouth/themes/omarchy/
|
||||
sudo cp -r ~/.local/share/omarchy/default/plymouth/* /usr/share/plymouth/themes/omarchy/
|
||||
sudo plymouth-set-default-theme omarchy
|
||||
|
||||
if command -v limine-mkinitcpio &>/dev/null; then
|
||||
|
||||
@@ -16,5 +16,11 @@ omarchy-refresh-config walker/config.toml
|
||||
omarchy-refresh-config elephant/calc.toml
|
||||
omarchy-refresh-config elephant/desktopapplications.toml
|
||||
|
||||
# Link all elephant menus
|
||||
mkdir -p ~/.config/elephant/menus
|
||||
for menu in $OMARCHY_PATH/default/elephant/*.lua; do
|
||||
ln -snf "$menu" ~/.config/elephant/menus/"$(basename "$menu")"
|
||||
done
|
||||
|
||||
# Restart service
|
||||
omarchy-restart-walker
|
||||
|
||||
@@ -5,4 +5,5 @@
|
||||
|
||||
omarchy-refresh-config waybar/config.jsonc
|
||||
omarchy-refresh-config waybar/style.css
|
||||
echo "top" >"$HOME/.config/waybar/.style"
|
||||
omarchy-restart-waybar
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove the GeForce NOW Flatpak app and its data.
|
||||
|
||||
set -e
|
||||
|
||||
if command -v flatpak >/dev/null && flatpak info com.nvidia.geforcenow &>/dev/null; then
|
||||
flatpak uninstall -y --delete-data com.nvidia.geforcenow
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "GeForce NOW removed."
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove Heroic Games Launcher and its game libraries, configs, and caches.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-pkg-drop heroic-games-launcher-bin
|
||||
|
||||
rm -rf \
|
||||
"$HOME/.config/heroic" \
|
||||
"$HOME/.local/share/heroic" \
|
||||
"$HOME/.cache/heroic" \
|
||||
"$HOME/Games/Heroic"
|
||||
|
||||
echo ""
|
||||
echo "Heroic and its data have been removed."
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove Lutris, Wine, umu-launcher, and all their configs and caches.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-pkg-drop lutris wine-staging wine-mono wine-gecko winetricks python-protobuf umu-launcher
|
||||
|
||||
rm -rf \
|
||||
"$HOME/.config/lutris" \
|
||||
"$HOME/.local/share/lutris" \
|
||||
"$HOME/.cache/lutris" \
|
||||
"$HOME/.local/share/umu" \
|
||||
"$HOME/.cache/umu" \
|
||||
"$HOME/.wine" \
|
||||
"$HOME/.cache/wine" \
|
||||
"$HOME/.cache/winetricks"
|
||||
|
||||
echo ""
|
||||
echo "Lutris, Wine, umu-launcher, and their configs have been removed."
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove the Minecraft launcher along with its worlds, mods, and caches.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-pkg-drop minecraft-launcher
|
||||
|
||||
rm -rf \
|
||||
"$HOME/.minecraft" \
|
||||
"$HOME/.config/Minecraft Launcher" \
|
||||
"$HOME/.local/share/minecraft-launcher" \
|
||||
"$HOME/.cache/minecraft"
|
||||
|
||||
echo ""
|
||||
echo "Minecraft and its data have been removed."
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove Moonlight and its configs and caches.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-pkg-drop moonlight-qt
|
||||
|
||||
rm -rf \
|
||||
"$HOME/.config/Moonlight Game Streaming Project" \
|
||||
"$HOME/.cache/Moonlight Game Streaming Project"
|
||||
|
||||
echo ""
|
||||
echo "Moonlight and its data have been removed."
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove RetroArch, all libretro cores, and its config/saves. Leaves ~/Games/roms and ~/Games/bios alone.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-pkg-drop \
|
||||
retroarch \
|
||||
retroarch-assets-glui retroarch-assets-ozone retroarch-assets-xmb \
|
||||
libretro-beetle-pce libretro-beetle-pce-fast libretro-beetle-psx libretro-beetle-psx-hw libretro-beetle-supergrafx \
|
||||
libretro-blastem \
|
||||
libretro-bsnes libretro-bsnes-hd libretro-bsnes2014 \
|
||||
libretro-core-info \
|
||||
libretro-desmume libretro-dolphin libretro-flycast \
|
||||
libretro-gambatte libretro-genesis-plus-gx \
|
||||
libretro-kronos \
|
||||
libretro-mame libretro-mame2016 libretro-melonds libretro-mesen libretro-mesen-s libretro-mgba libretro-mupen64plus-next \
|
||||
libretro-nestopia \
|
||||
libretro-overlays \
|
||||
libretro-parallel-n64 libretro-picodrive libretro-play libretro-ppsspp \
|
||||
libretro-sameboy libretro-scummvm libretro-shaders-slang libretro-snes9x \
|
||||
libretro-yabause \
|
||||
libretro-fbneo-git \
|
||||
retroarch-joypad-autoconfig-git
|
||||
|
||||
rm -rf \
|
||||
"$HOME/.config/retroarch" \
|
||||
"$HOME/.local/share/retroarch" \
|
||||
"$HOME/.cache/retroarch"
|
||||
|
||||
echo ""
|
||||
echo "RetroArch and its cores have been removed."
|
||||
echo "ROMs and BIOS files at ~/Games/roms and ~/Games/bios were left in place."
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove Steam and all of its game libraries, configs, and caches.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-pkg-drop steam
|
||||
|
||||
rm -rf \
|
||||
"$HOME/.steam" \
|
||||
"$HOME/.local/share/Steam" \
|
||||
"$HOME/.config/steam" \
|
||||
"$HOME/.cache/steam"
|
||||
|
||||
echo ""
|
||||
echo "Steam and its data have been removed."
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove the Xbox Cloud Gaming web app.
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-webapp-remove "Xbox Cloud Gaming"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Remove the xpadneo Xbox controller driver and undo its module/blacklist config.
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-pkg-drop xpadneo-dkms
|
||||
|
||||
sudo rm -f /etc/modprobe.d/blacklist-xpad.conf /etc/modules-load.d/xpadneo.conf
|
||||
|
||||
echo ""
|
||||
echo "Xbox controller support removed. Reboot to fully unload xpadneo and restore xpad."
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Reload Helix configuration (used by the Omarchy theme switching).
|
||||
# omarchy:summary=Reload Helix configuration
|
||||
|
||||
if pgrep -x helix >/dev/null; then
|
||||
pkill -USR1 helix
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
for dev in /sys/bus/i2c/drivers/i2c_hid_acpi/i2c-*; do
|
||||
[ -e "$dev" ] || continue
|
||||
[[ -e $dev ]] || continue
|
||||
I2C_DEVICE=$(basename "$dev")
|
||||
echo "Resetting $I2C_DEVICE via i2c_hid_acpi unbind/rebind..."
|
||||
echo "$I2C_DEVICE" | sudo tee /sys/bus/i2c/drivers/i2c_hid_acpi/unbind > /dev/null
|
||||
|
||||
Executable
+384
@@ -0,0 +1,384 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Set the screensaver logo text from an SVG/PNG or the default
|
||||
# omarchy:args=<default|path-to-logo.svg|png> [--width <columns>] [--height <rows>] [--mode <braille|block>] [--threshold <percent>] [--invert] [--stdout]
|
||||
# omarchy:examples=omarchy screensaver set logo ~/logo.svg | omarchy screensaver set logo default | omarchy screensaver set logo ~/logo.png --width 80 --mode block --stdout
|
||||
|
||||
set -o pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: omarchy-screensaver-set-logo <default|path-to-logo.svg|png> [options]
|
||||
|
||||
Sets the screensaver logo text from an image.
|
||||
Pass "default" instead of an image path to restore the Omarchy default.
|
||||
By default, writes to ~/.config/omarchy/branding/screensaver.txt.
|
||||
|
||||
Options:
|
||||
-w, --width <columns> Maximum output width in terminal columns (default: 80)
|
||||
-H, --height <rows> Maximum output height in terminal rows (default: 26)
|
||||
-m, --mode <braille|block> Output style (default: braille)
|
||||
-t, --threshold <percent> Pixel threshold from 0-100 (default: 50)
|
||||
--invert Treat light pixels as the logo instead of dark pixels
|
||||
--no-trim Preserve surrounding whitespace/background
|
||||
--stdout Print converted text instead of writing the screensaver file
|
||||
--help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
width=80
|
||||
height=26
|
||||
mode=braille
|
||||
threshold=50
|
||||
invert=false
|
||||
trim=true
|
||||
output_path="$HOME/.config/omarchy/branding/screensaver.txt"
|
||||
image_path=""
|
||||
reset_default=false
|
||||
|
||||
while (($# > 0)); do
|
||||
case "$1" in
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-w | --width)
|
||||
shift
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Missing value for --width" >&2
|
||||
exit 1
|
||||
fi
|
||||
width="$1"
|
||||
;;
|
||||
--width=*)
|
||||
width="${1#*=}"
|
||||
;;
|
||||
-H | --height)
|
||||
shift
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Missing value for --height" >&2
|
||||
exit 1
|
||||
fi
|
||||
height="$1"
|
||||
;;
|
||||
--height=*)
|
||||
height="${1#*=}"
|
||||
;;
|
||||
-m | --mode)
|
||||
shift
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Missing value for --mode" >&2
|
||||
exit 1
|
||||
fi
|
||||
mode="$1"
|
||||
;;
|
||||
--mode=*)
|
||||
mode="${1#*=}"
|
||||
;;
|
||||
--block | --blocks)
|
||||
mode=block
|
||||
;;
|
||||
--braille)
|
||||
mode=braille
|
||||
;;
|
||||
-t | --threshold)
|
||||
shift
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Missing value for --threshold" >&2
|
||||
exit 1
|
||||
fi
|
||||
threshold="$1"
|
||||
;;
|
||||
--threshold=*)
|
||||
threshold="${1#*=}"
|
||||
;;
|
||||
--invert)
|
||||
invert=true
|
||||
;;
|
||||
--no-trim)
|
||||
trim=false
|
||||
;;
|
||||
--stdout)
|
||||
output_path="-"
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
if [[ $1 == "default" && -z $image_path ]]; then
|
||||
reset_default=true
|
||||
elif [[ -z $image_path ]]; then
|
||||
image_path="$1"
|
||||
else
|
||||
echo "Unexpected argument: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if (($# > 0)); then
|
||||
while (($# > 0)); do
|
||||
if [[ $1 == "default" && -z $image_path ]]; then
|
||||
reset_default=true
|
||||
elif [[ -z $image_path ]]; then
|
||||
image_path="$1"
|
||||
else
|
||||
echo "Unexpected argument: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ $reset_default == "true" ]]; then
|
||||
if [[ -n $image_path ]]; then
|
||||
echo "default does not accept an image path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
default_path="${OMARCHY_PATH:-$HOME/.local/share/omarchy}/logo.txt"
|
||||
if [[ ! -f $default_path ]]; then
|
||||
echo "Default screensaver logo text not found: $default_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $output_path == "-" ]]; then
|
||||
cat "$default_path"
|
||||
else
|
||||
mkdir -p "$(dirname "$output_path")"
|
||||
cp "$default_path" "$output_path"
|
||||
echo "Restored default screensaver logo text to $output_path"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -z $image_path ]]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ $width =~ ^[0-9]+$ ]] || (( width < 1 )); then
|
||||
echo "Invalid width: $width" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ $height =~ ^[0-9]+$ ]] || (( height < 1 )); then
|
||||
echo "Invalid height: $height" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $mode != "braille" && $mode != "block" ]]; then
|
||||
echo "Invalid mode: $mode (expected braille or block)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ $threshold =~ ^[0-9]+$ ]] || (( threshold < 0 || threshold > 100 )); then
|
||||
echo "Invalid threshold: $threshold (expected 0-100)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f $image_path ]]; then
|
||||
echo "Logo file not found: $image_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if omarchy-cmd-missing magick; then
|
||||
echo "ImageMagick is required to convert logo images" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$mode" in
|
||||
braille)
|
||||
pixel_width=$((width * 2))
|
||||
pixel_height=$((height * 4))
|
||||
;;
|
||||
block)
|
||||
pixel_width=$width
|
||||
pixel_height=$((height * 2))
|
||||
;;
|
||||
esac
|
||||
|
||||
alpha_min=$(magick -background none "$image_path" -alpha extract -format '%[fx:minima]' info: 2>/dev/null) || {
|
||||
echo "Unable to read logo image: $image_path" >&2
|
||||
exit 1
|
||||
}
|
||||
alpha_max=$(magick -background none "$image_path" -alpha extract -format '%[fx:maxima]' info: 2>/dev/null) || {
|
||||
echo "Unable to read logo image: $image_path" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
use_alpha=false
|
||||
if awk -v min="$alpha_min" -v max="$alpha_max" 'BEGIN { exit !(min < 0.999 && max > min) }'; then
|
||||
use_alpha=true
|
||||
fi
|
||||
|
||||
magick_args=(-background none "$image_path" -auto-orient)
|
||||
|
||||
if [[ $use_alpha == "true" ]]; then
|
||||
magick_args+=(-alpha extract -alpha off)
|
||||
if [[ $invert == "true" ]]; then
|
||||
magick_args+=(-negate)
|
||||
fi
|
||||
else
|
||||
magick_args+=(-alpha remove -alpha off -colorspace Gray)
|
||||
if [[ $invert == "false" ]]; then
|
||||
magick_args+=(-negate)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $trim == "true" ]]; then
|
||||
magick_args+=(-bordercolor black -border 1 -trim +repage)
|
||||
fi
|
||||
|
||||
magick_args+=(-resize "${pixel_width}x${pixel_height}" -threshold "${threshold}%" -negate -compress none pbm:-)
|
||||
|
||||
tmp_output=$(mktemp)
|
||||
trap 'rm -f "$tmp_output"' EXIT
|
||||
|
||||
if [[ $mode == "braille" ]]; then
|
||||
if ! magick "${magick_args[@]}" | awk '
|
||||
BEGIN {
|
||||
braille_base = 10240
|
||||
dot[0,0] = 1
|
||||
dot[0,1] = 2
|
||||
dot[0,2] = 4
|
||||
dot[1,0] = 8
|
||||
dot[1,1] = 16
|
||||
dot[1,2] = 32
|
||||
dot[0,3] = 64
|
||||
dot[1,3] = 128
|
||||
}
|
||||
{
|
||||
sub(/#.*/, "")
|
||||
for (i = 1; i <= NF; i++) {
|
||||
token[++token_count] = $i
|
||||
}
|
||||
}
|
||||
END {
|
||||
if (token[1] != "P1") {
|
||||
exit 1
|
||||
}
|
||||
|
||||
width = token[2]
|
||||
height = token[3]
|
||||
pixel_offset = 4
|
||||
|
||||
for (y = 0; y < height; y += 4) {
|
||||
line = ""
|
||||
for (x = 0; x < width; x += 2) {
|
||||
code = 0
|
||||
for (dy = 0; dy < 4; dy++) {
|
||||
for (dx = 0; dx < 2; dx++) {
|
||||
if (y + dy < height && x + dx < width) {
|
||||
pixel = token[pixel_offset + ((y + dy) * width) + x + dx]
|
||||
if (pixel == 1) {
|
||||
code += dot[dx,dy]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (code == 0) {
|
||||
line = line " "
|
||||
} else {
|
||||
line = line sprintf("%c", braille_base + code)
|
||||
}
|
||||
}
|
||||
sub(/[ ]+$/, "", line)
|
||||
lines[++line_count] = line
|
||||
}
|
||||
|
||||
first = 1
|
||||
while (first <= line_count && lines[first] ~ /^[ ]*$/) {
|
||||
first++
|
||||
}
|
||||
|
||||
last = line_count
|
||||
while (last >= first && lines[last] ~ /^[ ]*$/) {
|
||||
last--
|
||||
}
|
||||
|
||||
for (i = first; i <= last; i++) {
|
||||
print lines[i]
|
||||
}
|
||||
}
|
||||
' >"$tmp_output"; then
|
||||
echo "Unable to convert logo image: $image_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if ! magick "${magick_args[@]}" | awk '
|
||||
BEGIN {
|
||||
block["11"] = "█"
|
||||
block["10"] = "▀"
|
||||
block["01"] = "▄"
|
||||
block["00"] = " "
|
||||
}
|
||||
{
|
||||
sub(/#.*/, "")
|
||||
for (i = 1; i <= NF; i++) {
|
||||
token[++token_count] = $i
|
||||
}
|
||||
}
|
||||
END {
|
||||
if (token[1] != "P1") {
|
||||
exit 1
|
||||
}
|
||||
|
||||
width = token[2]
|
||||
height = token[3]
|
||||
pixel_offset = 4
|
||||
|
||||
for (y = 0; y < height; y += 2) {
|
||||
line = ""
|
||||
for (x = 0; x < width; x++) {
|
||||
top = token[pixel_offset + (y * width) + x]
|
||||
bottom = (y + 1 < height) ? token[pixel_offset + ((y + 1) * width) + x] : 0
|
||||
line = line block[top bottom]
|
||||
}
|
||||
sub(/[ ]+$/, "", line)
|
||||
lines[++line_count] = line
|
||||
}
|
||||
|
||||
first = 1
|
||||
while (first <= line_count && lines[first] ~ /^[ ]*$/) {
|
||||
first++
|
||||
}
|
||||
|
||||
last = line_count
|
||||
while (last >= first && lines[last] ~ /^[ ]*$/) {
|
||||
last--
|
||||
}
|
||||
|
||||
for (i = first; i <= last; i++) {
|
||||
print lines[i]
|
||||
}
|
||||
}
|
||||
' >"$tmp_output"; then
|
||||
echo "Unable to convert logo image: $image_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -s $tmp_output ]]; then
|
||||
echo "No logo pixels found in: $image_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $output_path == "-" ]]; then
|
||||
cat "$tmp_output"
|
||||
else
|
||||
mkdir -p "$(dirname "$output_path")"
|
||||
cp "$tmp_output" "$output_path"
|
||||
echo "Wrote screensaver logo text to $output_path"
|
||||
fi
|
||||
@@ -37,8 +37,8 @@ case "$dns" in
|
||||
Cloudflare)
|
||||
sudo tee /etc/systemd/resolved.conf >/dev/null <<'EOF'
|
||||
[Resolve]
|
||||
DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com
|
||||
FallbackDNS=9.9.9.9 149.112.112.112
|
||||
DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com
|
||||
FallbackDNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
|
||||
DNSOverTLS=opportunistic
|
||||
EOF
|
||||
lock_dns_to_resolved
|
||||
@@ -47,8 +47,8 @@ EOF
|
||||
Google)
|
||||
sudo tee /etc/systemd/resolved.conf >/dev/null <<'EOF'
|
||||
[Resolve]
|
||||
DNS=8.8.8.8#dns.google 8.8.4.4#dns.google
|
||||
FallbackDNS=9.9.9.9 149.112.112.112
|
||||
DNS=8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google
|
||||
FallbackDNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
|
||||
DNSOverTLS=opportunistic
|
||||
EOF
|
||||
lock_dns_to_resolved
|
||||
@@ -74,7 +74,7 @@ Custom)
|
||||
sudo tee /etc/systemd/resolved.conf >/dev/null <<EOF
|
||||
[Resolve]
|
||||
DNS=$dns_servers
|
||||
FallbackDNS=9.9.9.9 149.112.112.112
|
||||
FallbackDNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
|
||||
EOF
|
||||
lock_dns_to_resolved
|
||||
;;
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
# omarchy:summary=Install a theme from a git repository
|
||||
# omarchy:args=[git-repo-url]
|
||||
# omarchy:examples=omarchy theme install https://github.com/example/omarchy-example-theme.git
|
||||
# omarchy:examples=omarchy theme install git@github.com:example/omarchy-example-theme.git
|
||||
|
||||
if [[ -z $1 ]]; then
|
||||
echo -e "\e[32mSee https://manuals.omamix.org/2/the-omarchy-manual/90/extra-themes\n\e[0m"
|
||||
REPO_URL=$(gum input --placeholder="Git repo URL for theme" --header="")
|
||||
REPO_URL=$(gum input --placeholder="Git repo URL (https or git@host:org/repo.git)" --header="")
|
||||
else
|
||||
REPO_URL="$1"
|
||||
fi
|
||||
@@ -16,7 +17,11 @@ if [[ -z $REPO_URL ]]; then
|
||||
fi
|
||||
|
||||
THEMES_DIR="$HOME/.config/omarchy/themes"
|
||||
THEME_NAME=$(basename "$REPO_URL" .git | sed -E 's/^omarchy-//; s/-theme$//' | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# Strip user@host: prefix from scp-style SSH URLs so basename sees just the path
|
||||
REPO_PATH="$REPO_URL"
|
||||
[[ $REPO_PATH != *"://"* && $REPO_PATH == *:*/* ]] && REPO_PATH="${REPO_PATH#*:}"
|
||||
THEME_NAME=$(basename "$REPO_PATH" .git | sed -E 's/^omarchy-//; s/-theme$//' | tr '[:upper:]' '[:lower:]')
|
||||
THEME_PATH="$THEMES_DIR/$THEME_NAME"
|
||||
|
||||
# Remove existing theme if present
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
THEME_NAME_PATH="$HOME/.config/omarchy/current/theme.name"
|
||||
|
||||
if [[ -f $THEME_NAME_PATH ]]; then
|
||||
omarchy-theme-set "$(cat $THEME_NAME_PATH)"
|
||||
OMARCHY_THEME_SKIP_BACKGROUND=1 omarchy-theme-set "$(cat $THEME_NAME_PATH)"
|
||||
fi
|
||||
|
||||
@@ -45,7 +45,9 @@ mv "$NEXT_THEME_PATH" "$CURRENT_THEME_PATH"
|
||||
echo "$THEME_NAME" >"$HOME/.config/omarchy/current/theme.name"
|
||||
|
||||
# Change background with theme
|
||||
omarchy-theme-bg-next
|
||||
if [[ $OMARCHY_THEME_SKIP_BACKGROUND != "1" ]]; then
|
||||
omarchy-theme-bg-next
|
||||
fi
|
||||
|
||||
# Restart components to apply new theme
|
||||
if pgrep -x waybar >/dev/null; then
|
||||
|
||||
Executable
+231
@@ -0,0 +1,231 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:group=transcode
|
||||
# omarchy:name=
|
||||
# omarchy:summary=Transcode pictures and videos for sharing
|
||||
# omarchy:args=[--path path] [input] [format] [resolution]
|
||||
# omarchy:examples=omarchy transcode|omarchy transcode --path ~/Downloads|omarchy transcode ~/Videos/demo.mov mp4 1080p|omarchy transcode ~/Pictures/wallpaper.heic jpg medium
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
omarchy transcode [--path path] [input] [format] [resolution]
|
||||
|
||||
With no input, fuzzy-pick a picture or video from ~/Pictures and ~/Videos,
|
||||
or only from --path when provided. Then pick the output format and resolution.
|
||||
|
||||
Options:
|
||||
--path path Limit interactive fuzzy file selection to this path
|
||||
|
||||
Formats:
|
||||
Pictures: jpg, png
|
||||
Videos: mp4, gif
|
||||
|
||||
Resolutions:
|
||||
Pictures: high, medium, low
|
||||
Videos: 4k, 1080p, 720p
|
||||
EOF
|
||||
}
|
||||
|
||||
pick_file() {
|
||||
local search_path="$1"
|
||||
local paths=()
|
||||
|
||||
if [[ -n $search_path ]]; then
|
||||
[[ -e $search_path ]] || { echo "Path not found: $search_path" >&2; return 1; }
|
||||
paths=("$search_path")
|
||||
else
|
||||
paths=("$HOME/Pictures" "$HOME/Videos")
|
||||
fi
|
||||
|
||||
find "${paths[@]}" -type f \
|
||||
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' -o -iname '*.gif' -o -iname '*.heic' -o -iname '*.avif' \
|
||||
-o -iname '*.mp4' -o -iname '*.mov' -o -iname '*.m4v' -o -iname '*.mkv' -o -iname '*.webm' -o -iname '*.avi' \) \
|
||||
-printf '%T@\t%p\n' 2>/dev/null | sort -rn | cut -f2- | fzf --layout=reverse-list --prompt="Transcode file> "
|
||||
}
|
||||
|
||||
pick_option() {
|
||||
local prompt="$1"
|
||||
shift
|
||||
|
||||
gum choose --header "$prompt" "$@"
|
||||
}
|
||||
|
||||
media_type() {
|
||||
local mime
|
||||
mime=$(file -b --mime-type "$1")
|
||||
|
||||
case "$mime" in
|
||||
image/*) echo picture ;;
|
||||
video/*) echo video ;;
|
||||
*)
|
||||
echo "Unsupported file type: $mime" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
output_path() {
|
||||
local input="$1"
|
||||
local format="$2"
|
||||
local resolution="$3"
|
||||
local dir base stem
|
||||
|
||||
dir=$(dirname -- "$input")
|
||||
base=$(basename -- "$input")
|
||||
stem="${base%.*}"
|
||||
|
||||
printf '%s/%s-%s.%s' "$dir" "$stem" "$resolution" "$format"
|
||||
}
|
||||
|
||||
transcode_picture() {
|
||||
local input="$1" format="$2" resolution="$3" output="$4"
|
||||
local resize
|
||||
|
||||
case "$resolution" in
|
||||
high) resize='3160x>' ;;
|
||||
medium) resize='2160x>' ;;
|
||||
low) resize='1080x>' ;;
|
||||
*)
|
||||
echo "Invalid picture resolution: $resolution" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$format" in
|
||||
jpg)
|
||||
magick "$input" -resize "$resize" -quality 85 -strip "$output"
|
||||
;;
|
||||
png)
|
||||
magick "$input" -resize "$resize" -strip -define png:compression-filter=5 \
|
||||
-define png:compression-level=9 \
|
||||
-define png:compression-strategy=1 \
|
||||
-define png:exclude-chunk=all \
|
||||
"$output"
|
||||
;;
|
||||
*)
|
||||
echo "Invalid picture format: $format" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
transcode_video() {
|
||||
local input="$1" format="$2" resolution="$3" output="$4"
|
||||
local scale
|
||||
|
||||
case "$resolution" in
|
||||
4k) scale='scale=-2:2160' ;;
|
||||
1080p) scale='scale=-2:1080' ;;
|
||||
720p) scale='scale=-2:720' ;;
|
||||
*)
|
||||
echo "Invalid video resolution: $resolution" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$format" in
|
||||
mp4)
|
||||
if [[ $resolution == "4k" ]]; then
|
||||
ffmpeg -i "$input" -vf "$scale" -c:v libx265 -preset slow -crf 24 -c:a aac -b:a 192k "$output"
|
||||
else
|
||||
ffmpeg -i "$input" -vf "$scale" -c:v libx264 -preset fast -crf 23 -c:a copy "$output"
|
||||
fi
|
||||
;;
|
||||
gif)
|
||||
ffmpeg -i "$input" -vf "fps=10,$scale:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" "$output"
|
||||
;;
|
||||
*)
|
||||
echo "Invalid video format: $format" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
copy_to_clipboard() {
|
||||
local output="$1"
|
||||
local uri
|
||||
|
||||
uri="file://$(realpath -- "$output")"
|
||||
printf '%s\n' "$uri" | wl-copy --type text/uri-list
|
||||
}
|
||||
|
||||
main() {
|
||||
local input="" format="" resolution="" search_path=""
|
||||
local type output positional=()
|
||||
|
||||
while (( $# > 0 )); do
|
||||
case "$1" in
|
||||
--path)
|
||||
shift
|
||||
[[ $# -gt 0 ]] || { echo "Missing value for --path" >&2; return 2; }
|
||||
search_path="$1"
|
||||
;;
|
||||
--help | -h)
|
||||
usage
|
||||
return 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
positional+=("$@")
|
||||
break
|
||||
;;
|
||||
--*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
return 2
|
||||
;;
|
||||
*)
|
||||
positional+=("$1")
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
input="${positional[0]:-}"
|
||||
format="${positional[1]:-}"
|
||||
resolution="${positional[2]:-}"
|
||||
|
||||
if [[ -z $input ]]; then
|
||||
input=$(pick_file "$search_path")
|
||||
fi
|
||||
|
||||
[[ -n $input ]] || return 1
|
||||
[[ -f $input ]] || { echo "File not found: $input" >&2; return 1; }
|
||||
|
||||
type=$(media_type "$input")
|
||||
|
||||
if [[ -z $format ]]; then
|
||||
if [[ $type == "picture" ]]; then
|
||||
format=$(pick_option "Select format..." jpg png)
|
||||
else
|
||||
format=$(pick_option "Select format..." mp4 gif)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z $resolution ]]; then
|
||||
if [[ $type == "picture" ]]; then
|
||||
resolution=$(pick_option "Select resolution..." high medium low)
|
||||
else
|
||||
resolution=$(pick_option "Select resolution..." 4k 1080p 720p)
|
||||
fi
|
||||
fi
|
||||
|
||||
output=$(output_path "$input" "$format" "$resolution")
|
||||
|
||||
if [[ $type == "picture" ]]; then
|
||||
transcode_picture "$input" "$format" "$resolution" "$output"
|
||||
else
|
||||
transcode_video "$input" "$format" "$resolution" "$output"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
copy_to_clipboard "$output"
|
||||
echo "Your $type has been transcoded into $format as $resolution. It's on your clipboard."
|
||||
echo ""
|
||||
echo "It's also in $output"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# omarchy:summary=Prompt for confirmation before starting an update
|
||||
|
||||
gum style --border normal --border-foreground 6 --padding "1 2" \
|
||||
gum style --border normal --padding "1 2" \
|
||||
"Ready to update?" \
|
||||
"" \
|
||||
"• You cannot stop the update once you start!" \
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
echo
|
||||
|
||||
running_kernel=$(uname -r)
|
||||
kernel_updated=false
|
||||
kernel_updated=true
|
||||
|
||||
for kernel in /usr/lib/modules/*/vmlinuz; do
|
||||
if [[ -f $kernel ]] && pacman -Qo "$kernel" &>/dev/null; then
|
||||
installed_kernel=$(basename "$(dirname "$kernel")")
|
||||
|
||||
if [[ $installed_kernel != $running_kernel ]]; then
|
||||
kernel_updated=true
|
||||
if [[ $installed_kernel == $running_kernel ]]; then
|
||||
kernel_updated=false
|
||||
break
|
||||
fi
|
||||
fi
|
||||
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Set Waybar style
|
||||
# omarchy:args=<top|pill|float|toggle|list>
|
||||
# omarchy:examples=omarchy waybar set pill | omarchy waybar set float | omarchy waybar set toggle
|
||||
|
||||
OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy}
|
||||
STYLE_DIR="$OMARCHY_PATH/config/waybar/styles"
|
||||
CONFIG_DIR="$OMARCHY_PATH/config/waybar/configs"
|
||||
CURRENT_STYLE_FILE="$HOME/.config/waybar/.style"
|
||||
STYLE=${1:-toggle}
|
||||
|
||||
list_styles() {
|
||||
for style in "$STYLE_DIR"/*.css; do
|
||||
[[ -e $style ]] || continue
|
||||
basename "$style" .css
|
||||
done
|
||||
}
|
||||
|
||||
current_style() {
|
||||
if [[ -f $CURRENT_STYLE_FILE ]]; then
|
||||
read -r current <"$CURRENT_STYLE_FILE"
|
||||
[[ -n $current ]] && printf '%s\n' "$current" && return
|
||||
fi
|
||||
|
||||
echo "top"
|
||||
}
|
||||
|
||||
if [[ $STYLE == "list" ]]; then
|
||||
list_styles
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ $STYLE == "default" ]]; then
|
||||
STYLE="top"
|
||||
fi
|
||||
|
||||
if [[ $STYLE == "toggle" ]]; then
|
||||
if [[ $(current_style) == "pill" ]]; then
|
||||
STYLE="top"
|
||||
else
|
||||
STYLE="pill"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -f $STYLE_DIR/$STYLE.css || ! -f $CONFIG_DIR/$STYLE.jsonc ]]; then
|
||||
echo "Unknown Waybar style '$STYLE'"
|
||||
echo "Available styles:"
|
||||
list_styles
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$HOME/.config/waybar"
|
||||
cp "$CONFIG_DIR/$STYLE.jsonc" "$HOME/.config/waybar/config.jsonc"
|
||||
cp "$STYLE_DIR/$STYLE.css" "$HOME/.config/waybar/style.css"
|
||||
echo "$STYLE" >"$CURRENT_STYLE_FILE"
|
||||
|
||||
omarchy-restart-waybar
|
||||
Executable
+395
@@ -0,0 +1,395 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Restore the saved layout for the current Hyprland workspace
|
||||
# omarchy:args=
|
||||
# omarchy:examples=omarchy workspace restore
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
monitor=$(omarchy-hyprland-monitor-focused)
|
||||
workspace=$(hyprctl monitors -j | jq -r --arg monitor "$monitor" '.[] | select(.name == $monitor) | .activeWorkspace.id')
|
||||
file="$HOME/.config/hypr/workspaces/$monitor-$workspace.tsv"
|
||||
|
||||
if [[ ! -f $file ]]; then
|
||||
notify-send -u low " No saved workspace $workspace for $monitor" "$file" -t 3000
|
||||
exit 1
|
||||
fi
|
||||
|
||||
restore_data=$(grep -v '^#' "$file" || true)
|
||||
|
||||
if [[ -z $restore_data ]]; then
|
||||
notify-send -u low " No windows saved for workspace $workspace" "$file" -t 3000
|
||||
exit 1
|
||||
fi
|
||||
|
||||
restore_map=$(mktemp)
|
||||
assigned_addresses=$(mktemp)
|
||||
trap 'rm -f "$restore_map" "$assigned_addresses"' EXIT
|
||||
|
||||
declare -a classes commands xs ys ws hs focuseds addresses launched
|
||||
count=0
|
||||
|
||||
while IFS=$'\t' read -r _ saved_workspace mode class command x y w h focused; do
|
||||
[[ -n $class ]] || continue
|
||||
|
||||
workspace=$saved_workspace
|
||||
classes[count]=$class
|
||||
commands[count]=$command
|
||||
xs[count]=$x
|
||||
ys[count]=$y
|
||||
ws[count]=$w
|
||||
hs[count]=$h
|
||||
focuseds[count]=${focused:-false}
|
||||
addresses[count]=""
|
||||
launched[count]=false
|
||||
(( count += 1 ))
|
||||
done <<< "$restore_data"
|
||||
|
||||
hyprctl dispatch workspace "$workspace" >/dev/null
|
||||
|
||||
for (( i = 0; i < count; i++ )); do
|
||||
class=${classes[i]}
|
||||
hyprctl keyword windowrulev2 "workspace $workspace silent,class:^($class)$" >/dev/null
|
||||
|
||||
if [[ ${mode:-tiled} == "floating" ]]; then
|
||||
hyprctl keyword windowrulev2 "float,class:^($class)$" >/dev/null
|
||||
else
|
||||
hyprctl keyword windowrulev2 "tile,class:^($class)$" >/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
existing_unassigned_json() {
|
||||
local class=$1
|
||||
|
||||
{
|
||||
hyprctl clients -j | jq -r --arg class "$class" '.[] | select(.class == $class or .initialClass == $class) | .address' |
|
||||
grep -Fvx -f "$assigned_addresses" || true
|
||||
} | jq -R -s -c 'split("\n")[:-1]'
|
||||
}
|
||||
|
||||
wait_for_address() {
|
||||
local class=$1
|
||||
local existing=${2:-[]}
|
||||
local tries=0
|
||||
local address=""
|
||||
|
||||
while [[ -z $address ]]; do
|
||||
address=$(hyprctl clients -j | jq -r --arg class "$class" --argjson existing "$existing" \
|
||||
'.[] | select((.class == $class or .initialClass == $class) and (.address as $address | $existing | index($address) | not)) | .address' | head -n1)
|
||||
|
||||
if [[ -n $address ]]; then
|
||||
printf '%s\n' "$address"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sleep 0.2
|
||||
(( tries += 1 ))
|
||||
|
||||
# Single-instance apps may focus/reuse an existing window instead of creating a new one.
|
||||
if (( tries >= 25 )) && [[ $existing != "[]" ]]; then
|
||||
jq -r '.[0]' <<< "$existing"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if (( tries >= 75 )); then
|
||||
echo "Timed out waiting for $class" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
ensure_window() {
|
||||
local id=$1
|
||||
local class=${classes[id]}
|
||||
local command=${commands[id]}
|
||||
local existing address
|
||||
|
||||
if [[ ${launched[id]} == "true" ]]; then
|
||||
last_address=${addresses[id]}
|
||||
return 0
|
||||
fi
|
||||
|
||||
existing=$(existing_unassigned_json "$class")
|
||||
|
||||
if [[ $existing != "[]" && ( $class == chrome-* || $class == chromium* ) ]]; then
|
||||
address=$(jq -r '.[0]' <<< "$existing")
|
||||
else
|
||||
hyprctl dispatch exec "[workspace $workspace silent] $command" >/dev/null
|
||||
address=$(wait_for_address "$class" "$existing") || return 1
|
||||
fi
|
||||
|
||||
hyprctl dispatch movetoworkspacesilent "$workspace,address:$address" >/dev/null || true
|
||||
|
||||
if [[ ${mode:-tiled} == "floating" ]]; then
|
||||
hyprctl dispatch setfloating "address:$address" >/dev/null || true
|
||||
hyprctl dispatch resizewindowpixel exact "${ws[id]}" "${hs[id]}",address:"$address" >/dev/null || true
|
||||
hyprctl dispatch movewindowpixel exact "${xs[id]}" "${ys[id]}",address:"$address" >/dev/null || true
|
||||
else
|
||||
hyprctl dispatch settiled "address:$address" >/dev/null || true
|
||||
hyprctl dispatch focuswindow "address:$address" >/dev/null || true
|
||||
fi
|
||||
|
||||
addresses[id]=$address
|
||||
launched[id]=true
|
||||
printf '%s\n' "$address" >>"$assigned_addresses"
|
||||
printf '%s\t%s\t%s\t%s\t%s\t%s\n' "$address" "$id" "${xs[id]}" "${ys[id]}" "${ws[id]}" "${hs[id]}" >>"$restore_map"
|
||||
|
||||
if [[ ${focuseds[id]} == "true" ]]; then
|
||||
focused_address=$address
|
||||
fi
|
||||
|
||||
sleep 0.4
|
||||
last_address=$address
|
||||
}
|
||||
|
||||
choose_rep() {
|
||||
local best=""
|
||||
local best_area=-1
|
||||
local id area
|
||||
|
||||
for id in "$@"; do
|
||||
area=$(( ws[id] * hs[id] ))
|
||||
if (( area > best_area )); then
|
||||
best=$id
|
||||
best_area=$area
|
||||
fi
|
||||
done
|
||||
|
||||
printf '%s\n' "$best"
|
||||
}
|
||||
|
||||
find_launched_address() {
|
||||
local id
|
||||
|
||||
for id in "$@"; do
|
||||
if [[ ${launched[id]} == "true" ]]; then
|
||||
printf '%s\n' "${addresses[id]}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
opposite_direction() {
|
||||
case $1 in
|
||||
l) echo r ;;
|
||||
r) echo l ;;
|
||||
u) echo d ;;
|
||||
d) echo u ;;
|
||||
esac
|
||||
}
|
||||
|
||||
abs() {
|
||||
local value=$1
|
||||
if (( value < 0 )); then
|
||||
echo $(( -value ))
|
||||
else
|
||||
echo "$value"
|
||||
fi
|
||||
}
|
||||
|
||||
find_partition() {
|
||||
local ids=("$@")
|
||||
local best_score=9223372036854775807
|
||||
local best_a=""
|
||||
local best_b=""
|
||||
local best_dir=""
|
||||
local orientation i j id edge start cut gap right bottom area_a area_b score valid a b
|
||||
|
||||
for orientation in v h; do
|
||||
for i in "${ids[@]}"; do
|
||||
for j in "${ids[@]}"; do
|
||||
if [[ $orientation == "v" ]]; then
|
||||
edge=$(( xs[i] + ws[i] ))
|
||||
start=${xs[j]}
|
||||
[[ $edge -lt $start ]] || continue
|
||||
else
|
||||
edge=$(( ys[i] + hs[i] ))
|
||||
start=${ys[j]}
|
||||
[[ $edge -lt $start ]] || continue
|
||||
fi
|
||||
|
||||
cut=$(( (edge + start) / 2 ))
|
||||
gap=$(( start - edge ))
|
||||
valid=true
|
||||
a=""
|
||||
b=""
|
||||
area_a=0
|
||||
area_b=0
|
||||
|
||||
for id in "${ids[@]}"; do
|
||||
if [[ $orientation == "v" ]]; then
|
||||
right=$(( xs[id] + ws[id] ))
|
||||
if (( right <= cut )); then
|
||||
a="$a $id"
|
||||
area_a=$(( area_a + ws[id] * hs[id] ))
|
||||
elif (( xs[id] >= cut )); then
|
||||
b="$b $id"
|
||||
area_b=$(( area_b + ws[id] * hs[id] ))
|
||||
else
|
||||
valid=false
|
||||
break
|
||||
fi
|
||||
else
|
||||
bottom=$(( ys[id] + hs[id] ))
|
||||
if (( bottom <= cut )); then
|
||||
a="$a $id"
|
||||
area_a=$(( area_a + ws[id] * hs[id] ))
|
||||
elif (( ys[id] >= cut )); then
|
||||
b="$b $id"
|
||||
area_b=$(( area_b + ws[id] * hs[id] ))
|
||||
else
|
||||
valid=false
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
[[ $valid == "true" && -n $a && -n $b ]] || continue
|
||||
|
||||
score=$(abs $(( area_a - area_b )))
|
||||
score=$(( score * 1000 - gap ))
|
||||
|
||||
if (( score < best_score )); then
|
||||
best_score=$score
|
||||
best_a=${a# }
|
||||
best_b=${b# }
|
||||
if [[ $orientation == "v" ]]; then
|
||||
best_dir=r
|
||||
else
|
||||
best_dir=d
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
if [[ -z $best_a || -z $best_b ]]; then
|
||||
fallback_partition "${ids[@]}"
|
||||
return
|
||||
fi
|
||||
|
||||
read -r -a part_a <<< "$best_a"
|
||||
read -r -a part_b <<< "$best_b"
|
||||
part_dir=$best_dir
|
||||
}
|
||||
|
||||
fallback_partition() {
|
||||
local ids=("$@")
|
||||
local sorted=()
|
||||
local line id bbox_min_x=999999 bbox_min_y=999999 bbox_max_x=0 bbox_max_y=0 bbox_w bbox_h key index
|
||||
|
||||
for id in "${ids[@]}"; do
|
||||
(( xs[id] < bbox_min_x )) && bbox_min_x=${xs[id]}
|
||||
(( ys[id] < bbox_min_y )) && bbox_min_y=${ys[id]}
|
||||
(( xs[id] + ws[id] > bbox_max_x )) && bbox_max_x=$(( xs[id] + ws[id] ))
|
||||
(( ys[id] + hs[id] > bbox_max_y )) && bbox_max_y=$(( ys[id] + hs[id] ))
|
||||
done
|
||||
|
||||
bbox_w=$(( bbox_max_x - bbox_min_x ))
|
||||
bbox_h=$(( bbox_max_y - bbox_min_y ))
|
||||
|
||||
while read -r line; do
|
||||
sorted+=("${line#* }")
|
||||
done < <(
|
||||
for id in "${ids[@]}"; do
|
||||
if (( bbox_w >= bbox_h )); then
|
||||
key=${xs[id]}
|
||||
else
|
||||
key=${ys[id]}
|
||||
fi
|
||||
printf '%s %s\n' "$key" "$id"
|
||||
done | sort -n
|
||||
)
|
||||
|
||||
part_a=()
|
||||
part_b=()
|
||||
for index in "${!sorted[@]}"; do
|
||||
if (( index < ${#sorted[@]} / 2 )); then
|
||||
part_a+=("${sorted[index]}")
|
||||
else
|
||||
part_b+=("${sorted[index]}")
|
||||
fi
|
||||
done
|
||||
|
||||
if (( bbox_w >= bbox_h )); then
|
||||
part_dir=r
|
||||
else
|
||||
part_dir=d
|
||||
fi
|
||||
}
|
||||
|
||||
materialize_group() {
|
||||
local ids=("$@")
|
||||
local rep_a rep_b addr_a addr_b dir opposite
|
||||
|
||||
if (( ${#ids[@]} == 0 )); then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if (( ${#ids[@]} == 1 )); then
|
||||
ensure_window "${ids[0]}" >/dev/null || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
find_partition "${ids[@]}"
|
||||
dir=$part_dir
|
||||
opposite=$(opposite_direction "$dir")
|
||||
|
||||
addr_a=$(find_launched_address "${part_a[@]}" || true)
|
||||
addr_b=$(find_launched_address "${part_b[@]}" || true)
|
||||
|
||||
if [[ -z $addr_a && -z $addr_b ]]; then
|
||||
rep_a=$(choose_rep "${part_a[@]}")
|
||||
ensure_window "$rep_a" || return 0
|
||||
addr_a=$last_address
|
||||
hyprctl dispatch focuswindow "address:$addr_a" >/dev/null || true
|
||||
hyprctl dispatch layoutmsg preselect "$dir" >/dev/null || true
|
||||
rep_b=$(choose_rep "${part_b[@]}")
|
||||
ensure_window "$rep_b" || true
|
||||
addr_b=${last_address:-}
|
||||
elif [[ -n $addr_a && -z $addr_b ]]; then
|
||||
hyprctl dispatch focuswindow "address:$addr_a" >/dev/null || true
|
||||
hyprctl dispatch layoutmsg preselect "$dir" >/dev/null || true
|
||||
rep_b=$(choose_rep "${part_b[@]}")
|
||||
ensure_window "$rep_b" || true
|
||||
addr_b=${last_address:-}
|
||||
elif [[ -z $addr_a && -n $addr_b ]]; then
|
||||
hyprctl dispatch focuswindow "address:$addr_b" >/dev/null || true
|
||||
hyprctl dispatch layoutmsg preselect "$opposite" >/dev/null || true
|
||||
rep_a=$(choose_rep "${part_a[@]}")
|
||||
ensure_window "$rep_a" || true
|
||||
addr_a=${last_address:-}
|
||||
fi
|
||||
|
||||
materialize_group "${part_a[@]}"
|
||||
materialize_group "${part_b[@]}"
|
||||
}
|
||||
|
||||
ids=()
|
||||
for (( i = 0; i < count; i++ )); do
|
||||
ids+=("$i")
|
||||
done
|
||||
|
||||
if [[ ${mode:-tiled} == "floating" ]]; then
|
||||
for id in "${ids[@]}"; do
|
||||
ensure_window "$id" >/dev/null || true
|
||||
done
|
||||
else
|
||||
materialize_group "${ids[@]}"
|
||||
|
||||
for _ in 1 2 3 4; do
|
||||
while IFS=$'\t' read -r address _ _ _ w h; do
|
||||
hyprctl dispatch resizewindowpixel exact "$w" "$h",address:"$address" >/dev/null || true
|
||||
done < <(sort -t $'\t' -k3,3n -k4,4n "$restore_map")
|
||||
sleep 0.1
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ -n ${focused_address:-} ]]; then
|
||||
hyprctl dispatch focuswindow "address:$focused_address" >/dev/null || true
|
||||
fi
|
||||
|
||||
notify-send -u low " Restored workspace $workspace for $monitor" -t 3000
|
||||
hyprctl dispatch workspace "$workspace" >/dev/null
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Save the current Hyprland workspace app layout to ~/.config/hypr/workspaces/<monitor-name>-<workspace-id>.tsv
|
||||
# omarchy:args=
|
||||
# omarchy:examples=omarchy workspace save
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
monitor=$(omarchy-hyprland-monitor-focused)
|
||||
workspace=$(hyprctl monitors -j | jq -r --arg monitor "$monitor" '.[] | select(.name == $monitor) | .activeWorkspace.id')
|
||||
|
||||
mkdir -p ~/.config/hypr/workspaces
|
||||
file="$HOME/.config/hypr/workspaces/$monitor-$workspace.tsv"
|
||||
clients=$(hyprctl clients -j)
|
||||
active_address=$(hyprctl activewindow -j | jq -r '.address // ""')
|
||||
|
||||
webapp_command() {
|
||||
local class=$1
|
||||
local initial_title=$2
|
||||
local encoded host path
|
||||
|
||||
[[ $class == chrome-* ]] || return 1
|
||||
|
||||
if [[ $initial_title == http://* || $initial_title == https://* ]]; then
|
||||
printf 'omarchy-launch-webapp %s\n' "${initial_title//_/\/}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
encoded=${class#chrome-}
|
||||
encoded=${encoded%-Default}
|
||||
|
||||
if [[ $encoded == *__* ]]; then
|
||||
host=${encoded%%__*}
|
||||
path=${encoded#*__}
|
||||
printf 'omarchy-launch-webapp https://%s/%s\n' "$host" "${path//_/\/}"
|
||||
else
|
||||
printf 'omarchy-launch-webapp https://%s\n' "${encoded//_/\/}"
|
||||
fi
|
||||
}
|
||||
|
||||
launch_command() {
|
||||
local class=$1
|
||||
local initial_title=$2
|
||||
local pid=$3
|
||||
|
||||
if webapp_command "$class" "$initial_title"; then
|
||||
return 0
|
||||
elif [[ -r /proc/$pid/cmdline ]]; then
|
||||
tr '\0' ' ' <"/proc/$pid/cmdline" | sed 's/[[:space:]]*$//'
|
||||
else
|
||||
echo "$class"
|
||||
fi
|
||||
}
|
||||
|
||||
{
|
||||
printf '# monitor\tworkspace\tmode\tclass\tcommand\tx\ty\tw\th\tfocused\n'
|
||||
|
||||
jq -r --argjson workspace "$workspace" '
|
||||
[.[] | select(.workspace.id == $workspace)]
|
||||
| sort_by(.at[0], .at[1])
|
||||
| .[]
|
||||
| [(.initialClass // .class), .initialTitle, .pid, .at[0], .at[1], .size[0], .size[1], .address]
|
||||
| @tsv
|
||||
' <<< "$clients" | while IFS=$'\t' read -r class initial_title pid x y w h address; do
|
||||
command=$(launch_command "$class" "$initial_title" "$pid")
|
||||
focused=false
|
||||
if [[ $address == "$active_address" ]]; then
|
||||
focused=true
|
||||
fi
|
||||
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$monitor" "$workspace" "tiled" "$class" "$command" "$x" "$y" "$w" "$h" "$focused"
|
||||
done
|
||||
} >"$file"
|
||||
|
||||
notify-send -u low " Saved workspace $workspace for $monitor" -t 3000
|
||||
@@ -1,4 +1 @@
|
||||
--ozone-platform=wayland
|
||||
--ozone-platform-hint=wayland
|
||||
--enable-features=TouchpadOverscrollHistoryNavigation
|
||||
--load-extension=~/.local/share/omarchy/default/chromium/extensions/copy-url
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--ozone-platform=wayland
|
||||
--ozone-platform-hint=wayland
|
||||
--enable-features=TouchpadOverscrollHistoryNavigation
|
||||
--enable-features=TouchpadOverscrollHistoryNavigation,VaapiVideoDecodeLinuxGL,VaapiVideoEncoder
|
||||
--load-extension=~/.local/share/omarchy/default/chromium/extensions/copy-url
|
||||
|
||||
@@ -27,7 +27,7 @@ input {
|
||||
# natural_scroll = true
|
||||
|
||||
# Use two-finger clicks for right-click instead of lower-right corner
|
||||
# clickfinger_behavior = true
|
||||
clickfinger_behavior = true
|
||||
|
||||
# Control the speed of your scrolling
|
||||
scroll_factor = 0.4
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"reload_style_on_change": true,
|
||||
"layer": "top",
|
||||
"position": "top",
|
||||
"spacing": 0,
|
||||
"height": 26,
|
||||
"margin-top": 10,
|
||||
"margin-left": 10,
|
||||
"margin-right": 10,
|
||||
"modules-left": ["custom/omarchy", "hyprland/workspaces", "hyprland/window"],
|
||||
"modules-center": ["clock", "custom/update", "custom/screenrecording-indicator", "custom/idle-indicator", "custom/notification-silencing-indicator"],
|
||||
"modules-right": [
|
||||
"mpris",
|
||||
"group/tray-expander",
|
||||
"backlight",
|
||||
"network",
|
||||
"bluetooth",
|
||||
"pulseaudio",
|
||||
"cpu",
|
||||
"battery"
|
||||
],
|
||||
"hyprland/workspaces": {
|
||||
"on-click": "activate",
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"default": "",
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7",
|
||||
"8": "8",
|
||||
"9": "9",
|
||||
"10": "0",
|
||||
"active": ""
|
||||
},
|
||||
"persistent-workspaces": {
|
||||
"1": [],
|
||||
"2": [],
|
||||
"3": [],
|
||||
"4": [],
|
||||
"5": []
|
||||
}
|
||||
},
|
||||
"custom/omarchy": {
|
||||
"format": "<span font='omarchy'>\ue900</span>",
|
||||
"on-click": "omarchy-menu",
|
||||
"on-click-right": "xdg-terminal-exec",
|
||||
"tooltip-format": "Omarchy Menu\n\nSuper + Alt + Space"
|
||||
},
|
||||
"custom/update": {
|
||||
"format": "",
|
||||
"exec": "omarchy-update-available",
|
||||
"on-click": "omarchy-launch-floating-terminal-with-presentation omarchy-update",
|
||||
"tooltip-format": "Omarchy update available",
|
||||
"signal": 7,
|
||||
"interval": 21600
|
||||
},
|
||||
"cpu": {
|
||||
"interval": 5,
|
||||
"format": "",
|
||||
"on-click": "omarchy-launch-or-focus-tui btop",
|
||||
"on-click-right": "alacritty"
|
||||
},
|
||||
"clock": {
|
||||
"format": "{:%I:%M %p}",
|
||||
"format-alt": "{:%A %d/%m/%Y}",
|
||||
"tooltip-format": "<span>{calendar}</span>",
|
||||
"on-click-right": "omarchy-launch-floating-terminal-with-presentation omarchy-tz-select"
|
||||
},
|
||||
"network": {
|
||||
"format-icons": ["", "", "", "", ""],
|
||||
"format": "{icon} {essid}",
|
||||
"format-wifi": "{icon} {essid}",
|
||||
"format-ethernet": "",
|
||||
"format-disconnected": "",
|
||||
"tooltip-format-wifi": "{essid} ({frequency} GHz)\n⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}",
|
||||
"tooltip-format-ethernet": "⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}",
|
||||
"tooltip-format-disconnected": "Disconnected",
|
||||
"interval": 3,
|
||||
"spacing": 1,
|
||||
"on-click": "omarchy-launch-wifi"
|
||||
},
|
||||
"battery": {
|
||||
"format": "{capacity}% {icon}",
|
||||
"format-discharging": "{icon}",
|
||||
"format-charging": "{icon}",
|
||||
"format-plugged": "",
|
||||
"format-icons": {
|
||||
"charging": ["", "", "", "", "", "", "", "", "", ""],
|
||||
"default": ["", "", "", "", "", "", "", "", "", ""]
|
||||
},
|
||||
"format-full": "",
|
||||
"tooltip-format-discharging": "{power:>1.0f}W↓ {capacity}%",
|
||||
"tooltip-format-charging": "{power:>1.0f}W↑ {capacity}%",
|
||||
"interval": 5,
|
||||
"on-click": "omarchy-menu power",
|
||||
"on-click-right": "notify-send -u low \"$(omarchy-battery-status)\"",
|
||||
"states": {
|
||||
"warning": 20,
|
||||
"critical": 10
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"format": "",
|
||||
"format-off": "",
|
||||
"format-disabled": "",
|
||||
"format-connected": "",
|
||||
"format-no-controller": "",
|
||||
"tooltip-format": "Devices connected: {num_connections}",
|
||||
"on-click": "omarchy-launch-bluetooth"
|
||||
},
|
||||
"pulseaudio": {
|
||||
"format": "{icon}",
|
||||
"on-click": "omarchy-launch-audio",
|
||||
"on-click-right": "pamixer -t",
|
||||
"tooltip-format": "Playing at {volume}%",
|
||||
"scroll-step": 5,
|
||||
"format-muted": "",
|
||||
"format-icons": {
|
||||
"headphone": "",
|
||||
"headset": "",
|
||||
"default": ["", "", ""]
|
||||
}
|
||||
},
|
||||
"group/tray-expander": {
|
||||
"orientation": "inherit",
|
||||
"drawer": {
|
||||
"transition-duration": 600,
|
||||
"children-class": "tray-group-item"
|
||||
},
|
||||
"modules": ["custom/expand-icon", "tray", "memory", "custom/weather"]
|
||||
},
|
||||
"custom/expand-icon": {
|
||||
"format": " ",
|
||||
"tooltip": false
|
||||
},
|
||||
"custom/screenrecording-indicator": {
|
||||
"on-click": "omarchy-capture-screenrecording",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/screen-recording.sh",
|
||||
"signal": 8,
|
||||
"return-type": "json"
|
||||
},
|
||||
"custom/idle-indicator": {
|
||||
"on-click": "omarchy-toggle-idle",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/idle.sh",
|
||||
"signal": 9,
|
||||
"return-type": "json"
|
||||
},
|
||||
"custom/notification-silencing-indicator": {
|
||||
"on-click": "omarchy-toggle-notification-silencing",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/notification-silencing.sh",
|
||||
"signal": 10,
|
||||
"return-type": "json"
|
||||
},
|
||||
"tray": {
|
||||
"icon-size": 12,
|
||||
"spacing": 12
|
||||
},
|
||||
"backlight": {
|
||||
"format": "{percent}% {icon}",
|
||||
"format-icons": ["🌑", "🌘", "🌗", "🌖", "🌕"]
|
||||
},
|
||||
"memory": {
|
||||
"format": " {used:0.1f}gb",
|
||||
"interval": 2,
|
||||
"on-click": "omarchy-launch-or-focus-tui btop"
|
||||
},
|
||||
"custom/weather": {
|
||||
"format": "{}°",
|
||||
"tooltip": true,
|
||||
"interval": 600,
|
||||
"exec": "omarchy-cmd-present wttrbar && wttrbar || true",
|
||||
"return-type": "json"
|
||||
},
|
||||
"mpris": {
|
||||
"format": "{player_icon} {artist} - {title}",
|
||||
"format-paused": "{status_icon} <i>{artist} - {title}</i>",
|
||||
"player-icons": {
|
||||
"default": "🎵",
|
||||
"mpv": "🎵"
|
||||
},
|
||||
"status-icons": {
|
||||
"paused": "⏸"
|
||||
},
|
||||
"max-length": 50
|
||||
},
|
||||
"hyprland/window": {
|
||||
"format": "{}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"reload_style_on_change": true,
|
||||
"layer": "top",
|
||||
"position": "top",
|
||||
"spacing": 0,
|
||||
"height": 26,
|
||||
"modules-left": ["custom/omarchy", "hyprland/workspaces", "hyprland/window"],
|
||||
"modules-center": ["clock", "custom/update", "custom/screenrecording-indicator", "custom/idle-indicator", "custom/notification-silencing-indicator"],
|
||||
"modules-right": [
|
||||
"mpris",
|
||||
"group/tray-expander",
|
||||
"backlight",
|
||||
"network",
|
||||
"bluetooth",
|
||||
"pulseaudio",
|
||||
"cpu",
|
||||
"battery"
|
||||
],
|
||||
"hyprland/workspaces": {
|
||||
"on-click": "activate",
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"default": "",
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "",
|
||||
"7": "",
|
||||
"8": "",
|
||||
"9": "",
|
||||
"10": "",
|
||||
"active": ""
|
||||
},
|
||||
"persistent-workspaces": {
|
||||
"1": [],
|
||||
"2": [],
|
||||
"3": [],
|
||||
"4": [],
|
||||
"5": []
|
||||
}
|
||||
},
|
||||
"custom/omarchy": {
|
||||
"format": "<span font='omarchy'>\ue900</span>",
|
||||
"on-click": "omarchy-menu",
|
||||
"on-click-right": "xdg-terminal-exec",
|
||||
"tooltip-format": "Omarchy Menu\n\nSuper + Alt + Space"
|
||||
},
|
||||
"custom/update": {
|
||||
"format": "",
|
||||
"exec": "omarchy-update-available",
|
||||
"on-click": "omarchy-launch-floating-terminal-with-presentation omarchy-update",
|
||||
"tooltip-format": "Omarchy update available",
|
||||
"signal": 7,
|
||||
"interval": 21600
|
||||
},
|
||||
"cpu": {
|
||||
"interval": 5,
|
||||
"format": "",
|
||||
"on-click": "omarchy-launch-or-focus-tui btop",
|
||||
"on-click-right": "alacritty"
|
||||
},
|
||||
"clock": {
|
||||
"format": "{:%I:%M %p}",
|
||||
"format-alt": "{:%A %d/%m/%Y}",
|
||||
"tooltip-format": "<span>{calendar}</span>",
|
||||
"on-click-right": "omarchy-launch-floating-terminal-with-presentation omarchy-tz-select"
|
||||
},
|
||||
"network": {
|
||||
"format-icons": ["", "", "", "", ""],
|
||||
"format": "{icon} {essid}",
|
||||
"format-wifi": "{icon} {essid}",
|
||||
"format-ethernet": "",
|
||||
"format-disconnected": "",
|
||||
"tooltip-format-wifi": "{essid} ({frequency} GHz)\n⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}",
|
||||
"tooltip-format-ethernet": "⇣{bandwidthDownBytes} ⇡{bandwidthUpBytes}",
|
||||
"tooltip-format-disconnected": "Disconnected",
|
||||
"interval": 3,
|
||||
"spacing": 1,
|
||||
"on-click": "omarchy-launch-wifi"
|
||||
},
|
||||
"battery": {
|
||||
"format": "{capacity}% {icon}",
|
||||
"format-discharging": "{capacity}% {icon}",
|
||||
"format-charging": "{capacity}% {icon}",
|
||||
"format-plugged": "",
|
||||
"format-icons": {
|
||||
"charging": ["", "", "", "", "", "", "", "", "", ""],
|
||||
"default": ["", "", "", "", "", "", "", "", "", ""]
|
||||
},
|
||||
"format-full": "",
|
||||
"tooltip-format-discharging": "{power:>1.0f}W↓ {capacity}%",
|
||||
"tooltip-format-charging": "{power:>1.0f}W↑ {capacity}%",
|
||||
"interval": 5,
|
||||
"on-click": "omarchy-menu power",
|
||||
"on-click-right": "notify-send -u low \"$(omarchy-battery-status)\"",
|
||||
"states": {
|
||||
"warning": 20,
|
||||
"critical": 10
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"format": "",
|
||||
"format-off": "",
|
||||
"format-disabled": "",
|
||||
"format-connected": "",
|
||||
"format-no-controller": "",
|
||||
"tooltip-format": "Devices connected: {num_connections}",
|
||||
"on-click": "omarchy-launch-bluetooth"
|
||||
},
|
||||
"pulseaudio": {
|
||||
"format": "{icon}",
|
||||
"on-click": "omarchy-launch-audio",
|
||||
"on-click-right": "pamixer -t",
|
||||
"tooltip-format": "Playing at {volume}%",
|
||||
"scroll-step": 5,
|
||||
"format-muted": "",
|
||||
"format-icons": {
|
||||
"headphone": "",
|
||||
"headset": "",
|
||||
"default": ["", "", ""]
|
||||
}
|
||||
},
|
||||
"group/tray-expander": {
|
||||
"orientation": "inherit",
|
||||
"drawer": {
|
||||
"transition-duration": 600,
|
||||
"children-class": "tray-group-item"
|
||||
},
|
||||
"modules": ["custom/expand-icon", "tray", "memory", "custom/weather"]
|
||||
},
|
||||
"custom/expand-icon": {
|
||||
"format": " ",
|
||||
"tooltip": false
|
||||
},
|
||||
"custom/screenrecording-indicator": {
|
||||
"on-click": "omarchy-capture-screenrecording",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/screen-recording.sh",
|
||||
"signal": 8,
|
||||
"return-type": "json"
|
||||
},
|
||||
"custom/idle-indicator": {
|
||||
"on-click": "omarchy-toggle-idle",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/idle.sh",
|
||||
"signal": 9,
|
||||
"return-type": "json"
|
||||
},
|
||||
"custom/notification-silencing-indicator": {
|
||||
"on-click": "omarchy-toggle-notification-silencing",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/notification-silencing.sh",
|
||||
"signal": 10,
|
||||
"return-type": "json"
|
||||
},
|
||||
"tray": {
|
||||
"icon-size": 12,
|
||||
"spacing": 12
|
||||
},
|
||||
"backlight": {
|
||||
"format": "{percent}% {icon}",
|
||||
"format-icons": ["🌑", "🌘", "🌗", "🌖", "🌕"]
|
||||
},
|
||||
"memory": {
|
||||
"format": " {used:0.1f}gb",
|
||||
"interval": 2,
|
||||
"on-click": "omarchy-launch-or-focus-tui btop"
|
||||
},
|
||||
"custom/weather": {
|
||||
"format": "{}°",
|
||||
"tooltip": true,
|
||||
"interval": 600,
|
||||
"exec": "omarchy-cmd-present wttrbar && wttrbar || true",
|
||||
"return-type": "json"
|
||||
},
|
||||
"mpris": {
|
||||
"format": "{player_icon} {artist} - {title}",
|
||||
"format-paused": "{status_icon} <i>{artist} - {title}</i>",
|
||||
"player-icons": {
|
||||
"default": "🎵",
|
||||
"mpv": "🎵"
|
||||
},
|
||||
"status-icons": {
|
||||
"paused": "⏸"
|
||||
}
|
||||
},
|
||||
"hyprland/window": {
|
||||
"format": "{}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"reload_style_on_change": true,
|
||||
"layer": "top",
|
||||
"position": "top",
|
||||
"spacing": 0,
|
||||
"height": 26,
|
||||
"modules-left": ["custom/omarchy", "hyprland/workspaces"],
|
||||
"modules-center": ["clock", "custom/update", "custom/voxtype", "custom/screenrecording-indicator", "custom/idle-indicator", "custom/notification-silencing-indicator"],
|
||||
"modules-right": [
|
||||
"group/tray-expander",
|
||||
"bluetooth",
|
||||
"network",
|
||||
"pulseaudio",
|
||||
"cpu",
|
||||
"battery"
|
||||
],
|
||||
"hyprland/workspaces": {
|
||||
"on-click": "activate",
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"default": "",
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7",
|
||||
"8": "8",
|
||||
"9": "9",
|
||||
"10": "0",
|
||||
"active": ""
|
||||
},
|
||||
"persistent-workspaces": {
|
||||
"1": [],
|
||||
"2": [],
|
||||
"3": [],
|
||||
"4": [],
|
||||
"5": []
|
||||
}
|
||||
},
|
||||
"custom/omarchy": {
|
||||
"format": "<span font='omarchy'>\ue900</span>",
|
||||
"on-click": "omarchy-menu",
|
||||
"on-click-right": "xdg-terminal-exec",
|
||||
"tooltip-format": "Omarchy Menu\n\nSuper + Alt + Space"
|
||||
},
|
||||
"custom/update": {
|
||||
"format": "",
|
||||
"exec": "omarchy-update-available",
|
||||
"on-click": "omarchy-launch-floating-terminal-with-presentation omarchy-update",
|
||||
"tooltip-format": "Omarchy update available",
|
||||
"signal": 7,
|
||||
"interval": 21600
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
"interval": 5,
|
||||
"format": "",
|
||||
"on-click": "omarchy-launch-or-focus-tui btop",
|
||||
"on-click-right": "alacritty"
|
||||
},
|
||||
"clock": {
|
||||
"format": "{:L%A %H:%M}",
|
||||
"format-alt": "{:L%d %B W%V %Y}",
|
||||
"tooltip": false,
|
||||
"on-click-right": "omarchy-launch-floating-terminal-with-presentation omarchy-tz-select"
|
||||
},
|
||||
"network": {
|
||||
"format-icons": ["", "", "", "", ""],
|
||||
"format": "{icon}",
|
||||
"format-wifi": "{icon}",
|
||||
"format-ethernet": "",
|
||||
"format-disconnected": "",
|
||||
"tooltip-format-wifi": "{essid} ({frequency} GHz)",
|
||||
"tooltip-format-ethernet": "Connected",
|
||||
"tooltip-format-disconnected": "Disconnected",
|
||||
"interval": 3,
|
||||
"spacing": 1,
|
||||
"on-click": "omarchy-launch-wifi"
|
||||
},
|
||||
"battery": {
|
||||
"format": "{capacity}% {icon}",
|
||||
"format-discharging": "{icon}",
|
||||
"format-charging": "{icon}",
|
||||
"format-plugged": "",
|
||||
"format-icons": {
|
||||
"charging": ["", "", "", "", "", "", "", "", "", ""],
|
||||
"default": ["", "", "", "", "", "", "", "", "", ""]
|
||||
},
|
||||
"format-full": "",
|
||||
"tooltip-format-discharging": "{power:>1.0f}W↓ {capacity}%",
|
||||
"tooltip-format-charging": "{power:>1.0f}W↑ {capacity}%",
|
||||
"interval": 5,
|
||||
"on-click": "omarchy-menu power",
|
||||
"on-click-right": "notify-send -u low \"$(omarchy-battery-status)\"",
|
||||
"states": {
|
||||
"warning": 20,
|
||||
"critical": 10
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"format": "",
|
||||
"format-off": "",
|
||||
"format-disabled": "",
|
||||
"format-connected": "",
|
||||
"format-no-controller": "",
|
||||
"tooltip-format": "Devices connected: {num_connections}",
|
||||
"on-click": "omarchy-launch-bluetooth"
|
||||
},
|
||||
"pulseaudio": {
|
||||
"format": "{icon}",
|
||||
"on-click": "omarchy-launch-audio",
|
||||
"on-click-right": "pamixer -t",
|
||||
"tooltip-format": "Playing at {volume}%",
|
||||
"scroll-step": 5,
|
||||
"format-muted": "",
|
||||
"format-icons": {
|
||||
"headphone": "",
|
||||
"headset": "",
|
||||
"default": ["", "", ""]
|
||||
}
|
||||
},
|
||||
"group/tray-expander": {
|
||||
"orientation": "inherit",
|
||||
"drawer": {
|
||||
"transition-duration": 600,
|
||||
"children-class": "tray-group-item"
|
||||
},
|
||||
"modules": ["custom/expand-icon", "tray"]
|
||||
},
|
||||
"custom/expand-icon": {
|
||||
"format": "",
|
||||
"tooltip": false,
|
||||
"on-scroll-up": "",
|
||||
"on-scroll-down": "",
|
||||
"on-scroll-left": "",
|
||||
"on-scroll-right": ""
|
||||
},
|
||||
"custom/screenrecording-indicator": {
|
||||
"on-click": "omarchy-capture-screenrecording",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/screen-recording.sh",
|
||||
"signal": 8,
|
||||
"return-type": "json"
|
||||
},
|
||||
"custom/idle-indicator": {
|
||||
"on-click": "omarchy-toggle-idle",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/idle.sh",
|
||||
"signal": 9,
|
||||
"return-type": "json"
|
||||
},
|
||||
"custom/notification-silencing-indicator": {
|
||||
"on-click": "omarchy-toggle-notification-silencing",
|
||||
"exec": "$OMARCHY_PATH/default/waybar/indicators/notification-silencing.sh",
|
||||
"signal": 10,
|
||||
"return-type": "json"
|
||||
},
|
||||
"custom/voxtype": {
|
||||
"exec": "omarchy-voxtype-status",
|
||||
"return-type": "json",
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"idle": "",
|
||||
"recording": "",
|
||||
"transcribing": ""
|
||||
},
|
||||
"tooltip": true,
|
||||
"on-click-right": "omarchy-voxtype-config",
|
||||
"on-click": "omarchy-voxtype-model"
|
||||
},
|
||||
"tray": {
|
||||
"icon-size": 12,
|
||||
"spacing": 17
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
@import "../omarchy/current/theme/waybar.css";
|
||||
|
||||
* {
|
||||
background-color: @background;
|
||||
color: @foreground;
|
||||
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 2px 2px;
|
||||
min-height: 0;
|
||||
font-family: 'JetBrainsMono Nerd Font';
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.modules-left {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.modules-right {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
all: initial;
|
||||
padding: 0 6px;
|
||||
margin: 0 1.5px;
|
||||
min-width: 9px;
|
||||
}
|
||||
|
||||
#workspaces button.empty {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#backlight,
|
||||
#custom-weather,
|
||||
#memory,
|
||||
#mpris,
|
||||
#window,
|
||||
#tray,
|
||||
#cpu,
|
||||
#battery,
|
||||
#network,
|
||||
#bluetooth,
|
||||
#pulseaudio,
|
||||
#custom-omarchy,
|
||||
#custom-screenrecording-indicator,
|
||||
#custom-idle-indicator,
|
||||
#custom-notification-silencing-indicator,
|
||||
#custom-update {
|
||||
min-width: 12px;
|
||||
margin: 0 7.5px;
|
||||
}
|
||||
|
||||
#custom-expand-icon {
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
tooltip {
|
||||
padding: 2px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#custom-update,
|
||||
#custom-screenrecording-indicator,
|
||||
#custom-idle-indicator,
|
||||
#custom-notification-silencing-indicator {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#custom-screenrecording-indicator.active,
|
||||
#custom-idle-indicator.active,
|
||||
#custom-notification-silencing-indicator.active {
|
||||
color: #a55555;
|
||||
}
|
||||
|
||||
#bluetooth {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
#mpris {
|
||||
margin-right: 10px;
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
@import "../omarchy/current/theme/waybar.css";
|
||||
|
||||
* {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
min-height: 0;
|
||||
font-family: 'JetBrainsMono Nerd Font';
|
||||
font-size: 14px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.modules-left {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.modules-right {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
window#waybar {
|
||||
background: @background;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
window#waybar.empty #window {
|
||||
background: transparent;
|
||||
color: transparent;
|
||||
padding: 0;
|
||||
margin-left: 5px;
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
mpris.empty {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
all: initial;
|
||||
padding: 3px 10px 3px 5px;
|
||||
margin: 0 5px;
|
||||
min-width: 9px;
|
||||
}
|
||||
|
||||
#workspaces button.active {
|
||||
background: @foreground;
|
||||
color: @background;
|
||||
border-radius: 30px;
|
||||
padding: 3px 10px 3px 5px;
|
||||
}
|
||||
|
||||
#workspaces button:hover {
|
||||
background: alpha(@foreground, .3);
|
||||
border-radius: 30px;
|
||||
padding: 3px 10px 3px 5px;
|
||||
transition: .7s;
|
||||
}
|
||||
|
||||
#workspaces button.active:hover {
|
||||
background: @foreground;
|
||||
color: @background;
|
||||
border-radius: 30px;
|
||||
padding: 3px 10px 3px 5px;
|
||||
}
|
||||
|
||||
#workspaces button.empty {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
#custom-weather,
|
||||
#memory,
|
||||
#mpris,
|
||||
#window,
|
||||
#tray-expander,
|
||||
#workspaces,
|
||||
#clock,
|
||||
#cpu,
|
||||
#battery,
|
||||
#network,
|
||||
#bluetooth,
|
||||
#pulseaudio,
|
||||
#custom-screenrecording-indicator,
|
||||
#custom-idle-indicator,
|
||||
#custom-notification-silencing-indicator,
|
||||
#custom-update {
|
||||
background-color: alpha(@foreground, .1);
|
||||
padding: 5px 10px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
#mpris:hover,
|
||||
#window:hover,
|
||||
#clock:hover,
|
||||
#backlight:hover,
|
||||
#cpu:hover,
|
||||
#network:hover,
|
||||
#bluetooth:hover,
|
||||
#pulseaudio:hover,
|
||||
#custom-screenrecording-indicator:hover,
|
||||
#custom-idle-indicator:hover,
|
||||
#custom-notification-silencing-indicator:hover,
|
||||
#custom-update:hover {
|
||||
background-color: alpha(@foreground, .2);
|
||||
transition: .7s;
|
||||
}
|
||||
|
||||
#custom-expand-icon {
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
#tray,
|
||||
#memory,
|
||||
#custom-weather {
|
||||
background-color: transparent;
|
||||
margin: 5px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
#custom-update,
|
||||
#custom-screenrecording-indicator,
|
||||
#custom-idle-indicator,
|
||||
#custom-notification-silencing-indicator {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#clock {
|
||||
border-radius: 10px;
|
||||
padding: 0 10px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#custom-screenrecording-indicator,
|
||||
#custom-idle-indicator,
|
||||
#custom-notification-silencing-indicator {
|
||||
border-radius: 10px;
|
||||
min-width: 12px;
|
||||
padding: 0 11px 0 10px;
|
||||
}
|
||||
|
||||
#custom-screenrecording-indicator.active,
|
||||
#custom-idle-indicator.active,
|
||||
#custom-notification-silencing-indicator.active {
|
||||
color: #a55555;
|
||||
}
|
||||
|
||||
#custom-omarchy,
|
||||
#battery {
|
||||
background-color: @foreground;
|
||||
color: @background;
|
||||
min-width: 10px;
|
||||
border-radius: 10px;
|
||||
padding: 0 10px;
|
||||
margin: 5px 0 5px 5px;
|
||||
}
|
||||
|
||||
#workspaces,
|
||||
#mpris {
|
||||
margin: 5px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#window,
|
||||
#mpris {
|
||||
border-radius: 10px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
#tray-expander {
|
||||
padding: 0 0 0 10px;
|
||||
margin-left: 1px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#backlight {
|
||||
background-color: alpha(@foreground, .1);
|
||||
border-radius: 10px;
|
||||
padding: 5px 10px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#network {
|
||||
border-radius: 10px 0 0 10px;
|
||||
}
|
||||
|
||||
#cpu {
|
||||
padding: 0 15px 0 10px;
|
||||
border-radius: 0 10px 10px 0;
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
#pulseaudio {
|
||||
padding: 0 15px 0 10px;
|
||||
}
|
||||
|
||||
tooltip {
|
||||
border-radius: 10px;
|
||||
background: @background;
|
||||
border: 3px solid alpha(@foreground, .5);
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
@import "../omarchy/current/theme/waybar.css";
|
||||
|
||||
* {
|
||||
background-color: @background;
|
||||
color: @foreground;
|
||||
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
min-height: 0;
|
||||
font-family: 'JetBrainsMono Nerd Font';
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.modules-left {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.modules-right {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
all: initial;
|
||||
padding: 0 6px;
|
||||
margin: 0 1.5px;
|
||||
min-width: 9px;
|
||||
}
|
||||
|
||||
#workspaces button.empty {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#cpu,
|
||||
#battery,
|
||||
#pulseaudio,
|
||||
#custom-omarchy,
|
||||
#custom-update {
|
||||
min-width: 12px;
|
||||
margin: 0 7.5px;
|
||||
}
|
||||
|
||||
#tray {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
#bluetooth {
|
||||
margin-right: 17px;
|
||||
}
|
||||
|
||||
#network {
|
||||
margin-right: 13px;
|
||||
}
|
||||
|
||||
#custom-expand-icon {
|
||||
margin-right: 18px;
|
||||
}
|
||||
|
||||
tooltip {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#custom-update {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#clock {
|
||||
margin-left: 8.75px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#custom-screenrecording-indicator,
|
||||
#custom-idle-indicator,
|
||||
#custom-notification-silencing-indicator {
|
||||
min-width: 12px;
|
||||
margin-left: 5px;
|
||||
margin-right: 0;
|
||||
font-size: 10px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
#custom-screenrecording-indicator.active {
|
||||
color: #a55555;
|
||||
}
|
||||
|
||||
#custom-idle-indicator.active,
|
||||
#custom-notification-silencing-indicator.active {
|
||||
color: #a55555;
|
||||
}
|
||||
|
||||
#custom-voxtype {
|
||||
min-width: 12px;
|
||||
margin: 0 0 0 7.5px;
|
||||
}
|
||||
|
||||
#custom-voxtype.recording {
|
||||
color: #a55555;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ _omarchy_complete() {
|
||||
fi
|
||||
}
|
||||
|
||||
complete -F _omarchy_complete omarchy
|
||||
complete -o default -F _omarchy_complete omarchy
|
||||
|
||||
# Hide individual omarchy-* binaries from initial-word command completion;
|
||||
# the unified `omarchy` dispatcher is the user-facing entry point.
|
||||
|
||||
@@ -1,53 +1,33 @@
|
||||
# Transcode a video to a good-balance 1080p that's great for sharing online
|
||||
# Transcoding helpers have moved to omarchy-transcode.
|
||||
|
||||
transcode-video-1080p() {
|
||||
ffmpeg -i "$1" -vf scale=1920:1080 -c:v libx264 -preset fast -crf 23 -c:a copy "${1%.*}-1080p.mp4"
|
||||
omarchy-transcode "$1" mp4 1080p
|
||||
}
|
||||
|
||||
# Transcode a video to a good-balance 4K that's great for sharing online
|
||||
transcode-video-4K() {
|
||||
ffmpeg -i "$1" -c:v libx265 -preset slow -crf 24 -c:a aac -b:a 192k "${1%.*}-optimized.mp4"
|
||||
omarchy-transcode "$1" mp4 4k
|
||||
}
|
||||
|
||||
transcode-video-gif() {
|
||||
omarchy-transcode "$1" gif 1080p
|
||||
}
|
||||
|
||||
# Transcode any image to JPG image that's great for shrinking wallpapers
|
||||
img2jpg() {
|
||||
img="$1"
|
||||
shift
|
||||
|
||||
magick "$img" "$@" -quality 85 -strip "${img%.*}-converted.jpg"
|
||||
omarchy-transcode "$1" jpg high
|
||||
}
|
||||
|
||||
# Transcode any image to a small JPG (max 1080px wide)
|
||||
img2jpg-small() {
|
||||
img="$1"
|
||||
shift
|
||||
|
||||
magick "$img" "$@" -resize 1080x\> -quality 85 -strip "${img%.*}-small.jpg"
|
||||
omarchy-transcode "$1" jpg low
|
||||
}
|
||||
|
||||
# Transcode any image to a 4K JPG (max 2160px wide)
|
||||
img2jpg-medium() {
|
||||
img="$1"
|
||||
shift
|
||||
|
||||
magick "$img" "$@" -resize 2160x\> -quality 85 -strip "${img%.*}-medium.jpg"
|
||||
omarchy-transcode "$1" jpg medium
|
||||
}
|
||||
|
||||
# Transcode any image to a 6K JPG (max 3160px wide)
|
||||
img2jpg-large() {
|
||||
img="$1"
|
||||
shift
|
||||
|
||||
magick "$img" "$@" -resize 3160x\> -quality 85 -strip "${img%.*}-large.jpg"
|
||||
omarchy-transcode "$1" jpg high
|
||||
}
|
||||
|
||||
# Transcode any image to compressed-but-lossless PNG
|
||||
img2png() {
|
||||
img="$1"
|
||||
shift
|
||||
|
||||
magick "$img" "$@" -strip -define png:compression-filter=5 \
|
||||
-define png:compression-level=9 \
|
||||
-define png:compression-strategy=1 \
|
||||
-define png:exclude-chunk=all \
|
||||
"${img%.*}-optimized.png"
|
||||
omarchy-transcode "$1" png high
|
||||
}
|
||||
|
||||
@@ -38,10 +38,18 @@ bindl = , switch:off:Lid Switch, exec, omarchy-hyprland-monitor-internal on
|
||||
bindd = , PRINT, Screenshot, exec, omarchy-capture-screenshot
|
||||
bindd = ALT, PRINT, Screenrecording, exec, omarchy-menu screenrecord
|
||||
bindd = SUPER, PRINT, Color picker, exec, pkill hyprpicker || hyprpicker -a
|
||||
bindd = SUPER CTRL, PRINT, Extract text (OCR) from screenshot, exec, omarchy-capture-text-extraction
|
||||
|
||||
# File sharing
|
||||
bindd = SUPER CTRL, S, Share, exec, omarchy-menu share
|
||||
|
||||
# Transcoding
|
||||
bindd = SUPER CTRL, R, Transcode, exec, omarchy-menu transcode
|
||||
|
||||
# Workspace layouts
|
||||
bindd = SUPER CTRL, HOME, Restore workspace layout, exec, omarchy-workspace-restore
|
||||
bindd = SUPER CTRL ALT, HOME, Save workspace layout, exec, omarchy-workspace-save
|
||||
|
||||
# Waybar-less information
|
||||
bindd = SUPER CTRL ALT, T, Show time, exec, notify-send -u low " $(date +"%A %H:%M · %d %B %Y · Week %V")"
|
||||
bindd = SUPER CTRL ALT, B, Show battery remaining, exec, notify-send -u low "$(omarchy-battery-status)"
|
||||
@@ -55,6 +63,9 @@ bindd = SUPER CTRL, T, Activity, exec, omarchy-launch-tui btop
|
||||
# Dictation
|
||||
bindd = SUPER CTRL, X, Toggle dictation, exec, voxtype record toggle
|
||||
|
||||
bindd = , F9, Start dictation (push-to-talk), exec, voxtype record start
|
||||
binddr = , F9, Stop dictation (push-to-talk), exec, voxtype record stop
|
||||
|
||||
# Zoom
|
||||
bindd = SUPER CTRL, Z, Zoom in, exec, hyprctl keyword cursor:zoom_factor $(hyprctl getoption cursor:zoom_factor -j | jq '.float + 1')
|
||||
bindd = SUPER CTRL ALT, Z, Reset zoom, exec, hyprctl keyword cursor:zoom_factor 1
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
# GUM environment variables for styling purposes
|
||||
# hyprlang noerror true
|
||||
source = ~/.config/omarchy/current/theme/gum.env.conf
|
||||
# hyprlang noerror false
|
||||
|
||||
# Cursor size
|
||||
env = XCURSOR_SIZE,24
|
||||
env = HYPRCURSOR_SIZE,24
|
||||
@@ -6,7 +11,6 @@ env = HYPRCURSOR_SIZE,24
|
||||
env = GDK_BACKEND,wayland,x11,*
|
||||
env = QT_QPA_PLATFORM,wayland;xcb
|
||||
env = QT_STYLE_OVERRIDE,kvantum
|
||||
env = SDL_VIDEODRIVER,wayland,x11
|
||||
env = MOZ_ENABLE_WAYLAND,1
|
||||
env = ELECTRON_OZONE_PLATFORM_HINT,wayland
|
||||
env = OZONE_PLATFORM,wayland
|
||||
|
||||
@@ -138,10 +138,3 @@ cursor {
|
||||
binds {
|
||||
hide_special_on_workspace_change = true
|
||||
}
|
||||
|
||||
# Style Gum confirm to match terminal theme
|
||||
env = GUM_CONFIRM_PROMPT_FOREGROUND,6 # Cyan
|
||||
env = GUM_CONFIRM_SELECTED_FOREGROUND,0 # Black
|
||||
env = GUM_CONFIRM_SELECTED_BACKGROUND,2 # Green
|
||||
env = GUM_CONFIRM_UNSELECTED_FOREGROUND,7 # White
|
||||
env = GUM_CONFIRM_UNSELECTED_BACKGROUND,8 # Dark grey
|
||||
|
||||
@@ -4,3 +4,7 @@ general {
|
||||
gaps_in = 0
|
||||
border_size = 0
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding = 0
|
||||
}
|
||||
|
||||
+136
-158
@@ -1,116 +1,105 @@
|
||||
# Omarchy Plymouth Theme Script
|
||||
|
||||
Window.SetBackgroundTopColor(0.101, 0.105, 0.149);
|
||||
Window.SetBackgroundBottomColor(0.101, 0.105, 0.149);
|
||||
Window.SetBackgroundBottomColor(0.101, 0.105, 0.149);
|
||||
|
||||
logo.image = Image("logo.png");
|
||||
logo.sprite = Sprite(logo.image);
|
||||
logo.sprite.SetX (Window.GetWidth() / 2 - logo.image.GetWidth() / 2);
|
||||
logo.sprite.SetY (Window.GetHeight() / 2 - logo.image.GetHeight() / 2);
|
||||
logo.sprite.SetOpacity (1);
|
||||
logo.sprite.SetX(Window.GetWidth() / 2 - logo.image.GetWidth() / 2);
|
||||
logo.sprite.SetY(Window.GetHeight() / 2 - logo.image.GetHeight() / 2);
|
||||
logo.sprite.SetOpacity(1);
|
||||
|
||||
# Use these to adjust the progress bar timing
|
||||
global.fake_progress_limit = 0.7; # Target percentage for fake progress (0.0 to 1.0)
|
||||
global.fake_progress_duration = 15.0; # Duration in seconds to reach limit
|
||||
|
||||
# Progress bar animation variables
|
||||
global.animation_frame = 0;
|
||||
global.fake_progress = 0.0;
|
||||
global.real_progress = 0.0;
|
||||
global.fake_progress_active = 0; # 0 / 1 boolean
|
||||
global.animation_frame = 0;
|
||||
global.fake_progress_start_time = 0; # Track when fake progress started
|
||||
global.fake_progress_active = 0;
|
||||
global.fake_progress_start_time = 0.0; # Track when fake progress started
|
||||
global.password_shown = 0; # Track if password dialog has been shown
|
||||
global.max_progress = 0.0; # Track the maximum progress reached to prevent backwards movement
|
||||
|
||||
fun refresh_callback ()
|
||||
{
|
||||
global.animation_frame++;
|
||||
|
||||
# Animate fake progress to limit over time with easing
|
||||
if (global.fake_progress_active == 1)
|
||||
{
|
||||
# Calculate elapsed time since start
|
||||
elapsed_time = global.animation_frame / 50.0; # Convert frames to seconds (50 FPS)
|
||||
|
||||
# Calculate linear progress ratio (0 to 1) based on time
|
||||
time_ratio = elapsed_time / global.fake_progress_duration;
|
||||
if (time_ratio > 1.0)
|
||||
time_ratio = 1.0;
|
||||
|
||||
# Apply easing curve: ease-out quadratic
|
||||
# Formula: 1 - (1 - x)^2
|
||||
eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio));
|
||||
|
||||
# Calculate fake progress based on eased ratio
|
||||
global.fake_progress = eased_ratio * global.fake_progress_limit;
|
||||
|
||||
# Update progress bar with fake progress
|
||||
update_progress_bar(global.fake_progress);
|
||||
}
|
||||
fun refresh_callback() {
|
||||
global.animation_frame++;
|
||||
|
||||
# Animate fake progress to limit over time with easing
|
||||
if (global.fake_progress_active == 1) {
|
||||
# Calculate elapsed time since start
|
||||
elapsed_time = global.animation_frame / 50.0; # Convert frames to seconds (50 FPS)
|
||||
|
||||
# Calculate linear progress ratio (0 to 1) based on time
|
||||
time_ratio = elapsed_time / global.fake_progress_duration;
|
||||
if (time_ratio > 1.0) time_ratio = 1.0;
|
||||
|
||||
# Apply easing curve: ease-out quadratic
|
||||
# Formula: 1 - (1 - x)^2
|
||||
eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio));
|
||||
|
||||
# Calculate fake progress based on eased ratio
|
||||
global.fake_progress = eased_ratio * global.fake_progress_limit;
|
||||
|
||||
# Update progress bar with fake progress
|
||||
update_progress_bar(global.fake_progress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Plymouth.SetRefreshFunction (refresh_callback);
|
||||
Plymouth.SetRefreshFunction(refresh_callback);
|
||||
|
||||
#----------------------------------------- Helper Functions --------------------------------
|
||||
|
||||
fun update_progress_bar(progress)
|
||||
{
|
||||
# Only update if progress is moving forward
|
||||
if (progress > global.max_progress)
|
||||
{
|
||||
global.max_progress = progress;
|
||||
width = Math.Int(progress_bar.original_image.GetWidth() * progress);
|
||||
if (width < 1) width = 1; # Ensure minimum width of 1 pixel
|
||||
|
||||
progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight());
|
||||
progress_bar.sprite.SetImage(progress_bar.image);
|
||||
}
|
||||
}
|
||||
fun update_progress_bar(progress) {
|
||||
# Only update if progress is moving forward
|
||||
if (progress > global.max_progress) {
|
||||
global.max_progress = progress;
|
||||
|
||||
fun show_progress_bar()
|
||||
{
|
||||
progress_box.sprite.SetOpacity(1);
|
||||
progress_bar.sprite.SetOpacity(1);
|
||||
}
|
||||
width = Math.Int(progress_bar.original_image.GetWidth() * progress);
|
||||
if (width < 1) width = 1; # Ensure minimum width of 1 pixel
|
||||
|
||||
fun hide_progress_bar()
|
||||
{
|
||||
progress_box.sprite.SetOpacity(0);
|
||||
progress_bar.sprite.SetOpacity(0);
|
||||
progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight());
|
||||
progress_bar.sprite.SetImage(progress_bar.image);
|
||||
}
|
||||
}
|
||||
|
||||
fun show_password_dialog()
|
||||
{
|
||||
lock.sprite.SetOpacity(1);
|
||||
entry.sprite.SetOpacity(1);
|
||||
}
|
||||
fun show_progress_bar() {
|
||||
progress_box.sprite.SetOpacity(1);
|
||||
progress_bar.sprite.SetOpacity(1);
|
||||
}
|
||||
|
||||
fun hide_password_dialog()
|
||||
{
|
||||
lock.sprite.SetOpacity(0);
|
||||
entry.sprite.SetOpacity(0);
|
||||
for (index = 0; bullet.sprites[index]; index++)
|
||||
bullet.sprites[index].SetOpacity(0);
|
||||
}
|
||||
fun hide_progress_bar() {
|
||||
progress_box.sprite.SetOpacity(0);
|
||||
progress_bar.sprite.SetOpacity(0);
|
||||
}
|
||||
|
||||
fun start_fake_progress()
|
||||
{
|
||||
# Don't reset if we already have progress
|
||||
if (global.max_progress == 0.0)
|
||||
{
|
||||
global.fake_progress = 0.0;
|
||||
global.real_progress = 0.0;
|
||||
update_progress_bar(0.0);
|
||||
}
|
||||
global.fake_progress_active = 1;
|
||||
global.animation_frame = 0;
|
||||
}
|
||||
fun show_password_dialog() {
|
||||
lock.sprite.SetOpacity(1);
|
||||
entry.sprite.SetOpacity(1);
|
||||
}
|
||||
|
||||
fun stop_fake_progress()
|
||||
{
|
||||
global.fake_progress_active = 0;
|
||||
fun hide_password_dialog() {
|
||||
lock.sprite.SetOpacity(0);
|
||||
entry.sprite.SetOpacity(0);
|
||||
|
||||
for (index = 0; bullet.sprites[index]; index++) {
|
||||
bullet.sprites[index].SetOpacity(0);
|
||||
}
|
||||
}
|
||||
|
||||
fun start_fake_progress() {
|
||||
global.fake_progress_active = 1;
|
||||
|
||||
# Reset fake progress
|
||||
global.animation_frame = 0;
|
||||
global.max_progress = 0.0;
|
||||
global.fake_progress = 0.0;
|
||||
global.fake_progress_start_time = 0.0;
|
||||
}
|
||||
|
||||
fun stop_fake_progress() {
|
||||
global.fake_progress_active = 0;
|
||||
}
|
||||
|
||||
#----------------------------------------- Dialogue --------------------------------
|
||||
|
||||
@@ -119,7 +108,7 @@ entry.image = Image("entry.png");
|
||||
bullet.image = Image("bullet.png");
|
||||
|
||||
entry.sprite = Sprite(entry.image);
|
||||
entry.x = Window.GetWidth()/2 - entry.image.GetWidth() / 2;
|
||||
entry.x = Window.GetWidth() / 2 - entry.image.GetWidth() / 2;
|
||||
entry.y = logo.sprite.GetY() + logo.image.GetHeight() + 40;
|
||||
entry.sprite.SetPosition(entry.x, entry.y, 10001);
|
||||
entry.sprite.SetOpacity(0);
|
||||
@@ -133,65 +122,60 @@ lock_width = 84 * lock_scale;
|
||||
scaled_lock = lock.image.Scale(lock_width, lock_height);
|
||||
lock.sprite = Sprite(scaled_lock);
|
||||
lock.x = entry.x - lock_width - 15;
|
||||
lock.y = entry.y + entry.image.GetHeight()/2 - lock_height/2;
|
||||
lock.y = entry.y + entry.image.GetHeight() / 2 - lock_height / 2;
|
||||
lock.sprite.SetPosition(lock.x, lock.y, 10001);
|
||||
lock.sprite.SetOpacity(0);
|
||||
|
||||
# Bullet array
|
||||
bullet.sprites = [];
|
||||
|
||||
fun display_normal_callback ()
|
||||
{
|
||||
hide_password_dialog();
|
||||
|
||||
# Get current mode
|
||||
mode = Plymouth.GetMode();
|
||||
|
||||
# Only show progress bar for boot and resume modes
|
||||
if ((mode == "boot" || mode == "resume") && global.password_shown == 1)
|
||||
{
|
||||
show_progress_bar();
|
||||
start_fake_progress();
|
||||
}
|
||||
fun display_normal_callback() {
|
||||
hide_password_dialog();
|
||||
|
||||
# Get current mode
|
||||
mode = Plymouth.GetMode();
|
||||
|
||||
# Only show progress bar for boot and resume modes
|
||||
if ((mode == "boot" || mode == "resume") && global.password_shown == 1) {
|
||||
show_progress_bar();
|
||||
start_fake_progress();
|
||||
}
|
||||
}
|
||||
|
||||
fun display_password_callback(prompt, bullets) {
|
||||
global.password_shown = 1; # Mark that password dialog has been shown
|
||||
|
||||
# Stop fake progress when password dialog appears
|
||||
stop_fake_progress();
|
||||
hide_progress_bar();
|
||||
show_password_dialog();
|
||||
|
||||
# Clear all bullets first
|
||||
for (index = 0; bullet.sprites[index]; index++) {
|
||||
bullet.sprites[index].SetOpacity(0);
|
||||
}
|
||||
|
||||
fun display_password_callback (prompt, bullets)
|
||||
{
|
||||
global.password_shown = 1; # Mark that password dialog has been shown
|
||||
|
||||
# Reset progress when password dialog appears
|
||||
stop_fake_progress();
|
||||
hide_progress_bar();
|
||||
global.max_progress = 0.0;
|
||||
global.fake_progress = 0.0;
|
||||
global.real_progress = 0.0;
|
||||
show_password_dialog();
|
||||
|
||||
# Clear all bullets first
|
||||
for (index = 0; bullet.sprites[index]; index++)
|
||||
bullet.sprites[index].SetOpacity(0);
|
||||
|
||||
# Create and show bullets for current password (max 21)
|
||||
max_bullets = 21;
|
||||
bullets_to_show = bullets;
|
||||
if (bullets_to_show > max_bullets)
|
||||
bullets_to_show = max_bullets;
|
||||
|
||||
for (index = 0; index < bullets_to_show; index++)
|
||||
{
|
||||
if (!bullet.sprites[index])
|
||||
{
|
||||
# Scale bullet image to 7x7 pixels
|
||||
scaled_bullet = bullet.image.Scale(7, 7);
|
||||
bullet.sprites[index] = Sprite(scaled_bullet);
|
||||
bullet.x = entry.x + 20 + index * (7 + 5);
|
||||
bullet.y = entry.y + entry.image.GetHeight() / 2 - 3.5;
|
||||
bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002);
|
||||
}
|
||||
bullet.sprites[index].SetOpacity(1);
|
||||
}
|
||||
# Create and show bullets for current password (max 21)
|
||||
max_bullets = 21;
|
||||
bullets_to_show = bullets;
|
||||
if (bullets_to_show > max_bullets) {
|
||||
bullets_to_show = max_bullets;
|
||||
}
|
||||
|
||||
for (index = 0; index < bullets_to_show; index++) {
|
||||
if (!bullet.sprites[index]) {
|
||||
# Scale bullet image to 7x7 pixels
|
||||
scaled_bullet = bullet.image.Scale(7, 7);
|
||||
bullet.sprites[index] = Sprite(scaled_bullet);
|
||||
bullet.x = entry.x + 20 + index * (7 + 5);
|
||||
bullet.y = entry.y + entry.image.GetHeight() / 2 - 3.5;
|
||||
bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002);
|
||||
}
|
||||
|
||||
bullet.sprites[index].SetOpacity(1);
|
||||
}
|
||||
}
|
||||
|
||||
Plymouth.SetDisplayNormalFunction(display_normal_callback);
|
||||
Plymouth.SetDisplayPasswordFunction(display_password_callback);
|
||||
|
||||
@@ -214,44 +198,38 @@ progress_bar.y = progress_box.y + (progress_box.image.GetHeight() - progress_bar
|
||||
progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);
|
||||
progress_bar.sprite.SetOpacity(0);
|
||||
|
||||
fun progress_callback (duration, progress)
|
||||
{
|
||||
global.real_progress = progress;
|
||||
|
||||
# If real progress is above limit, stop fake progress and use real progress
|
||||
if (progress > global.fake_progress_limit)
|
||||
{
|
||||
stop_fake_progress();
|
||||
update_progress_bar(progress);
|
||||
}
|
||||
fun progress_callback(duration, progress) {
|
||||
# Track when fake progress starts
|
||||
# Needed because duration and progress freeze during drive decryption
|
||||
if (global.fake_progress_start_time == 0.0) {
|
||||
global.fake_progress_start_time = duration;
|
||||
}
|
||||
|
||||
Plymouth.SetBootProgressFunction(progress_callback);
|
||||
global.real_progress = progress;
|
||||
|
||||
#----------------------------------------- Quit --------------------------------
|
||||
|
||||
fun quit_callback ()
|
||||
{
|
||||
logo.sprite.SetOpacity (1);
|
||||
# Use real progress once its unfrozen and exceeds fake progress
|
||||
if (duration > global.fake_progress_start_time && progress > global.fake_progress) {
|
||||
stop_fake_progress();
|
||||
update_progress_bar(progress);
|
||||
}
|
||||
}
|
||||
|
||||
Plymouth.SetQuitFunction(quit_callback);
|
||||
Plymouth.SetBootProgressFunction(progress_callback);
|
||||
|
||||
#----------------------------------------- Message --------------------------------
|
||||
|
||||
message_sprite = Sprite();
|
||||
message_sprite.SetPosition(10, 10, 10000);
|
||||
|
||||
fun display_message_callback (text)
|
||||
{
|
||||
my_image = Image.Text(text, 1, 1, 1);
|
||||
message_sprite.SetImage(my_image);
|
||||
fun display_message_callback(text) {
|
||||
message = Image.Text(text, 1, 1, 1);
|
||||
message_sprite.SetImage(message);
|
||||
message_sprite.SetOpacity(1);
|
||||
}
|
||||
|
||||
fun hide_message_callback (text)
|
||||
{
|
||||
fun hide_message_callback(text) {
|
||||
message_sprite.SetOpacity(0);
|
||||
}
|
||||
|
||||
Plymouth.SetDisplayMessageFunction (display_message_callback);
|
||||
Plymouth.SetHideMessageFunction (hide_message_callback);
|
||||
Plymouth.SetDisplayMessageFunction(display_message_callback);
|
||||
Plymouth.SetHideMessageFunction(hide_message_callback);
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
# Gum Style (generic) Variables
|
||||
env = FOREGROUND,#{{ foreground }}
|
||||
env = BACKGROUND,#{{ background }}
|
||||
env = BORDER_FOREGROUND,#{{ accent }}
|
||||
env = BORDER_BACKGROUND,#{{ background }}
|
||||
|
||||
# Gum Confirm Style Variables
|
||||
env = GUM_CONFIRM_PROMPT_FOREGROUND,#{{ accent }}
|
||||
env = GUM_CONFIRM_PROMPT_BACKGROUND,#{{ background }}
|
||||
env = GUM_CONFIRM_SELECTED_FOREGROUND,#{{ selection_foreground }}
|
||||
env = GUM_CONFIRM_SELECTED_BACKGROUND,#{{ selection_background }}
|
||||
env = GUM_CONFIRM_UNSELECTED_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_CONFIRM_UNSELECTED_BACKGROUND,#{{ background }}
|
||||
|
||||
# Gum Input Style Variables
|
||||
env = GUM_INPUT_PROMPT_FOREGROUND,#{{ accent }}
|
||||
env = GUM_INPUT_PROMPT_BACKGROUND,#{{ background }}
|
||||
env = GUM_INPUT_PLACEHOLDER_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_INPUT_PLACEHOLDER_BACKGROUND,#{{ background }}
|
||||
env = GUM_INPUT_CURSOR_FOREGROUND,#{{ cursor }}
|
||||
env = GUM_INPUT_CURSOR_BACKGROUND,#{{ background }}
|
||||
env = GUM_INPUT_HEADER_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_INPUT_HEADER_BACKGROUND,#{{ background }}
|
||||
|
||||
# Gum Choose Style Variables
|
||||
env = GUM_CHOOSE_CURSOR_FOREGROUND,#{{ accent }}
|
||||
env = GUM_CHOOSE_CURSOR_BACKGROUND,#{{ background }}
|
||||
env = GUM_CHOOSE_HEADER_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_CHOOSE_HEADER_BACKGROUND,#{{ background }}
|
||||
env = GUM_CHOOSE_ITEM_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_CHOOSE_ITEM_BACKGROUND,#{{ background }}
|
||||
env = GUM_CHOOSE_SELECTED_FOREGROUND,#{{ selection_foreground }}
|
||||
env = GUM_CHOOSE_SELECTED_BACKGROUND,#{{ selection_background }}
|
||||
|
||||
# Gum Filter Style Variables
|
||||
env = GUM_FILTER_PROMPT_FOREGROUND,#{{ accent }}
|
||||
env = GUM_FILTER_PROMPT_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILTER_TEXT_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_FILTER_TEXT_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILTER_MATCH_FOREGROUND,#{{ accent }}
|
||||
env = GUM_FILTER_CURSOR_TEXT_FOREGROUND,#{{ cursor }}
|
||||
env = GUM_FILTER_CURSOR_TEXT_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILTER_SELECTED_FOREGROUND,#{{ selection_foreground }}
|
||||
env = GUM_FILTER_SELECTED_BACKGROUND,#{{ selection_background }}
|
||||
env = GUM_FILTER_INDICATOR_FOREGROUND,#{{ accent }}
|
||||
env = GUM_FILTER_HEADER_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_FILTER_MATCH_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILTER_HEADER_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILTER_PLACEHOLDER_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_FILTER_PLACEHOLDER_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILTER_INDICATOR_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILTER_SELECTED_PREFIX_FOREGROUND,#{{ selection_foreground }}
|
||||
env = GUM_FILTER_SELECTED_PREFIX_BACKGROUND,#{{ selection_background }}
|
||||
env = GUM_FILTER_UNSELECTED_PREFIX_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_FILTER_UNSELECTED_PREFIX_BACKGROUND,#{{ background }}
|
||||
|
||||
# Gum Table Style Variables
|
||||
env = GUM_TABLE_HEADER_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_TABLE_HEADER_BACKGROUND,#{{ background }}
|
||||
env = GUM_TABLE_CELL_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_TABLE_CELL_BACKGROUND,#{{ background }}
|
||||
env = GUM_TABLE_BORDER_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_TABLE_BORDER_BACKGROUND,#{{ background }}
|
||||
env = GUM_TABLE_SELECTED_FOREGROUND,#{{ selection_foreground }}
|
||||
env = GUM_TABLE_SELECTED_BACKGROUND,#{{ selection_background }}
|
||||
|
||||
# Gum Spin Style Variables
|
||||
env = GUM_SPIN_SPINNER_FOREGROUND,#{{ accent }}
|
||||
env = GUM_SPIN_SPINNER_BACKGROUND,#{{ background }}
|
||||
env = GUM_SPIN_TITLE_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_SPIN_TITLE_BACKGROUND,#{{ background }}
|
||||
|
||||
# Gum File Style Variables
|
||||
env = GUM_FILE_CURSOR_FOREGROUND,#{{ cursor }}
|
||||
env = GUM_FILE_CURSOR_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILE_SYMLINK_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_FILE_SYMLINK_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILE_DIRECTORY_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_FILE_DIRECTORY_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILE_FILE_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_FILE_FILE_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILE_PERMISSIONS_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_FILE_PERMISSIONS_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILE_SELECTED_FOREGROUND,#{{ selection_foreground }}
|
||||
env = GUM_FILE_SELECTED_BACKGROUND,#{{ selection_background }}
|
||||
env = GUM_FILE_FILE_SIZE_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_FILE_FILE_SIZE_BACKGROUND,#{{ background }}
|
||||
env = GUM_FILE_HEADER_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_FILE_HEADER_BACKGROUND,#{{ background }}
|
||||
|
||||
# Gum Pager Style Variables
|
||||
env = GUM_PAGER_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_PAGER_BACKGROUND,#{{ background }}
|
||||
env = GUM_PAGER_LINE_NUMBER_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_PAGER_LINE_NUMBER_BACKGROUND,#{{ background }}
|
||||
env = GUM_PAGER_MATCH_FOREGROUND,#{{ accent }}
|
||||
env = GUM_PAGER_MATCH_BACKGROUND,#{{ background }}
|
||||
env = GUM_PAGER_MATCH_HIGH_FOREGROUND,#{{ accent }}
|
||||
env = GUM_PAGER_MATCH_HIGH_BACKGROUND,#{{ background }}
|
||||
env = GUM_PAGER_HELP_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_PAGER_HELP_BACKGROUND,#{{ background }}
|
||||
|
||||
# Gum Write Style Variables
|
||||
env = GUM_WRITE_BASE_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_WRITE_BASE_BACKGROUND,#{{ background }}
|
||||
env = GUM_WRITE_CURSOR_LINE_NUMBER_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_WRITE_CURSOR_LINE_NUMBER_BACKGROUND,#{{ background }}
|
||||
env = GUM_WRITE_CURSOR_LINE_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_WRITE_CURSOR_LINE_BACKGROUND,#{{ selection_background }}
|
||||
env = GUM_WRITE_CURSOR_FOREGROUND,#{{ cursor }}
|
||||
env = GUM_WRITE_CURSOR_BACKGROUND,#{{ background }}
|
||||
env = GUM_WRITE_END_OF_BUFFER_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_WRITE_END_OF_BUFFER_BACKGROUND,#{{ background }}
|
||||
env = GUM_WRITE_LINE_NUMBER_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_WRITE_LINE_NUMBER_BACKGROUND,#{{ background }}
|
||||
env = GUM_WRITE_HEADER_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_WRITE_HEADER_BACKGROUND,#{{ background }}
|
||||
env = GUM_WRITE_PLACEHOLDER_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_WRITE_PLACEHOLDER_BACKGROUND,#{{ background }}
|
||||
env = GUM_WRITE_PROMPT_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_WRITE_PROMPT_BACKGROUND,#{{ background }}
|
||||
|
||||
# Gum Log Style Variables
|
||||
env = GUM_LOG_LEVEL_FOREGROUND,#{{ accent }}
|
||||
env = GUM_LOG_LEVEL_BACKGROUND,#{{ background }}
|
||||
env = GUM_LOG_TIME_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_LOG_TIME_BACKGROUND,#{{ background }}
|
||||
env = GUM_LOG_PREFIX_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_LOG_PREFIX_BACKGROUND,#{{ background }}
|
||||
env = GUM_LOG_MESSAGE_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_LOG_MESSAGE_BACKGROUND,#{{ background }}
|
||||
env = GUM_LOG_KEY_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_LOG_KEY_BACKGROUND,#{{ background }}
|
||||
env = GUM_LOG_VALUE_FOREGROUND,#{{ foreground }}
|
||||
env = GUM_LOG_VALUE_BACKGROUND,#{{ background }}
|
||||
env = GUM_LOG_SEPARATOR_FOREGROUND,#{{ color8 }}
|
||||
env = GUM_LOG_SEPARATOR_BACKGROUND,#{{ background }}
|
||||
@@ -8,6 +8,7 @@ run_logged $OMARCHY_INSTALL/config/increase-sudo-tries.sh
|
||||
run_logged $OMARCHY_INSTALL/config/increase-lockout-limit.sh
|
||||
run_logged $OMARCHY_INSTALL/config/ssh-flakiness.sh
|
||||
run_logged $OMARCHY_INSTALL/config/increase-file-watchers.sh
|
||||
run_logged $OMARCHY_INSTALL/config/increase-fd-limit.sh
|
||||
run_logged $OMARCHY_INSTALL/config/detect-keyboard-layout.sh
|
||||
run_logged $OMARCHY_INSTALL/config/xcompose.sh
|
||||
run_logged $OMARCHY_INSTALL/config/mise-work.sh
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
NVIDIA="$(lspci | grep -i 'nvidia')"
|
||||
|
||||
if [[ -n $NVIDIA ]]; then
|
||||
if lspci | grep -qi 'nvidia'; then
|
||||
# Check which kernel is installed and set appropriate headers package
|
||||
KERNEL_HEADERS="$(pacman -Qqs '^linux(-zen|-lts|-hardened)?$' | head -1)-headers"
|
||||
|
||||
# Turing+ (GTX 16xx, RTX 20xx-50xx, RTX Pro, Quadro RTX, datacenter A/H/T/L series) have GSP firmware
|
||||
if echo "$NVIDIA" | grep -qE "GTX 16[0-9]{2}|RTX [2-5][0-9]{3}|RTX PRO [0-9]{4}|Quadro RTX|RTX A[0-9]{4}|A[1-9][0-9]{2}|H[1-9][0-9]{2}|T4|L[0-9]+"; then
|
||||
if omarchy-hw-nvidia-gsp; then
|
||||
PACKAGES=(nvidia-open-dkms nvidia-utils lib32-nvidia-utils libva-nvidia-driver)
|
||||
GPU_ARCH="turing_plus"
|
||||
# Maxwell (GTX 9xx), Pascal (GT/GTX 10xx, Quadro P, MX series), Volta (Titan V, Tesla V100, Quadro GV100) lack GSP
|
||||
elif echo "$NVIDIA" | grep -qE "GTX (9[0-9]{2}|10[0-9]{2})|GT 10[0-9]{2}|Quadro [PM][0-9]{3,4}|Quadro GV100|MX *[0-9]+|Titan (X|Xp|V)|Tesla V100"; then
|
||||
elif omarchy-hw-nvidia-without-gsp; then
|
||||
PACKAGES=(nvidia-580xx-dkms nvidia-580xx-utils lib32-nvidia-580xx-utils)
|
||||
GPU_ARCH="maxwell_pascal_volta"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Raise soft file descriptor limit from systemd's default of 1024 to 65536
|
||||
# so dev tools (VS Code, Docker, dev servers, databases) get the headroom they need
|
||||
sudo mkdir -p /etc/systemd/system.conf.d /etc/systemd/user.conf.d
|
||||
|
||||
sudo tee /etc/systemd/system.conf.d/99-omarchy-nofile.conf >/dev/null <<'EOF'
|
||||
[Manager]
|
||||
DefaultLimitNOFILESoft=65536
|
||||
EOF
|
||||
|
||||
sudo cp /etc/systemd/system.conf.d/99-omarchy-nofile.conf \
|
||||
/etc/systemd/user.conf.d/99-omarchy-nofile.conf
|
||||
@@ -7,6 +7,6 @@ xdg-user-dirs-update --set DESKTOP "$HOME"
|
||||
rmdir ~/Templates ~/Public ~/Desktop 2>/dev/null || true
|
||||
|
||||
touch ~/.config/gtk-3.0/bookmarks
|
||||
for dir in Downloads Pictures Videos; do
|
||||
for dir in Downloads Projects Pictures Videos; do
|
||||
printf 'file://%s/%s %s\n' "$HOME" "$dir" "$dir" >>~/.config/gtk-3.0/bookmarks
|
||||
done
|
||||
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
gsettings set org.gnome.desktop.interface gtk-enable-primary-paste true
|
||||
@@ -28,7 +28,6 @@ docker-compose
|
||||
dosfstools
|
||||
dotnet-runtime-9.0
|
||||
dust
|
||||
elephant-all
|
||||
evince
|
||||
exfatprogs
|
||||
expac
|
||||
@@ -94,6 +93,7 @@ nvim
|
||||
obs-studio
|
||||
obsidian
|
||||
omarchy-nvim
|
||||
omarchy-walker
|
||||
pamixer
|
||||
pinta
|
||||
playerctl
|
||||
@@ -120,6 +120,8 @@ sushi
|
||||
swaybg
|
||||
swayosd
|
||||
system-config-printer
|
||||
tesseract
|
||||
tesseract-data-eng
|
||||
tldr
|
||||
tree-sitter-cli
|
||||
tmux
|
||||
@@ -133,7 +135,6 @@ ufw-docker
|
||||
unzip
|
||||
usage
|
||||
uwsm
|
||||
walker
|
||||
waybar
|
||||
whois
|
||||
wireless-regdb
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
echo "Install tesseract OCR and language data files"
|
||||
|
||||
omarchy-pkg-add tesseract tesseract-data-eng
|
||||
@@ -0,0 +1,2 @@
|
||||
echo "Update Plymouth theme for a smoother progress bar animation"
|
||||
omarchy-refresh-plymouth
|
||||
@@ -1,36 +0,0 @@
|
||||
echo "Replace deprecated sainnhe.everforest VSCode extension with reesew.everforest-theme"
|
||||
|
||||
# Background:
|
||||
# The original "sainnhe.everforest" extension is no longer maintained — its
|
||||
# upstream repo (https://github.com/sainnhe/everforest-vscode) was archived
|
||||
# by the author, so it receives no updates or fixes.
|
||||
# "reesew.everforest-theme" is a maintained fork of that same extension,
|
||||
# published from https://github.com/reese/everforest-vscode, and is the
|
||||
# replacement we now ship in themes/everforest/vscode.json.
|
||||
|
||||
|
||||
# For each VS Code variant, uninstall the old extension and re-apply theme if the
|
||||
# current Omarchy theme is everforest (which will install the new extension automatically).
|
||||
|
||||
uninstall_old_extension() {
|
||||
local editor_cmd="$1"
|
||||
|
||||
omarchy-cmd-present "$editor_cmd" || return 0
|
||||
|
||||
if "$editor_cmd" --list-extensions | grep -Fxq "sainnhe.everforest"; then
|
||||
"$editor_cmd" --uninstall-extension sainnhe.everforest >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
uninstall_old_extension "code"
|
||||
uninstall_old_extension "code-insiders"
|
||||
uninstall_old_extension "codium"
|
||||
uninstall_old_extension "cursor"
|
||||
|
||||
# If the user is currently on the everforest theme, refresh it so the updated
|
||||
# vscode.json (with reesew.everforest-theme) is copied into ~/.config/omarchy/current/theme,
|
||||
# then omarchy-theme-set-vscode (called by the refresh) installs the new extension.
|
||||
THEME_NAME_PATH="$HOME/.config/omarchy/current/theme.name"
|
||||
if [[ -f $THEME_NAME_PATH ]] && [[ "$(cat "$THEME_NAME_PATH")" == "everforest" ]]; then
|
||||
omarchy-theme-refresh
|
||||
fi
|
||||
@@ -1,6 +0,0 @@
|
||||
echo "Replace coterie of individual Elephant packages with the single elephant-all package"
|
||||
|
||||
if omarchy-pkg-present omarchy-walker; then
|
||||
yes | sudo pacman -S --needed elephant-all
|
||||
sudo pacman -R --noconfirm omarchy-walker
|
||||
fi
|
||||
@@ -0,0 +1,20 @@
|
||||
echo "Enable VAAPI hardware video decoding/encoding in Chromium and Brave for h265 and other codecs"
|
||||
|
||||
add_flag() {
|
||||
local file=$1
|
||||
local flag=$2
|
||||
|
||||
[[ -f $file ]] || return
|
||||
grep -q "$flag" "$file" && return
|
||||
|
||||
if grep -q "^--enable-features=" "$file"; then
|
||||
sed -i "s/^--enable-features=\(.*\)$/--enable-features=\1,$flag/" "$file"
|
||||
else
|
||||
echo "--enable-features=$flag" >>"$file"
|
||||
fi
|
||||
}
|
||||
|
||||
for conf in chromium-flags.conf brave-flags.conf; do
|
||||
add_flag "$HOME/.config/$conf" "VaapiVideoDecodeLinuxGL"
|
||||
add_flag "$HOME/.config/$conf" "VaapiVideoEncoder"
|
||||
done
|
||||
@@ -0,0 +1,3 @@
|
||||
echo "Raise soft file descriptor limit so dev tools have headroom (takes effect after reboot)"
|
||||
|
||||
bash $OMARCHY_PATH/install/config/increase-fd-limit.sh
|
||||
@@ -0,0 +1,3 @@
|
||||
echo "Install ghui (GitHub TUI) via npx wrapper"
|
||||
|
||||
omarchy-npx-install @kitlangton/ghui ghui
|
||||
@@ -0,0 +1,10 @@
|
||||
echo "Remove stale Xe Panel Replay kernel cmdline from Dell XPS Panther Lake systems"
|
||||
|
||||
DEFAULT_LIMINE="/etc/default/limine"
|
||||
|
||||
if omarchy-hw-match "XPS" && omarchy-hw-intel-ptl; then
|
||||
if [[ -f $DEFAULT_LIMINE ]] && grep -q 'xe\.enable_panel_replay' "$DEFAULT_LIMINE"; then
|
||||
sudo sed -i '/^KERNEL_CMDLINE.*xe\.enable_panel_replay/d' "$DEFAULT_LIMINE"
|
||||
sudo limine-update
|
||||
fi
|
||||
fi
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
echo "Enable middle-click primary paste for GTK/Chromium-family apps (Ghostty, Brave, Chromium)"
|
||||
|
||||
if command -v gsettings >/dev/null; then
|
||||
gsettings set org.gnome.desktop.interface gtk-enable-primary-paste true || true
|
||||
fi
|
||||
@@ -2,7 +2,24 @@ return {
|
||||
{
|
||||
"catppuccin/nvim",
|
||||
name = "catppuccin",
|
||||
lazy = false,
|
||||
priority = 1000,
|
||||
config = function()
|
||||
require("catppuccin").setup()
|
||||
|
||||
local function brighten_borders()
|
||||
for _, group in ipairs({ "FloatBorder", "WinSeparator" }) do
|
||||
vim.api.nvim_set_hl(0, group, { fg = "#6c7086" })
|
||||
end
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd("ColorScheme", {
|
||||
pattern = "catppuccin*",
|
||||
callback = brighten_borders,
|
||||
})
|
||||
|
||||
brighten_borders()
|
||||
end,
|
||||
},
|
||||
{
|
||||
"LazyVim/LazyVim",
|
||||
|
||||
@@ -21,7 +21,7 @@ color6 = "#b0b0b0"
|
||||
color7 = "#ececec"
|
||||
|
||||
# Bright colors (ANSI 8-15)
|
||||
color8 = "#fdfdfd"
|
||||
color8 = "#5c5c5c"
|
||||
color9 = "#a4a4a4"
|
||||
color10 = "#b6b6b6"
|
||||
color11 = "#cecece"
|
||||
|
||||
Reference in New Issue
Block a user