mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-02 20:28:19 +02:00
Compare commits
60
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51c48de1ba | ||
|
|
34dbfc0d7c | ||
|
|
c7203b6714 | ||
|
|
5552be964b | ||
|
|
78bc4d34c5 | ||
|
|
27dfc23139 | ||
|
|
234f670310 | ||
|
|
080d287d74 | ||
|
|
286e6378e7 | ||
|
|
ffb080d80d | ||
|
|
6eb6c79831 | ||
|
|
98db372bce | ||
|
|
a1ed2cf37f | ||
|
|
06ee173aca | ||
|
|
a966fbbc33 | ||
|
|
b3755d423a | ||
|
|
723ea545b5 | ||
|
|
4078102b80 | ||
|
|
507062f077 | ||
|
|
49e65067d5 | ||
|
|
81687e4f34 | ||
|
|
75c0e965a0 | ||
|
|
378497c8a2 | ||
|
|
fe19eee32b | ||
|
|
14696c315e | ||
|
|
4178547bbf | ||
|
|
8984affcbe | ||
|
|
4e15165155 | ||
|
|
6fd95b3e37 | ||
|
|
42fed06d9f | ||
|
|
8963c0dd2d | ||
|
|
dc17299a69 | ||
|
|
132e42a45f | ||
|
|
36b7bc7342 | ||
|
|
b9654a9372 | ||
|
|
e4e7fae5ef | ||
|
|
46db57acc5 | ||
|
|
89c5cc2d74 | ||
|
|
7c2402ff5b | ||
|
|
b609519c83 | ||
|
|
6d583028d5 | ||
|
|
0a8bcbe40a | ||
|
|
448cf86ff3 | ||
|
|
2ac65b5273 | ||
|
|
d0af0f998b | ||
|
|
76894b9c74 | ||
|
|
b7ccb64082 | ||
|
|
de4819bd17 | ||
|
|
6f73a52510 | ||
|
|
b64046fd5e | ||
|
|
433346353e | ||
|
|
11bb11814b | ||
|
|
df3310a453 | ||
|
|
087545e17e | ||
|
|
442cd5917a | ||
|
|
21ac298e88 | ||
|
|
5ae7bad9b5 | ||
|
|
35c21d7bea | ||
|
|
29041f7a56 | ||
|
|
42bfa3582b |
@@ -1,67 +0,0 @@
|
||||
# Style
|
||||
|
||||
- Two spaces for indentation, no tabs
|
||||
- Use bash 5 conditionals: use `[[ ]]` for string/file tests and `(( ))` for numeric tests
|
||||
- In `[[ ]]`, don't quote variables, but do quote string literals when comparing values (e.g., `[[ $branch == "dev" ]]`)
|
||||
- Prefer `(( ))` over numeric operators inside `[[ ]]` (e.g., `(( count < 50 ))`, not `[[ $count -lt 50 ]]`)
|
||||
- For strings/paths with spaces, quote them instead of escaping spaces with `\ ` (e.g., `"$APP_DIR/Disk Usage.desktop"`, not `$APP_DIR/Disk\ Usage.desktop`)
|
||||
- Shebangs must use `#!/bin/bash` consistently (never `#!/usr/bin/env bash`)
|
||||
|
||||
# Command Naming
|
||||
|
||||
All commands start with `omarchy-`. Prefixes indicate purpose:
|
||||
|
||||
- `cmd-` - check if commands exist, misc utility commands
|
||||
- `pkg-` - package management helpers
|
||||
- `hw-` - hardware detection (return exit codes for use in conditionals)
|
||||
- `refresh-` - copy default config to user's `~/.config/`
|
||||
- `restart-` - restart a component
|
||||
- `launch-` - open applications
|
||||
- `install-` - install optional software
|
||||
- `setup-` - interactive setup wizards
|
||||
- `toggle-` - toggle features on/off
|
||||
- `theme-` - theme management
|
||||
- `update-` - update components
|
||||
|
||||
# Helper Commands
|
||||
|
||||
Use these instead of raw shell commands:
|
||||
|
||||
- `omarchy-cmd-missing` / `omarchy-cmd-present` - check for commands
|
||||
- `omarchy-pkg-missing` / `omarchy-pkg-present` - check for packages
|
||||
- `omarchy-pkg-add` - install packages (handles both pacman and AUR)
|
||||
- `omarchy-hw-asus-rog` - detect ASUS ROG hardware (and similar `hw-*` commands)
|
||||
|
||||
# Config Structure
|
||||
|
||||
- `config/` - default configs copied to `~/.config/`
|
||||
- `default/themed/*.tpl` - templates with `{{ variable }}` placeholders for theme colors
|
||||
- `themes/*/colors.toml` - theme color definitions (accent, background, foreground, color0-15)
|
||||
|
||||
# Refresh Pattern
|
||||
|
||||
To copy a default config to user config with automatic backup:
|
||||
|
||||
```bash
|
||||
omarchy-refresh-config hypr/hyprlock.conf
|
||||
```
|
||||
|
||||
This copies `~/.local/share/omarchy/config/hypr/hyprlock.conf` to `~/.config/hypr/hyprlock.conf`.
|
||||
|
||||
# Migrations
|
||||
|
||||
To create a new migration, run `omarchy-dev-add-migration --no-edit`. This creates a migration file named after the unix timestamp of the last commit.
|
||||
|
||||
Migration format:
|
||||
- No shebang line
|
||||
- Start with an `echo` describing what the migration does
|
||||
- Use `$OMARCHY_PATH` to reference the omarchy directory
|
||||
|
||||
Example:
|
||||
```bash
|
||||
echo "Disable fingerprint in hyprlock if fingerprint auth is not configured"
|
||||
|
||||
if omarchy-cmd-missing fprintd-list || ! fprintd-list "$USER" 2>/dev/null | grep -q "finger"; then
|
||||
sed -i 's/fingerprint:enabled = .*/fingerprint:enabled = false/' ~/.config/hypr/hyprlock.conf
|
||||
fi
|
||||
```
|
||||
@@ -1,2 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Hidden=true
|
||||
@@ -1,2 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Hidden=true
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 53 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB |
@@ -11,8 +11,8 @@ send_notification() {
|
||||
notify-send -u critical " Time to recharge!" "Battery is down to ${1}%" -i battery-caution -t 30000
|
||||
}
|
||||
|
||||
if [[ -n $BATTERY_LEVEL && $BATTERY_LEVEL =~ ^[0-9]+$ ]]; then
|
||||
if [[ $BATTERY_STATE == "discharging" ]] && (( BATTERY_LEVEL <= BATTERY_THRESHOLD )); then
|
||||
if [[ -n "$BATTERY_LEVEL" && "$BATTERY_LEVEL" =~ ^[0-9]+$ ]]; then
|
||||
if [[ $BATTERY_STATE == "discharging" && $BATTERY_LEVEL -le $BATTERY_THRESHOLD ]]; then
|
||||
if [[ ! -f $NOTIFICATION_FLAG ]]; then
|
||||
send_notification $BATTERY_LEVEL
|
||||
touch $NOTIFICATION_FLAG
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns true if a battery is present on the system.
|
||||
# Used by the battery monitor and other battery-related checks.
|
||||
|
||||
for bat in /sys/class/power_supply/BAT*; do
|
||||
[[ -r $bat/present ]] &&
|
||||
[[ $(cat $bat/present) == "1" ]] &&
|
||||
[[ $(cat $bat/type) == "Battery" ]] &&
|
||||
exit 0
|
||||
done
|
||||
|
||||
exit 1
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns the battery percentage remaining as an integer.
|
||||
# Used by the battery monitor and the Ctrl + Shift + Super + B hotkey.
|
||||
|
||||
upower -i $(upower -e | grep BAT) | awk '/percentage/ {
|
||||
print int($2)
|
||||
upower -i $(upower -e | grep BAT) \
|
||||
| awk -F: '/percentage/ {
|
||||
gsub(/[%[:space:]]/, "", $2);
|
||||
val=$2;
|
||||
printf("%d\n", (val+0.5))
|
||||
exit
|
||||
}'
|
||||
}'
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set the branch for Omarchy's git repository.
|
||||
|
||||
if (($# == 0)); then
|
||||
echo "Usage: omarchy-branch-set [master|rc|dev]"
|
||||
exit 1
|
||||
else
|
||||
branch="$1"
|
||||
fi
|
||||
|
||||
if [[ $branch != "master" && $branch != "rc" && $branch != "dev" ]]; then
|
||||
echo "Error: Invalid branch '$branch'. Must be one of: master, rc, dev"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git -C $OMARCHY_PATH switch $branch
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Adjust brightness on the most likely display device.
|
||||
# Usage: omarchy-brightness-display <step>
|
||||
|
||||
step="${1:-+5%}"
|
||||
|
||||
# Start with the first possible output, then refine to the most likely given an order heuristic.
|
||||
device="$(ls -1 /sys/class/backlight 2>/dev/null | head -n1)"
|
||||
for candidate in amdgpu_bl* intel_backlight acpi_video*; do
|
||||
if [[ -e /sys/class/backlight/$candidate ]]; then
|
||||
device="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Set the actual brightness of the display device.
|
||||
brightnessctl -d "$device" set "$step" >/dev/null
|
||||
|
||||
# Use SwayOSD to display the new brightness setting.
|
||||
omarchy-swayosd-brightness "$(brightnessctl -d "$device" -m | cut -d',' -f4 | tr -d '%')"
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Adjust the brightness on Apple Studio Displays and Apple XDR Displays using asdcontrol.
|
||||
|
||||
if (( $# == 0 )); then
|
||||
echo "Adjust Apple Display Brightness by passing +5000 or -5000 (or any range from 0-60000)"
|
||||
else
|
||||
device="$(sudo asdcontrol --detect /dev/usb/hiddev* | grep ^/dev/usb/hiddev | cut -d: -f1)"
|
||||
sudo asdcontrol "$device" -- "$1" >/dev/null
|
||||
value="$(sudo asdcontrol "$device" | awk -F= '/BRIGHTNESS=/{print $2+0}')"
|
||||
omarchy-swayosd-brightness "$(( value * 100 / 60000 ))"
|
||||
fi
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Adjust keyboard backlight brightness using available steps.
|
||||
# Usage: omarchy-brightness-keyboard <up|down|cycle>
|
||||
|
||||
direction="${1:-up}"
|
||||
|
||||
# Find keyboard backlight device (look for *kbd_backlight* pattern in leds class).
|
||||
device=""
|
||||
for candidate in /sys/class/leds/*kbd_backlight*; do
|
||||
if [[ -e $candidate ]]; then
|
||||
device="$(basename "$candidate")"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -z $device ]]; then
|
||||
echo "No keyboard backlight device found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get current and max brightness to determine step size.
|
||||
max_brightness="$(brightnessctl -d "$device" max)"
|
||||
current_brightness="$(brightnessctl -d "$device" get)"
|
||||
|
||||
# Calculate step as one unit (keyboards typically have discrete levels like 0-3).
|
||||
if [[ $direction == "cycle" ]]; then
|
||||
new_brightness=$(( (current_brightness + 1) % (max_brightness + 1) ))
|
||||
elif [[ $direction == "up" ]]; then
|
||||
new_brightness=$((current_brightness + 1))
|
||||
(( new_brightness > max_brightness )) && new_brightness=$max_brightness
|
||||
else
|
||||
new_brightness=$((current_brightness - 1))
|
||||
(( new_brightness < 0 )) && new_brightness=0
|
||||
fi
|
||||
|
||||
# Set the new brightness.
|
||||
brightnessctl -d "$device" set "$new_brightness" >/dev/null
|
||||
|
||||
# Use SwayOSD to display the new brightness setting.
|
||||
percent=$((new_brightness * 100 / max_brightness))
|
||||
omarchy-swayosd-kbd-brightness "$percent"
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set the Omarchy channel, which dictates what git branch and package repository is used.
|
||||
#
|
||||
# Stable uses the master branch, which only sees updates on official releases, and
|
||||
# the stable package repository, which typically lags the edge by a month to ensure
|
||||
# better compatibility.
|
||||
#
|
||||
# Edge tracks the latest package repository, but still relies on the master branch,
|
||||
# so new packages which require config changes may cause conflicts or errors.
|
||||
#
|
||||
# Dev tracks the active development dev branch, which may include partial or broken updates,
|
||||
# as well as the latest package repository. This should only be used by Omarchy developers
|
||||
# and people with a lot of experience managing Linux systems.
|
||||
|
||||
if (($# == 0)); then
|
||||
echo "Usage: omarchy-channel-set [stable|rc|edge|dev]"
|
||||
exit 1
|
||||
else
|
||||
channel="$1"
|
||||
fi
|
||||
|
||||
case "$channel" in
|
||||
"stable") omarchy-branch-set "master" && omarchy-refresh-pacman "stable" ;;
|
||||
"rc") omarchy-branch-set "rc" && omarchy-refresh-pacman "rc" ;;
|
||||
"edge") omarchy-branch-set "master" && omarchy-refresh-pacman "edge" ;;
|
||||
"dev") omarchy-branch-set "dev" && omarchy-refresh-pacman "edge" ;;
|
||||
*) echo "Unknown channel: $channel"; exit 1; ;;
|
||||
esac
|
||||
|
||||
omarchy-update -y
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
echo "Adjust Apple Display Brightness by passing +5000 or -5000 (or any range from 0-60000)"
|
||||
else
|
||||
DEVICE="$(sudo asdcontrol --detect /dev/usb/hiddev* | grep ^/dev/usb/hiddev | cut -d: -f1)"
|
||||
sudo asdcontrol "$DEVICE" -- "$1" >/dev/null
|
||||
VALUE="$(sudo asdcontrol "$DEVICE" | awk -F= '/BRIGHTNESS=/{print $2+0}')"
|
||||
swayosd-client \
|
||||
--monitor "$(hyprctl monitors -j | jq -r '.[]|select(.focused==true).name')" \
|
||||
--custom-icon display-brightness \
|
||||
--custom-progress "$(awk -v v="$VALUE" 'BEGIN{printf "%.2f", v/60000}')" \
|
||||
--custom-progress-text "$(( VALUE * 100 / 60000 ))%"
|
||||
fi
|
||||
@@ -1,13 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Switch between audio outputs while preserving the mute status. By default mapped to Super + Mute.
|
||||
|
||||
focused_monitor="$(hyprctl monitors -j | jq -r '.[] | select(.focused == true).name')"
|
||||
|
||||
sinks=$(pactl -f json list sinks | jq '[.[] | select((.ports | length == 0) or ([.ports[]? | .availability != "not available"] | any))]')
|
||||
sinks_count=$(echo "$sinks" | jq '. | length')
|
||||
|
||||
if (( sinks_count == 0 )); then
|
||||
if [ "$sinks_count" -eq 0 ]; then
|
||||
swayosd-client \
|
||||
--monitor "$focused_monitor" \
|
||||
--custom-message "No audio devices found"
|
||||
@@ -17,7 +15,7 @@ fi
|
||||
current_sink_name=$(pactl get-default-sink)
|
||||
current_sink_index=$(echo "$sinks" | jq -r --arg name "$current_sink_name" 'map(.name) | index($name)')
|
||||
|
||||
if [[ $current_sink_index != "null" ]]; then
|
||||
if [ "$current_sink_index" != "null" ]; then
|
||||
next_sink_index=$(((current_sink_index + 1) % sinks_count))
|
||||
else
|
||||
next_sink_index=0
|
||||
@@ -27,28 +25,20 @@ next_sink=$(echo "$sinks" | jq -r ".[$next_sink_index]")
|
||||
next_sink_name=$(echo "$next_sink" | jq -r '.name')
|
||||
|
||||
next_sink_description=$(echo "$next_sink" | jq -r '.description')
|
||||
if [[ $next_sink_description == "(null)" ]] || [[ $next_sink_description == "null" ]] || [[ -z $next_sink_description ]]; then
|
||||
# For Bluetooth devices, the friendly name is on the Device entry (device.id), not the Sink entry (object.id)
|
||||
device_id=$(echo "$next_sink" | jq -r '.properties."device.id"')
|
||||
if [[ $device_id != "null" ]] && [[ -n $device_id ]]; then
|
||||
next_sink_description=$(wpctl status | grep -E "^\s*│?\s+${device_id}\." | sed -E 's/^.*[0-9]+\.\s+//' | sed -E 's/\s+\[.*$//')
|
||||
fi
|
||||
# Fall back to object.id lookup if device.id didn't yield a result
|
||||
if [[ -z $next_sink_description ]]; then
|
||||
sink_id=$(echo "$next_sink" | jq -r '.properties."object.id"')
|
||||
next_sink_description=$(wpctl status | grep -E "\s+\*?\s+${sink_id}\." | sed -E 's/^.*[0-9]+\.\s+//' | sed -E 's/\s+\[.*$//')
|
||||
fi
|
||||
if [ "$next_sink_description" = "(null)" ] || [ "$next_sink_description" = "null" ] || [ -z "$next_sink_description" ]; then
|
||||
sink_id=$(echo "$next_sink" | jq -r '.properties."object.id"')
|
||||
next_sink_description=$(wpctl status | grep -E "\s+\*?\s+${sink_id}\." | sed -E 's/^.*[0-9]+\.\s+//' | sed -E 's/\s+\[.*$//')
|
||||
fi
|
||||
|
||||
next_sink_volume=$(echo "$next_sink" | jq -r \
|
||||
'.volume | to_entries[0].value.value_percent | sub("%"; "")')
|
||||
next_sink_is_muted=$(echo "$next_sink" | jq -r '.mute')
|
||||
|
||||
if [[ $next_sink_is_muted = "true" ]] || (( next_sink_volume == 0 )); then
|
||||
if [ "$next_sink_is_muted" = "true" ] || [ "$next_sink_volume" -eq 0 ]; then
|
||||
icon_state="muted"
|
||||
elif (( next_sink_volume <= 33 )); then
|
||||
elif [ "$next_sink_volume" -le 33 ]; then
|
||||
icon_state="low"
|
||||
elif (( next_sink_volume <= 66 )); then
|
||||
elif [ "$next_sink_volume" -le 66 ]; then
|
||||
icon_state="medium"
|
||||
else
|
||||
icon_state="high"
|
||||
@@ -56,7 +46,7 @@ fi
|
||||
|
||||
next_sink_volume_icon="sink-volume-${icon_state}-symbolic"
|
||||
|
||||
if [[ $next_sink_name != $current_sink_name ]]; then
|
||||
if [ "$next_sink_name" != "$current_sink_name" ]; then
|
||||
pactl set-default-sink "$next_sink_name"
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Finish the installation of Omarchy with items that can only be done after logging in.
|
||||
|
||||
set -e
|
||||
|
||||
FIRST_RUN_MODE=~/.local/state/omarchy/first-run.mode
|
||||
|
||||
if [[ -f $FIRST_RUN_MODE ]]; then
|
||||
if [[ -f "$FIRST_RUN_MODE" ]]; then
|
||||
rm -f "$FIRST_RUN_MODE"
|
||||
|
||||
bash "$OMARCHY_PATH/install/first-run/battery-monitor.sh"
|
||||
@@ -14,7 +12,6 @@ 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/elephant.sh"
|
||||
sudo rm -f /etc/sudoers.d/first-run
|
||||
|
||||
bash "$OMARCHY_PATH/install/first-run/welcome.sh"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns true if any of the commands passed in as arguments are missing on the system.
|
||||
|
||||
for cmd in "$@"; do
|
||||
if ! command -v "$cmd" &>/dev/null; then
|
||||
exit 0
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns true if all the commands passed in as arguments exit on the system.
|
||||
|
||||
for cmd in "$@"; do
|
||||
command -v "$cmd" &>/dev/null || exit 1
|
||||
done
|
||||
|
||||
@@ -1,49 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Start and stop a screenrecording, which will be saved to ~/Videos by default.
|
||||
# Alternative location can be set via OMARCHY_SCREENRECORD_DIR or XDG_VIDEOS_DIR ENVs.
|
||||
# Resolution is capped to 4K for monitors above 4K, native otherwise.
|
||||
# Override via --resolution= (e.g. --resolution=1920x1080, --resolution=0x0 for native).
|
||||
|
||||
[[ -f ~/.config/user-dirs.dirs ]] && source ~/.config/user-dirs.dirs
|
||||
OUTPUT_DIR="${OMARCHY_SCREENRECORD_DIR:-${XDG_VIDEOS_DIR:-$HOME/Videos}}"
|
||||
|
||||
if [[ ! -d $OUTPUT_DIR ]]; then
|
||||
if [[ ! -d "$OUTPUT_DIR" ]]; then
|
||||
notify-send "Screen recording directory does not exist: $OUTPUT_DIR" -u critical -t 3000
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DESKTOP_AUDIO="false"
|
||||
MICROPHONE_AUDIO="false"
|
||||
SCOPE=""
|
||||
AUDIO="false"
|
||||
WEBCAM="false"
|
||||
WEBCAM_DEVICE=""
|
||||
RESOLUTION=""
|
||||
STOP_RECORDING="false"
|
||||
RECORDING_FILE="/tmp/omarchy-screenrecord-filename"
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--with-desktop-audio) DESKTOP_AUDIO="true" ;;
|
||||
--with-microphone-audio) MICROPHONE_AUDIO="true" ;;
|
||||
--with-webcam) WEBCAM="true" ;;
|
||||
--webcam-device=*) WEBCAM_DEVICE="${arg#*=}" ;;
|
||||
--resolution=*) RESOLUTION="${arg#*=}" ;;
|
||||
--stop-recording) STOP_RECORDING="true" ;;
|
||||
--with-audio) AUDIO="true" ;;
|
||||
--with-webcam) WEBCAM="true" ;;
|
||||
output|region) SCOPE="$arg" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
cleanup_webcam() {
|
||||
pkill -f "WebcamOverlay" 2>/dev/null
|
||||
}
|
||||
|
||||
start_webcam_overlay() {
|
||||
cleanup_webcam
|
||||
|
||||
# Auto-detect first available webcam if none specified
|
||||
if [[ -z $WEBCAM_DEVICE ]]; then
|
||||
WEBCAM_DEVICE=$(v4l2-ctl --list-devices 2>/dev/null | grep -m1 "^[[:space:]]*/dev/video" | tr -d '\t')
|
||||
if [[ -z $WEBCAM_DEVICE ]]; then
|
||||
notify-send "No webcam devices found" -u critical -t 3000
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get monitor scale
|
||||
local scale=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .scale')
|
||||
|
||||
@@ -53,7 +36,7 @@ start_webcam_overlay() {
|
||||
# Try preferred 16:9 resolutions in order, use first available
|
||||
local preferred_resolutions=("640x360" "1280x720" "1920x1080")
|
||||
local video_size_arg=""
|
||||
local available_formats=$(v4l2-ctl --list-formats-ext -d "$WEBCAM_DEVICE" 2>/dev/null)
|
||||
local available_formats=$(v4l2-ctl --list-formats-ext -d /dev/video0 2>/dev/null)
|
||||
|
||||
for resolution in "${preferred_resolutions[@]}"; do
|
||||
if echo "$available_formats" | grep -q "$resolution"; then
|
||||
@@ -62,7 +45,7 @@ start_webcam_overlay() {
|
||||
fi
|
||||
done
|
||||
|
||||
ffplay -f v4l2 $video_size_arg -framerate 30 "$WEBCAM_DEVICE" \
|
||||
ffplay -f v4l2 $video_size_arg -framerate 30 /dev/video0 \
|
||||
-vf "scale=${target_width}:-1" \
|
||||
-window_title "WebcamOverlay" \
|
||||
-noborder \
|
||||
@@ -72,73 +55,36 @@ start_webcam_overlay() {
|
||||
sleep 1
|
||||
}
|
||||
|
||||
cleanup_webcam() {
|
||||
pkill -f "WebcamOverlay" 2>/dev/null
|
||||
}
|
||||
|
||||
default_resolution() {
|
||||
local width height
|
||||
read -r width height < <(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.width) \(.height)"')
|
||||
if ((width > 3840 || height > 2160)); then
|
||||
echo "3840x2160"
|
||||
else
|
||||
echo "0x0"
|
||||
fi
|
||||
}
|
||||
|
||||
start_screenrecording() {
|
||||
local filename="$OUTPUT_DIR/screenrecording-$(date +'%Y-%m-%d_%H-%M-%S').mp4"
|
||||
local audio_devices=""
|
||||
local audio_args=()
|
||||
local audio_args=""
|
||||
|
||||
[[ $DESKTOP_AUDIO == "true" ]] && audio_devices+="default_output"
|
||||
# Merge audio tracks into one - separate tracks only play one at a time in most players
|
||||
[[ "$AUDIO" == "true" ]] && audio_args="-a default_output|default_input"
|
||||
|
||||
if [[ $MICROPHONE_AUDIO == "true" ]]; then
|
||||
# Merge audio tracks into one - separate tracks only play one at a time in most players
|
||||
[[ -n $audio_devices ]] && audio_devices+="|"
|
||||
audio_devices+="default_input"
|
||||
fi
|
||||
|
||||
[[ -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[@]}" &
|
||||
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
|
||||
|
||||
if kill -0 $pid 2>/dev/null; then
|
||||
echo "$filename" >"$RECORDING_FILE"
|
||||
toggle_screenrecording_indicator
|
||||
fi
|
||||
gpu-screen-recorder -w "$@" -f 60 -c mp4 -o "$filename" $audio_args &
|
||||
toggle_screenrecording_indicator
|
||||
}
|
||||
|
||||
stop_screenrecording() {
|
||||
pkill -SIGINT -f "^gpu-screen-recorder" # SIGINT required to save video properly
|
||||
pkill -SIGINT -f "gpu-screen-recorder" # SIGINT required to save video properly
|
||||
|
||||
# Wait a maximum of 5 seconds to finish before hard killing
|
||||
local count=0
|
||||
while pgrep -f "^gpu-screen-recorder" >/dev/null && ((count < 50)); do
|
||||
while pgrep -f "gpu-screen-recorder" >/dev/null && [ $count -lt 50 ]; do
|
||||
sleep 0.1
|
||||
count=$((count + 1))
|
||||
done
|
||||
|
||||
toggle_screenrecording_indicator
|
||||
cleanup_webcam
|
||||
|
||||
if pgrep -f "^gpu-screen-recorder" >/dev/null; then
|
||||
pkill -9 -f "^gpu-screen-recorder"
|
||||
if pgrep -f "gpu-screen-recorder" >/dev/null; then
|
||||
pkill -9 -f "gpu-screen-recorder"
|
||||
cleanup_webcam
|
||||
notify-send "Screen recording error" "Recording process had to be force-killed. Video may be corrupted." -u critical -t 5000
|
||||
else
|
||||
trim_first_frame
|
||||
cleanup_webcam
|
||||
notify-send "Screen recording saved to $OUTPUT_DIR" -t 2000
|
||||
fi
|
||||
|
||||
rm -f "$RECORDING_FILE"
|
||||
toggle_screenrecording_indicator
|
||||
}
|
||||
|
||||
toggle_screenrecording_indicator() {
|
||||
@@ -146,29 +92,51 @@ toggle_screenrecording_indicator() {
|
||||
}
|
||||
|
||||
screenrecording_active() {
|
||||
pgrep -f "^gpu-screen-recorder" >/dev/null
|
||||
}
|
||||
|
||||
trim_first_frame() {
|
||||
local latest
|
||||
latest=$(cat "$RECORDING_FILE" 2>/dev/null)
|
||||
|
||||
if [[ -n $latest && -f $latest ]]; then
|
||||
local trimmed="${latest%.mp4}-trimmed.mp4"
|
||||
if ffmpeg -y -ss 0.1 -i "$latest" -c copy "$trimmed" -loglevel quiet 2>/dev/null; then
|
||||
mv "$trimmed" "$latest"
|
||||
else
|
||||
rm -f "$trimmed"
|
||||
fi
|
||||
fi
|
||||
pgrep -f "gpu-screen-recorder" >/dev/null || pgrep -x slurp >/dev/null || pgrep -f "WebcamOverlay" >/dev/null
|
||||
}
|
||||
|
||||
if screenrecording_active; then
|
||||
stop_screenrecording
|
||||
elif [[ $STOP_RECORDING == "true" ]]; then
|
||||
exit 1
|
||||
else
|
||||
[[ $WEBCAM == "true" ]] && start_webcam_overlay
|
||||
if pgrep -x slurp >/dev/null; then
|
||||
pkill -x slurp 2>/dev/null
|
||||
elif pgrep -f "WebcamOverlay" >/dev/null && ! pgrep -f "gpu-screen-recorder" >/dev/null; then
|
||||
cleanup_webcam
|
||||
else
|
||||
stop_screenrecording
|
||||
fi
|
||||
elif [[ "$SCOPE" == "output" ]]; then
|
||||
[[ "$WEBCAM" == "true" ]] && start_webcam_overlay
|
||||
|
||||
start_screenrecording || cleanup_webcam
|
||||
if ! output=$(slurp -o -f "%o"); then
|
||||
[[ "$WEBCAM" == "true" ]] && cleanup_webcam
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$output" ]]; then
|
||||
notify-send "Error" "Could not detect monitor" -u critical
|
||||
[[ "$WEBCAM" == "true" ]] && cleanup_webcam
|
||||
exit 1
|
||||
fi
|
||||
|
||||
start_screenrecording "$output"
|
||||
else
|
||||
[[ "$WEBCAM" == "true" ]] && start_webcam_overlay
|
||||
|
||||
scale=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .scale')
|
||||
|
||||
if ! region=$(slurp -f "%wx%h+%x+%y"); then
|
||||
[[ "$WEBCAM" == "true" ]] && cleanup_webcam
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$region" =~ ^([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)$ ]]; then
|
||||
w=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[1]} * $scale}")
|
||||
h=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[2]} * $scale}")
|
||||
x=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[3]} * $scale}")
|
||||
y=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[4]} * $scale}")
|
||||
scaled_region="${w}x${h}+${x}+${y}"
|
||||
else
|
||||
scaled_region="$region"
|
||||
fi
|
||||
|
||||
start_screenrecording region -region "$scaled_region"
|
||||
fi
|
||||
|
||||
@@ -1,35 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run the Omarchy screensaver using random effects from TTE.
|
||||
|
||||
screensaver_in_focus() {
|
||||
hyprctl activewindow -j | jq -e '.class == "org.omarchy.screensaver"' >/dev/null 2>&1
|
||||
hyprctl activewindow -j | jq -e '.class == "Screensaver"' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
exit_screensaver() {
|
||||
hyprctl keyword cursor:invisible false &>/dev/null || true
|
||||
hyprctl keyword cursor:invisible false
|
||||
pkill -x tte 2>/dev/null
|
||||
pkill -f org.omarchy.screensaver 2>/dev/null
|
||||
pkill -f "alacritty --class Screensaver" 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Exit the screensaver on signals and input from keyboard and mouse
|
||||
trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT
|
||||
|
||||
printf '\033]11;rgb:00/00/00\007' # Set background color to black
|
||||
|
||||
hyprctl keyword cursor:invisible true &>/dev/null
|
||||
|
||||
tty=$(tty 2>/dev/null)
|
||||
|
||||
while true; do
|
||||
effect=$(tte 2>&1 | grep -oP '{\K[^}]+' | tr ',' ' ' | tr ' ' '\n' | sed -n '/^beams$/,$p' | sort -u | shuf -n1)
|
||||
tte -i ~/.config/omarchy/branding/screensaver.txt \
|
||||
--frame-rate 120 --canvas-width 0 --canvas-height 0 --reuse-canvas --anchor-canvas c --anchor-text c\
|
||||
--random-effect --exclude-effects dev_worm \
|
||||
--no-eol --no-restore-cursor &
|
||||
--frame-rate 240 --canvas-width 0 --canvas-height $(($(tput lines) - 2)) --anchor-canvas c --anchor-text c \
|
||||
"$effect" &
|
||||
|
||||
while pgrep -t "${tty#/dev/}" -x tte >/dev/null; do
|
||||
if read -n1 -t 1 || ! screensaver_in_focus; then
|
||||
while pgrep -x tte >/dev/null; do
|
||||
if read -n 1 -t 3 || ! screensaver_in_focus; then
|
||||
exit_screensaver
|
||||
fi
|
||||
done
|
||||
|
||||
+33
-80
@@ -1,130 +1,83 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Take a screenshot of the whole screen, a specific window, or a user-drawn region.
|
||||
# Saves to ~/Pictures by default, but that can be changed via OMARCHY_SCREENSHOT_DIR or XDG_PICTURES_DIR ENVs.
|
||||
# Editor defaults to Satty but can be changed via --editor=<name> or OMARCHY_SCREENSHOT_EDITOR env
|
||||
|
||||
[[ -f ~/.config/user-dirs.dirs ]] && source ~/.config/user-dirs.dirs
|
||||
OUTPUT_DIR="${OMARCHY_SCREENSHOT_DIR:-${XDG_PICTURES_DIR:-$HOME/Pictures}}"
|
||||
|
||||
if [[ ! -d $OUTPUT_DIR ]]; then
|
||||
if [[ ! -d "$OUTPUT_DIR" ]]; then
|
||||
notify-send "Screenshot directory does not exist: $OUTPUT_DIR" -u critical -t 3000
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pkill slurp && exit 0
|
||||
|
||||
SCREENSHOT_EDITOR="${OMARCHY_SCREENSHOT_EDITOR:-satty}"
|
||||
|
||||
# Parse --editor flag from any position
|
||||
ARGS=()
|
||||
for arg in "$@"; do
|
||||
if [[ $arg == --editor=* ]]; then
|
||||
SCREENSHOT_EDITOR="${arg#--editor=}"
|
||||
else
|
||||
ARGS+=("$arg")
|
||||
fi
|
||||
done
|
||||
set -- "${ARGS[@]}"
|
||||
|
||||
open_editor() {
|
||||
local filepath="$1"
|
||||
if [[ $SCREENSHOT_EDITOR == "satty" ]]; then
|
||||
satty --filename "$filepath" \
|
||||
--output-filename "$filepath" \
|
||||
--actions-on-enter save-to-clipboard \
|
||||
--save-after-copy \
|
||||
--copy-command 'wl-copy'
|
||||
else
|
||||
$SCREENSHOT_EDITOR "$filepath"
|
||||
fi
|
||||
}
|
||||
|
||||
MODE="${1:-smart}"
|
||||
PROCESSING="${2:-slurp}"
|
||||
|
||||
# accounting for portrait/transformed displays
|
||||
JQ_MONITOR_GEO='
|
||||
def format_geo:
|
||||
.x as $x | .y as $y |
|
||||
(.width / .scale | floor) as $w |
|
||||
(.height / .scale | floor) as $h |
|
||||
.transform as $t |
|
||||
if $t == 1 or $t == 3 then
|
||||
"\($x),\($y) \($h)x\($w)"
|
||||
else
|
||||
"\($x),\($y) \($w)x\($h)"
|
||||
end;
|
||||
'
|
||||
|
||||
get_rectangles() {
|
||||
local active_workspace=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .activeWorkspace.id')
|
||||
hyprctl monitors -j | jq -r --arg ws "$active_workspace" "${JQ_MONITOR_GEO} .[] | select(.activeWorkspace.id == (\$ws | tonumber)) | format_geo"
|
||||
hyprctl monitors -j | jq -r --arg ws "$active_workspace" '.[] | select(.activeWorkspace.id == ($ws | tonumber)) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"'
|
||||
hyprctl clients -j | jq -r --arg ws "$active_workspace" '.[] | select(.workspace.id == ($ws | tonumber)) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"'
|
||||
}
|
||||
|
||||
# Select based on mode
|
||||
case "$MODE" in
|
||||
region)
|
||||
hyprpicker -r -z >/dev/null 2>&1 & PID=$!
|
||||
wayfreeze & PID=$!
|
||||
sleep .1
|
||||
SELECTION=$(slurp 2>/dev/null)
|
||||
kill $PID 2>/dev/null
|
||||
;;
|
||||
windows)
|
||||
hyprpicker -r -z >/dev/null 2>&1 & PID=$!
|
||||
wayfreeze & PID=$!
|
||||
sleep .1
|
||||
SELECTION=$(get_rectangles | slurp -r 2>/dev/null)
|
||||
kill $PID 2>/dev/null
|
||||
;;
|
||||
fullscreen)
|
||||
SELECTION=$(hyprctl monitors -j | jq -r "${JQ_MONITOR_GEO} .[] | select(.focused == true) | format_geo")
|
||||
SELECTION=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"')
|
||||
;;
|
||||
smart|*)
|
||||
RECTS=$(get_rectangles)
|
||||
hyprpicker -r -z >/dev/null 2>&1 & PID=$!
|
||||
wayfreeze & PID=$!
|
||||
sleep .1
|
||||
SELECTION=$(echo "$RECTS" | slurp 2>/dev/null)
|
||||
kill $PID 2>/dev/null
|
||||
|
||||
# If the selection area is L * W < 20, we'll assume you were trying to select whichever
|
||||
# window or output it was inside of to prevent accidental 2px snapshots
|
||||
if [[ $SELECTION =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]]; then
|
||||
if ((${BASH_REMATCH[3]} * ${BASH_REMATCH[4]} < 20)); then
|
||||
click_x="${BASH_REMATCH[1]}"
|
||||
click_y="${BASH_REMATCH[2]}"
|
||||
# If the selction area is L * W < 20, we'll assume you were trying to select whichever
|
||||
# window or output it was inside of to prevent accidental 2px snapshots
|
||||
if [[ "$SELECTION" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]]; then
|
||||
if (( ${BASH_REMATCH[3]} * ${BASH_REMATCH[4]} < 20 )); then
|
||||
click_x="${BASH_REMATCH[1]}"
|
||||
click_y="${BASH_REMATCH[2]}"
|
||||
|
||||
while IFS= read -r rect; do
|
||||
if [[ $rect =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+) ]]; then
|
||||
rect_x="${BASH_REMATCH[1]}"
|
||||
rect_y="${BASH_REMATCH[2]}"
|
||||
rect_width="${BASH_REMATCH[3]}"
|
||||
rect_height="${BASH_REMATCH[4]}"
|
||||
while IFS= read -r rect; do
|
||||
if [[ "$rect" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+) ]]; then
|
||||
rect_x="${BASH_REMATCH[1]}"
|
||||
rect_y="${BASH_REMATCH[2]}"
|
||||
rect_width="${BASH_REMATCH[3]}"
|
||||
rect_height="${BASH_REMATCH[4]}"
|
||||
|
||||
if ((click_x >= rect_x && click_x < rect_x + rect_width && click_y >= rect_y && click_y < rect_y + rect_height)); then
|
||||
SELECTION="${rect_x},${rect_y} ${rect_width}x${rect_height}"
|
||||
break
|
||||
if (( click_x >= rect_x && click_x < rect_x+rect_width && click_y >= rect_y && click_y < rect_y+rect_height )); then
|
||||
SELECTION="${rect_x},${rect_y} ${rect_width}x${rect_height}"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done <<<"$RECTS"
|
||||
done <<< "$RECTS"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
;;
|
||||
esac
|
||||
|
||||
[[ -z $SELECTION ]] && exit 0
|
||||
|
||||
FILENAME="screenshot-$(date +'%Y-%m-%d_%H-%M-%S').png"
|
||||
FILEPATH="$OUTPUT_DIR/$FILENAME"
|
||||
[ -z "$SELECTION" ] && exit 0
|
||||
|
||||
if [[ $PROCESSING == "slurp" ]]; then
|
||||
grim -g "$SELECTION" "$FILEPATH" || exit 1
|
||||
wl-copy <"$FILEPATH"
|
||||
|
||||
(
|
||||
ACTION=$(notify-send "Screenshot saved to clipboard and file" "Edit with Super + Alt + , (or click this)" -t 10000 -i "$FILEPATH" -A "default=edit")
|
||||
[[ $ACTION == "default" ]] && open_editor "$FILEPATH"
|
||||
) &
|
||||
grim -g "$SELECTION" - |
|
||||
satty --filename - \
|
||||
--output-filename "$OUTPUT_DIR/screenshot-$(date +'%Y-%m-%d_%H-%M-%S').png" \
|
||||
--early-exit \
|
||||
--actions-on-enter save-to-clipboard \
|
||||
--save-after-copy \
|
||||
--copy-command 'wl-copy'
|
||||
else
|
||||
grim -g "$SELECTION" - | wl-copy
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Share clipboard, file, or folder using LocalSend. Bound to Super + Ctrl + S by default.
|
||||
|
||||
if (($# == 0)); then
|
||||
echo "Usage: omarchy-cmd-share [clipboard|file|folder]"
|
||||
exit 1
|
||||
@@ -25,7 +23,7 @@ else
|
||||
# Pick one or more files from home directory
|
||||
FILES=$(find "$HOME" -type f 2>/dev/null | fzf --multi)
|
||||
fi
|
||||
[[ -z $FILES ]] && exit 0
|
||||
[ -z "$FILES" ] && exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns the current working directory of the active terminal window,
|
||||
# so a new terminal window can be started in the same directory.
|
||||
|
||||
# Go from current active terminal to its child shell process and run cwd there
|
||||
terminal_pid=$(hyprctl activewindow | awk '/pid:/ {print $2}')
|
||||
shell_pid=$(pgrep -P "$terminal_pid" | tail -n1)
|
||||
|
||||
if [[ -n $shell_pid ]]; then
|
||||
cwd=$(readlink -f "/proc/$shell_pid/cwd" 2>/dev/null)
|
||||
shell=$(readlink -f "/proc/$shell_pid/exe" 2>/dev/null)
|
||||
|
||||
# Check if $shell is a valid shell and $cwd is a directory.
|
||||
if grep -qs "$shell" /etc/shells && [[ -d $cwd ]]; then
|
||||
if [[ -d $cwd ]]; then
|
||||
echo "$cwd"
|
||||
else
|
||||
echo "$HOME"
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Add an EFI boot entry for the Omarchy UKI, allowing the system to boot directly
|
||||
# without a bootloader like Limine. Requires UEFI firmware and a built UKI.
|
||||
|
||||
if [[ ! -d /sys/firmware/efi ]]; then
|
||||
echo "Error: System is not booted in UEFI mode" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! efibootmgr &>/dev/null; then
|
||||
echo "Error: efibootmgr is not available or not functional" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if cat /sys/class/dmi/id/bios_vendor 2>/dev/null | grep -qi "American Megatrends"; then
|
||||
echo "Error: American Megatrends firmware may not safely support custom EFI entries" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if cat /sys/class/dmi/id/bios_vendor 2>/dev/null | grep -qi "Apple"; then
|
||||
echo "Error: Apple firmware uses its own boot manager" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
uki_file=$(find /boot/EFI/Linux/ -name "omarchy*.efi" -printf "%f\n" 2>/dev/null | head -1)
|
||||
|
||||
if [[ -z $uki_file ]]; then
|
||||
echo "Error: No Omarchy UKI found in /boot/EFI/Linux/" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
boot_source=$(findmnt -n -o SOURCE /boot)
|
||||
disk=$(echo "$boot_source" | sed 's/p\?[0-9]*$//')
|
||||
part=$(echo "$boot_source" | grep -o 'p\?[0-9]*$' | sed 's/^p//')
|
||||
|
||||
if gum confirm "Setup direct boot (so snapshot booting must be done via bios)?"; then
|
||||
echo "Creating EFI boot entry for $uki_file"
|
||||
|
||||
sudo efibootmgr --create \
|
||||
--disk "$disk" \
|
||||
--part "$part" \
|
||||
--label "Omarchy" \
|
||||
--loader "\\EFI\\Linux\\$uki_file"
|
||||
fi
|
||||
+3
-37
@@ -1,36 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Return exhaustive debugging information about the system to help diagnose problems.
|
||||
|
||||
NO_SUDO=false
|
||||
PRINT_ONLY=false
|
||||
|
||||
while (( $# > 0 )); do
|
||||
case "$1" in
|
||||
--no-sudo)
|
||||
NO_SUDO=true
|
||||
shift
|
||||
;;
|
||||
--print)
|
||||
PRINT_ONLY=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
echo "Usage: omarchy-debug [--no-sudo] [--print]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
LOG_FILE="/tmp/omarchy-debug.log"
|
||||
|
||||
if [[ $NO_SUDO = "true" ]]; then
|
||||
DMESG_OUTPUT="(skipped - --no-sudo flag used)"
|
||||
else
|
||||
DMESG_OUTPUT="$(sudo dmesg)"
|
||||
fi
|
||||
|
||||
cat > "$LOG_FILE" <<EOF
|
||||
Date: $(date)
|
||||
Hostname: $(hostname)
|
||||
@@ -44,10 +15,10 @@ $(inxi -Farz)
|
||||
=========================================
|
||||
DMESG
|
||||
=========================================
|
||||
$DMESG_OUTPUT
|
||||
$(sudo dmesg)
|
||||
|
||||
=========================================
|
||||
JOURNALCTL (CURRENT BOOT, WARNINGS+ERRORS)
|
||||
JOURNALCTL (CURRENT BOOT, ERRORS ONLY)
|
||||
=========================================
|
||||
$(journalctl -b -p 4..1)
|
||||
|
||||
@@ -57,11 +28,6 @@ INSTALLED PACKAGES
|
||||
$({ expac -S '%n %v (%r)' $(pacman -Qqe) 2>/dev/null; comm -13 <(pacman -Sql | sort) <(pacman -Qqe | sort) | xargs -r expac -Q '%n %v (AUR)'; } | sort)
|
||||
EOF
|
||||
|
||||
if [[ $PRINT_ONLY = "true" ]]; then
|
||||
cat "$LOG_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
OPTIONS=("View log" "Save in current directory")
|
||||
if ping -c 1 8.8.8.8 >/dev/null 2>&1; then
|
||||
OPTIONS=("Upload log" "${OPTIONS[@]}")
|
||||
@@ -73,7 +39,7 @@ case "$ACTION" in
|
||||
"Upload log")
|
||||
echo "Uploading debug log to 0x0.st..."
|
||||
URL=$(curl -sF "file=@$LOG_FILE" -Fexpires=24 https://0x0.st)
|
||||
if (( $? == 0 )) && [[ -n $URL ]]; then
|
||||
if [ $? -eq 0 ] && [ -n "$URL" ]; then
|
||||
echo "✓ Log uploaded successfully!"
|
||||
echo "Share this URL:"
|
||||
echo ""
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Creates a new Omarchy migration named after the unix timestamp of the last commit.
|
||||
# Only intended for Omarchy developers.
|
||||
|
||||
# FIXME: Update behavior
|
||||
cd ~/.local/share/omarchy
|
||||
migration_file="$HOME/.local/share/omarchy/migrations/$(git log -1 --format=%cd --date=unix).sh"
|
||||
touch $migration_file
|
||||
|
||||
if [[ $1 != "--no-edit" ]]; then
|
||||
nvim $migration_file
|
||||
fi
|
||||
|
||||
echo $migration_file
|
||||
nvim $migration_file
|
||||
|
||||
Executable
+344
@@ -0,0 +1,344 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Omarchy Disk Configuration Tool
|
||||
|
||||
Interactive partition editor and validator for Omarchy installations.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _find_root_partition(disk_config):
|
||||
for dev_mod in disk_config.device_modifications:
|
||||
for part in dev_mod.partitions:
|
||||
if part.mountpoint == Path('/'):
|
||||
return part
|
||||
|
||||
if part.btrfs_subvols:
|
||||
for subvol in part.btrfs_subvols:
|
||||
if subvol.mountpoint == Path('/'):
|
||||
return part
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def validate_disk_config(config, interactive=True):
|
||||
from archinstall.lib.models.device import FilesystemType, Size, Unit, EncryptionType
|
||||
from archinstall.lib.output import info, warn
|
||||
|
||||
if not config.disk_config:
|
||||
return 'CONTINUE'
|
||||
|
||||
validation_warnings = []
|
||||
|
||||
boot_partition = None
|
||||
for dev_mod in config.disk_config.device_modifications:
|
||||
for part in dev_mod.partitions:
|
||||
if part.mountpoint == Path('/boot') or part.mountpoint == Path('/efi'):
|
||||
boot_partition = part
|
||||
break
|
||||
|
||||
if boot_partition:
|
||||
min_boot_size = Size(2, Unit.GiB, boot_partition.length.sector_size)
|
||||
if boot_partition.length >= min_boot_size:
|
||||
size_gb = boot_partition.length.convert(Unit.GiB).value
|
||||
info(f'✓ Boot partition size: {size_gb:.1f} GiB')
|
||||
else:
|
||||
size_mb = boot_partition.length.convert(Unit.MiB).value
|
||||
warn(f'⚠ Boot partition is only {size_mb:.0f} MiB')
|
||||
warn(' Omarchy recommends at least 2 GiB for boot partition')
|
||||
warn(' Multiple kernels may not fit')
|
||||
validation_warnings.append('boot_size')
|
||||
else:
|
||||
warn('⚠ Could not find boot partition (/boot or /efi)')
|
||||
warn(' System may not boot correctly')
|
||||
validation_warnings.append('no_boot')
|
||||
|
||||
root_partition = _find_root_partition(config.disk_config)
|
||||
|
||||
if root_partition:
|
||||
if root_partition.fs_type == FilesystemType.Btrfs:
|
||||
info('✓ Root filesystem is btrfs')
|
||||
|
||||
if root_partition.btrfs_subvols:
|
||||
subvol_names = [str(sv.name) for sv in root_partition.btrfs_subvols]
|
||||
subvol_mounts = {str(sv.mountpoint): str(sv.name) for sv in root_partition.btrfs_subvols}
|
||||
|
||||
required_subvols = {
|
||||
'/': '@',
|
||||
'/home': '@home',
|
||||
'/var/log': '@log',
|
||||
'/var/cache/pacman/pkg': '@pkg',
|
||||
}
|
||||
|
||||
missing_subvols = []
|
||||
for mount, expected_name in required_subvols.items():
|
||||
if mount not in subvol_mounts:
|
||||
missing_subvols.append(f'{expected_name} → {mount}')
|
||||
elif subvol_mounts[mount] != expected_name:
|
||||
warn(f'⚠ Subvolume at {mount} is named "{subvol_mounts[mount]}" not "{expected_name}"')
|
||||
|
||||
if missing_subvols:
|
||||
warn(f'⚠ Missing recommended subvolumes: {", ".join(missing_subvols)}')
|
||||
warn(' Omarchy recommends: @, @home, @log, @pkg')
|
||||
warn(' Some features (like Snapper) may not work optimally')
|
||||
info(f' Current subvolumes: {", ".join(subvol_names)}')
|
||||
validation_warnings.append('missing_subvols')
|
||||
else:
|
||||
info(f'✓ Btrfs subvolumes: {", ".join(subvol_names)}')
|
||||
else:
|
||||
warn('⚠ Btrfs partition has no subvolumes defined')
|
||||
warn(' Omarchy recommends subvolumes for snapshots')
|
||||
warn(' Required: @ (root), @home, @log, @pkg')
|
||||
validation_warnings.append('no_subvols')
|
||||
else:
|
||||
fs_name = root_partition.fs_type.value if root_partition.fs_type else 'unknown'
|
||||
warn(f'⚠ Root filesystem is {fs_name}, not btrfs')
|
||||
warn(' Omarchy is designed for btrfs with snapshots')
|
||||
warn(' Some features may not work correctly')
|
||||
validation_warnings.append('not_btrfs')
|
||||
|
||||
is_encrypted = False
|
||||
if config.disk_config.disk_encryption:
|
||||
enc = config.disk_config.disk_encryption
|
||||
if enc.encryption_type != EncryptionType.NoEncryption:
|
||||
is_encrypted = root_partition in enc.partitions
|
||||
|
||||
if is_encrypted:
|
||||
info('✓ Root partition is encrypted with LUKS')
|
||||
|
||||
if config.disk_config.disk_encryption.iter_time != 2000:
|
||||
old_time = config.disk_config.disk_encryption.iter_time
|
||||
config.disk_config.disk_encryption.iter_time = 2000
|
||||
info(f'✓ Adjusted iteration time: {old_time}ms → 2000ms')
|
||||
else:
|
||||
info('✓ Iteration time: 2000ms (optimal)')
|
||||
else:
|
||||
warn('⚠ Root partition is NOT encrypted')
|
||||
warn(' Omarchy recommends LUKS encryption for security')
|
||||
validation_warnings.append('no_encryption')
|
||||
else:
|
||||
warn('⚠ Could not identify root partition')
|
||||
validation_warnings.append('no_root')
|
||||
|
||||
if validation_warnings and interactive:
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
gum_path = shutil.which('gum')
|
||||
if gum_path:
|
||||
warn('')
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['gum', 'choose', '--header', 'Validation warnings detected. What would you like to do?',
|
||||
'Re-edit partitions', 'Continue anyway', 'Abort'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
choice = result.stdout.strip() if result.stdout else ''
|
||||
|
||||
if choice == 'Re-edit partitions':
|
||||
return 'RE_EDIT'
|
||||
elif choice == 'Abort':
|
||||
return 'ABORT'
|
||||
else:
|
||||
info('Continuing despite warnings')
|
||||
return 'CONTINUE'
|
||||
|
||||
except (subprocess.CalledProcessError, KeyboardInterrupt):
|
||||
return 'ABORT'
|
||||
|
||||
return 'CONTINUE'
|
||||
|
||||
|
||||
def apply_omarchy_partition_defaults():
|
||||
import archinstall.lib.interactions.disk_conf as disk_conf_module
|
||||
from archinstall.lib.models.device import (
|
||||
PartitionModification, ModificationStatus, PartitionType,
|
||||
Size, Unit, SectorSize, FilesystemType, PartitionFlag,
|
||||
DeviceModification, BDevice
|
||||
)
|
||||
from archinstall.lib.interactions.disk_conf import get_default_btrfs_subvols
|
||||
from archinstall.lib.disk.device_handler import device_handler
|
||||
|
||||
def _boot_partition_2gib(sector_size: SectorSize, using_gpt: bool) -> PartitionModification:
|
||||
flags = [PartitionFlag.BOOT]
|
||||
size = Size(2, Unit.GiB, sector_size)
|
||||
start = Size(1, Unit.MiB, sector_size)
|
||||
if using_gpt:
|
||||
flags.append(PartitionFlag.ESP)
|
||||
|
||||
return PartitionModification(
|
||||
status=ModificationStatus.Create,
|
||||
type=PartitionType.Primary,
|
||||
start=start,
|
||||
length=size,
|
||||
mountpoint=Path('/boot'),
|
||||
fs_type=FilesystemType.Fat32,
|
||||
flags=flags,
|
||||
)
|
||||
|
||||
def _select_main_filesystem_btrfs() -> FilesystemType:
|
||||
return FilesystemType.Btrfs
|
||||
|
||||
def _select_mount_options_compressed() -> list[str]:
|
||||
return ['compress=zstd']
|
||||
|
||||
def _suggest_single_disk_auto_subvolumes(
|
||||
device: BDevice,
|
||||
filesystem_type: FilesystemType | None = None,
|
||||
separate_home: bool | None = None,
|
||||
):
|
||||
if not filesystem_type:
|
||||
filesystem_type = FilesystemType.Btrfs
|
||||
|
||||
if filesystem_type == FilesystemType.Btrfs:
|
||||
using_subvolumes = True
|
||||
mount_options = ['compress=zstd']
|
||||
else:
|
||||
using_subvolumes = False
|
||||
mount_options = []
|
||||
|
||||
sector_size = device.device_info.sector_size
|
||||
device_modification = DeviceModification(device, wipe=True)
|
||||
using_gpt = device_handler.partition_table.is_gpt()
|
||||
|
||||
boot_partition = _boot_partition_2gib(sector_size, using_gpt)
|
||||
device_modification.add_partition(boot_partition)
|
||||
|
||||
total_size = device.device_info.total_size
|
||||
available_space = total_size - boot_partition.length - Size(1, Unit.MiB, sector_size)
|
||||
|
||||
root_partition = PartitionModification(
|
||||
status=ModificationStatus.Create,
|
||||
type=PartitionType.Primary,
|
||||
start=boot_partition.start + boot_partition.length,
|
||||
length=available_space,
|
||||
mountpoint=None if using_subvolumes else Path('/'),
|
||||
fs_type=filesystem_type,
|
||||
mount_options=mount_options,
|
||||
)
|
||||
|
||||
if using_subvolumes:
|
||||
root_partition.btrfs_subvols = get_default_btrfs_subvols()
|
||||
|
||||
device_modification.add_partition(root_partition)
|
||||
return device_modification
|
||||
|
||||
disk_conf_module._boot_partition = _boot_partition_2gib
|
||||
disk_conf_module.select_main_filesystem_format = _select_main_filesystem_btrfs
|
||||
disk_conf_module.select_mount_options = _select_mount_options_compressed
|
||||
disk_conf_module.suggest_single_disk_layout = _suggest_single_disk_auto_subvolumes
|
||||
|
||||
|
||||
def load_config(config_file: Path, creds_file: Path | None = None):
|
||||
from archinstall.lib.args import ArchConfig, Arguments
|
||||
|
||||
with open(config_file) as f:
|
||||
config_data = json.load(f)
|
||||
|
||||
if creds_file and creds_file.exists():
|
||||
with open(creds_file) as f:
|
||||
creds_data = json.load(f)
|
||||
config_data.update(creds_data)
|
||||
|
||||
args = Arguments(
|
||||
config=config_file,
|
||||
creds=creds_file,
|
||||
mountpoint=Path('/mnt'),
|
||||
silent=True,
|
||||
)
|
||||
|
||||
return ArchConfig.from_config(config_data, args)
|
||||
|
||||
|
||||
def save_config(config, output_file: Path):
|
||||
from archinstall.lib.output import info
|
||||
|
||||
try:
|
||||
config_dict = config.safe_json()
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump(config_dict, f, indent=2, default=str)
|
||||
info(f'✓ Configuration saved to: {output_file}')
|
||||
except Exception as e:
|
||||
from archinstall.lib.output import error
|
||||
error(f'Failed to save config: {e}')
|
||||
raise
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Omarchy Disk Configuration Tool')
|
||||
parser.add_argument('--config', type=Path, required=True, help='Path to config file')
|
||||
parser.add_argument('--creds', type=Path, help='Path to credentials file')
|
||||
parser.add_argument('--output', type=Path, help='Output path (default: overwrites input)')
|
||||
parser.add_argument('--non-interactive', action='store_true', help='Skip interactive prompts')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
output_file = args.output or args.config
|
||||
|
||||
if not args.config.exists():
|
||||
print(f'ERROR: Config file not found: {args.config}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if args.creds and not args.creds.exists():
|
||||
print(f'ERROR: Credentials file not found: {args.creds}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
from archinstall.lib.output import info, error
|
||||
from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu
|
||||
from archinstall.tui.curses_menu import Tui
|
||||
|
||||
apply_omarchy_partition_defaults()
|
||||
|
||||
info('Loading configuration...')
|
||||
config = load_config(args.config, args.creds)
|
||||
|
||||
if not config.disk_config:
|
||||
error('No disk configuration found in config file')
|
||||
sys.exit(1)
|
||||
|
||||
while True:
|
||||
info('Launching partition editor...')
|
||||
|
||||
with Tui():
|
||||
edited_disk_config = DiskLayoutConfigurationMenu(config.disk_config).run()
|
||||
if edited_disk_config:
|
||||
config.disk_config = edited_disk_config
|
||||
info('✓ Partition configuration updated')
|
||||
else:
|
||||
info('No changes made in partition editor')
|
||||
|
||||
interactive = not args.non_interactive
|
||||
validation_result = validate_disk_config(config, interactive=interactive)
|
||||
|
||||
if validation_result == 'RE_EDIT':
|
||||
continue
|
||||
elif validation_result == 'ABORT':
|
||||
info('Disk configuration cancelled by user')
|
||||
sys.exit(1)
|
||||
else:
|
||||
break
|
||||
|
||||
save_config(config, output_file)
|
||||
info('✓ Disk configuration complete!')
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print('\nCancelled by user', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f'ERROR: {e}', file=sys.stderr)
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+5
-26
@@ -1,7 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns drive information about a given volumne, like /dev/nvme0, which is used by omarchy-drive-select.
|
||||
|
||||
# Drive, like /dev/nvme0, to display information about
|
||||
if (($# == 0)); then
|
||||
echo "Usage: omarchy-drive-info [/dev/drive]"
|
||||
exit 1
|
||||
@@ -11,7 +10,7 @@ fi
|
||||
|
||||
# Find the root drive in case we are looking at partitions
|
||||
root_drive=$(lsblk -no PKNAME "$drive" 2>/dev/null | tail -n1)
|
||||
if [[ -n $root_drive ]]; then
|
||||
if [[ -n "$root_drive" ]]; then
|
||||
root_drive="/dev/$root_drive"
|
||||
else
|
||||
root_drive="$drive"
|
||||
@@ -19,31 +18,11 @@ fi
|
||||
|
||||
# Get basic disk information
|
||||
size=$(lsblk -dno SIZE "$drive" 2>/dev/null)
|
||||
vendor=$(lsblk -dno VENDOR "$root_drive" 2>/dev/null | sed 's/ *$//')
|
||||
model=$(lsblk -dno MODEL "$root_drive" 2>/dev/null | sed 's/ *$//')
|
||||
|
||||
# Combine vendor and model, avoiding duplication
|
||||
label=""
|
||||
if [[ -n $vendor && -n $model ]]; then
|
||||
if [[ $model == *$vendor* ]]; then
|
||||
label="$model"
|
||||
else
|
||||
label="$vendor $model"
|
||||
fi
|
||||
elif [[ -n $model ]]; then
|
||||
label="$model"
|
||||
elif [[ -n $vendor ]]; then
|
||||
label="$vendor"
|
||||
fi
|
||||
model=$(lsblk -dno MODEL "$root_drive" 2>/dev/null)
|
||||
|
||||
# Format display string
|
||||
display="$drive"
|
||||
[[ -n $size ]] && display="$display ($size)"
|
||||
[[ -n $label ]] && display="$display - $label"
|
||||
|
||||
# Append compact partition summary
|
||||
part_summary=$(lsblk -nro TYPE,NAME,FSTYPE,MOUNTPOINT "$root_drive" 2>/dev/null | \
|
||||
awk '$1=="part" { printf "%s%s%s", s, ($3==""?"unknown":$3), ($4==""?"":"("$4")"); s=", " }')
|
||||
[[ -n $part_summary ]] && display+=" [$part_summary]"
|
||||
[[ -n "$size" ]] && display="$display ($size)"
|
||||
[[ -n "$model" ]] && display="$display - $model"
|
||||
|
||||
echo "$display"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Select a drive from a list with info that includes space and brand. Used by omarchy-drive-set-password.
|
||||
# Select a drive from a list with info that includes space and brand
|
||||
|
||||
if (($# == 0)); then
|
||||
drives=$(lsblk -dpno NAME | grep -E '/dev/(sd|hd|vd|nvme|mmcblk|xv)')
|
||||
@@ -10,7 +10,7 @@ fi
|
||||
|
||||
drives_with_info=""
|
||||
while IFS= read -r drive; do
|
||||
[[ -n $drive ]] || continue
|
||||
[[ -n "$drive" ]] || continue
|
||||
drives_with_info+="$(omarchy-drive-info "$drive")"$'\n'
|
||||
done <<<"$drives"
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set a new encryption password for a drive selected.
|
||||
|
||||
encrypted_drives=$(blkid -t TYPE=crypto_LUKS -o device)
|
||||
|
||||
if [[ -n $encrypted_drives ]]; then
|
||||
if (( $(wc -l <<<encrypted_drives) == 1 )); then
|
||||
if [[ $(wc -l <<<"$encrypted_drives") -eq 1 ]]; then
|
||||
drive_to_change="$encrypted_drives"
|
||||
else
|
||||
drive_to_change="$(omarchy-drive-select "$encrypted_drives")"
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns the name of the current monospace font being used by extracting it from the Waybar stylesheet.
|
||||
# This can be changed using omarchy-font-set.
|
||||
|
||||
grep -oP 'font-family:\s*["'\'']?\K[^;"'\'']+' ~/.config/waybar/style.css | head -n1
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns a list of all the monospace fonts available on the system that can be set using omarchy-font-set.
|
||||
|
||||
fc-list :spacing=100 -f "%{family[0]}\n" | grep -v -i -E 'emoji|signwriting|omarchy' | sort -u
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set the system-wide monospace font that should be used by the terminal, hyprlock, waybar, swayosd, etc.
|
||||
# The font name must be one of the ones returned by omarchy-font-list.
|
||||
|
||||
font_name="$1"
|
||||
|
||||
if [[ -n $font_name ]]; then
|
||||
if [[ -n "$font_name" && "$font_name" != "CNCLD" ]]; then
|
||||
if fc-list | grep -iq "$font_name"; then
|
||||
if [[ -f ~/.config/alacritty/alacritty.toml ]]; then
|
||||
sed -i "s/family = \".*\"/family = \"$font_name\"/g" ~/.config/alacritty/alacritty.toml
|
||||
@@ -21,7 +18,6 @@ if [[ -n $font_name ]]; then
|
||||
pkill -SIGUSR2 ghostty
|
||||
fi
|
||||
|
||||
sed -i "s/font_family = .*/font_family = $font_name/g" ~/.config/hypr/hyprlock.conf
|
||||
sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/waybar/style.css
|
||||
sed -i "s/font-family: .*/font-family: '$font_name';/g" ~/.config/swayosd/style.css
|
||||
xmlstarlet ed -L \
|
||||
@@ -31,10 +27,7 @@ if [[ -n $font_name ]]; then
|
||||
|
||||
omarchy-restart-waybar
|
||||
omarchy-restart-swayosd
|
||||
|
||||
if pgrep -x ghostty; then
|
||||
notify-send " You must restart Ghostty to see font change"
|
||||
fi
|
||||
omarchy-restart-walker
|
||||
|
||||
omarchy-hook font-set "$font_name"
|
||||
else
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if hibernation is supported
|
||||
if [[ ! -f /sys/power/image_size ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Sum all swap sizes (excluding zram)
|
||||
SWAPSIZE_KB=$(awk '!/Filename|zram/ {sum += $3} END {print sum+0}' /proc/swaps)
|
||||
SWAPSIZE=$(( 1024 * ${SWAPSIZE_KB:-0} ))
|
||||
|
||||
HIBERNATION_IMAGE_SIZE=$(cat /sys/power/image_size)
|
||||
|
||||
if (( SWAPSIZE > HIBERNATION_IMAGE_SIZE )) && [[ -f /etc/mkinitcpio.conf.d/omarchy_resume.conf ]]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Removes hibernation setup: disables swap, removes swapfile, removes fstab entry,
|
||||
# removes resume hook, and removes suspend-then-hibernate configuration.
|
||||
|
||||
MKINITCPIO_CONF="/etc/mkinitcpio.conf.d/omarchy_resume.conf"
|
||||
|
||||
# Check if hibernation is configured
|
||||
if [[ ! -f $MKINITCPIO_CONF ]] || ! grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
|
||||
echo "Hibernation is not set up"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! gum confirm "Remove hibernation setup?"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
SWAP_SUBVOLUME="/swap"
|
||||
SWAP_FILE="$SWAP_SUBVOLUME/swapfile"
|
||||
|
||||
# Disable swap if active
|
||||
if swapon --show | grep -q "$SWAP_FILE"; then
|
||||
echo "Disabling swap on $SWAP_FILE"
|
||||
sudo swapoff "$SWAP_FILE"
|
||||
fi
|
||||
|
||||
# Remove swapfile
|
||||
if [[ -f $SWAP_FILE ]]; then
|
||||
echo "Removing swapfile"
|
||||
sudo rm "$SWAP_FILE"
|
||||
fi
|
||||
|
||||
# Remove swap subvolume
|
||||
if sudo btrfs subvolume show "$SWAP_SUBVOLUME" &>/dev/null; then
|
||||
echo "Removing Btrfs subvolume $SWAP_SUBVOLUME"
|
||||
sudo btrfs subvolume delete "$SWAP_SUBVOLUME"
|
||||
fi
|
||||
|
||||
# Remove fstab entry
|
||||
if grep -Fq "$SWAP_FILE" /etc/fstab; then
|
||||
echo "Removing swapfile from /etc/fstab"
|
||||
sudo cp -a /etc/fstab "/etc/fstab.$(date +%Y%m%d%H%M%S).back"
|
||||
sudo sed -i "\|$SWAP_FILE|d" /etc/fstab
|
||||
sudo sed -i '/^# Btrfs swapfile for system hibernation$/d' /etc/fstab
|
||||
fi
|
||||
|
||||
# Remove suspend-then-hibernate configuration
|
||||
echo "Removing suspend-then-hibernate configuration"
|
||||
sudo rm -f /etc/systemd/logind.conf.d/lid.conf
|
||||
sudo rm -f /etc/systemd/sleep.conf.d/hibernate.conf
|
||||
|
||||
# Remove mkinitcpio resume hook
|
||||
echo "Removing resume hook"
|
||||
sudo rm "$MKINITCPIO_CONF"
|
||||
|
||||
echo "Regenerating initramfs..."
|
||||
sudo limine-mkinitcpio
|
||||
|
||||
echo "Hibernation removed"
|
||||
@@ -1,100 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Creates a swap file in the btrfs subvolume, adds the swap file to /etc/fstab,
|
||||
# adds a resume hook to mkinitcpio, and configures suspend-then-hibernate.
|
||||
|
||||
if [[ ! -f /sys/power/image_size ]]; then
|
||||
echo -e "Hibernation is not supported on your system" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v limine-mkinitcpio &>/dev/null; then
|
||||
echo "Skipping hibernation setup (requires Limine bootloader)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
MKINITCPIO_CONF="/etc/mkinitcpio.conf.d/omarchy_resume.conf"
|
||||
|
||||
# Check if hibernation is already configured
|
||||
if [[ -f $MKINITCPIO_CONF ]] && grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
|
||||
echo "Hibernation is already set up"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $1 != "--force" ]]; then
|
||||
MEM_TOTAL_HUMAN=$(free --human | awk '/Mem/ {print $2}')
|
||||
if ! gum confirm "Use $MEM_TOTAL_HUMAN on boot drive to make hibernation available?"; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
SWAP_SUBVOLUME="/swap"
|
||||
SWAP_FILE="$SWAP_SUBVOLUME/swapfile"
|
||||
|
||||
# Create btrfs subvolume for swap
|
||||
if ! sudo btrfs subvolume show "$SWAP_SUBVOLUME" &>/dev/null; then
|
||||
echo "Creating Btrfs subvolume"
|
||||
sudo btrfs subvolume create "$SWAP_SUBVOLUME"
|
||||
sudo chattr +C "$SWAP_SUBVOLUME"
|
||||
fi
|
||||
|
||||
# Create swapfile
|
||||
if ! sudo swaplabel "$SWAP_FILE" &>/dev/null; then
|
||||
echo "Creating swapfile in Btrfs subvolume"
|
||||
MEM_TOTAL_KB="$(awk '/MemTotal/ {print $2}' /proc/meminfo)k"
|
||||
sudo btrfs filesystem mkswapfile -s "$MEM_TOTAL_KB" "$SWAP_FILE"
|
||||
fi
|
||||
|
||||
# Add swapfile to fstab
|
||||
if ! grep -Fq "$SWAP_FILE" /etc/fstab; then
|
||||
echo "Adding swapfile to /etc/fstab"
|
||||
sudo cp -a /etc/fstab "/etc/fstab.$(date +%Y%m%d%H%M%S).back"
|
||||
printf "\n# Btrfs swapfile for system hibernation\n%s none swap defaults,pri=0 0 0\n" "$SWAP_FILE" | sudo tee -a /etc/fstab >/dev/null
|
||||
fi
|
||||
|
||||
# Enable swap
|
||||
if ! swapon --show | grep -q "$SWAP_FILE"; then
|
||||
echo "Enabling swap on $SWAP_FILE"
|
||||
sudo swapon -p 0 "$SWAP_FILE"
|
||||
fi
|
||||
|
||||
# Add resume hook to mkinitcpio
|
||||
sudo mkdir -p /etc/mkinitcpio.conf.d
|
||||
echo "Adding resume hook to $MKINITCPIO_CONF"
|
||||
echo "HOOKS+=(resume)" | sudo tee "$MKINITCPIO_CONF" >/dev/null
|
||||
|
||||
# Ensure keyboard backlight doesn't prevent sleep
|
||||
sudo cp -p "$OMARCHY_PATH/default/systemd/system-sleep/keyboard-backlight" /usr/lib/systemd/system-sleep/
|
||||
|
||||
# Add resume= kernel parameters so the initramfs resume hook knows where to find the
|
||||
# hibernation image. Without these, resume happens late (after GPU drivers load) and fails.
|
||||
RESUME_DROP_IN="/etc/limine-entry-tool.d/resume.conf"
|
||||
if [[ ! -f $RESUME_DROP_IN ]]; then
|
||||
echo "Adding resume kernel parameters"
|
||||
sudo swapon -p 0 "$SWAP_FILE" 2>/dev/null
|
||||
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
|
||||
RESUME_OFFSET=$(btrfs inspect-internal map-swapfile -r "$SWAP_FILE")
|
||||
sudo mkdir -p /etc/limine-entry-tool.d
|
||||
echo "KERNEL_CMDLINE[default]+=\"resume=$RESUME_DEVICE resume_offset=$RESUME_OFFSET\"" | sudo tee "$RESUME_DROP_IN" >/dev/null
|
||||
fi
|
||||
|
||||
# Use ACPI alarm for RTC wakeup on s2idle systems (needed for suspend-then-hibernate)
|
||||
if grep -q "\[s2idle\]" /sys/power/mem_sleep 2>/dev/null; then
|
||||
LIMINE_DROP_IN="/etc/limine-entry-tool.d/rtc-alarm.conf"
|
||||
if [[ ! -f $LIMINE_DROP_IN ]]; then
|
||||
echo "Enabling ACPI RTC alarm for s2idle suspend"
|
||||
sudo mkdir -p /etc/limine-entry-tool.d
|
||||
echo 'KERNEL_CMDLINE[default]+="rtc_cmos.use_acpi_alarm=1"' | sudo tee "$LIMINE_DROP_IN" >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# Regenerate initramfs and boot entry
|
||||
echo "Regenerating initramfs..."
|
||||
sudo limine-mkinitcpio
|
||||
sudo limine-update
|
||||
|
||||
echo
|
||||
|
||||
if [[ $1 != "--force" ]] && gum confirm "Reboot to enable hibernation?"; then
|
||||
omarchy-system-reboot
|
||||
fi
|
||||
+1
-3
@@ -1,10 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run a named hook, like post-update (available in ~/.config/omarchy/hooks/post-update).
|
||||
|
||||
set -e
|
||||
|
||||
if (( $# < 1 )); then
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: omarchy-hook [name] [args...]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect whether the computer is an Asus ROG machine.
|
||||
|
||||
[[ $(cat /sys/class/dmi/id/sys_vendor 2>/dev/null) == "ASUSTeK COMPUTER INC." ]] &&
|
||||
grep -q "ROG" /sys/class/dmi/id/product_family 2>/dev/null
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect whether the computer is a Framework Laptop 16.
|
||||
|
||||
[[ $(cat /sys/class/dmi/id/sys_vendor 2>/dev/null) == "Framework" ]] &&
|
||||
grep -q "Laptop 16" /sys/class/dmi/id/product_name 2>/dev/null
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect whether the computer is a Microsoft Surface device.
|
||||
|
||||
[[ $(cat /sys/class/dmi/id/sys_vendor 2>/dev/null) == "Microsoft Corporation" ]] &&
|
||||
grep -q "Surface" /sys/class/dmi/id/product_name 2>/dev/null
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Get the active monitor (the one with the cursor)
|
||||
MONITOR_INFO=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true)')
|
||||
ACTIVE_MONITOR=$(echo "$MONITOR_INFO" | jq -r '.name')
|
||||
CURRENT_SCALE=$(echo "$MONITOR_INFO" | jq -r '.scale')
|
||||
|
||||
# Cycle through scales: 1 → 1.6 → 2 → 3 → 1
|
||||
CURRENT_INT=$(awk -v s="$CURRENT_SCALE" 'BEGIN { printf "%.0f", s * 10 }')
|
||||
|
||||
case "$CURRENT_INT" in
|
||||
10) NEW_SCALE=1.6 ;;
|
||||
16) NEW_SCALE=2 ;;
|
||||
20) NEW_SCALE=3 ;;
|
||||
*) NEW_SCALE=1 ;;
|
||||
esac
|
||||
|
||||
hyprctl keyword misc:disable_scale_notification true
|
||||
hyprctl keyword monitor "$ACTIVE_MONITOR,preferred,auto,$NEW_SCALE"
|
||||
hyprctl keyword misc:disable_scale_notification false
|
||||
notify-send " Display scaling set to ${NEW_SCALE}x"
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Toggles the window gaps globally between no gaps and the default 10/5/2.
|
||||
|
||||
gaps=$(hyprctl getoption general:gaps_out -j | jq -r '.custom' | awk '{print $1}')
|
||||
|
||||
if [[ $gaps == "0" ]]; then
|
||||
hyprctl keyword general:gaps_out 10
|
||||
hyprctl keyword general:gaps_in 5
|
||||
hyprctl keyword general:border_size 2
|
||||
else
|
||||
hyprctl keyword general:gaps_out 0
|
||||
hyprctl keyword general:gaps_in 0
|
||||
hyprctl keyword general:border_size 0
|
||||
fi
|
||||
@@ -2,45 +2,21 @@
|
||||
|
||||
# Toggle to pop-out a tile to stay fixed on a display basis.
|
||||
|
||||
# Usage:
|
||||
# omarchy-hyprland-window-pop [width height [x y]]
|
||||
#
|
||||
# Arguments:
|
||||
# width Optional. Width of the floating window. Default: 1300
|
||||
# height Optional. Height of the floating window. Default: 900
|
||||
# x Optional. X position of the window. Must provide both X and Y to take effect.
|
||||
# y Optional. Y position of the window. Must provide both X and Y to take effect.
|
||||
#
|
||||
# Behavior:
|
||||
# - If the window is already pinned, it will be unpinned and removed from the pop layer.
|
||||
# - If the window is not pinned, it will be floated, resized, moved/centered, pinned, brought to top, and popped.
|
||||
|
||||
width=${1:-1300}
|
||||
height=${2:-900}
|
||||
x=${3:-}
|
||||
y=${4:-}
|
||||
|
||||
active=$(hyprctl activewindow -j)
|
||||
pinned=$(echo "$active" | jq ".pinned")
|
||||
addr=$(echo "$active" | jq -r ".address")
|
||||
pinned=$(echo "$active" | jq .pinned)
|
||||
addr=$(echo "$active" | jq -r ".address")
|
||||
[ -z "$addr" ] && { echo "No active window"; exit 0; }
|
||||
|
||||
if [[ $pinned == "true" ]]; then
|
||||
if [ "$pinned" = "true" ]; then
|
||||
hyprctl -q --batch \
|
||||
"dispatch pin address:$addr;" \
|
||||
"dispatch togglefloating address:$addr;" \
|
||||
"dispatch tagwindow -pop address:$addr;"
|
||||
elif [[ -n $addr ]]; then
|
||||
hyprctl dispatch togglefloating address:$addr
|
||||
hyprctl dispatch resizeactive exact $width $height address:$addr
|
||||
|
||||
if [[ -n $x && -n $y ]]; then
|
||||
hyprctl dispatch moveactive $x $y address:$addr
|
||||
else
|
||||
hyprctl dispatch centerwindow address:$addr
|
||||
fi
|
||||
|
||||
"dispatch pin address:$addr;" \
|
||||
"dispatch togglefloating address:$addr;" \
|
||||
"dispatch tagwindow -pop address:$addr;"
|
||||
else
|
||||
hyprctl -q --batch \
|
||||
"dispatch pin address:$addr;" \
|
||||
"dispatch alterzorder top address:$addr;" \
|
||||
"dispatch tagwindow +pop address:$addr;"
|
||||
"dispatch togglefloating address:$addr;" \
|
||||
"dispatch centerwindow address:$addr;" \
|
||||
"dispatch pin address:$addr;" \
|
||||
"dispatch alterzorder top address:$addr;" \
|
||||
"dispatch tagwindow +pop address:$addr;"
|
||||
fi
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check current single_window_aspect_ratio setting
|
||||
CURRENT_VALUE=$(hyprctl getoption "layout:single_window_aspect_ratio" 2>/dev/null | head -1)
|
||||
|
||||
# Parse vec2 output: "vec2: [1, 1]" or "vec2: [0, 0]"
|
||||
if [[ $CURRENT_VALUE == *"[1, 1]"* ]]; then
|
||||
hyprctl keyword layout:single_window_aspect_ratio "0 0"
|
||||
notify-send " Disable single-window square aspect ratio"
|
||||
else
|
||||
hyprctl keyword layout:single_window_aspect_ratio "1 1"
|
||||
notify-send " Enable single-window square aspect"
|
||||
fi
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Toggle the layout on the current active workspace between dwindle and scrolling
|
||||
|
||||
ACTIVE_WORKSPACE=$(hyprctl activeworkspace -j | jq -r '.id')
|
||||
CURRENT_LAYOUT=$(hyprctl activeworkspace -j | jq -r '.tiledLayout')
|
||||
|
||||
case "$CURRENT_LAYOUT" in
|
||||
dwindle) NEW_LAYOUT=scrolling ;;
|
||||
*) NEW_LAYOUT=dwindle ;;
|
||||
esac
|
||||
|
||||
hyprctl keyword workspace $ACTIVE_WORKSPACE, layout:$NEW_LAYOUT
|
||||
notify-send " Workspace layout set to $NEW_LAYOUT"
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
workspace_id=$(hyprctl activeworkspace -j | jq -r .id)
|
||||
gaps=$(hyprctl workspacerules -j | jq -r ".[] | select(.workspaceString==\"$workspace_id\") | .gapsOut[0] // 0")
|
||||
|
||||
if [[ $gaps == "0" ]]; then
|
||||
hyprctl keyword "workspace $workspace_id, gapsout:10, gapsin:5, bordersize:2"
|
||||
else \
|
||||
hyprctl keyword "workspace $workspace_id, gapsout:0, gapsin:0, bordersize:0"
|
||||
fi
|
||||
Executable
+268
@@ -0,0 +1,268 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Omarchy Install
|
||||
|
||||
Installs Arch Linux with Omarchy customizations using archinstall as a library.
|
||||
For disk configuration, use omarchy-disk-config.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def load_config(config_file: Path, creds_file: Path | None = None):
|
||||
from archinstall.lib.args import ArchConfig, Arguments
|
||||
|
||||
with open(config_file) as f:
|
||||
config_data = json.load(f)
|
||||
|
||||
if creds_file and creds_file.exists():
|
||||
with open(creds_file) as f:
|
||||
creds_data = json.load(f)
|
||||
config_data.update(creds_data)
|
||||
|
||||
args = Arguments(
|
||||
config=config_file,
|
||||
creds=creds_file,
|
||||
mountpoint=Path('/mnt'),
|
||||
silent=True,
|
||||
skip_ntp=True,
|
||||
skip_wkd=True,
|
||||
)
|
||||
|
||||
return ArchConfig.from_config(config_data, args)
|
||||
|
||||
|
||||
def load_omarchy_packages() -> list[str]:
|
||||
omarchy_path = Path('/usr/share/omarchy/install')
|
||||
packages = []
|
||||
|
||||
base_packages_file = omarchy_path / 'omarchy-base.packages'
|
||||
if base_packages_file.exists():
|
||||
with open(base_packages_file) as f:
|
||||
packages.extend([line.strip() for line in f if line.strip() and not line.startswith('#')])
|
||||
|
||||
return packages
|
||||
|
||||
|
||||
def perform_installation(config_file: Path, creds_file: Path | None = None) -> None:
|
||||
from archinstall.lib.disk.filesystem import FilesystemHandler
|
||||
from archinstall.lib.installer import Installer
|
||||
from archinstall.lib.models.device import DiskLayoutType, EncryptionType
|
||||
from archinstall.lib.output import error, info
|
||||
from archinstall.lib.profile.profiles_handler import profile_handler
|
||||
from archinstall.lib.authentication.authentication_handler import auth_handler
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
info('Loading configuration...')
|
||||
config = load_config(config_file, creds_file)
|
||||
|
||||
if not config.disk_config:
|
||||
error('No disk configuration found in config file')
|
||||
error('Use omarchy-disk-config to configure disk layout first')
|
||||
sys.exit(1)
|
||||
|
||||
disk_config = config.disk_config
|
||||
|
||||
if disk_config.config_type != DiskLayoutType.Pre_mount:
|
||||
info('Performing filesystem operations...')
|
||||
fs_handler = FilesystemHandler(disk_config)
|
||||
fs_handler.perform_filesystem_operations()
|
||||
|
||||
mountpoint = Path('/mnt')
|
||||
|
||||
info('Loading Omarchy base packages...')
|
||||
omarchy_packages = load_omarchy_packages()
|
||||
|
||||
info('Starting Omarchy installation...')
|
||||
|
||||
with Installer(
|
||||
mountpoint,
|
||||
disk_config,
|
||||
kernels=config.kernels or ['linux'],
|
||||
) as installation:
|
||||
|
||||
info('Mounting filesystems...')
|
||||
if disk_config.config_type != DiskLayoutType.Pre_mount:
|
||||
installation.mount_ordered_layout()
|
||||
|
||||
installation.sanity_check()
|
||||
|
||||
if disk_config.disk_encryption and disk_config.disk_encryption.encryption_type != EncryptionType.NoEncryption:
|
||||
info('Generating encryption keys...')
|
||||
installation.generate_key_files()
|
||||
|
||||
if config.mirror_config:
|
||||
info('Configuring mirrors...')
|
||||
installation.set_mirrors(config.mirror_config, on_target=False)
|
||||
|
||||
info('Installing base system...')
|
||||
installation.minimal_installation(
|
||||
optional_repositories=config.mirror_config.optional_repositories if config.mirror_config else [],
|
||||
mkinitcpio=not config.uki,
|
||||
hostname=config.hostname,
|
||||
locale_config=config.locale_config,
|
||||
)
|
||||
|
||||
if config.mirror_config:
|
||||
installation.set_mirrors(config.mirror_config, on_target=True)
|
||||
|
||||
if config.swap:
|
||||
info('Setting up swap...')
|
||||
installation.setup_swap('zram')
|
||||
|
||||
all_packages = omarchy_packages + (config.packages or [])
|
||||
if all_packages:
|
||||
info(f'Installing {len(all_packages)} packages...')
|
||||
installation.add_additional_packages(all_packages)
|
||||
|
||||
if config.bootloader:
|
||||
info(f'Installing bootloader: {config.bootloader.value}...')
|
||||
installation.add_bootloader(config.bootloader, config.uki)
|
||||
|
||||
if config.network_config:
|
||||
info('Configuring network...')
|
||||
config.network_config.install_network_config(installation, config.profile_config)
|
||||
|
||||
if config.auth_config and config.auth_config.users:
|
||||
info('Creating users...')
|
||||
installation.create_users(config.auth_config.users)
|
||||
auth_handler.setup_auth(installation, config.auth_config, config.hostname)
|
||||
|
||||
if config.app_config:
|
||||
info('Installing applications...')
|
||||
from archinstall.lib.applications.application_handler import application_handler
|
||||
application_handler.install_applications(installation, config.app_config)
|
||||
|
||||
if config.profile_config:
|
||||
info('Installing profile...')
|
||||
profile_handler.install_profile_config(installation, config.profile_config)
|
||||
|
||||
if config.timezone:
|
||||
installation.set_timezone(config.timezone)
|
||||
|
||||
if config.ntp:
|
||||
installation.activate_time_synchronization()
|
||||
|
||||
from archinstall.lib.installer import accessibility_tools_in_use
|
||||
if accessibility_tools_in_use():
|
||||
installation.enable_espeakup()
|
||||
|
||||
if config.auth_config and config.auth_config.root_enc_password:
|
||||
from archinstall.lib.models.users import User
|
||||
root_user = User('root', config.auth_config.root_enc_password, False)
|
||||
installation.set_user_password(root_user)
|
||||
|
||||
if config.profile_config and config.profile_config.profile:
|
||||
config.profile_config.profile.post_install(installation)
|
||||
|
||||
if config.services:
|
||||
info('Enabling services...')
|
||||
installation.enable_service(config.services)
|
||||
|
||||
if disk_config.has_default_btrfs_vols():
|
||||
btrfs_options = disk_config.btrfs_options
|
||||
snapshot_config = btrfs_options.snapshot_config if btrfs_options else None
|
||||
snapshot_type = snapshot_config.snapshot_type if snapshot_config else None
|
||||
if snapshot_type:
|
||||
# Disable limine-snapper-sync plugin during install (limine not configured yet)
|
||||
plugin_path = mountpoint / 'usr/lib/snapper/plugins/10-limine-snapper-sync'
|
||||
plugin_disabled = mountpoint / 'usr/lib/snapper/plugins/10-limine-snapper-sync.disabled'
|
||||
if plugin_path.exists():
|
||||
plugin_path.rename(plugin_disabled)
|
||||
|
||||
installation.setup_btrfs_snapshot(snapshot_type, config.bootloader)
|
||||
|
||||
# Re-enable the plugin after snapper is configured
|
||||
if plugin_disabled.exists():
|
||||
plugin_disabled.rename(plugin_path)
|
||||
|
||||
info('Mounting offline resources for chroot access...')
|
||||
from archinstall.lib.general import SysCommand
|
||||
import os
|
||||
import shutil
|
||||
|
||||
offline_mirror_src = Path('/var/cache/omarchy/mirror/offline')
|
||||
offline_mirror_dst = mountpoint / 'var/cache/omarchy/mirror/offline'
|
||||
packages_src = Path('/opt/packages')
|
||||
packages_dst = mountpoint / 'opt/packages'
|
||||
|
||||
os.makedirs(offline_mirror_dst, exist_ok=True)
|
||||
os.makedirs(packages_dst, exist_ok=True)
|
||||
|
||||
if offline_mirror_src.exists():
|
||||
SysCommand(f'mount --bind {offline_mirror_src} {offline_mirror_dst}')
|
||||
|
||||
if packages_src.exists():
|
||||
SysCommand(f'mount --bind {packages_src} {packages_dst}')
|
||||
|
||||
pacman_conf_src = Path('/etc/pacman.conf')
|
||||
pacman_conf_dst = mountpoint / 'etc/pacman.conf'
|
||||
if pacman_conf_src.exists():
|
||||
shutil.copy(pacman_conf_src, pacman_conf_dst)
|
||||
|
||||
info('Copying user info to chroot...')
|
||||
os.makedirs(mountpoint / 'tmp', exist_ok=True)
|
||||
|
||||
if os.path.exists('/tmp/omarchy-user-name.txt'):
|
||||
shutil.copy('/tmp/omarchy-user-name.txt', mountpoint / 'tmp/omarchy-user-name.txt')
|
||||
if os.path.exists('/tmp/omarchy-user-email.txt'):
|
||||
shutil.copy('/tmp/omarchy-user-email.txt', mountpoint / 'tmp/omarchy-user-email.txt')
|
||||
|
||||
if config.custom_commands:
|
||||
info('Running Omarchy custom commands...')
|
||||
from archinstall.lib.installer import run_custom_user_commands
|
||||
run_custom_user_commands(config.custom_commands, installation)
|
||||
|
||||
info('Generating fstab...')
|
||||
installation.genfstab()
|
||||
|
||||
end_time = time.time()
|
||||
duration_seconds = int(end_time - start_time)
|
||||
duration_mins = duration_seconds // 60
|
||||
duration_secs = duration_seconds % 60
|
||||
|
||||
timing_file = mountpoint / 'tmp/omarchy-install-time.txt'
|
||||
with open(timing_file, 'w') as f:
|
||||
f.write(f"{duration_mins}m {duration_secs}s\n")
|
||||
|
||||
info(f'Installation complete! Total time: {duration_mins}m {duration_secs}s')
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Omarchy Install')
|
||||
parser.add_argument('--config', type=Path, required=True, help='Path to config file')
|
||||
parser.add_argument('--creds', type=Path, help='Path to credentials file')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.config.exists():
|
||||
print(f'ERROR: Config file not found: {args.config}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if args.creds and not args.creds.exists():
|
||||
print(f'ERROR: Credentials file not found: {args.creds}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
perform_installation(
|
||||
config_file=args.config,
|
||||
creds_file=args.creds,
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
print('\nInstallation cancelled by user', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f'ERROR: Installation failed: {e}', file=sys.stderr)
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,8 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Allow Chromium to sign in to Google accounts by adding the correct
|
||||
# oauth client id and secret to ~/.config/chromium-flags.conf.
|
||||
|
||||
if [[ -f ~/.config/chromium-flags.conf ]]; then
|
||||
CONF=~/.config/chromium-flags.conf
|
||||
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install one of the supported development environments. Usually called via Install > Development > * in the Omarchy Menu.
|
||||
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Usage: omarchy-install-dev-env <ruby|node|bun|deno|go|laravel|symfony|php|python|elixir|phoenix|rust|java|zig|ocaml|dotnet|clojure|scala>" >&2
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: omarchy-install-dev-env <ruby|node|bun|go|laravel|symfony|php|python|elixir|phoenix|rust|java|ocaml|dotnet|clojure>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install_php() {
|
||||
omarchy-pkg-add php composer php-sqlite xdebug
|
||||
sudo pacman -S php composer php-sqlite xdebug --noconfirm
|
||||
|
||||
# Install Path for Composer
|
||||
if [[ :$PATH: != *:$HOME/.config/composer/vendor/bin:* ]]; then
|
||||
if [[ ":$PATH:" != *":$HOME/.config/composer/vendor/bin:"* ]]; then
|
||||
echo 'export PATH="$HOME/.config/composer/vendor/bin:$PATH"' >>"$HOME/.bashrc"
|
||||
source "$HOME/.bashrc"
|
||||
echo "Added Composer global bin directory to PATH."
|
||||
@@ -43,7 +41,7 @@ install_php() {
|
||||
|
||||
install_node() {
|
||||
echo -e "Installing Node.js...\n"
|
||||
mise use --global node
|
||||
mise use --global node@lts
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
@@ -52,8 +50,6 @@ ruby)
|
||||
omarchy-pkg-add libyaml
|
||||
mise use --global ruby@latest
|
||||
mise settings add idiomatic_version_file_enable_tools ruby
|
||||
mise settings add ruby.compile false
|
||||
echo "gem: --no-document" >~/.gemrc
|
||||
mise x ruby -- gem install rails --no-document
|
||||
echo -e "\nYou can now run: rails new myproject"
|
||||
;;
|
||||
@@ -142,10 +138,4 @@ clojure)
|
||||
omarchy-pkg-add rlwrap
|
||||
mise use --global clojure@latest
|
||||
;;
|
||||
scala)
|
||||
echo -e "Installing Scala...\n"
|
||||
mise use --global java@latest
|
||||
mise use --global scala@latest
|
||||
mise use --global scala-cli@latest
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install one of the supported databases in a Docker container with the suitable development options.
|
||||
# Usually called via Install > Development > Docker DB from the Omarchy Menu.
|
||||
|
||||
options=("MySQL" "PostgreSQL" "Redis" "MongoDB" "MariaDB" "MSSQL")
|
||||
|
||||
if (( $# == 0 )); then
|
||||
if [[ "$#" -eq 0 ]]; then
|
||||
choices=$(printf "%s\n" "${options[@]}" | gum choose --header "Select database (return to install, esc to cancel)") || main_menu
|
||||
else
|
||||
choices="$@"
|
||||
fi
|
||||
|
||||
if [[ -n $choices ]]; then
|
||||
if [[ -n "$choices" ]]; then
|
||||
for db in $choices; do
|
||||
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 ;;
|
||||
PostgreSQL) sudo docker run -d --restart unless-stopped -p "127.0.0.1:5432:5432" --name=postgres17 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:17 ;;
|
||||
MariaDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:3306:3306" --name=mariadb11 -e MARIADB_ROOT_PASSWORD= -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true mariadb:11.8 ;;
|
||||
Redis) sudo docker run -d --restart unless-stopped -p "127.0.0.1:6379:6379" --name=redis redis:7 ;;
|
||||
MongoDB) sudo docker run -d --restart unless-stopped -p "127.0.0.1:27017:27017" --name mongodb -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin123 mongo:noble ;;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install and start the Dropbox service. Must then be authenticated via the web.
|
||||
|
||||
echo "Installing all dependencies..."
|
||||
omarchy-pkg-add dropbox dropbox-cli libappindicator-gtk3 python-gpgme nautilus-dropbox
|
||||
|
||||
echo "Starting Dropbox..."
|
||||
uwsm-app -- dropbox-cli start &>/dev/null &
|
||||
echo "See Dropbox icon behind hover tray in top right and right-click for setup."
|
||||
echo "See Dropbox icon behind hover tray in top right and right-click for setup."
|
||||
|
||||
Executable
+110
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Omarchy Final Configurations Installer
|
||||
#
|
||||
# This script runs from archinstall's custom_commands after base packages
|
||||
# and user creation. It switches to the created user and runs install.sh
|
||||
# to complete package installation and system configuration.
|
||||
#
|
||||
# archinstall runs custom_commands as root via:
|
||||
# arch-chroot -S /mnt bash /var/tmp/user-command.0.sh
|
||||
#
|
||||
|
||||
set -eEo pipefail
|
||||
|
||||
# Setup comprehensive logging for chroot execution
|
||||
# This ensures all output is captured even though we're running inside chroot
|
||||
CHROOT_LOG_FILE="/var/log/omarchy-install-chroot.log"
|
||||
mkdir -p "$(dirname "$CHROOT_LOG_FILE")"
|
||||
touch "$CHROOT_LOG_FILE"
|
||||
|
||||
# Redirect all output to both the log file and stdout
|
||||
# This way:
|
||||
# 1. Output is saved to /var/log/omarchy-install-chroot.log (inside chroot = /mnt/var/log on ISO)
|
||||
# 2. Output still goes to stdout so arch-chroot can potentially capture it
|
||||
# 3. We use exec to redirect the entire script's output from this point forward
|
||||
exec > >(tee -a "$CHROOT_LOG_FILE") 2>&1
|
||||
|
||||
# Log script start with timestamp
|
||||
echo "========================================"
|
||||
echo "Omarchy Chroot Install Starting"
|
||||
echo "Started at: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "Log file: $CHROOT_LOG_FILE"
|
||||
echo "========================================"
|
||||
echo
|
||||
|
||||
# Find the first non-root user (UID >= 1000, < 60000)
|
||||
OMARCHY_USER=$(getent passwd | awk -F: '$3 >= 1000 && $3 < 60000 {print $1; exit}')
|
||||
|
||||
if [[ -z "$OMARCHY_USER" ]]; then
|
||||
echo "ERROR: No non-root user found!"
|
||||
echo "Users created:"
|
||||
getent passwd | awk -F: '$3 >= 1000 {print $1, $3}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Setting up Omarchy for user: $OMARCHY_USER"
|
||||
|
||||
# Setup passwordless sudo (will be removed by post-install)
|
||||
echo "Setting up passwordless sudo..."
|
||||
mkdir -p /etc/sudoers.d
|
||||
cat >/etc/sudoers.d/99-omarchy-installer <<EOF
|
||||
root ALL=(ALL:ALL) NOPASSWD: ALL
|
||||
%wheel ALL=(ALL:ALL) NOPASSWD: ALL
|
||||
$OMARCHY_USER ALL=(ALL:ALL) NOPASSWD: ALL
|
||||
EOF
|
||||
chmod 440 /etc/sudoers.d/99-omarchy-installer
|
||||
|
||||
# Get user info from /tmp (written by configurator)
|
||||
if [[ -f /tmp/omarchy-user-name.txt ]]; then
|
||||
OMARCHY_USER_NAME=$(cat /tmp/omarchy-user-name.txt)
|
||||
else
|
||||
OMARCHY_USER_NAME=""
|
||||
fi
|
||||
|
||||
if [[ -f /tmp/omarchy-user-email.txt ]]; then
|
||||
OMARCHY_USER_EMAIL=$(cat /tmp/omarchy-user-email.txt)
|
||||
else
|
||||
OMARCHY_USER_EMAIL=""
|
||||
fi
|
||||
|
||||
# Run install.sh as the user
|
||||
echo "========================================"
|
||||
echo "Running Omarchy installation as user: $OMARCHY_USER"
|
||||
echo "========================================"
|
||||
echo
|
||||
|
||||
# Use runuser instead of su for better output handling
|
||||
# runuser doesn't go through PAM and preserves stdout/stderr better
|
||||
runuser -u "$OMARCHY_USER" -- bash -c "
|
||||
set -eEo pipefail
|
||||
export PYTHONUNBUFFERED=1
|
||||
export OMARCHY_CHROOT_INSTALL=1
|
||||
export OMARCHY_ARCHINSTALL_WRAPPER=1
|
||||
export OMARCHY_USER='$OMARCHY_USER'
|
||||
export OMARCHY_USER_NAME='$OMARCHY_USER_NAME'
|
||||
export OMARCHY_USER_EMAIL='$OMARCHY_USER_EMAIL'
|
||||
cd ~
|
||||
source /usr/share/omarchy/install.sh
|
||||
"
|
||||
|
||||
exit_code=$?
|
||||
|
||||
if [[ $exit_code -eq 0 ]]; then
|
||||
echo
|
||||
echo "========================================"
|
||||
echo "Omarchy install.sh completed successfully!"
|
||||
echo "========================================"
|
||||
echo
|
||||
echo "========================================"
|
||||
echo "Omarchy Chroot Install Completed"
|
||||
echo "Finished at: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "Log file: $CHROOT_LOG_FILE"
|
||||
echo "========================================"
|
||||
else
|
||||
echo
|
||||
echo "========================================"
|
||||
echo "ERROR: Omarchy install.sh exited with code $exit_code"
|
||||
echo "========================================"
|
||||
exit $exit_code
|
||||
fi
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install and launch Geforce Now.
|
||||
|
||||
set -e
|
||||
|
||||
omarchy-pkg-add flatpak
|
||||
cd /tmp
|
||||
|
||||
# Download and run GeForce NOW
|
||||
curl -LO https://international.download.nvidia.com/GFNLinux/GeForceNOWSetup.bin
|
||||
chmod +x GeForceNOWSetup.bin
|
||||
./GeForceNOWSetup.bin
|
||||
|
||||
# Ensure a separate browser process not started by GFN is available.
|
||||
# If not, it seems like GFN has a tendency to hang on login.
|
||||
setsid omarchy-launch-browser
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install the NordVPN service with optional GUI.
|
||||
|
||||
echo "Installing NordVPN..."
|
||||
omarchy-pkg-aur-add nordvpn-bin
|
||||
|
||||
echo "Enabling NordVPN daemon..."
|
||||
sudo systemctl enable --now nordvpnd
|
||||
|
||||
echo "Adding user to nordvpn group..."
|
||||
sudo usermod -aG nordvpn "$USER"
|
||||
|
||||
echo -e "\nNordVPN installed! After reboot, run 'nordvpn login' to authenticate."
|
||||
|
||||
echo
|
||||
gum confirm "Reboot now to make NordVPN usable?" && sudo reboot now
|
||||
@@ -1,9 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install and launch Steam after first letting the user pick the correct grahics card drivers.
|
||||
|
||||
set -e
|
||||
|
||||
echo "Now pick dependencies matching your graphics card"
|
||||
sudo pacman -S steam
|
||||
sudo pacman -Syu --noconfirm steam
|
||||
setsid gtk-launch steam >/dev/null 2>&1 &
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install the Tailscale mesh VPN service and a web app for the Tailscale Admin Console.
|
||||
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
curl -fsSL https://neuralink.com/tsui/install.sh | bash
|
||||
|
||||
echo -e "\nStarting Tailscale..."
|
||||
sudo tailscale up --accept-routes
|
||||
|
||||
omarchy-webapp-install "Tailscale" "https://login.tailscale.com/admin/machines" https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/tailscale-light.png
|
||||
echo -e "\nAdd tsui to sudoers..."
|
||||
echo "$USER ALL=(ALL) NOPASSWD: $(which tsui)" | sudo tee /etc/sudoers.d/tsui
|
||||
|
||||
omarchy-tui-install "Tailscale" "sudo tsui" float https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/tailscale-light.png
|
||||
omarchy-webapp-install "Tailscale Admin Console" "https://login.tailscale.com/admin/machines" https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/tailscale-light.png
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install one of the approved terminals and set it as the default for Omarchy (Super + Return etc).
|
||||
|
||||
if (($# == 0)); then
|
||||
echo "Usage: omarchy-install-terminal [alacritty|ghostty|kitty]"
|
||||
exit 1
|
||||
@@ -11,25 +9,35 @@ package="$1"
|
||||
|
||||
# Map package name to desktop entry ID
|
||||
case "$package" in
|
||||
alacritty) desktop_id="Alacritty.desktop" ;;
|
||||
ghostty) desktop_id="com.mitchellh.ghostty.desktop" ;;
|
||||
kitty) desktop_id="kitty.desktop" ;;
|
||||
*)
|
||||
echo "Unknown terminal: $package"
|
||||
exit 1
|
||||
;;
|
||||
alacritty)
|
||||
desktop_id="Alacritty.desktop"
|
||||
;;
|
||||
ghostty)
|
||||
desktop_id="com.mitchellh.ghostty.desktop"
|
||||
;;
|
||||
kitty)
|
||||
desktop_id="kitty.desktop"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown terminal: $package"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Install package
|
||||
if omarchy-pkg-add $package; then
|
||||
# Set as default terminal
|
||||
echo "Setting $package as new default terminal..."
|
||||
sed -i "/export TERMINAL=/ c\export TERMINAL=$package" ~/.config/uwsm/default
|
||||
|
||||
# Copy custom desktop entry for alacritty with X-TerminalArg* keys
|
||||
if [[ $package == "alacritty" ]]; then
|
||||
if [ "$package" = "alacritty" ]; then
|
||||
mkdir -p ~/.local/share/applications
|
||||
cp $OMARCHY_PATH/applications/Alacritty.desktop ~/.local/share/applications/
|
||||
cp "$OMARCHY_PATH/applications/Alacritty.desktop" ~/.local/share/applications/
|
||||
fi
|
||||
|
||||
# Update xdg-terminals.list to prioritize the proper terminal
|
||||
cat >~/.config/xdg-terminals.list <<EOF
|
||||
cat > ~/.config/xdg-terminals.list << EOF
|
||||
# Terminal emulator preference order for xdg-terminal-exec
|
||||
# The first found and valid terminal will be used
|
||||
$desktop_id
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install VSCode and configure it to use the gnome-libsecret password store, not to update automatically, and to use the current Omarchy theme.
|
||||
|
||||
echo "Installing VSCode..."
|
||||
omarchy-pkg-add visual-studio-code-bin
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install support for using Xbox controllers with Steam/RetroArch/etc.
|
||||
|
||||
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
|
||||
@@ -1,5 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the fastfetch TUI that gives information about the current system.
|
||||
|
||||
exec omarchy-launch-or-focus-tui "bash -c 'fastfetch; read -n 1 -s'"
|
||||
exec setsid uwsm-app -- xdg-terminal-exec --app-id=com.omarchy.Omarchy -e bash -c 'fastfetch; read -n 1 -s'
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the Omarchy audio controls TUI (provided by wiremix).
|
||||
|
||||
omarchy-launch-or-focus-tui wiremix
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the Omarchy bluetooth controls TUI (provided by bluetui).
|
||||
# Also attempts to unblock bluetooth service if rfkill had blocked it.
|
||||
|
||||
rfkill unblock bluetooth
|
||||
exec omarchy-launch-or-focus-tui bluetui
|
||||
@@ -1,15 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the default browser as determined by xdg-settings.
|
||||
# Automatically converts --private into the correct flag for the given browser.
|
||||
|
||||
default_browser=$(xdg-settings get default-web-browser)
|
||||
browser_exec=$(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$default_browser 2>/dev/null | head -1)
|
||||
|
||||
if $browser_exec --help | grep -q MOZ_LOG; then
|
||||
if [[ $browser_exec =~ (firefox|zen|librewolf) ]]; then
|
||||
private_flag="--private-window"
|
||||
elif [[ $browser_exec =~ edge ]]; then
|
||||
private_flag="--inprivate"
|
||||
else
|
||||
private_flag="--incognito"
|
||||
fi
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the default editor as determined by $EDITOR (set via ~/.config/uwsm/default) (or nvim if missing).
|
||||
# Starts suitable editors in a terminal window and otherwise as a regular application.
|
||||
|
||||
omarchy-cmd-present "$EDITOR" || EDITOR=nvim
|
||||
|
||||
case "$EDITOR" in
|
||||
nvim | vim | nano | micro | hx | helix | fresh)
|
||||
exec omarchy-launch-tui "$EDITOR" "$@"
|
||||
nvim | vim | nano | micro | hx | helix)
|
||||
exec setsid uwsm-app -- xdg-terminal-exec "$EDITOR" "$@"
|
||||
;;
|
||||
*)
|
||||
exec setsid uwsm-app -- "$EDITOR" "$@"
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch a floating terminal with the Omarchy logo presentation, then execute the command passed in, and finally end with the omarchy-show-done presentation.
|
||||
# Used by actions such as Update System.
|
||||
|
||||
cmd="$*"
|
||||
exec setsid uwsm-app -- xdg-terminal-exec --app-id=org.omarchy.terminal --title=Omarchy -e bash -c "omarchy-show-logo; $cmd; if (( \$? != 130 )); then omarchy-show-done; fi"
|
||||
exec setsid uwsm-app -- xdg-terminal-exec --app-id=com.omarchy.Omarchy --title=Omarchy -e bash -c "omarchy-show-logo; $cmd; omarchy-show-done"
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch or focus on a given command identified by the passed in window-pattern.
|
||||
# Use by some default bindings, like the one for Spotify, to ensure there is only one instance of the application open.
|
||||
|
||||
if (($# == 0)); then
|
||||
echo "Usage: omarchy-launch-or-focus [window-pattern] [launch-command]"
|
||||
exit 1
|
||||
@@ -15,5 +12,5 @@ WINDOW_ADDRESS=$(hyprctl clients -j | jq -r --arg p "$WINDOW_PATTERN" '.[]|selec
|
||||
if [[ -n $WINDOW_ADDRESS ]]; then
|
||||
hyprctl dispatch focuswindow "address:$WINDOW_ADDRESS"
|
||||
else
|
||||
eval exec setsid $LAUNCH_COMMAND
|
||||
eval exec $LAUNCH_COMMAND
|
||||
fi
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch or focus on a given TUI identified by the passed in as the command.
|
||||
# Use by commands like omarchy-launch-wifi to ensure there is only one wifi configuration screen open.
|
||||
|
||||
APP_ID="org.omarchy.$(basename "$1")"
|
||||
LAUNCH_COMMAND="omarchy-launch-tui $@"
|
||||
|
||||
exec omarchy-launch-or-focus "$APP_ID" "$LAUNCH_COMMAND"
|
||||
@@ -1,8 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch or focus on a given web app identified by the window-pattern.
|
||||
# Use by some default bindings, like the one for WhatsApp, to ensure there is only one instance of the application open.
|
||||
|
||||
if (($# == 0)); then
|
||||
echo "Usage: omarchy-launch-or-focus-webapp [window-pattern] [url-and-flags...]"
|
||||
exit 1
|
||||
@@ -12,4 +9,4 @@ WINDOW_PATTERN="$1"
|
||||
shift
|
||||
LAUNCH_COMMAND="omarchy-launch-webapp $@"
|
||||
|
||||
exec omarchy-launch-or-focus "$WINDOW_PATTERN" "$LAUNCH_COMMAND"
|
||||
exec omarchy-launch-or-focus "$WINDOW_PATTERN" "$LAUNCH_COMMAND"
|
||||
@@ -1,54 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the Omarchy screensaver in the default terminal on the system with the correct font configuration.
|
||||
|
||||
# Exit early if we don't have the tte show
|
||||
if ! command -v tte &>/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Exit early if screensave is already running
|
||||
pgrep -f org.omarchy.screensaver && exit 0
|
||||
pgrep -f "alacritty --class Screensaver" && exit 0
|
||||
|
||||
# Allow screensaver to be turned off but also force started
|
||||
if [[ -f ~/.local/state/omarchy/toggles/screensaver-off ]] && [[ $1 != "force" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Silently quit Walker on overlay
|
||||
walker -q
|
||||
|
||||
focused=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true).name')
|
||||
terminal=$(xdg-terminal-exec --print-id)
|
||||
|
||||
for m in $(hyprctl monitors -j | jq -r '.[] | .name'); do
|
||||
hyprctl dispatch focusmonitor $m
|
||||
|
||||
case $terminal in
|
||||
*Alacritty*)
|
||||
hyprctl dispatch exec -- \
|
||||
alacritty --class=org.omarchy.screensaver \
|
||||
--config-file ~/.local/share/omarchy/default/alacritty/screensaver.toml \
|
||||
-e omarchy-cmd-screensaver
|
||||
;;
|
||||
*ghostty*)
|
||||
hyprctl dispatch exec -- \
|
||||
ghostty --class=org.omarchy.screensaver \
|
||||
--config-file=~/.local/share/omarchy/default/ghostty/screensaver \
|
||||
--font-size=18 \
|
||||
-e omarchy-cmd-screensaver
|
||||
;;
|
||||
*kitty*)
|
||||
hyprctl dispatch exec -- \
|
||||
kitty --class=org.omarchy.screensaver \
|
||||
--override font_size=18 \
|
||||
--override window_padding_width=0 \
|
||||
-e omarchy-cmd-screensaver
|
||||
;;
|
||||
*)
|
||||
notify-send "✋ Screensaver only runs in Alacritty, Ghostty, or Kitty"
|
||||
;;
|
||||
esac
|
||||
# FIXME: Find a way to make this generic where we it can work for kitty + ghostty
|
||||
hyprctl dispatch exec -- \
|
||||
alacritty --class Screensaver \
|
||||
--config-file ~/.local/share/omarchy/default/alacritty/screensaver.toml \
|
||||
-e omarchy-cmd-screensaver
|
||||
done
|
||||
|
||||
hyprctl dispatch focusmonitor $focused
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the TUI command passed in as an argument in the default terminal with an org.omarchy.COMMAND app id for styling.
|
||||
|
||||
exec setsid uwsm-app -- xdg-terminal-exec --app-id=org.omarchy.$(basename $1) -e "$1" "${@:2}"
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the Walker application launcher while ensuring that it's data provider (called elephant) is running first.
|
||||
|
||||
# Ensure elephant is running before launching walker
|
||||
if ! pgrep -x elephant > /dev/null; then
|
||||
setsid uwsm-app -- elephant &
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the passed in URL as a web app in the default browser (or chromium if the default doesn't support --app).
|
||||
|
||||
browser=$(xdg-settings get default-web-browser)
|
||||
|
||||
case $browser in
|
||||
google-chrome* | brave-browser* | microsoft-edge* | opera* | vivaldi* | helium*) ;;
|
||||
google-chrome* | brave-browser* | microsoft-edge* | opera* | vivaldi* | helium-browser*) ;;
|
||||
*) browser="chromium.desktop" ;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the Omarchy wifi controls (provided by the Impala TUI).
|
||||
# Attempts to unblock the wifi service first in case it should be been blocked.
|
||||
|
||||
rfkill unblock wifi
|
||||
omarchy-launch-or-focus-tui impala
|
||||
exec setsid uwsm-app -- xdg-terminal-exec --app-id=com.omarchy.Impala -e impala "$@"
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Locks the system using hyprlock, but not before ensuring 1password has also been locked, and the screensaver stopped.
|
||||
|
||||
# Lock the screen
|
||||
pidof hyprlock || hyprlock &
|
||||
|
||||
# Set keyboard layout to default (first layout)
|
||||
hyprctl switchxkblayout all 0 > /dev/null 2>&1
|
||||
|
||||
# Ensure 1password is locked
|
||||
if pgrep -x "1password" >/dev/null; then
|
||||
1password --lock &
|
||||
fi
|
||||
|
||||
# Avoid running screensaver when locked
|
||||
pkill -f org.omarchy.screensaver
|
||||
pkill -f "alacritty --class Screensaver"
|
||||
|
||||
+76
-217
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Launch the Omarchy Menu or takes a parameter to jump straight to a submenu.
|
||||
|
||||
export PATH="$HOME/.local/share/omarchy/bin:$PATH"
|
||||
|
||||
# Set to true when going directly to a submenu, so we can exit directly
|
||||
@@ -10,9 +8,9 @@ BACK_TO_EXIT=false
|
||||
back_to() {
|
||||
local parent_menu="$1"
|
||||
|
||||
if [[ $BACK_TO_EXIT == "true" ]]; then
|
||||
if [[ "$BACK_TO_EXIT" == "true" ]]; then
|
||||
exit 0
|
||||
elif [[ -n $parent_menu ]]; then
|
||||
elif [[ -n "$parent_menu" ]]; then
|
||||
"$parent_menu"
|
||||
else
|
||||
show_main_menu
|
||||
@@ -27,19 +25,19 @@ menu() {
|
||||
|
||||
read -r -a args <<<"$extra"
|
||||
|
||||
if [[ -n $preselect ]]; then
|
||||
if [[ -n "$preselect" ]]; then
|
||||
local index
|
||||
index=$(echo -e "$options" | grep -nxF "$preselect" | cut -d: -f1)
|
||||
if [[ -n $index ]]; then
|
||||
if [[ -n "$index" ]]; then
|
||||
args+=("-c" "$index")
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "$options" | omarchy-launch-walker --dmenu --width 295 --minheight 1 --maxheight 630 -p "$prompt…" "${args[@]}" 2>/dev/null
|
||||
echo -e "$options" | omarchy-launch-walker --dmenu --width 295 --minheight 1 --maxheight 600 -p "$prompt…" "${args[@]}" 2>/dev/null
|
||||
}
|
||||
|
||||
terminal() {
|
||||
xdg-terminal-exec --app-id=org.omarchy.terminal "$@"
|
||||
xdg-terminal-exec --app-id=com.omarchy.Omarchy "$@"
|
||||
}
|
||||
|
||||
present_terminal() {
|
||||
@@ -52,15 +50,15 @@ open_in_editor() {
|
||||
}
|
||||
|
||||
install() {
|
||||
present_terminal "echo 'Installing $1...'; omarchy-pkg-add $2"
|
||||
present_terminal "echo 'Installing $1...'; sudo pacman -S --noconfirm $2"
|
||||
}
|
||||
|
||||
install_and_launch() {
|
||||
present_terminal "echo 'Installing $1...'; omarchy-pkg-add $2 && setsid gtk-launch $3"
|
||||
present_terminal "echo 'Installing $1...'; sudo pacman -S --noconfirm $2 && setsid gtk-launch $3"
|
||||
}
|
||||
|
||||
install_font() {
|
||||
present_terminal "echo 'Installing $1...'; omarchy-pkg-add $2 && sleep 2 && omarchy-font-set '$3'"
|
||||
present_terminal "echo 'Installing $1...'; sudo pacman -S --noconfirm --needed $2 && sleep 2 && omarchy-font-set '$3'"
|
||||
}
|
||||
|
||||
install_terminal() {
|
||||
@@ -68,11 +66,11 @@ install_terminal() {
|
||||
}
|
||||
|
||||
aur_install() {
|
||||
present_terminal "echo 'Installing $1 from AUR...'; omarchy-pkg-aur-add $2"
|
||||
present_terminal "echo 'Installing $1 from AUR...'; yay -S --noconfirm $2"
|
||||
}
|
||||
|
||||
aur_install_and_launch() {
|
||||
present_terminal "echo 'Installing $1 from AUR...'; omarchy-pkg-aur-add $2 && setsid gtk-launch $3"
|
||||
present_terminal "echo 'Installing $1 from AUR...'; yay -S --noconfirm $2 && setsid gtk-launch $3"
|
||||
}
|
||||
|
||||
show_learn_menu() {
|
||||
@@ -88,72 +86,45 @@ show_learn_menu() {
|
||||
}
|
||||
|
||||
show_trigger_menu() {
|
||||
case $(menu "Trigger" " Capture\n Share\n Toggle\n Hardware") in
|
||||
case $(menu "Trigger" " Capture\n Share\n Toggle") in
|
||||
*Capture*) show_capture_menu ;;
|
||||
*Share*) show_share_menu ;;
|
||||
*Toggle*) show_toggle_menu ;;
|
||||
*Hardware*) show_hardware_menu ;;
|
||||
*) show_main_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_capture_menu() {
|
||||
case $(menu "Capture" " Screenshot\n Screenrecord\n Color") in
|
||||
*Screenshot*) omarchy-cmd-screenshot ;;
|
||||
*Screenshot*) show_screenshot_menu ;;
|
||||
*Screenrecord*) show_screenrecord_menu ;;
|
||||
*Color*) pkill hyprpicker || hyprpicker -a ;;
|
||||
*) back_to show_trigger_menu ;;
|
||||
*) show_trigger_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_webcam_list() {
|
||||
v4l2-ctl --list-devices 2>/dev/null | while IFS= read -r line; do
|
||||
if [[ $line != $'\t'* && -n $line ]]; then
|
||||
local name="$line"
|
||||
IFS= read -r device || break
|
||||
device=$(echo "$device" | tr -d '\t' | head -1)
|
||||
[[ -n $device ]] && echo "$device $name"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
show_webcam_select_menu() {
|
||||
local devices=$(get_webcam_list)
|
||||
local count=$(echo "$devices" | grep -c . 2>/dev/null || echo 0)
|
||||
|
||||
if [[ -z $devices ]] || ((count == 0)); then
|
||||
notify-send "No webcam devices found" -u critical -t 3000
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ((count == 1)); then
|
||||
echo "$devices" | awk '{print $1}'
|
||||
else
|
||||
menu "Select Webcam" "$devices" | awk '{print $1}'
|
||||
fi
|
||||
show_screenshot_menu() {
|
||||
case $(menu "Screenshot" " Snap with Editing\n Straight to Clipboard") in
|
||||
*Editing*) omarchy-cmd-screenshot smart ;;
|
||||
*Clipboard*) omarchy-cmd-screenshot smart clipboard ;;
|
||||
*) show_capture_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_screenrecord_menu() {
|
||||
omarchy-cmd-screenrecord --stop-recording && exit 0
|
||||
|
||||
case $(menu "Screenrecord" " With no audio\n With desktop audio\n With desktop + microphone audio\n With desktop + microphone audio + webcam") in
|
||||
*"With no audio") omarchy-cmd-screenrecord ;;
|
||||
*"With desktop audio") omarchy-cmd-screenrecord --with-desktop-audio ;;
|
||||
*"With desktop + microphone audio") omarchy-cmd-screenrecord --with-desktop-audio --with-microphone-audio ;;
|
||||
*"With desktop + microphone audio + webcam")
|
||||
local device=$(show_webcam_select_menu) || {
|
||||
back_to show_capture_menu
|
||||
return
|
||||
}
|
||||
omarchy-cmd-screenrecord --with-desktop-audio --with-microphone-audio --with-webcam --webcam-device="$device"
|
||||
;;
|
||||
case $(menu "Screenrecord" " Region\n Region + Audio\n Display\n Display + Audio\n Display + Webcam") in
|
||||
*"Region + Audio"*) omarchy-cmd-screenrecord region --with-audio ;;
|
||||
*Region*) omarchy-cmd-screenrecord ;;
|
||||
*"Display + Audio"*) omarchy-cmd-screenrecord output --with-audio ;;
|
||||
*"Display + Webcam"*) omarchy-cmd-screenrecord output --with-audio --with-webcam ;;
|
||||
*Display*) omarchy-cmd-screenrecord output ;;
|
||||
*) back_to show_capture_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_share_menu() {
|
||||
case $(menu "Share" " Clipboard\n File \n Folder") in
|
||||
*Clipboard*) omarchy-cmd-share clipboard ;;
|
||||
*Clipboard*) terminal bash -c "omarchy-cmd-share clipboard" ;;
|
||||
*File*) terminal bash -c "omarchy-cmd-share file" ;;
|
||||
*Folder*) terminal bash -c "omarchy-cmd-share folder" ;;
|
||||
*) back_to show_trigger_menu ;;
|
||||
@@ -161,23 +132,11 @@ show_share_menu() {
|
||||
}
|
||||
|
||||
show_toggle_menu() {
|
||||
case $(menu "Toggle" " Screensaver\n Nightlight\n Idle Lock\n Top Bar\n Workspace Layout\n Window Gaps\n 1-Window Ratio\n Display Scaling") in
|
||||
|
||||
case $(menu "Toggle" " Screensaver\n Nightlight\n Idle Lock\n Top Bar") in
|
||||
*Screensaver*) omarchy-toggle-screensaver ;;
|
||||
*Nightlight*) omarchy-toggle-nightlight ;;
|
||||
*Idle*) omarchy-toggle-idle ;;
|
||||
*Bar*) omarchy-toggle-waybar ;;
|
||||
*Layout*) omarchy-hyprland-workspace-layout-toggle ;;
|
||||
*Ratio*) omarchy-hyprland-window-single-square-aspect-toggle ;;
|
||||
*Gaps*) omarchy-hyprland-window-gaps-toggle ;;
|
||||
*Scaling*) omarchy-hyprland-monitor-scaling-cycle ;;
|
||||
*) back_to show_trigger_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_hardware_menu() {
|
||||
case $(menu "Toggle" " Hybrid GPU") in
|
||||
*"Hybrid GPU"*) present_terminal omarchy-toggle-hybrid-gpu ;;
|
||||
*) show_trigger_menu ;;
|
||||
esac
|
||||
}
|
||||
@@ -186,7 +145,7 @@ show_style_menu() {
|
||||
case $(menu "Style" " Theme\n Font\n Background\n Hyprland\n Screensaver\n About") in
|
||||
*Theme*) show_theme_menu ;;
|
||||
*Font*) show_font_menu ;;
|
||||
*Background*) show_background_menu ;;
|
||||
*Background*) omarchy-theme-bg-next ;;
|
||||
*Hyprland*) open_in_editor ~/.config/hypr/looknfeel.conf ;;
|
||||
*Screensaver*) open_in_editor ~/.config/omarchy/branding/screensaver.txt ;;
|
||||
*About*) open_in_editor ~/.config/omarchy/branding/about.txt ;;
|
||||
@@ -195,16 +154,17 @@ show_style_menu() {
|
||||
}
|
||||
|
||||
show_theme_menu() {
|
||||
omarchy-launch-walker -m menus:omarchythemes --width 800 --minheight 400
|
||||
}
|
||||
|
||||
show_background_menu() {
|
||||
omarchy-launch-walker -m menus:omarchyBackgroundSelector --width 800 --minheight 400
|
||||
theme=$(menu "Theme" "$(omarchy-theme-list)" "" "$(omarchy-theme-current)")
|
||||
if [[ "$theme" == "CNCLD" || -z "$theme" ]]; then
|
||||
back_to show_style_menu
|
||||
else
|
||||
omarchy-theme-set "$theme"
|
||||
fi
|
||||
}
|
||||
|
||||
show_font_menu() {
|
||||
theme=$(menu "Font" "$(omarchy-font-list)" "--width 350" "$(omarchy-font-current)")
|
||||
if [[ $theme == "CNCLD" || -z $theme ]]; then
|
||||
if [[ "$theme" == "CNCLD" || -z "$theme" ]]; then
|
||||
back_to show_style_menu
|
||||
else
|
||||
omarchy-font-set "$theme"
|
||||
@@ -212,20 +172,26 @@ show_font_menu() {
|
||||
}
|
||||
|
||||
show_setup_menu() {
|
||||
local options=" Audio\n Wifi\n Bluetooth\n Power Profile\n System Sleep\n Monitors"
|
||||
[[ -f ~/.config/hypr/bindings.conf ]] && options="$options\n Keybindings"
|
||||
[[ -f ~/.config/hypr/input.conf ]] && options="$options\n Input"
|
||||
options="$options\n DNS\n Security\n Config"
|
||||
local options=" Audio\n Wifi\n Bluetooth\n Power Profile\n Monitors"
|
||||
[ -f ~/.config/hypr/bindings.conf ] && options="$options\n Keybindings"
|
||||
[ -f ~/.config/hypr/input.conf ] && options="$options\n Input"
|
||||
options="$options\n Defaults\n DNS\n Security\n Config"
|
||||
|
||||
case $(menu "Setup" "$options") in
|
||||
*Audio*) omarchy-launch-audio ;;
|
||||
*Wifi*) omarchy-launch-wifi ;;
|
||||
*Bluetooth*) omarchy-launch-bluetooth ;;
|
||||
*Audio*) xdg-terminal-exec --app-id=com.omarchy.Wiremix -e wiremix ;;
|
||||
*Wifi*)
|
||||
rfkill unblock wifi
|
||||
omarchy-launch-wifi
|
||||
;;
|
||||
*Bluetooth*)
|
||||
rfkill unblock bluetooth
|
||||
blueberry
|
||||
;;
|
||||
*Power*) show_setup_power_menu ;;
|
||||
*System*) show_setup_system_menu ;;
|
||||
*Monitors*) open_in_editor ~/.config/hypr/monitors.conf ;;
|
||||
*Keybindings*) open_in_editor ~/.config/hypr/bindings.conf ;;
|
||||
*Input*) open_in_editor ~/.config/hypr/input.conf ;;
|
||||
*Defaults*) open_in_editor ~/.config/uwsm/default ;;
|
||||
*DNS*) present_terminal omarchy-setup-dns ;;
|
||||
*Security*) show_setup_security_menu ;;
|
||||
*Config*) show_setup_config_menu ;;
|
||||
@@ -236,24 +202,15 @@ show_setup_menu() {
|
||||
show_setup_power_menu() {
|
||||
profile=$(menu "Power Profile" "$(omarchy-powerprofiles-list)" "" "$(powerprofilesctl get)")
|
||||
|
||||
if [[ $profile == "CNCLD" || -z $profile ]]; then
|
||||
if [[ "$profile" == "CNCLD" || -z "$profile" ]]; then
|
||||
back_to show_setup_menu
|
||||
else
|
||||
powerprofilesctl set "$profile"
|
||||
fi
|
||||
}
|
||||
|
||||
show_setup_security_menu() {
|
||||
case $(menu "Setup" " Fingerprint\n Fido2") in
|
||||
*Fingerprint*) present_terminal omarchy-setup-fingerprint ;;
|
||||
*Fido2*) present_terminal omarchy-setup-fido2 ;;
|
||||
*) show_setup_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_setup_config_menu() {
|
||||
case $(menu "Setup" " Defaults\n Hyprland\n Hypridle\n Hyprlock\n Hyprsunset\n Swayosd\n Walker\n Waybar\n XCompose") in
|
||||
*Defaults*) open_in_editor ~/.config/uwsm/default ;;
|
||||
case $(menu "Setup" " Hyprland\n Hypridle\n Hyprlock\n Hyprsunset\n Swayosd\n Walker\n Waybar\n XCompose") in
|
||||
*Hyprland*) open_in_editor ~/.config/hypr/hyprland.conf ;;
|
||||
*Hypridle*) open_in_editor ~/.config/hypr/hypridle.conf && omarchy-restart-hypridle ;;
|
||||
*Hyprlock*) open_in_editor ~/.config/hypr/hyprlock.conf ;;
|
||||
@@ -262,29 +219,14 @@ show_setup_config_menu() {
|
||||
*Walker*) open_in_editor ~/.config/walker/config.toml && omarchy-restart-walker ;;
|
||||
*Waybar*) open_in_editor ~/.config/waybar/config.jsonc && omarchy-restart-waybar ;;
|
||||
*XCompose*) open_in_editor ~/.XCompose && omarchy-restart-xcompose ;;
|
||||
*) show_setup_menu ;;
|
||||
*) show_main_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_setup_system_menu() {
|
||||
local options=""
|
||||
|
||||
if [[ -f ~/.local/state/omarchy/toggles/suspend-off ]]; then
|
||||
options="$options Enable Suspend"
|
||||
else
|
||||
options="$options Disable Suspend"
|
||||
fi
|
||||
|
||||
if omarchy-hibernation-available; then
|
||||
options="$options\n Disable Hibernate"
|
||||
else
|
||||
options="$options\n Enable Hibernate"
|
||||
fi
|
||||
|
||||
case $(menu "System" "$options") in
|
||||
*Suspend*) omarchy-toggle-suspend ;;
|
||||
*"Enable Hibernate"*) present_terminal omarchy-hibernation-setup ;;
|
||||
*"Disable Hibernate"*) present_terminal omarchy-hibernation-remove ;;
|
||||
show_setup_security_menu() {
|
||||
case $(menu "Setup" " Fingerprint\n Fido2") in
|
||||
*Fingerprint*) present_terminal omarchy-setup-fingerprint ;;
|
||||
*Fido2*) present_terminal omarchy-setup-fido2 ;;
|
||||
*) show_setup_menu ;;
|
||||
esac
|
||||
}
|
||||
@@ -308,10 +250,9 @@ show_install_menu() {
|
||||
}
|
||||
|
||||
show_install_service_menu() {
|
||||
case $(menu "Install" " Dropbox\n Tailscale\n NordVPN\n Bitwarden\n Chromium Account") in
|
||||
case $(menu "Install" " Dropbox\n Tailscale\n Bitwarden\n Chromium Account") in
|
||||
*Dropbox*) present_terminal omarchy-install-dropbox ;;
|
||||
*Tailscale*) present_terminal omarchy-install-tailscale ;;
|
||||
*NordVPN*) present_terminal omarchy-install-nordvpn ;;
|
||||
*Bitwarden*) install_and_launch "Bitwarden" "bitwarden bitwarden-cli" "bitwarden" ;;
|
||||
*Chromium*) present_terminal omarchy-install-chromium-google-account ;;
|
||||
*) show_install_menu ;;
|
||||
@@ -346,27 +287,24 @@ show_install_ai_menu() {
|
||||
echo ollama
|
||||
)
|
||||
|
||||
case $(menu "Install" " Dictation\n Claude Code\n Codex\n Gemini CLI\n Copilot CLI\n Cursor CLI\n LM Studio\n Ollama\n Crush") in
|
||||
*Dictation*) present_terminal omarchy-voxtype-install ;;
|
||||
case $(menu "Install" " Claude Code\n Cursor CLI\n Gemini\n OpenAI Codex\n LM Studio\n Ollama\n Crush\n opencode") in
|
||||
*Claude*) install "Claude Code" "claude-code" ;;
|
||||
*Codex*) install "Codex" "openai-codex" ;;
|
||||
*Gemini*) install "Gemini CLI" "gemini-cli" ;;
|
||||
*Copilot*) install "Copilot CLI" "github-copilot-cli" ;;
|
||||
*Cursor*) install "Cursor CLI" "cursor-cli" ;;
|
||||
*OpenAI*) install "OpenAI Codex" "openai-codex-bin" ;;
|
||||
*Gemini*) install "Gemini" "gemini-cli" ;;
|
||||
*Studio*) install "LM Studio" "lmstudio" ;;
|
||||
*Ollama*) install "Ollama" $ollama_pkg ;;
|
||||
*Crush*) install "Crush" "crush-bin" ;;
|
||||
*opencode*) install "opencode" "opencode" ;;
|
||||
*) show_install_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_install_gaming_menu() {
|
||||
case $(menu "Install" " Steam\n NVIDIA GeForce NOW\n RetroArch [AUR]\n Minecraft\n Xbox Controller [AUR]") in
|
||||
case $(menu "Install" " Steam\n RetroArch [AUR]\n Minecraft") 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" ;;
|
||||
*Minecraft*) install_and_launch "Minecraft" "minecraft-launcher" "minecraft-launcher" ;;
|
||||
*Xbox*) present_terminal omarchy-install-xbox-controllers ;;
|
||||
*) show_install_menu ;;
|
||||
esac
|
||||
}
|
||||
@@ -374,26 +312,24 @@ show_install_gaming_menu() {
|
||||
show_install_style_menu() {
|
||||
case $(menu "Install" " Theme\n Background\n Font") in
|
||||
*Theme*) present_terminal omarchy-theme-install ;;
|
||||
*Background*) omarchy-theme-bg-install ;;
|
||||
*Background*) nautilus ~/.config/omarchy/current/theme/backgrounds ;;
|
||||
*Font*) show_install_font_menu ;;
|
||||
*) show_install_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
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
|
||||
*Cascadia*) install_font "Cascadia Mono" "ttf-cascadia-mono-nerd" "CaskaydiaMono Nerd Font" ;;
|
||||
case $(menu "Install" " Meslo LG Mono\n Fira Code\n Victor Code\n Bistream Vera Mono" "--width 350") in
|
||||
*Meslo*) install_font "Meslo LG Mono" "ttf-meslo-nerd" "MesloLGL Nerd Font" ;;
|
||||
*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" ;;
|
||||
*Iosevka*) install_font "Iosevka" "ttf-iosevka-nerd" "Iosevka Nerd Font Mono" ;;
|
||||
*) show_install_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_install_development_menu() {
|
||||
case $(menu "Install" " Ruby on Rails\n Docker DB\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
|
||||
case $(menu "Install" " Ruby on Rails\n Docker DB\n JavaScript\n Go\n PHP\n Python\n Elixir\n Zig\n Rust\n Java\n .NET\n OCaml\n Clojure") in
|
||||
*Rails*) present_terminal "omarchy-install-dev-env ruby" ;;
|
||||
*Docker*) present_terminal omarchy-install-docker-dbs ;;
|
||||
*JavaScript*) show_install_javascript_menu ;;
|
||||
@@ -407,7 +343,6 @@ show_install_development_menu() {
|
||||
*NET*) present_terminal "omarchy-install-dev-env dotnet" ;;
|
||||
*OCaml*) present_terminal "omarchy-install-dev-env ocaml" ;;
|
||||
*Clojure*) present_terminal "omarchy-install-dev-env clojure" ;;
|
||||
*Scala*) present_terminal "omarchy-install-dev-env scala" ;;
|
||||
*) show_install_menu ;;
|
||||
esac
|
||||
}
|
||||
@@ -439,13 +374,10 @@ 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 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 ;;
|
||||
*Preinstalls*) present_terminal omarchy-remove-preinstalls ;;
|
||||
*Dictation*) present_terminal omarchy-voxtype-remove ;;
|
||||
*Theme*) present_terminal omarchy-theme-remove ;;
|
||||
*Windows*) present_terminal "omarchy-windows-vm remove" ;;
|
||||
*Fingerprint*) present_terminal "omarchy-setup-fingerprint --remove" ;;
|
||||
@@ -454,55 +386,9 @@ 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" ;;
|
||||
*JavaScript*) show_remove_javascript_menu ;;
|
||||
*Go*) present_terminal "omarchy-remove-dev-env go" ;;
|
||||
*PHP*) show_remove_php_menu ;;
|
||||
*Python*) present_terminal "omarchy-remove-dev-env python" ;;
|
||||
*Elixir*) show_remove_elixir_menu ;;
|
||||
*Zig*) present_terminal "omarchy-remove-dev-env zig" ;;
|
||||
*Rust*) present_terminal "omarchy-remove-dev-env rust" ;;
|
||||
*Java*) present_terminal "omarchy-remove-dev-env java" ;;
|
||||
*NET*) present_terminal "omarchy-remove-dev-env dotnet" ;;
|
||||
*OCaml*) present_terminal "omarchy-remove-dev-env ocaml" ;;
|
||||
*Clojure*) present_terminal "omarchy-remove-dev-env clojure" ;;
|
||||
*Scala*) present_terminal "omarchy-remove-dev-env scala" ;;
|
||||
*) show_remove_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_remove_javascript_menu() {
|
||||
case $(menu "Remove" " Node.js\n Bun\n Deno") in
|
||||
*Node*) present_terminal "omarchy-remove-dev-env node" ;;
|
||||
*Bun*) present_terminal "omarchy-remove-dev-env bun" ;;
|
||||
*Deno*) present_terminal "omarchy-remove-dev-env deno" ;;
|
||||
*) show_remove_development_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_remove_php_menu() {
|
||||
case $(menu "Remove" " PHP\n Laravel\n Symfony") in
|
||||
*PHP*) present_terminal "omarchy-remove-dev-env php" ;;
|
||||
*Laravel*) present_terminal "omarchy-remove-dev-env laravel" ;;
|
||||
*Symfony*) present_terminal "omarchy-remove-dev-env symfony" ;;
|
||||
*) show_remove_development_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_remove_elixir_menu() {
|
||||
case $(menu "Remove" " Elixir\n Phoenix") in
|
||||
*Elixir*) present_terminal "omarchy-remove-dev-env elixir" ;;
|
||||
*Phoenix*) present_terminal "omarchy-remove-dev-env phoenix" ;;
|
||||
*) show_remove_development_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_update_menu() {
|
||||
case $(menu "Update" " Omarchy\n Channel\n Config\n Extra Themes\n Process\n Hardware\n Firmware\n Password\n Timezone\n Time") in
|
||||
case $(menu "Update" " Omarchy\n Config\n Extra Themes\n Process\n Hardware\n Firmware\n Password\n Timezone\n Time") in
|
||||
*Omarchy*) present_terminal omarchy-update ;;
|
||||
*Channel*) show_update_channel_menu ;;
|
||||
*Config*) show_update_config_menu ;;
|
||||
*Themes*) present_terminal omarchy-theme-update ;;
|
||||
*Process*) show_update_process_menu ;;
|
||||
@@ -515,15 +401,6 @@ show_update_menu() {
|
||||
esac
|
||||
}
|
||||
|
||||
show_update_channel_menu() {
|
||||
case $(menu "Update channel" "🟢 Stable\n🟡 RC\n🟠 Edge\n🔴 Dev") in
|
||||
*Stable*) present_terminal "omarchy-channel-set stable" ;;
|
||||
*RC*) present_terminal "omarchy-channel-set rc" ;;
|
||||
*Edge*) present_terminal "omarchy-channel-set edge" ;;
|
||||
*Dev*) present_terminal "omarchy-channel-set dev" ;;
|
||||
*) show_update_menu ;;
|
||||
esac
|
||||
}
|
||||
show_update_process_menu() {
|
||||
case $(menu "Restart" " Hypridle\n Hyprsunset\n Swayosd\n Walker\n Waybar") in
|
||||
*Hypridle*) omarchy-restart-hypridle ;;
|
||||
@@ -536,14 +413,13 @@ show_update_process_menu() {
|
||||
}
|
||||
|
||||
show_update_config_menu() {
|
||||
case $(menu "Use default config" " Hyprland\n Hypridle\n Hyprlock\n Hyprsunset\n Plymouth\n Swayosd\n Tmux\n Walker\n Waybar") in
|
||||
case $(menu "Use default config" " Hyprland\n Hypridle\n Hyprlock\n Hyprsunset\n Plymouth\n Swayosd\n Walker\n Waybar") in
|
||||
*Hyprland*) present_terminal omarchy-refresh-hyprland ;;
|
||||
*Hypridle*) present_terminal omarchy-refresh-hypridle ;;
|
||||
*Hyprlock*) present_terminal omarchy-refresh-hyprlock ;;
|
||||
*Hyprsunset*) present_terminal omarchy-refresh-hyprsunset ;;
|
||||
*Plymouth*) present_terminal omarchy-refresh-plymouth ;;
|
||||
*Swayosd*) present_terminal omarchy-refresh-swayosd ;;
|
||||
*Tmux*) present_terminal omarchy-refresh-tmux ;;
|
||||
*Walker*) present_terminal omarchy-refresh-walker ;;
|
||||
*Waybar*) present_terminal omarchy-refresh-waybar ;;
|
||||
*) show_update_menu ;;
|
||||
@@ -567,24 +443,13 @@ show_update_password_menu() {
|
||||
esac
|
||||
}
|
||||
|
||||
show_about() {
|
||||
omarchy-launch-about
|
||||
}
|
||||
|
||||
show_system_menu() {
|
||||
local options=" Screensaver\n Lock"
|
||||
[[ ! -f ~/.local/state/omarchy/toggles/suspend-off ]] && options="$options\n Suspend"
|
||||
omarchy-hibernation-available && options="$options\n Hibernate"
|
||||
options="$options\n Logout\n Restart\n Shutdown"
|
||||
|
||||
case $(menu "System" "$options") in
|
||||
*Screensaver*) omarchy-launch-screensaver force ;;
|
||||
case $(menu "System" " Lock\n Screensaver\n Suspend\n Restart\n Shutdown") in
|
||||
*Lock*) omarchy-lock-screen ;;
|
||||
*Screensaver*) omarchy-launch-screensaver force ;;
|
||||
*Suspend*) systemctl suspend ;;
|
||||
*Hibernate*) systemctl hibernate ;;
|
||||
*Logout*) omarchy-system-logout ;;
|
||||
*Restart*) omarchy-system-reboot ;;
|
||||
*Shutdown*) omarchy-system-shutdown ;;
|
||||
*Restart*) omarchy-state clear re*-required && systemctl reboot --no-wall ;;
|
||||
*Shutdown*) omarchy-state clear re*-required && systemctl poweroff --no-wall ;;
|
||||
*) back_to show_main_menu ;;
|
||||
esac
|
||||
}
|
||||
@@ -598,28 +463,22 @@ go_to_menu() {
|
||||
*apps*) walker -p "Launch…" ;;
|
||||
*learn*) show_learn_menu ;;
|
||||
*trigger*) show_trigger_menu ;;
|
||||
*toggle*) show_toggle_menu ;;
|
||||
*share*) show_share_menu ;;
|
||||
*background*) show_background_menu ;;
|
||||
*capture*) show_capture_menu ;;
|
||||
*style*) show_style_menu ;;
|
||||
*theme*) show_theme_menu ;;
|
||||
*screenshot*) show_screenshot_menu ;;
|
||||
*screenrecord*) show_screenrecord_menu ;;
|
||||
*setup*) show_setup_menu ;;
|
||||
*power*) show_setup_power_menu ;;
|
||||
*install*) show_install_menu ;;
|
||||
*remove*) show_remove_menu ;;
|
||||
*update*) show_update_menu ;;
|
||||
*about*) show_about ;;
|
||||
*about*) omarchy-launch-about ;;
|
||||
*system*) show_system_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Allow user extensions and overrides
|
||||
USER_EXTENSIONS="$HOME/.config/omarchy/extensions/menu.sh"
|
||||
[[ -f $USER_EXTENSIONS ]] && source "$USER_EXTENSIONS"
|
||||
|
||||
if [[ -n $1 ]]; then
|
||||
if [[ -n "$1" ]]; then
|
||||
BACK_TO_EXIT=true
|
||||
go_to_menu "$1"
|
||||
else
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Display Hyprland keybindings defined in your configuration using walker for an interactive search menu.
|
||||
# A script to display Hyprland keybindings defined in your configuration
|
||||
# using walker for an interactive search menu.
|
||||
|
||||
declare -A KEYCODE_SYM_MAP
|
||||
|
||||
@@ -12,7 +13,7 @@ build_keymap_cache() {
|
||||
}
|
||||
|
||||
while IFS=, read -r code sym; do
|
||||
[[ -z $code || -z $sym ]] && continue
|
||||
[[ -z "$code" || -z "$sym" ]] && continue
|
||||
KEYCODE_SYM_MAP["$code"]="$sym"
|
||||
done < <(
|
||||
awk '
|
||||
@@ -42,13 +43,13 @@ lookup_keycode_cached() {
|
||||
|
||||
parse_keycodes() {
|
||||
local start end elapsed
|
||||
[[ ${DEBUG:-0} == "1" ]] && start=$(date +%s.%N)
|
||||
[[ "${DEBUG:-0}" == "1" ]] && start=$(date +%s.%N)
|
||||
while IFS= read -r line; do
|
||||
if [[ $line =~ code:([0-9]+) ]]; then
|
||||
if [[ "$line" =~ code:([0-9]+) ]]; then
|
||||
code="${BASH_REMATCH[1]}"
|
||||
symbol=$(lookup_keycode_cached "$code" "$XKB_KEYMAP_CACHE")
|
||||
echo "${line/code:${code}/$symbol}"
|
||||
elif [[ $line =~ mouse:([0-9]+) ]]; then
|
||||
elif [[ "$line" =~ mouse:([0-9]+) ]]; then
|
||||
code="${BASH_REMATCH[1]}"
|
||||
|
||||
case "$code" in
|
||||
@@ -64,7 +65,7 @@ parse_keycodes() {
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $DEBUG == "1" ]]; then
|
||||
if [[ "$DEBUG" == "1" ]]; then
|
||||
end=$(date +%s.%N)
|
||||
# fall back to awk if bc is missing
|
||||
if command -v bc >/dev/null 2>&1; then
|
||||
@@ -88,7 +89,6 @@ dynamic_bindings() {
|
||||
jq -r '.[] | {modmask, key, keycode, description, dispatcher, arg} | "\(.modmask),\(.key)@\(.keycode),\(.description),\(.dispatcher),\(.arg)"' |
|
||||
sed -r \
|
||||
-e 's/null//' \
|
||||
-e 's,~/.local/share/omarchy/bin/,,' \
|
||||
-e 's,uwsm app -- ,,' \
|
||||
-e 's,uwsm-app -- ,,' \
|
||||
-e 's/@0//' \
|
||||
@@ -168,47 +168,35 @@ prioritize_entries() {
|
||||
line = $0
|
||||
prio = 50
|
||||
if (match(line, /Terminal/)) prio = 0
|
||||
if (match(line, /Tmux/)) prio = 1
|
||||
if (match(line, /Browser/) && !match(line, /Browser[[:space:]]*\(/) && !match(line, /SUPER SHIFT.*\+.*B.*→.*Browser/)) prio = 2
|
||||
if (match(line, /File manager/) && !match(line, /File manager \(cwd\)/)) prio = 3
|
||||
if (match(line, /Launch apps/)) prio = 4
|
||||
if (match(line, /Omarchy menu/)) prio = 5
|
||||
if (match(line, /System menu/)) prio = 6
|
||||
if (match(line, /Theme menu/)) prio = 7
|
||||
if (match(line, /Full screen/)) prio = 8
|
||||
if (match(line, /Full width/)) prio = 9
|
||||
if (match(line, /Close window/)) prio = 10
|
||||
if (match(line, /Close all windows/)) prio = 11
|
||||
if (match(line, /Lock system/)) prio = 12
|
||||
if (match(line, /Toggle window floating/)) prio = 13
|
||||
if (match(line, /Toggle window split/)) prio = 14
|
||||
if (match(line, /Pop window/)) prio = 15
|
||||
if (match(line, /Universal/)) prio = 16
|
||||
if (match(line, /Clipboard/)) prio = 17
|
||||
if (match(line, /Audio controls/)) prio = 18
|
||||
if (match(line, /Bluetooth controls/)) prio = 19
|
||||
if (match(line, /Wifi controls/)) prio = 20
|
||||
if (match(line, /Emoji picker/)) prio = 21
|
||||
if (match(line, /Color picker/)) prio = 22
|
||||
if (match(line, /Screenshot/)) prio = 23
|
||||
if (match(line, /Screenrecording/)) prio = 24
|
||||
if (match(line, /SUPER SHIFT.*\+.*B.*→.*Browser/)) prio = 25
|
||||
if (match(line, /File manager \(cwd\)/)) prio = 26
|
||||
if (match(line, /(Switch|Next|Former|Previous).*workspace/)) prio = 27
|
||||
if (match(line, /Move window to workspace/)) prio = 28
|
||||
if (match(line, /Move window silently to workspace/)) prio = 29
|
||||
if (match(line, /Swap window/)) prio = 30
|
||||
if (match(line, /Move window focus/)) prio = 31
|
||||
if (match(line, /Move window$/)) prio = 32
|
||||
if (match(line, /Resize window/)) prio = 33
|
||||
if (match(line, /Expand window/)) prio = 34
|
||||
if (match(line, /Shrink window/)) prio = 35
|
||||
if (match(line, /scratchpad/)) prio = 36
|
||||
if (match(line, /notification/)) prio = 37
|
||||
if (match(line, /Toggle window transparency/)) prio = 38
|
||||
if (match(line, /Toggle workspace gaps/)) prio = 39
|
||||
if (match(line, /Toggle nightlight/)) prio = 40
|
||||
if (match(line, /Toggle locking/)) prio = 41
|
||||
if (match(line, /Browser/) && !match(line, /Browser[[:space:]]*\(/)) prio = 1
|
||||
if (match(line, /File manager/)) prio = 2
|
||||
if (match(line, /Launch apps/)) prio = 3
|
||||
if (match(line, /Omarchy menu/)) prio = 4
|
||||
if (match(line, /System menu/)) prio = 5
|
||||
if (match(line, /Theme menu/)) prio = 6
|
||||
if (match(line, /Full screen/)) prio = 7
|
||||
if (match(line, /Close window/)) prio = 8
|
||||
if (match(line, /Toggle window floating/)) prio = 9
|
||||
if (match(line, /Toggle window split/)) prio = 10
|
||||
if (match(line, /Universal/)) prio = 11
|
||||
if (match(line, /Clipboard/)) prio = 12
|
||||
if (match(line, /Emoji picker/)) prio = 13
|
||||
if (match(line, /Color picker/)) prio = 14
|
||||
if (match(line, /Screenshot/)) prio = 15
|
||||
if (match(line, /Screenrecording/)) prio = 16
|
||||
if (match(line, /(Switch|Next|Former|Previous).*workspace/)) prio = 17
|
||||
if (match(line, /Move window to workspace/)) prio = 18
|
||||
if (match(line, /Swap window/)) prio = 19
|
||||
if (match(line, /Move window focus/)) prio = 20
|
||||
if (match(line, /Move window$/)) prio = 21
|
||||
if (match(line, /Resize window/)) prio = 22
|
||||
if (match(line, /Expand window/)) prio = 23
|
||||
if (match(line, /Shrink window/)) prio = 24
|
||||
if (match(line, /scratchpad/)) prio = 25
|
||||
if (match(line, /notification/)) prio = 26
|
||||
if (match(line, /Toggle window transparency/)) prio = 27
|
||||
if (match(line, /Toggle workspace gaps/)) prio = 28
|
||||
if (match(line, /Toggle nightlight/)) prio = 29
|
||||
if (match(line, /group/)) prio = 94
|
||||
if (match(line, /Scroll active workspace/)) prio = 95
|
||||
if (match(line, /Cycle to/)) prio = 96
|
||||
@@ -223,25 +211,18 @@ prioritize_entries() {
|
||||
cut -f2-
|
||||
}
|
||||
|
||||
output_keybindings() {
|
||||
build_keymap_cache
|
||||
monitor_height=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .height')
|
||||
menu_height=$((monitor_height * 40 / 100))
|
||||
|
||||
{
|
||||
dynamic_bindings
|
||||
static_bindings
|
||||
} |
|
||||
sort -u |
|
||||
parse_keycodes |
|
||||
parse_bindings |
|
||||
prioritize_entries
|
||||
}
|
||||
build_keymap_cache
|
||||
|
||||
if [[ $1 == "--print" || $1 == "-p" ]]; then
|
||||
output_keybindings
|
||||
else
|
||||
monitor_height=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .height')
|
||||
menu_height=$((monitor_height * 40 / 100))
|
||||
{
|
||||
dynamic_bindings
|
||||
static_bindings
|
||||
} |
|
||||
sort -u |
|
||||
parse_keycodes |
|
||||
parse_bindings |
|
||||
prioritize_entries |
|
||||
walker --dmenu -p 'Keybindings' --width 800 --height "$menu_height"
|
||||
|
||||
output_keybindings |
|
||||
walker --dmenu -p 'Keybindings' --width 800 --height "$menu_height"
|
||||
fi
|
||||
|
||||
+2
-4
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run all pending migrations to bring the system in line with the installed version.
|
||||
|
||||
# Where we store an empty file for each migration that has already been performed.
|
||||
STATE_DIR="$HOME/.local/state/omarchy/migrations"
|
||||
mkdir -p "$STATE_DIR"
|
||||
@@ -10,10 +8,10 @@ mkdir -p "$STATE_DIR"
|
||||
mkdir -p "$STATE_DIR/skipped"
|
||||
|
||||
# Run any pending migrations
|
||||
for file in ~/.local/share/omarchy/migrations/*.sh; do
|
||||
for file in /usr/share/omarchy/migrations/*.sh; do
|
||||
filename=$(basename "$file")
|
||||
|
||||
if [[ ! -f $STATE_DIR/$filename && ! -f $STATE_DIR/skipped/$filename ]]; then
|
||||
if [[ ! -f "$STATE_DIR/$filename" && ! -f "$STATE_DIR/skipped/$filename" ]]; then
|
||||
echo -e "\e[32m\nRunning migration (${filename%.sh})\e[0m"
|
||||
|
||||
if bash $file; then
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Dismiss a mako notification on the basis of its summary. Used by the first-run notifications to dismiss them after clicking for action.
|
||||
|
||||
if (($# == 0)); then
|
||||
echo "Usage: omarchy-notification-dismiss <summary>"
|
||||
exit 1
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Add the named packages to the system if they're missing. Returns false if it couldn't be done.
|
||||
|
||||
if omarchy-pkg-missing "$@"; then
|
||||
sudo pacman -S --noconfirm --needed "$@" || exit 1
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns true if the AUR is up and available.
|
||||
# Used by omarchy-update-system-pkgs to ensure the AUR is available before updating packages from it.
|
||||
|
||||
curl -sf --connect-timeout 30 --retry 3 --retry-delay 3 -A "omarchy-update" \
|
||||
"https://aur.archlinux.org/rpc/?v=5&type=info&arg=base" >/dev/null
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Add the named packages to the system from the AUR if they're missing. Returns false if it couldn't be done.
|
||||
|
||||
if omarchy-pkg-missing "$@"; then
|
||||
yay -S --noconfirm --needed "$@" || exit 1
|
||||
fi
|
||||
|
||||
for pkg in "$@"; do
|
||||
# Secondary check to handle states where pacman doesn't actually register an error
|
||||
if ! pacman -Q "$pkg" &>/dev/null; then
|
||||
echo -e "\033[31mError: Package '$pkg' did not install\033[0m" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Show a fuzzy-finder TUI for picking new AUR packages to install.
|
||||
|
||||
fzf_args=(
|
||||
--multi
|
||||
--preview 'yay -Siia {1}'
|
||||
@@ -18,10 +16,9 @@ fzf_args=(
|
||||
|
||||
pkg_names=$(yay -Slqa | fzf "${fzf_args[@]}")
|
||||
|
||||
if [[ -n $pkg_names ]]; then
|
||||
# Add aur/ prefix to each package name and convert to space-separated for yay
|
||||
sudo -v
|
||||
echo "$pkg_names" | sed 's/^/aur\//' | tr '\n' ' ' | xargs yay -S --noconfirm
|
||||
if [[ -n "$pkg_names" ]]; then
|
||||
# Convert newline-separated selections to space-separated for yay
|
||||
echo "$pkg_names" | tr '\n' ' ' | xargs yay -S --noconfirm
|
||||
sudo updatedb
|
||||
omarchy-show-done
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Remove all the named packages from the system if they're installed (otherwise ignore).
|
||||
|
||||
for pkg in "$@"; do
|
||||
if pacman -Q "$pkg" &>/dev/null; then
|
||||
sudo pacman -Rns --noconfirm "$pkg"
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
IGNORED_PACKAGES_FILE="$OMARCHY_PATH/install/packages.ignored"
|
||||
|
||||
if [[ -f $IGNORED_PACKAGES_FILE ]]; then
|
||||
tr '\r\n' ',' <"$IGNORED_PACKAGES_FILE" | sed 's/,$//'
|
||||
fi
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Show a fuzzy-finder TUI for picking new Arch and OPR packages to install.
|
||||
|
||||
fzf_args=(
|
||||
--multi
|
||||
--preview 'pacman -Sii {1}'
|
||||
@@ -16,7 +14,7 @@ fzf_args=(
|
||||
|
||||
pkg_names=$(pacman -Slq | fzf "${fzf_args[@]}")
|
||||
|
||||
if [[ -n $pkg_names ]]; then
|
||||
if [[ -n "$pkg_names" ]]; then
|
||||
# Convert newline-separated selections to space-separated for yay
|
||||
echo "$pkg_names" | tr '\n' ' ' | xargs sudo pacman -S --noconfirm
|
||||
omarchy-show-done
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns true if any of the named packages are missing from the system (or false if they're all there).
|
||||
|
||||
for pkg in "$@"; do
|
||||
if ! pacman -Q "$pkg" &>/dev/null; then
|
||||
exit 0
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
PINNED_PACKAGES_FILE="$OMARCHY_PATH/install/packages.pinned"
|
||||
|
||||
if [[ -f $PINNED_PACKAGES_FILE ]]; then
|
||||
tr '\r\n' ',' <"$PINNED_PACKAGES_FILE" | sed 's/,$//'
|
||||
fi
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns true if all of the named packages are installed on the system (or false if any of them are missing).
|
||||
|
||||
for pkg in "$@"; do
|
||||
pacman -Q "$pkg" &>/dev/null || exit 1
|
||||
done
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Show a fuzzy-finder TUI for picking packages installed on the system to be removed.
|
||||
|
||||
fzf_args=(
|
||||
--multi
|
||||
--preview 'yay -Qi {1}'
|
||||
@@ -16,7 +14,7 @@ fzf_args=(
|
||||
|
||||
pkg_names=$(yay -Qqe | fzf "${fzf_args[@]}")
|
||||
|
||||
if [[ -n $pkg_names ]]; then
|
||||
if [[ -n "$pkg_names" ]]; then
|
||||
# Convert newline-separated selections to space-separated for yay
|
||||
echo "$pkg_names" | tr '\n' ' ' | xargs sudo pacman -Rns --noconfirm
|
||||
omarchy-show-done
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Returns a list of all the available power profiles on the system.
|
||||
# Used by the Omarchy Menu under Setup > Power Profile.
|
||||
|
||||
powerprofilesctl list |
|
||||
awk '/^\s*[* ]\s*[a-zA-Z0-9\-]+:$/ { gsub(/^[*[:space:]]+|:$/,""); print }' |
|
||||
tac
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ensure all default .desktop, web apps, and TUIs are installed.
|
||||
|
||||
# Copy and sync icon files
|
||||
mkdir -p ~/.local/share/icons/hicolor/48x48/apps/
|
||||
cp ~/.local/share/omarchy/applications/icons/*.png ~/.local/share/icons/hicolor/48x48/apps/
|
||||
cp /usr/share/omarchy/applications/icons/*.png ~/.local/share/icons/hicolor/48x48/apps/
|
||||
gtk-update-icon-cache ~/.local/share/icons/hicolor &>/dev/null
|
||||
|
||||
# Copy .desktop declarations
|
||||
mkdir -p ~/.local/share/applications
|
||||
cp ~/.local/share/omarchy/applications/*.desktop ~/.local/share/applications/
|
||||
cp ~/.local/share/omarchy/applications/hidden/*.desktop ~/.local/share/applications/
|
||||
|
||||
# Refresh the webapps and TUIs
|
||||
bash $OMARCHY_PATH/install/packaging/icons.sh
|
||||
bash $OMARCHY_PATH/install/packaging/webapps.sh
|
||||
bash $OMARCHY_PATH/install/packaging/tuis.sh
|
||||
cp /usr/share/omarchy/applications/*.desktop ~/.local/share/applications/
|
||||
cp /usr/share/omarchy/applications/hidden/*.desktop ~/.local/share/applications/
|
||||
|
||||
update-desktop-database ~/.local/share/applications
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Refresh the ~/.config/chromium-flags.conf file from the Omarchy defaults.
|
||||
|
||||
CONFIG_FILE="$HOME/.config/chromium-flags.conf"
|
||||
INSTALL_GOOGLE_ACCOUNTS=false
|
||||
|
||||
# Check if google accounts were installed
|
||||
if [[ -f $CONFIG_FILE ]] && \
|
||||
grep -q -- "--oauth2-client-id" "$CONFIG_FILE" && \
|
||||
grep -q -- "--oauth2-client-secret" "$CONFIG_FILE"; then
|
||||
INSTALL_GOOGLE_ACCOUNTS=true
|
||||
fi
|
||||
|
||||
# Refresh the Chromium configuration
|
||||
omarchy-refresh-config chromium-flags.conf
|
||||
|
||||
# Re-install Google accounts if previously configured
|
||||
if [[ $INSTALL_GOOGLE_ACCOUNTS == "true" ]]; then
|
||||
omarchy-install-chromium-google-account
|
||||
fi
|
||||
@@ -1,16 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copies the named config from ~/.local/share/omarchy/config/X/Y/Z -> ~/.config/X/Y/Z.
|
||||
# If the config already exists, a backup of the existing will be taken as .bak.TIMESTAMP.
|
||||
|
||||
# This script deploys /etc/skel/.config/X/Y/Z -> ~/.config/X/Y/Z
|
||||
config_file=$1
|
||||
|
||||
if [[ -z $config_file ]]; then
|
||||
if [[ -z "$config_file" ]]; then
|
||||
cat <<USAGE
|
||||
Usage: $0 [config_file]
|
||||
|
||||
Must provide a file path from the .config directory to be refreshed.
|
||||
To copy ~/.local/share/omarchy/config/hypr/hyprlock.conf to ~/.config/hypr/hyprlock.conf
|
||||
To copy /etc/skel/.config/hypr/hyprlock.conf to ~/.config/hypr/hyprlock.conf
|
||||
|
||||
$0 hypr/hyprlock.conf
|
||||
USAGE
|
||||
@@ -19,10 +17,10 @@ fi
|
||||
|
||||
# Backup the destination file (with timestamp) to avoid clobbering (Ex: hyprlock.conf.bak.1753817951)
|
||||
user_config_file="${HOME}/.config/$config_file"
|
||||
default_config_file="${HOME}/.local/share/omarchy/config/$config_file"
|
||||
default_config_file="/etc/skel/.config/$config_file"
|
||||
backup_config_file="$user_config_file.bak.$(date +%s)"
|
||||
|
||||
if [[ -f $user_config_file ]]; then
|
||||
if [[ -f "$user_config_file" ]]; then
|
||||
# Create preliminary backup
|
||||
cp -f "$user_config_file" "$backup_config_file" 2>/dev/null
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Overwrite the user config for fastfetch with the Omarchy default.
|
||||
|
||||
omarchy-refresh-config fastfetch/config.jsonc
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Overwrite the user config for hypridle with the Omarchy default and restart the service.
|
||||
|
||||
omarchy-refresh-config hypr/hypridle.conf
|
||||
omarchy-restart-hypridle
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Overwrite all the user configs in ~/.config/hypr with the Omarchy defaults.
|
||||
|
||||
omarchy-refresh-config hypr/autostart.conf
|
||||
omarchy-refresh-config hypr/bindings.conf
|
||||
omarchy-refresh-config hypr/envs.conf
|
||||
omarchy-refresh-config hypr/input.conf
|
||||
omarchy-refresh-config hypr/looknfeel.conf
|
||||
omarchy-refresh-config hypr/hyprland.conf
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Overwrite the user config for hyprlock with the Omarchy default.
|
||||
|
||||
omarchy-refresh-config hypr/hyprlock.conf
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Overwrite the user config for hyprsunset with the Omarchy default and restart the service.
|
||||
#
|
||||
omarchy-refresh-config hypr/hyprsunset.conf
|
||||
omarchy-restart-hyprsunset
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Overwrite the user config for the Limine bootloader and rebuild it.
|
||||
|
||||
if [[ -f /boot/EFI/Linux/omarchy_linux.efi ]] && [[ -f /boot/EFI/Linux/$(cat /etc/machine-id)_linux.efi ]]; then
|
||||
if [[ -f /boot/EFI/linux/omarchy_linux.efi ]] && [[ -f /boot/EFI/linux/$(cat /etc/machine-id)_linux.efi ]]; then
|
||||
echo "Cleanup extra UKI"
|
||||
sudo rm -f /boot/EFI/Linux/$(cat /etc/machine-id)_linux.efi
|
||||
fi
|
||||
@@ -10,7 +8,27 @@ echo "Resetting limine config"
|
||||
|
||||
sudo mv /boot/limine.conf /boot/limine.conf.bak
|
||||
|
||||
sudo cp ~/.local/share/omarchy/default/limine/limine.conf /boot/limine.conf
|
||||
sudo tee /boot/limine.conf <<EOF >/dev/null
|
||||
### Read more at config document: https://github.com/limine-bootloader/limine/blob/trunk/CONFIG.md
|
||||
#timeout: 3
|
||||
default_entry: 2
|
||||
interface_branding: Omarchy Bootloader
|
||||
interface_branding_color: 2
|
||||
hash_mismatch_panic: no
|
||||
|
||||
term_background: 1a1b26
|
||||
backdrop: 1a1b26
|
||||
|
||||
# Terminal colors (Tokyo Night palette)
|
||||
term_palette: 15161e;f7768e;9ece6a;e0af68;7aa2f7;bb9af7;7dcfff;a9b1d6
|
||||
term_palette_bright: 414868;f7768e;9ece6a;e0af68;7aa2f7;bb9af7;7dcfff;c0caf5
|
||||
|
||||
# Text colors
|
||||
term_foreground: c0caf5
|
||||
term_foreground_bright: c0caf5
|
||||
term_background_bright: 24283b
|
||||
|
||||
EOF
|
||||
|
||||
sudo limine-update
|
||||
sudo limine-snapper-sync
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Overwrite the package configuration for /etc/pacman with the Omarchy default of using its dedicated mirrors and repositories, then update all packages.
|
||||
# This is used after switching between Omarchy release channels to ensure the right packages for the right channel are available.
|
||||
|
||||
# Take backup of existing files
|
||||
sudo cp -f /etc/pacman.conf /etc/pacman.conf.bak
|
||||
sudo cp -f /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak
|
||||
|
||||
channel="${1:-stable}"
|
||||
|
||||
if [[ $channel != "stable" && $channel != "rc" && $channel != "edge" ]]; then
|
||||
echo "Error: Invalid channel '$channel'. Must be one of: stable, rc, edge"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Setting channel to $channel"
|
||||
echo
|
||||
|
||||
sudo cp -f "$OMARCHY_PATH/default/pacman/pacman-$channel.conf" /etc/pacman.conf
|
||||
sudo cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-$channel" /etc/pacman.d/mirrorlist
|
||||
|
||||
# Reset all package DBs and then update
|
||||
sudo pacman -Syyuu --noconfirm
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user