diff --git a/AGENTS.md b/AGENTS.md index c0c87cb3..689f4c50 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,6 +12,7 @@ All commands start with `omarchy-`. Prefixes indicate purpose: - `cmd-` - check if commands exist, misc utility commands +- `capture-` - screenshots, screen recordings, and other capture tools - `pkg-` - package management helpers - `hw-` - hardware detection (return exit codes for use in conditionals) - `refresh-` - copy default config to user's `~/.config/` diff --git a/applications/hidden/lstopo.desktop b/applications/hidden/lstopo.desktop new file mode 100644 index 00000000..e1e3e173 --- /dev/null +++ b/applications/hidden/lstopo.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/applications/icons/Cliamp.png b/applications/icons/Cliamp.png new file mode 100644 index 00000000..94b3b06e Binary files /dev/null and b/applications/icons/Cliamp.png differ diff --git a/bin/omarchy b/bin/omarchy new file mode 100755 index 00000000..511aeb97 --- /dev/null +++ b/bin/omarchy @@ -0,0 +1,1028 @@ +#!/bin/bash + +set -o pipefail + +OMARCHY_BIN_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +METADATA_SCAN_LIMIT=80 + +COMMAND_KEYS=() +ROUTE_COLLISIONS=() +declare -A COMMAND_ROUTE +declare -A COMMAND_FALLBACK_ROUTE +declare -A COMMAND_BINARY +declare -A COMMAND_GROUP +declare -A COMMAND_NAME +declare -A COMMAND_SUMMARY +declare -A COMMAND_USAGE +declare -A COMMAND_ARGS +declare -A COMMAND_EXAMPLES +declare -A COMMAND_REQUIRES_SUDO +declare -A COMMAND_ALIASES +declare -A COMMAND_HAS_SUMMARY +declare -A COMMAND_METADATA_ERRORS +declare -A ROUTE_TO_KEY +declare -A ROUTE_IS_ALIAS +declare -A BINARY_TO_KEY +declare -A GROUP_DESCRIPTIONS + +GROUP_DESCRIPTIONS[ac]="AC power detection" +GROUP_DESCRIPTIONS[battery]="Battery status helpers" +GROUP_DESCRIPTIONS[branch]="Omarchy git branch management" +GROUP_DESCRIPTIONS[brightness]="Display and keyboard brightness" +GROUP_DESCRIPTIONS[capture]="Screenshots and screen recording" +GROUP_DESCRIPTIONS[channel]="Omarchy release channel management" +GROUP_DESCRIPTIONS[cmd]="Command and shortcut helpers" +GROUP_DESCRIPTIONS[config]="System configuration helpers" +GROUP_DESCRIPTIONS[debug]="Diagnostics and support logs" +GROUP_DESCRIPTIONS[dev]="Omarchy development tools" +GROUP_DESCRIPTIONS[drive]="Drive selection and encryption" +GROUP_DESCRIPTIONS[font]="Font management" +GROUP_DESCRIPTIONS[hibernation]="Hibernation setup and removal" +GROUP_DESCRIPTIONS[hook]="User hook runner" +GROUP_DESCRIPTIONS[hw]="Hardware detection and controls" +GROUP_DESCRIPTIONS[hyprland]="Hyprland window, monitor, and toggle controls" +GROUP_DESCRIPTIONS[install]="Optional software installers" +GROUP_DESCRIPTIONS[launch]="Application launchers" +GROUP_DESCRIPTIONS[menu]="Omarchy menu commands" +GROUP_DESCRIPTIONS[migrate]="Migration runner" +GROUP_DESCRIPTIONS[notification]="Notification helpers" +GROUP_DESCRIPTIONS[npx]="NPX package wrappers" +GROUP_DESCRIPTIONS[pkg]="Package management helpers" +GROUP_DESCRIPTIONS[plymouth]="Plymouth boot theme management" +GROUP_DESCRIPTIONS[powerprofiles]="Power profile management" +GROUP_DESCRIPTIONS[refresh]="Reset config to defaults" +GROUP_DESCRIPTIONS[reinstall]="Reinstall and reset workflows" +GROUP_DESCRIPTIONS[remove]="Removal workflows" +GROUP_DESCRIPTIONS[restart]="Restart Omarchy components" +GROUP_DESCRIPTIONS[setup]="Interactive setup wizards" +GROUP_DESCRIPTIONS[snapshot]="System snapshots" +GROUP_DESCRIPTIONS[state]="Persistent Omarchy state" +GROUP_DESCRIPTIONS[sudo]="Sudo configuration helpers" +GROUP_DESCRIPTIONS[swayosd]="SwayOSD status display helpers" +GROUP_DESCRIPTIONS[system]="Reboot, shutdown, logout, and lock" +GROUP_DESCRIPTIONS[theme]="Theme management" +GROUP_DESCRIPTIONS[toggle]="Toggle Omarchy features" +GROUP_DESCRIPTIONS[tui]="Terminal UI launchers" +GROUP_DESCRIPTIONS[tz]="Timezone selection" +GROUP_DESCRIPTIONS[update]="Omarchy and system updates" +GROUP_DESCRIPTIONS[upload]="Upload helpers" +GROUP_DESCRIPTIONS[version]="Version and channel information" +GROUP_DESCRIPTIONS[voxtype]="Voxtype dictation" +GROUP_DESCRIPTIONS[webapp]="Web app launchers" +GROUP_DESCRIPTIONS[wifi]="Wi-Fi helpers" +GROUP_DESCRIPTIONS[windows]="Windows VM management" + +join_words() { + local separator="$1" + shift + local joined="" + + for word in "$@"; do + if [[ -z $joined ]]; then + joined="$word" + else + joined+="$separator$word" + fi + done + + printf '%s' "$joined" +} + +append_pipe_value() { + local current="$1" + local addition="$2" + + if [[ -z $current ]]; then + printf '%s' "$addition" + else + printf '%s|%s' "$current" "$addition" + fi +} + +register_route() { + local route="$1" + local key="$2" + local is_alias="${3:-false}" + + [[ -z $route || -z $key ]] && return + + if [[ -n ${ROUTE_TO_KEY[$route]} && ${ROUTE_TO_KEY[$route]} != "$key" ]]; then + ROUTE_COLLISIONS+=("$route -> ${ROUTE_TO_KEY[$route]} conflicts with $key") + return + fi + + ROUTE_TO_KEY["$route"]="$key" + if [[ $is_alias == "true" ]]; then + ROUTE_IS_ALIAS["$route"]="true" + fi +} + +register_command() { + local file="$1" + local file_binary="${file##*/}" + local group="" + local name="" + local summary="" + local usage="" + local binary="" + local args="" + local examples="" + local aliases="" + local requires_sudo="" + local line="" + local metadata_key="" + local metadata_value="" + local line_count=0 + local name_seen="false" + local fallback_summary="" + local has_summary="false" + local metadata_errors="" + + while IFS= read -r line && (( line_count < METADATA_SCAN_LIMIT )); do + line_count=$((line_count + 1)) + + if (( line_count == 1 )) && [[ $line == "#!"* ]]; then + continue + fi + + if [[ $line =~ ^[[:space:]]*$ ]]; then + continue + fi + + if [[ ! $line =~ ^[[:space:]]*# ]]; then + break + fi + + if [[ $line =~ ^[[:space:]]*#[[:space:]]*omarchy:([[:alnum:]_-]+)=(.*)$ ]]; then + metadata_key="${BASH_REMATCH[1]}" + metadata_value="${BASH_REMATCH[2]}" + metadata_value="${metadata_value%$'\r'}" + metadata_value="${metadata_value//$'\t'/ }" + + case "$metadata_key" in + group) + group="$metadata_value" + ;; + name) + name="$metadata_value" + name_seen="true" + ;; + summary) + summary="$metadata_value" + [[ -n $metadata_value ]] && has_summary="true" + ;; + args) + args="$metadata_value" + ;; + examples) + examples="$metadata_value" + ;; + alias | aliases) + aliases="$metadata_value" + ;; + requires-sudo) + requires_sudo="$metadata_value" + [[ $metadata_value == "true" ]] || metadata_errors=$(append_pipe_value "$metadata_errors" "requires-sudo must be omitted or true") + ;; + *) + ;; + esac + elif [[ -z $fallback_summary && $line =~ ^[[:space:]]*#[[:space:]]*(.+)$ ]]; then + fallback_summary="${BASH_REMATCH[1]}" + fallback_summary="${fallback_summary%$'\r'}" + fallback_summary="${fallback_summary//$'\t'/ }" + + if [[ -z $fallback_summary || $fallback_summary == omarchy:* ]]; then + fallback_summary="" + fi + fi + done <"$file" + + local stem="${file_binary#omarchy-}" + local fallback_group="$stem" + local fallback_name="" + local fallback_route="omarchy ${stem//-/ }" + + if [[ $stem == *-* ]]; then + fallback_group="${stem%%-*}" + fallback_name="${stem#*-}" + fallback_name="${fallback_name//-/ }" + fi + + [[ -z $binary ]] && binary="$file_binary" + [[ -z $group ]] && group="$fallback_group" + [[ $name_seen != "true" ]] && name="$fallback_name" + [[ -z $summary && -n $fallback_summary ]] && summary="$fallback_summary" + [[ -z $summary ]] && summary="Run the ${stem//-/ } command" + local route="omarchy $group" + if [[ -n $name ]]; then + route+=" $name" + fi + + if [[ -z $usage ]]; then + usage="$route" + if [[ -n $args ]]; then + usage+=" $args" + fi + fi + + [[ $requires_sudo == "true" ]] || requires_sudo="false" + + local key="$file_binary" + COMMAND_KEYS+=("$key") + COMMAND_ROUTE["$key"]="$route" + COMMAND_FALLBACK_ROUTE["$key"]="$fallback_route" + COMMAND_BINARY["$key"]="$binary" + COMMAND_GROUP["$key"]="$group" + COMMAND_NAME["$key"]="$name" + COMMAND_SUMMARY["$key"]="$summary" + COMMAND_USAGE["$key"]="$usage" + COMMAND_ARGS["$key"]="$args" + COMMAND_EXAMPLES["$key"]="$examples" + COMMAND_REQUIRES_SUDO["$key"]="$requires_sudo" + COMMAND_HAS_SUMMARY["$key"]="$has_summary" + COMMAND_METADATA_ERRORS["$key"]="$metadata_errors" + + BINARY_TO_KEY["$binary"]="$key" + register_route "$route" "$key" + register_route "$fallback_route" "$key" + + local old_ifs="$IFS" + local alias_route="" + IFS='|' + for alias_route in $aliases; do + alias_route="${alias_route# }" + alias_route="${alias_route% }" + [[ -z $alias_route || $alias_route == "$route" ]] && continue + register_route "$alias_route" "$key" true + COMMAND_ALIASES["$key"]=$(append_pipe_value "${COMMAND_ALIASES[$key]}" "$alias_route") + done + IFS="$old_ifs" +} + +load_commands() { + local file="" + + for file in "$OMARCHY_BIN_DIR"/omarchy-*; do + [[ -f $file && -x $file ]] || continue + register_command "$file" + done + +} + +load_command_by_binary() { + local binary="$1" + local file="$OMARCHY_BIN_DIR/$binary" + + [[ -f $file && -x $file ]] || return 1 + register_command "$file" +} + +load_child_commands_by_binary() { + local binary="$1" + local file="" + + for file in "$OMARCHY_BIN_DIR/$binary"-*; do + [[ -f $file && -x $file ]] || continue + register_command "$file" + done +} + +group_has_child_commands() { + local group="$1" + local file="" + + for file in "$OMARCHY_BIN_DIR/omarchy-$group"-*; do + [[ -f $file && -x $file ]] && return 0 + done + + return 1 +} + +group_has_binary_commands() { + local group="$1" + + [[ -x $OMARCHY_BIN_DIR/omarchy-$group ]] && return 0 + group_has_child_commands "$group" +} + +command_requires_args() { + local key="$1" + local args="${COMMAND_ARGS[$key]}" + local required="$args" + + while [[ $required =~ ^(.*)\[[^][]*\](.*)$ ]]; do + required="${BASH_REMATCH[1]}${BASH_REMATCH[2]}" + done + + required="${required// /}" + [[ -n $required ]] +} + +load_group_extra_commands() { + local group="$1" + + case "$group" in + install) + load_command_by_binary omarchy-pkg-add + ;; + esac +} + +load_group_commands() { + local group="$1" + local file="" + + if [[ -f $OMARCHY_BIN_DIR/omarchy-$group && -x $OMARCHY_BIN_DIR/omarchy-$group ]]; then + register_command "$OMARCHY_BIN_DIR/omarchy-$group" + fi + + for file in "$OMARCHY_BIN_DIR/omarchy-$group"-*; do + [[ -f $file && -x $file ]] || continue + register_command "$file" + done + + load_group_extra_commands "$group" +} + +resolve_direct_route() { + local argc="$1" + shift + local args=("$@") + local prefix_count=0 + local route="" + local binary="" + local candidate="" + + for (( prefix_count = argc; prefix_count >= 1; prefix_count-- )); do + route="omarchy $(join_words " " "${args[@]:0:prefix_count}")" + + binary="omarchy-$(join_words "-" "${args[@]:0:prefix_count}")" + candidate="$OMARCHY_BIN_DIR/$binary" + if [[ -f $candidate && -x $candidate ]]; then + DIRECT_RESOLVED_BINARY="$binary" + DIRECT_RESOLVED_COUNT="$prefix_count" + DIRECT_RESOLVED_ROUTE="$route" + return 0 + fi + done + + return 1 +} + +sorted_keys() { + local include_all="$1" + local key="" + + for key in "${COMMAND_KEYS[@]}"; do + printf '%s\t%s\n' "${COMMAND_ROUTE[$key]}" "$key" + done | sort -u | cut -f2- +} + +fallback_group_for_key() { + local key="$1" + local fallback="${COMMAND_FALLBACK_ROUTE[$key]#omarchy }" + + printf '%s' "${fallback%% *}" +} + +command_route_for_group() { + local key="$1" + local group="$2" + + if [[ $(fallback_group_for_key "$key") == "$group" && ${COMMAND_GROUP[$key]} != "$group" ]]; then + printf '%s' "${COMMAND_FALLBACK_ROUTE[$key]}" + else + printf '%s' "${COMMAND_ROUTE[$key]}" + fi +} + +command_usage_for_group() { + local key="$1" + local group="$2" + local route="" + + route=$(command_route_for_group "$key" "$group") + if [[ -n ${COMMAND_ARGS[$key]} ]]; then + route+=" ${COMMAND_ARGS[$key]}" + fi + + printf '%s' "$route" +} + +sorted_group_keys() { + local group="$1" + local include_all="$2" + local key="" + local fallback_group="" + local route="" + + for key in "${COMMAND_KEYS[@]}"; do + fallback_group=$(fallback_group_for_key "$key") + if [[ ${COMMAND_GROUP[$key]} != "$group" && $fallback_group != "$group" ]]; then + continue + fi + + route=$(command_route_for_group "$key" "$group") + printf '%s\t%s\n' "$route" "$key" + done | sort -u | cut -f2- +} + +examples_as_lines() { + local examples="$1" + local old_ifs="$IFS" + local example="" + IFS='|' + + for example in $examples; do + example="${example# }" + example="${example% }" + [[ -n $example ]] && printf '%s\n' "$example" + done + + IFS="$old_ifs" +} + +pipe_values_as_lines() { + local values="$1" + local old_ifs="$IFS" + local value="" + IFS='|' + + for value in $values; do + value="${value# }" + value="${value% }" + [[ -n $value ]] && printf '%s\n' "$value" + done + + IFS="$old_ifs" +} + +show_group_list() { + local sorted_group="" + + printf '%s\n' "${!GROUP_DESCRIPTIONS[@]}" | sort | while IFS= read -r sorted_group; do + [[ -n $sorted_group ]] || continue + printf ' %-14s %s\n' "$sorted_group" "${GROUP_DESCRIPTIONS[$sorted_group]}" + done +} + +show_main_help() { + cat <<'EOF' +Omarchy command center + +Usage: + omarchy [args...] + omarchy commands [--all] [--json] [--check] + omarchy --help + omarchy --help + +Common commands: + omarchy update Update Omarchy and system packages + omarchy theme list List available themes + omarchy theme set Apply a theme + omarchy font list List available fonts + omarchy screenshot Take a screenshot + omarchy debug Print debugging information + +Groups: +EOF + show_group_list + cat <<'EOF' + +Discovery: + omarchy commands List all commands + omarchy commands --all Include commands explicitly marked hidden + omarchy commands --json Machine-readable command list + omarchy commands --check Validate command metadata and routes + omarchy dev benchmark Measure CLI response times + omarchy dev bin metadata Show bin metadata fields and defaults +EOF +} + +show_commands_help() { + cat <<'EOF' +Usage: + omarchy commands [--all] [--json] [--markdown] [--check] + +List commands known to the Omarchy command center. + +Options: + --all Accepted for compatibility + --json Emit machine-readable JSON + --markdown Emit a Markdown command table + --check Validate command metadata and route collisions +EOF +} + +print_command_table() { + local rows="$1" + local max_width=0 + local width=0 + local command="" + local rest="" + local summary="" + + while IFS=$'\t' read -r command rest; do + [[ -n $command ]] || continue + width=${#command} + (( width > max_width )) && max_width=$width + done <<<"$rows" + + while IFS=$'\t' read -r command rest; do + [[ -n $command ]] || continue + + printf ' %-*s %s\n' "$max_width" "$command" "$rest" + done <<<"$rows" +} + +show_commands() { + local include_all="$1" + local key="" + local route="" + local usage="" + local rows="" + local alias_rows="" + + if [[ $include_all == "true" ]]; then + echo "Omarchy commands (all):" + else + echo "Omarchy commands:" + fi + + while IFS= read -r key; do + [[ -n $key ]] || continue + usage="${COMMAND_USAGE[$key]}" + rows+="$usage"$'\t'"${COMMAND_SUMMARY[$key]}"$'\n' + done < <(sorted_keys "$include_all") + + print_command_table "$rows" + + for route in "${!ROUTE_IS_ALIAS[@]}"; do + key="${ROUTE_TO_KEY[$route]}" + alias_rows+="$route"$'\t'"${COMMAND_ROUTE[$key]}"$'\n' + done + + if [[ -n $alias_rows ]]; then + echo "" + echo "Aliases:" + print_command_table "$(printf '%s' "$alias_rows" | sort)" + fi +} + +markdown_escape() { + local value="$1" + value="${value//|/\\|}" + printf '%s' "$value" +} + +show_commands_markdown() { + local include_all="$1" + local key="" + + echo "| Command | Binary | Summary |" + echo "| --- | --- | --- |" + + while IFS= read -r key; do + [[ -n $key ]] || continue + printf '| `%s` | `%s` | %s |\n' \ + "$(markdown_escape "${COMMAND_USAGE[$key]}")" \ + "$(markdown_escape "${COMMAND_BINARY[$key]}")" \ + "$(markdown_escape "${COMMAND_SUMMARY[$key]}")" + done < <(sorted_keys "$include_all") +} + +emit_command_records() { + local include_all="$1" + local key="" + + while IFS= read -r key; do + [[ -n $key ]] || continue + printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \ + "${COMMAND_ROUTE[$key]}" \ + "${COMMAND_BINARY[$key]}" \ + "${COMMAND_GROUP[$key]}" \ + "${COMMAND_NAME[$key]}" \ + "${COMMAND_SUMMARY[$key]}" \ + "${COMMAND_REQUIRES_SUDO[$key]}" \ + "${COMMAND_ARGS[$key]}" \ + "${COMMAND_EXAMPLES[$key]}" \ + "${COMMAND_ALIASES[$key]}" \ + "${COMMAND_FALLBACK_ROUTE[$key]}" \ + "${COMMAND_USAGE[$key]}" + done < <(sorted_keys "$include_all") +} + +commands_json_filter() { + cat <<'EOF' +[inputs | split("\t") | { + route: .[0], + binary: .[1], + group: .[2], + name: .[3], + summary: .[4], + requires_sudo: (.[5] == "true"), + args: .[6], + examples: (.[7] | split("|") | map(gsub("^ +| +$"; "")) | map(select(length > 0))), + aliases: (.[8] | split("|") | map(gsub("^ +| +$"; "")) | map(select(length > 0))), + filename_route: .[9], + routes: ([.[0], .[9]] + (.[8] | split("|") | map(gsub("^ +| +$"; "")) | map(select(length > 0))) | unique) +}] | {ok: true, commands: .} +EOF +} + +show_commands_json() { + local include_all="$1" + + emit_command_records "$include_all" | jq -Rn "$(commands_json_filter)" +} + +show_commands_check() { + local failures=0 + local collision="" + local key="" + local error="" + + for collision in "${ROUTE_COLLISIONS[@]}"; do + echo "Route collision: $collision" >&2 + failures=$((failures + 1)) + done + + for key in "${COMMAND_KEYS[@]}"; do + if [[ ${COMMAND_HAS_SUMMARY[$key]} != "true" ]]; then + echo "Missing metadata summary: ${COMMAND_BINARY[$key]}" >&2 + failures=$((failures + 1)) + fi + + if [[ -n ${COMMAND_METADATA_ERRORS[$key]} ]]; then + while IFS= read -r error; do + [[ -n $error ]] || continue + echo "Invalid metadata in ${COMMAND_BINARY[$key]}: $error" >&2 + failures=$((failures + 1)) + done < <(pipe_values_as_lines "${COMMAND_METADATA_ERRORS[$key]}") + fi + + if [[ ! -x $OMARCHY_BIN_DIR/${COMMAND_BINARY[$key]} ]]; then + echo "Missing binary: ${COMMAND_BINARY[$key]}" >&2 + failures=$((failures + 1)) + fi + done + + if (( failures > 0 )); then + echo "Command metadata check failed ($failures issues)" >&2 + return 1 + fi + + echo "Command metadata check passed (${#COMMAND_KEYS[@]} commands)" +} + +show_command_json() { + local key="$1" + + printf '%s\n' "$key" | while IFS= read -r key; do + printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \ + "${COMMAND_ROUTE[$key]}" \ + "${COMMAND_BINARY[$key]}" \ + "${COMMAND_GROUP[$key]}" \ + "${COMMAND_NAME[$key]}" \ + "${COMMAND_SUMMARY[$key]}" \ + "${COMMAND_REQUIRES_SUDO[$key]}" \ + "${COMMAND_ARGS[$key]}" \ + "${COMMAND_EXAMPLES[$key]}" \ + "${COMMAND_ALIASES[$key]}" \ + "${COMMAND_FALLBACK_ROUTE[$key]}" \ + "${COMMAND_USAGE[$key]}" + done | jq -Rn "$(commands_json_filter) | {ok: true, command: .commands[0]}" +} + +parse_commands_args() { + local include_all="false" + local json="false" + local markdown="false" + local check="false" + + shift + + while (( $# > 0 )); do + case "$1" in + --all) + include_all="true" + ;; + --json) + json="true" + ;; + --markdown) + markdown="true" + ;; + --check) + check="true" + ;; + --help | -h) + show_commands_help + return 0 + ;; + *) + echo "Unknown option for omarchy commands: $1" >&2 + show_commands_help >&2 + return 2 + ;; + esac + shift + done + + if [[ $check == "true" ]]; then + show_commands_check + elif [[ $json == "true" ]]; then + show_commands_json "$include_all" + elif [[ $markdown == "true" ]]; then + show_commands_markdown "$include_all" + else + show_commands "$include_all" + fi +} + +group_exists() { + local group="$1" + local key="" + + for key in "${COMMAND_KEYS[@]}"; do + if [[ ${COMMAND_GROUP[$key]} == "$group" && -n ${COMMAND_NAME[$key]} ]]; then + return 0 + fi + done + + return 1 +} + +show_group_help() { + local group="$1" + local include_all="${2:-false}" + local key="" + local rows="" + local title="${GROUP_DESCRIPTIONS[$group]}" + + if [[ -n $title ]]; then + echo "${group^} commands — $title:" + else + echo "${group^} commands:" + fi + + while IFS= read -r key; do + [[ -n $key ]] || continue + rows+="$(command_usage_for_group "$key" "$group")"$'\t'$'\t'"${COMMAND_SUMMARY[$key]}"$'\n' + done < <(sorted_group_keys "$group" "$include_all") + + if [[ -n $rows ]]; then + print_command_table "$rows" + else + echo " No documented commands found. Try: omarchy commands --all" + fi +} + +show_related_commands() { + local key="$1" + local group="${COMMAND_GROUP[$key]}" + local child_key="" + local rows="" + + [[ -z ${COMMAND_NAME[$key]} ]] || return + + while IFS= read -r child_key; do + [[ -n $child_key && $child_key != "$key" ]] || continue + rows+="$(command_usage_for_group "$child_key" "$group")"$'\t'$'\t'"${COMMAND_SUMMARY[$child_key]}"$'\n' + done < <(sorted_group_keys "$group" false) + + if [[ -n $rows ]]; then + echo "" + echo "Related commands:" + print_command_table "$rows" + fi +} + +show_command_help() { + local key="$1" + local aliases="${COMMAND_ALIASES[$key]}" + local examples="${COMMAND_EXAMPLES[$key]}" + local args="${COMMAND_ARGS[$key]}" + local example="" + local alias="" + + echo "Usage:" + echo " ${COMMAND_USAGE[$key]}" + echo "" + echo "${COMMAND_SUMMARY[$key]}" + + if [[ -n $args ]]; then + echo "" + echo "Arguments:" + echo " $args" + fi + + if [[ -n $examples ]]; then + echo "" + echo "Examples:" + while IFS= read -r example; do + printf ' %s\n' "$example" + done < <(examples_as_lines "$examples") + fi + + if [[ -n $aliases ]]; then + echo "" + echo "Aliases:" + while IFS= read -r alias; do + printf ' %s\n' "$alias" + done < <(pipe_values_as_lines "$aliases") + fi + + echo "" + echo "Binary:" + echo " ${COMMAND_BINARY[$key]}" + + if [[ ${COMMAND_FALLBACK_ROUTE[$key]} != "${COMMAND_ROUTE[$key]}" ]]; then + echo "" + echo "Filename route:" + echo " ${COMMAND_FALLBACK_ROUTE[$key]}" + fi + + show_related_commands "$key" +} + +resolve_route() { + local argc="$1" + shift + local args=("$@") + local prefix_count=0 + local route="" + local key="" + + for (( prefix_count = argc; prefix_count >= 1; prefix_count-- )); do + route="omarchy $(join_words " " "${args[@]:0:prefix_count}")" + key="${ROUTE_TO_KEY[$route]}" + + if [[ -n $key ]]; then + RESOLVED_KEY="$key" + RESOLVED_COUNT="$prefix_count" + RESOLVED_ROUTE="$route" + return 0 + fi + done + + return 1 +} + +suggest_command() { + local first="$1" + local candidate="" + + for candidate in "${!ROUTE_TO_KEY[@]}"; do + candidate="${candidate#omarchy }" + if [[ $candidate == "$first"* ]]; then + printf '%s' "${candidate%% *}" + return 0 + fi + done + + return 1 +} + +dispatch_fast_or_help() { + local args=("$@") + local remaining=() + local key="" + local binary_path="" + + if resolve_direct_route "$#" "${args[@]}"; then + remaining=("${args[@]:DIRECT_RESOLVED_COUNT}") + binary_path="$OMARCHY_BIN_DIR/$DIRECT_RESOLVED_BINARY" + + if (( ${#remaining[@]} > 0 )) && [[ ${remaining[0]} == "--help" || ${remaining[0]} == "-h" ]]; then + if ! load_command_by_binary "$DIRECT_RESOLVED_BINARY"; then + echo "Binary is missing or not executable: $DIRECT_RESOLVED_BINARY" >&2 + return 127 + fi + + if (( DIRECT_RESOLVED_COUNT == 1 )); then + load_child_commands_by_binary "$DIRECT_RESOLVED_BINARY" + fi + + key="${BINARY_TO_KEY[$DIRECT_RESOLVED_BINARY]}" + if [[ " ${remaining[*]} " == *" --json "* ]]; then + show_command_json "$key" + else + show_command_help "$key" + fi + return 0 + fi + + if (( ${#remaining[@]} == 0 )); then + load_command_by_binary "$DIRECT_RESOLVED_BINARY" + key="${BINARY_TO_KEY[$DIRECT_RESOLVED_BINARY]}" + + if [[ -n $key ]] && command_requires_args "$key"; then + if (( DIRECT_RESOLVED_COUNT == 1 )) && group_has_child_commands "$1"; then + load_group_commands "$1" + show_group_help "$1" + else + show_command_help "$key" + fi + return 0 + fi + fi + + exec "$binary_path" "${remaining[@]}" + fi + + if (( $# == 1 )) && group_has_binary_commands "$1"; then + load_group_commands "$1" + show_group_help "$1" + return 0 + fi + + if (( $# >= 2 )) && [[ $2 == "--help" || $2 == "-h" ]] && group_has_binary_commands "$1"; then + load_group_commands "$1" + show_group_help "$1" + return 0 + fi + + load_commands + dispatch_or_help "$@" +} + +dispatch_or_help() { + local args=("$@") + local remaining=() + local key="" + local binary_path="" + local suggestion="" + + if resolve_route "$#" "${args[@]}"; then + key="$RESOLVED_KEY" + remaining=("${args[@]:RESOLVED_COUNT}") + + if (( ${#remaining[@]} > 0 )) && [[ ${remaining[0]} == "--help" || ${remaining[0]} == "-h" ]]; then + if [[ " ${remaining[*]} " == *" --json "* ]]; then + show_command_json "$key" + else + show_command_help "$key" + fi + return 0 + fi + + binary_path="$OMARCHY_BIN_DIR/${COMMAND_BINARY[$key]}" + if [[ ! -x $binary_path ]]; then + echo "Binary is missing or not executable: ${COMMAND_BINARY[$key]}" >&2 + return 127 + fi + + if (( ${#remaining[@]} == 0 )) && command_requires_args "$key"; then + if (( RESOLVED_COUNT == 1 )) && group_exists "$1"; then + show_group_help "$1" + else + show_command_help "$key" + fi + return 0 + fi + + exec "$binary_path" "${remaining[@]}" + fi + + if (( $# == 1 )) && group_exists "$1"; then + show_group_help "$1" + return 0 + fi + + if (( $# >= 2 )) && [[ $2 == "--help" || $2 == "-h" ]] && group_exists "$1"; then + show_group_help "$1" + return 0 + fi + + echo "Unknown Omarchy command: omarchy ${args[*]}" >&2 + suggestion=$(suggest_command "${args[0]}") + if [[ -n $suggestion ]]; then + echo "Did you mean: omarchy $suggestion ?" >&2 + fi + echo "Run 'omarchy commands --all' to discover available commands." >&2 + return 127 +} + +main() { + if (( $# == 0 )); then + show_main_help + return 0 + fi + + case "$1" in + --help | -h) + show_main_help + ;; + commands) + load_commands + parse_commands_args "$@" + ;; + *) + dispatch_fast_or_help "$@" + ;; + esac +} + +main "$@" diff --git a/bin/omarchy-ac-present b/bin/omarchy-ac-present index a2f632a9..df205ae8 100755 --- a/bin/omarchy-ac-present +++ b/bin/omarchy-ac-present @@ -1,6 +1,6 @@ #!/bin/bash -# Returns true if AC power is connected. +# omarchy:summary=Returns true if AC power is connected. for ac in /sys/class/power_supply/AC* /sys/class/power_supply/ADP*; do [[ -r $ac/online && $(cat "$ac/online") == "1" ]] && exit 0 diff --git a/bin/omarchy-audio-input-mute b/bin/omarchy-audio-input-mute new file mode 100755 index 00000000..19e12f23 --- /dev/null +++ b/bin/omarchy-audio-input-mute @@ -0,0 +1,21 @@ +#!/bin/bash + +# omarchy:summary=Toggle microphone mute. Drives the hardware mic-mute LED on laptops that expose one. + +wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle >/dev/null + +if pactl get-source-mute @DEFAULT_SOURCE@ | rg -q 'yes'; then + led=on + osd_message='Microphone muted' + osd_icon='microphone-sensitivity-muted-symbolic' +else + led=off + osd_message='Microphone on' + osd_icon='audio-input-microphone-symbolic' +fi + +omarchy-brightness-keyboard-mute "$led" + +omarchy-swayosd-client \ + --custom-message "$osd_message" \ + --custom-icon "$osd_icon" diff --git a/bin/omarchy-cmd-audio-switch b/bin/omarchy-audio-output-switch similarity index 95% rename from bin/omarchy-cmd-audio-switch rename to bin/omarchy-audio-output-switch index 7d1ea015..f5f94d44 100755 --- a/bin/omarchy-cmd-audio-switch +++ b/bin/omarchy-audio-output-switch @@ -1,6 +1,6 @@ #!/bin/bash -# Switch between audio outputs while preserving the mute status. By default mapped to Super + Mute. +# omarchy:summary=Switch between audio outputs while preserving the mute status. By default mapped to Super + Mute. sinks=$(pactl -f json list sinks | jq '[.[] | select((.ports | length == 0) or ([.ports[]? | .availability != "not available"] | any))]') sinks_count=$(echo "$sinks" | jq '. | length') diff --git a/bin/omarchy-battery-capacity b/bin/omarchy-battery-capacity index fa4b4c03..10e54794 100755 --- a/bin/omarchy-battery-capacity +++ b/bin/omarchy-battery-capacity @@ -1,7 +1,6 @@ #!/bin/bash -# Returns the battery full capacity in Wh (rounded to whole number). -# Used by omarchy-battery-status for displaying battery capacity. +# omarchy:summary=Returns the battery full capacity in Wh (rounded to whole number). battery_info=$(upower -i $(upower -e | grep BAT)) diff --git a/bin/omarchy-battery-monitor b/bin/omarchy-battery-monitor index 6b348b11..63b33277 100755 --- a/bin/omarchy-battery-monitor +++ b/bin/omarchy-battery-monitor @@ -1,6 +1,6 @@ #!/bin/bash -# Designed to be run by systemd timer every 30 seconds and alerts if battery is low +# omarchy:summary=Designed to be run by systemd timer every 30 seconds and alerts if battery is low BATTERY_THRESHOLD=10 NOTIFICATION_FLAG="/run/user/$UID/omarchy_battery_notified" diff --git a/bin/omarchy-battery-present b/bin/omarchy-battery-present index 2b052a7a..fb221e8c 100755 --- a/bin/omarchy-battery-present +++ b/bin/omarchy-battery-present @@ -1,7 +1,6 @@ #!/bin/bash -# Returns true if a battery is present on the system. -# Used by the battery monitor and other battery-related checks. +# omarchy:summary=Returns true if a battery is present on the system. for bat in /sys/class/power_supply/BAT*; do [[ -r $bat/present ]] && diff --git a/bin/omarchy-battery-remaining b/bin/omarchy-battery-remaining index 26ea718f..d9b451f2 100755 --- a/bin/omarchy-battery-remaining +++ b/bin/omarchy-battery-remaining @@ -1,7 +1,6 @@ #!/bin/bash -# Returns the battery percentage remaining as an integer. -# Used by the battery monitor and the Ctrl + Shift + Super + B hotkey. +# omarchy:summary=Returns the battery percentage remaining as an integer. upower -i $(upower -e | grep BAT) | awk '/percentage/ { print int($2) diff --git a/bin/omarchy-battery-remaining-time b/bin/omarchy-battery-remaining-time index c4f39593..7aa77b11 100755 --- a/bin/omarchy-battery-remaining-time +++ b/bin/omarchy-battery-remaining-time @@ -1,6 +1,6 @@ #!/bin/bash -# Returns the battery time remaining (to empty or full) in a compact format. +# omarchy:summary=Returns the battery time remaining (to empty or full) in a compact format. battery_info=$(upower -i $(upower -e | grep BAT)) diff --git a/bin/omarchy-battery-status b/bin/omarchy-battery-status index 021c0aa4..0390df1f 100755 --- a/bin/omarchy-battery-status +++ b/bin/omarchy-battery-status @@ -1,7 +1,6 @@ #!/bin/bash -# Returns a formatted battery status string with percentage and power draw/charge. -# Used by the battery notification hotkey (Ctrl + Shift + Super + B). +# omarchy:summary=Returns a formatted battery status string with percentage and power draw/charge. battery_info=$(upower -i $(upower -e | grep BAT)) diff --git a/bin/omarchy-branch-set b/bin/omarchy-branch-set index 87d19bda..931bca25 100755 --- a/bin/omarchy-branch-set +++ b/bin/omarchy-branch-set @@ -1,6 +1,7 @@ #!/bin/bash -# Set the branch for Omarchy's git repository. +# omarchy:summary=Set the branch for Omarchy's git repository. +# omarchy:args= if (($# == 0)); then echo "Usage: omarchy-branch-set [master|rc|dev]" diff --git a/bin/omarchy-brightness-display b/bin/omarchy-brightness-display index 493265d4..558a47de 100755 --- a/bin/omarchy-brightness-display +++ b/bin/omarchy-brightness-display @@ -1,10 +1,15 @@ #!/bin/bash -# Adjust brightness on the most likely display device. -# Usage: omarchy-brightness-display +# omarchy:summary=Adjust brightness on the most likely display device. +# omarchy:args= step="${1:-+5%}" +if omarchy-hyprland-monitor-focused-apple; then + omarchy-brightness-display-apple "$step" + exit +fi + # 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 @@ -14,6 +19,31 @@ for candidate in amdgpu_bl* intel_backlight acpi_video*; do fi done +# Current brightness percentage +current=$(brightnessctl -d "$device" -m | cut -d',' -f4 | tr -d '%') + +# Apply non-uniform step size: 1% steps if at or below 5%, otherwise set an +# absolute target percentage to avoid raw backlight rounding causing uneven OSD steps. +if [[ $step == "+5%" ]]; then + if (( current < 5 )); then + (( target = current + 1 )) + else + (( target = current + 5 )) + fi + + (( target > 100 )) && target=100 + step="$target%" +elif [[ $step == "5%-" ]]; then + if (( current <= 5 )); then + (( target = current - 1 )) + else + (( target = current - 5 )) + fi + + (( target < 1 )) && target=1 + step="$target%" +fi + # Set the actual brightness of the display device. brightnessctl -d "$device" set "$step" >/dev/null diff --git a/bin/omarchy-brightness-display-apple b/bin/omarchy-brightness-display-apple index 64006820..28c9e2ea 100755 --- a/bin/omarchy-brightness-display-apple +++ b/bin/omarchy-brightness-display-apple @@ -1,12 +1,32 @@ #!/bin/bash -# Adjust the brightness on Apple Studio Displays and Apple XDR Displays using asdcontrol. +# omarchy:summary=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)" + echo "Adjust Apple Display brightness by passing +5%, 5%-, or 100%" else - device="$(sudo asdcontrol --detect /dev/usb/hiddev* | grep ^/dev/usb/hiddev | cut -d: -f1)" - sudo asdcontrol "$device" -- "$1" >/dev/null + step="$1" + if [[ $step =~ ^([0-9]+)%-$ ]]; then + step="-${BASH_REMATCH[1]}%" + fi + + devices=() + for path in /dev/usb/hiddev* /dev/hiddev*; do + [[ -e $path ]] && devices+=("$path") + done + + if (( ${#devices[@]} == 0 )); then + echo "No Apple Display HID device found" + exit 1 + fi + + device="$(sudo asdcontrol --detect "${devices[@]}" | grep -E '^/dev/(usb/)?hiddev' | cut -d: -f1 | head -n1)" + if [[ -z $device ]]; then + echo "No Apple Display HID device found" + exit 1 + fi + + sudo asdcontrol "$device" -- "$step" >/dev/null value="$(sudo asdcontrol "$device" | awk -F= '/BRIGHTNESS=/{print $2+0}')" omarchy-swayosd-brightness "$(( value * 100 / 60000 ))" fi diff --git a/bin/omarchy-brightness-keyboard b/bin/omarchy-brightness-keyboard index 7e7e738b..f161da47 100755 --- a/bin/omarchy-brightness-keyboard +++ b/bin/omarchy-brightness-keyboard @@ -1,7 +1,7 @@ #!/bin/bash -# Adjust keyboard backlight brightness using available steps. -# Usage: omarchy-brightness-keyboard +# omarchy:summary=Adjust keyboard backlight brightness using available steps. +# omarchy:args= direction="${1:-up}" diff --git a/bin/omarchy-brightness-keyboard-mute b/bin/omarchy-brightness-keyboard-mute new file mode 100755 index 00000000..65f73264 --- /dev/null +++ b/bin/omarchy-brightness-keyboard-mute @@ -0,0 +1,14 @@ +#!/bin/bash + +# omarchy:summary=Set the mic-mute indicator LED on laptops that expose a platform::micmute LED node. +# omarchy:args= + +if [[ -e /sys/class/leds/platform::micmute/brightness ]]; then + case "$1" in + on) value=1 ;; + off) value=0 ;; + *) echo "Usage: $(basename "$0") " >&2; exit 1 ;; + esac + + brightnessctl --device="platform::micmute" set "$value" >/dev/null 2>&1 || true +fi diff --git a/bin/omarchy-capture-screenrecording b/bin/omarchy-capture-screenrecording new file mode 100755 index 00000000..5636bb9e --- /dev/null +++ b/bin/omarchy-capture-screenrecording @@ -0,0 +1,294 @@ +#!/bin/bash + +# omarchy:summary=Start or stop screen recording +# omarchy:group=capture +# omarchy:args=[--with-desktop-audio] [--with-microphone-audio] [--with-webcam] [--webcam-device=] [--resolution=] [--stop-recording] +# omarchy:examples=omarchy screenrecord | omarchy capture screenrecord --with-desktop-audio +# omarchy:aliases=omarchy screenrecord +# +# Env: OMARCHY_SCREENRECORD_USE_PORTAL=true skips the built-in slurp picker and +# uses gpu-screen-recorder's xdg-desktop-portal capture backend instead. The +# portal backend was originally added (PR #3401) for HDR-aware capture, support +# for monitors driven by external GPUs, and window capture — enable it if any +# of those matter to you. Off by default because the portal path can fail EGL +# DMA-BUF modifier import on some configurations, leaving recording unable to +# start. +# +# Env: OMARCHY_SCREENRECORD_DEBUG=true appends gpu-screen-recorder's stderr (and +# the picker target it was launched with) to /tmp/omarchy-screenrecord.log so +# users can attach a log when reporting capture failures. + +[[ -f ~/.config/user-dirs.dirs ]] && source ~/.config/user-dirs.dirs +OUTPUT_DIR="${OMARCHY_SCREENRECORD_DIR:-${XDG_VIDEOS_DIR:-$HOME/Videos}}" + +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" +WEBCAM="false" +WEBCAM_DEVICE="" +RESOLUTION="" +STOP_RECORDING="false" +RECORDING_FILE="/tmp/omarchy-screenrecord-filename" +LOG_FILE=$([[ ${OMARCHY_SCREENRECORD_DEBUG:-false} == "true" ]] && echo "/tmp/omarchy-screenrecord.log" || echo "/dev/null") + +for arg in "$@"; do + case "$arg" in + --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" ;; + esac +done + +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') + + # Target width (base 360px, scaled to monitor) + local target_width=$(awk "BEGIN {printf \"%.0f\", 360 * $scale}") + + # Try preferred 16:9 resolutions in order, use first available + local preferred_resolutions=("640x360" "1280x720" "1920x1080") + local video_size_arg="" + local available_formats=$(v4l2-ctl --list-formats-ext -d "$WEBCAM_DEVICE" 2>/dev/null) + + for resolution in "${preferred_resolutions[@]}"; do + if echo "$available_formats" | grep -q "$resolution"; then + video_size_arg="-video_size $resolution" + break + fi + done + + ffplay -f v4l2 $video_size_arg -framerate 30 "$WEBCAM_DEVICE" \ + -vf "crop=iw/2:ih,scale=${target_width}:-1" \ + -window_title "WebcamOverlay" \ + -noborder \ + -fflags nobuffer -flags low_delay \ + -probesize 32 -analyzeduration 0 \ + -loglevel quiet & + 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 +} + +# Monitor + window rectangles on the focused workspace, in slurp's "X,Y WxH" format. +# Mirrors omarchy-capture-screenshot so the picker UX is identical. +get_rectangles() { + local active_workspace=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .activeWorkspace.id') + hyprctl monitors -j | jq -r --arg ws "$active_workspace" ' + .[] | select(.activeWorkspace.id == ($ws | tonumber)) | + "\(.x),\(.y) \(.width / .scale | floor)x\(.height / .scale | floor)"' + hyprctl clients -j | jq -r --arg ws "$active_workspace" ' + .[] | select(.workspace.id == ($ws | tonumber)) | + "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"' +} + +# Echoes "monitor:NAME" when the selection matches an entire monitor, otherwise +# "region:WxH+X+Y" with physical-pixel coordinates ready for gpu-screen-recorder. +# Returns non-zero if the user cancelled the picker. +select_capture_target() { + local rects=$(get_rectangles) + hyprpicker -r -z >/dev/null 2>&1 & + local picker_pid=$! + sleep .1 + local selection=$(echo "$rects" | slurp 2>/dev/null) + kill $picker_pid 2>/dev/null + + # X and Y can be negative (Hyprland monitor positions in multi-display layouts); + # widths and heights are always positive. + [[ $selection =~ ^(-?[0-9]+),(-?[0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]] || return 1 + local sx=${BASH_REMATCH[1]} sy=${BASH_REMATCH[2]} + local sw=${BASH_REMATCH[3]} sh=${BASH_REMATCH[4]} + + # A bare click (area < 20px²) snaps to whichever rectangle the click landed + # inside, so users don't end up with accidental 2px recordings. + if ((sw * sh < 20)); then + while IFS= read -r rect; do + [[ $rect =~ ^(-?[0-9]+),(-?[0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]] || continue + local rx=${BASH_REMATCH[1]} ry=${BASH_REMATCH[2]} + local rw=${BASH_REMATCH[3]} rh=${BASH_REMATCH[4]} + if ((sx >= rx && sx < rx + rw && sy >= ry && sy < ry + rh)); then + sx=$rx sy=$ry sw=$rw sh=$rh + break + fi + done <<<"$rects" + fi + + # When the selection exactly matches a monitor, prefer -w over a + # region capture — same kms backend, but no scaling math and full native res. + local monitor=$(hyprctl monitors -j | jq -r --argjson x "$sx" --argjson y "$sy" --argjson w "$sw" --argjson h "$sh" ' + .[] | select(.x == $x and .y == $y and (.width / .scale | floor) == $w and (.height / .scale | floor) == $h) | .name' | head -1) + + if [[ -n $monitor ]]; then + echo "monitor:$monitor" + return + fi + + # gpu-screen-recorder wants region geometry in the compositor's logical + # coordinate space — same space slurp returns — so pass the values through + # untouched. (gsr scales to physical pixels itself based on the monitor.) + echo "region:${sw}x${sh}+${sx}+${sy}" +} + +start_screenrecording() { + local capture_args=() + local target + + # Opt-in path for HDR, external-GPU monitors, and window capture (all things + # the portal backend supports and the kms backend doesn't). Default flow uses + # slurp + the kms backend, which avoids the EGL DMA-BUF modifier import + # failures the portal path can hit on some configurations. + if [[ ${OMARCHY_SCREENRECORD_USE_PORTAL:-false} == "true" ]]; then + target="portal" + capture_args=(-w portal -s "${RESOLUTION:-$(default_resolution)}") + else + target=$(select_capture_target) || return 1 + + case $target in + monitor:*) + capture_args=(-w "${target#monitor:}" -s "${RESOLUTION:-$(default_resolution)}") + ;; + region:*) + capture_args=(-w "${target#region:}") + [[ -n $RESOLUTION ]] && capture_args+=(-s "$RESOLUTION") + ;; + esac + fi + + [[ $WEBCAM == "true" ]] && start_webcam_overlay + + local filename="$OUTPUT_DIR/screenrecording-$(date +'%Y-%m-%d_%H-%M-%S').mp4" + local audio_devices="" + local audio_args=() + + [[ $DESKTOP_AUDIO == "true" ]] && audio_devices+="default_output" + + 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) + + echo "===== $(date '+%F %T') args: $* target: $target =====" >>"$LOG_FILE" + gpu-screen-recorder "${capture_args[@]}" -k auto -f 60 -fm cfr -fallback-cpu-encoding yes -o "$filename" "${audio_args[@]}" 2>>"$LOG_FILE" & + local pid=$! + + 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 +} + +stop_screenrecording() { + 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 + 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" + notify-send "Screen recording error" "Recording process had to be force-killed. Video may be corrupted." -u critical -t 5000 + else + finalize_recording + local filename=$(cat "$RECORDING_FILE" 2>/dev/null) + local preview="${filename%.mp4}-preview.png" + + # Generate a preview thumbnail from the first frame + ffmpeg -y -i "$filename" -ss 00:00:00.1 -vframes 1 -q:v 2 "$preview" -loglevel quiet 2>/dev/null + + ( + ACTION=$(notify-send "Screen recording saved" "Open with Super + Alt + , (or click this)" -t 10000 -i "${preview:-$filename}" -A "default=open") + [[ $ACTION == "default" ]] && mpv "$filename" + rm -f "$preview" + ) & + fi + + rm -f "$RECORDING_FILE" +} + +toggle_screenrecording_indicator() { + pkill -RTMIN+8 waybar +} + +screenrecording_active() { + pgrep -f "^gpu-screen-recorder" >/dev/null +} + +finalize_recording() { + local latest + latest=$(cat "$RECORDING_FILE" 2>/dev/null) + [[ -f $latest ]] || return + + # Re-encode only when the first GOP contains discardable warmup packets — stream copy can't + # trim those (it rewinds to the keyframe). Clean recordings stay on the fast stream-copy path. + local video_codec=(-c:v copy) + if ffprobe -v error -select_streams v:0 -read_intervals %+0.2 -show_entries packet=flags -of csv=p=0 "$latest" 2>/dev/null | grep -q D; then + video_codec=(-c:v libx264 -preset veryfast -crf 20) + fi + + # Trim the first frame, and normalize audio to -14 LUFS if present, in a single pass + local args=(-y -ss 0.1 -i "$latest" "${video_codec[@]}") + if ffprobe -v error -select_streams a -show_entries stream=codec_type -of csv=p=0 "$latest" 2>/dev/null | grep -q audio; then + # Hard-mute the first 400ms to drop the PipeWire capture-open pop (a near-clipping + # transient around 130-200ms that a gentle fade-in can't attenuate enough), then a + # 50ms fade avoids a click at the boundary before loudnorm normalizes the rest. + args+=(-af "volume=enable='lt(t,0.4)':volume=0,afade=t=in:st=0.4:d=0.05,loudnorm=I=-14:TP=-1.5:LRA=11") + fi + + local processed="${latest%.mp4}-processed.mp4" + if ffmpeg "${args[@]}" "$processed" -loglevel quiet 2>/dev/null; then + mv "$processed" "$latest" + else + rm -f "$processed" + fi +} + +if screenrecording_active; then + stop_screenrecording +elif [[ $STOP_RECORDING == "true" ]]; then + exit 1 +else + start_screenrecording || cleanup_webcam +fi diff --git a/bin/omarchy-cmd-screenshot b/bin/omarchy-capture-screenshot similarity index 88% rename from bin/omarchy-cmd-screenshot rename to bin/omarchy-capture-screenshot index 9036c995..627eda07 100755 --- a/bin/omarchy-cmd-screenshot +++ b/bin/omarchy-capture-screenshot @@ -1,8 +1,10 @@ #!/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= or OMARCHY_SCREENSHOT_EDITOR env +# omarchy:summary=Take a screenshot +# omarchy:group=capture +# omarchy:args=[smart|region|windows|fullscreen] [slurp|copy] [--editor=] +# omarchy:examples=omarchy screenshot | omarchy capture screenshot region +# omarchy:aliases=omarchy screenshot [[ -f ~/.config/user-dirs.dirs ]] && source ~/.config/user-dirs.dirs OUTPUT_DIR="${OMARCHY_SCREENSHOT_DIR:-${XDG_PICTURES_DIR:-$HOME/Pictures}}" @@ -63,6 +65,13 @@ get_rectangles() { hyprctl clients -j | jq -r --arg ws "$active_workspace" '.[] | select(.workspace.id == ($ws | tonumber)) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"' } +# Keep hyprpicker alive until after grim captures so the screenshot sees the +# frozen overlay rather than live content shifting during teardown. +cleanup_freeze() { + [[ -n $PID ]] && kill $PID 2>/dev/null +} +trap cleanup_freeze EXIT + # Select based on mode case "$MODE" in region) @@ -70,14 +79,12 @@ region) PID=$! sleep .1 SELECTION=$(slurp 2>/dev/null) - kill $PID 2>/dev/null ;; windows) hyprpicker -r -z >/dev/null 2>&1 & 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") @@ -88,7 +95,6 @@ smart | *) 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 diff --git a/bin/omarchy-capture-text-extraction b/bin/omarchy-capture-text-extraction new file mode 100755 index 00000000..cb0c62b5 --- /dev/null +++ b/bin/omarchy-capture-text-extraction @@ -0,0 +1,26 @@ +#!/bin/bash + +# omarchy:summary=Extract text from a screenshot region with OCR +# omarchy:group=capture +# omarchy:examples=omarchy capture ocr + +# Keep hyprpicker alive until after grim captures so the screenshot sees the +# frozen overlay rather than live content shifting during teardown. +cleanup_freeze() { + [[ -n $PID ]] && kill $PID 2>/dev/null +} +trap cleanup_freeze EXIT + +hyprpicker -r -z >/dev/null 2>&1 & +PID=$! +sleep .1 +SELECTION=$(slurp 2>/dev/null) + +[[ -z $SELECTION ]] && exit 0 + +TEXT=$(grim -g "$SELECTION" - | tesseract stdin stdout --oem 1 --psm 6 -l eng --dpi 300 -c preserve_interword_spaces=1 2>/dev/null) || exit 1 + +[[ -z $TEXT ]] && exit 1 + +printf "%s" "$TEXT" | wl-copy +notify-send "󰴑 Copied text from selection to clipboard" diff --git a/bin/omarchy-channel-set b/bin/omarchy-channel-set index 8494f973..b6c15d71 100755 --- a/bin/omarchy-channel-set +++ b/bin/omarchy-channel-set @@ -1,17 +1,8 @@ #!/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. +# omarchy:summary=Set the Omarchy channel, which dictates what git branch and package repository is used. +# omarchy:args= +# omarchy:requires-sudo=true if (($# == 0)); then echo "Usage: omarchy-channel-set [stable|rc|edge|dev]" diff --git a/bin/omarchy-cmd-mic-mute b/bin/omarchy-cmd-mic-mute deleted file mode 100755 index 3931d0b8..00000000 --- a/bin/omarchy-cmd-mic-mute +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# Toggle microphone mute. Dell XPS and ThinkPad systems get special handling for the hardware LED. - -if omarchy-hw-match "XPS"; then - omarchy-cmd-mic-mute-xps -elif omarchy-hw-match "ThinkPad"; then - omarchy-cmd-mic-mute-thinkpad -else - omarchy-swayosd-client --input-volume mute-toggle -fi diff --git a/bin/omarchy-cmd-mic-mute-thinkpad b/bin/omarchy-cmd-mic-mute-thinkpad deleted file mode 100755 index a6e551a7..00000000 --- a/bin/omarchy-cmd-mic-mute-thinkpad +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# Toggle microphone mute on ThinkPad systems. Uses wpctl for reliable toggling -# and syncs the platform::micmute LED via brightnessctl. - -wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle >/dev/null - -if pactl get-source-mute @DEFAULT_SOURCE@ | grep -q 'yes'; then - osd_message='Microphone muted' - osd_icon='microphone-sensitivity-muted-symbolic' - led_value=1 -else - osd_message='Microphone on' - osd_icon='audio-input-microphone-symbolic' - led_value=0 -fi - -brightnessctl --device="platform::micmute" set "$led_value" >/dev/null 2>&1 || true - -swayosd-client \ - --monitor "$(omarchy-hyprland-monitor-focused)" \ - --custom-message "$osd_message" \ - --custom-icon "$osd_icon" diff --git a/bin/omarchy-cmd-mic-mute-xps b/bin/omarchy-cmd-mic-mute-xps deleted file mode 100755 index 16b2da19..00000000 --- a/bin/omarchy-cmd-mic-mute-xps +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Toggle microphone mute on Dell XPS systems. Uses wpctl for reliable toggling -# and syncs the ALSA capture switch so the hardware mic mute LED follows state. - -wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle >/dev/null - -if pactl get-source-mute @DEFAULT_SOURCE@ | rg -q 'yes'; then - alsa_value='off,off' - osd_message='Microphone muted' - osd_icon='microphone-sensitivity-muted-symbolic' -else - alsa_value='on,on' - osd_message='Microphone on' - osd_icon='audio-input-microphone-symbolic' -fi - -if [[ -e /sys/class/leds/platform::micmute/brightness ]]; then - default_source=$(pactl get-default-source) - alsa_card=$(pactl -f json list sources | jq -r --arg source "$default_source" ' - .[] | select(.name == $source) | - .properties["alsa.card"] // .properties["api.alsa.card"] // .properties["api.alsa.pcm.card"] // empty - ' | head -1) - - if [[ -n $alsa_card ]]; then - cards=("$alsa_card") - else - mapfile -t cards < <(compgen -G '/proc/asound/card*' | rg -o 'card[0-9]+' | sed 's/card//' | sort -u) - fi - - for card in "${cards[@]}"; do - while IFS= read -r control; do - if [[ $control != *"Jack Microphone"* ]]; then - amixer -c "$card" cset "$control" "$alsa_value" >/dev/null 2>&1 || true - break 2 - fi - done < <(amixer -c "$card" controls 2>/dev/null | rg -o "name='[^']*Microphone Capture Switch'") - done -fi - -omarchy-swayosd-client \ - --custom-message "$osd_message" \ - --custom-icon "$osd_icon" diff --git a/bin/omarchy-cmd-missing b/bin/omarchy-cmd-missing index 6f14ec29..470d69c3 100755 --- a/bin/omarchy-cmd-missing +++ b/bin/omarchy-cmd-missing @@ -1,6 +1,6 @@ #!/bin/bash -# Returns true if any of the commands passed in as arguments are missing on the system. +# omarchy:summary=Check whether any required commands are missing for cmd in "$@"; do if ! command -v "$cmd" &>/dev/null; then diff --git a/bin/omarchy-cmd-present b/bin/omarchy-cmd-present index f1e96be2..4e758760 100755 --- a/bin/omarchy-cmd-present +++ b/bin/omarchy-cmd-present @@ -1,6 +1,6 @@ #!/bin/bash -# Returns true if all the commands passed in as arguments exit on the system. +# omarchy:summary=Check whether all required commands are available for cmd in "$@"; do command -v "$cmd" &>/dev/null || exit 1 diff --git a/bin/omarchy-cmd-screenrecord b/bin/omarchy-cmd-screenrecord deleted file mode 100755 index 1e45d4ab..00000000 --- a/bin/omarchy-cmd-screenrecord +++ /dev/null @@ -1,191 +0,0 @@ -#!/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 - notify-send "Screen recording directory does not exist: $OUTPUT_DIR" -u critical -t 3000 - exit 1 -fi - -DESKTOP_AUDIO="false" -MICROPHONE_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" ;; - esac -done - -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') - - # Target width (base 360px, scaled to monitor) - local target_width=$(awk "BEGIN {printf \"%.0f\", 360 * $scale}") - - # Try preferred 16:9 resolutions in order, use first available - local preferred_resolutions=("640x360" "1280x720" "1920x1080") - local video_size_arg="" - local available_formats=$(v4l2-ctl --list-formats-ext -d "$WEBCAM_DEVICE" 2>/dev/null) - - for resolution in "${preferred_resolutions[@]}"; do - if echo "$available_formats" | grep -q "$resolution"; then - video_size_arg="-video_size $resolution" - break - fi - done - - ffplay -f v4l2 $video_size_arg -framerate 30 "$WEBCAM_DEVICE" \ - -vf "crop=iw/2:ih,scale=${target_width}:-1" \ - -window_title "WebcamOverlay" \ - -noborder \ - -fflags nobuffer -flags low_delay \ - -probesize 32 -analyzeduration 0 \ - -loglevel quiet & - 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=() - - [[ $DESKTOP_AUDIO == "true" ]] && audio_devices+="default_output" - - 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 -} - -stop_screenrecording() { - 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 - 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" - notify-send "Screen recording error" "Recording process had to be force-killed. Video may be corrupted." -u critical -t 5000 - else - finalize_recording - local filename=$(cat "$RECORDING_FILE" 2>/dev/null) - local preview="${filename%.mp4}-preview.png" - - # Generate a preview thumbnail from the first frame - ffmpeg -y -i "$filename" -ss 00:00:00.1 -vframes 1 -q:v 2 "$preview" -loglevel quiet 2>/dev/null - - ( - ACTION=$(notify-send "Screen recording saved" "Open with Super + Alt + , (or click this)" -t 10000 -i "${preview:-$filename}" -A "default=open") - [[ $ACTION == "default" ]] && mpv "$filename" - rm -f "$preview" - ) & - fi - - rm -f "$RECORDING_FILE" -} - -toggle_screenrecording_indicator() { - pkill -RTMIN+8 waybar -} - -screenrecording_active() { - pgrep -f "^gpu-screen-recorder" >/dev/null -} - -finalize_recording() { - local latest - latest=$(cat "$RECORDING_FILE" 2>/dev/null) - [[ -f $latest ]] || return - - # Trim the first frame, and normalize audio to -14 LUFS if present, in a single pass - local args=(-y -ss 0.1 -i "$latest") - if ffprobe -v error -select_streams a -show_entries stream=codec_type -of csv=p=0 "$latest" 2>/dev/null | grep -q audio; then - args+=(-af loudnorm=I=-14:TP=-1.5:LRA=11 -c:v copy) - else - args+=(-c copy) - fi - - local processed="${latest%.mp4}-processed.mp4" - if ffmpeg "${args[@]}" "$processed" -loglevel quiet 2>/dev/null; then - mv "$processed" "$latest" - else - rm -f "$processed" - fi -} - -if screenrecording_active; then - stop_screenrecording -elif [[ $STOP_RECORDING == "true" ]]; then - exit 1 -else - [[ $WEBCAM == "true" ]] && start_webcam_overlay - - start_screenrecording || cleanup_webcam -fi diff --git a/bin/omarchy-cmd-terminal-cwd b/bin/omarchy-cmd-terminal-cwd index 81fb91c2..d0f731a4 100755 --- a/bin/omarchy-cmd-terminal-cwd +++ b/bin/omarchy-cmd-terminal-cwd @@ -1,9 +1,7 @@ #!/bin/bash -# Returns the current working directory of the active terminal window, -# so a new terminal window can be started in the same directory. +# omarchy:summary=Print the current working directory of the active terminal window -# 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) diff --git a/bin/omarchy-config-direct-boot b/bin/omarchy-config-direct-boot index 6bb82123..ebd618b9 100755 --- a/bin/omarchy-config-direct-boot +++ b/bin/omarchy-config-direct-boot @@ -1,7 +1,7 @@ #!/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. +# omarchy:summary=Add or remove an EFI boot entry for the Omarchy UKI, allowing the system to boot directly +# omarchy:requires-sudo=true if [[ ! -d /sys/firmware/efi ]]; then echo "Error: System is not booted in UEFI mode" >&2 @@ -23,23 +23,36 @@ if cat /sys/class/dmi/id/bios_vendor 2>/dev/null | grep -qi "Apple"; then exit 1 fi -uki_file=$(find /boot/EFI/Linux/ -name "omarchy*.efi" -printf "%f\n" 2>/dev/null | head -1) +existing_entry=$(efibootmgr | grep -E "^Boot[0-9A-Fa-f]+\*? Omarchy([[:space:]]|$)" | head -1) -if [[ -z $uki_file ]]; then - echo "Error: No Omarchy UKI found in /boot/EFI/Linux/" >&2 - exit 1 -fi +if [[ -n $existing_entry ]]; then + boot_num=$(echo "$existing_entry" | sed -n 's/^Boot\([0-9A-Fa-f]\+\).*/\1/p') -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 "Disable direct boot (remove Omarchy EFI entry)?"; then + echo "Removing EFI boot entry $boot_num" + sudo efibootmgr --bootnum "$boot_num" --delete-bootnum >/dev/null + fi -if gum confirm "Setup direct boot (so snapshot booting must be done via bios)?"; then - echo "Creating EFI boot entry for $uki_file" + exit 0 +else + uki_file=$(find /boot/EFI/Linux/ -name "omarchy*.efi" -printf "%f\n" 2>/dev/null | head -1) - sudo efibootmgr --create \ - --disk "$disk" \ - --part "$part" \ - --label "Omarchy" \ - --loader "\\EFI\\Linux\\$uki_file" + 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 fi diff --git a/bin/omarchy-debug b/bin/omarchy-debug index 23b6630d..830caa1b 100755 --- a/bin/omarchy-debug +++ b/bin/omarchy-debug @@ -1,6 +1,9 @@ #!/bin/bash -# Return exhaustive debugging information about the system to help diagnose problems. +# omarchy:summary=Print debugging information +# omarchy:args=[--no-sudo] [--print] +# omarchy:examples=omarchy debug --print --no-sudo +# omarchy:requires-sudo=true NO_SUDO=false PRINT_ONLY=false diff --git a/bin/omarchy-dev-add-migration b/bin/omarchy-dev-add-migration index 3ca47a2f..bff94502 100755 --- a/bin/omarchy-dev-add-migration +++ b/bin/omarchy-dev-add-migration @@ -1,7 +1,6 @@ #!/bin/bash -# Creates a new Omarchy migration named after the unix timestamp of the last commit. -# Only intended for Omarchy developers. +# omarchy:summary=Creates a new Omarchy migration named after the unix timestamp of the last commit. cd ~/.local/share/omarchy migration_file="$HOME/.local/share/omarchy/migrations/$(git log -1 --format=%cd --date=unix).sh" diff --git a/bin/omarchy-dev-benchmark b/bin/omarchy-dev-benchmark new file mode 100755 index 00000000..1108e798 --- /dev/null +++ b/bin/omarchy-dev-benchmark @@ -0,0 +1,111 @@ +#!/bin/bash + +# omarchy:summary=Measure Omarchy CLI response times +# omarchy:args=[--repeat=] +# omarchy:examples=omarchy dev benchmark | omarchy dev benchmark --repeat=10 + +set -euo pipefail + +OMARCHY_BIN_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +CLI="$OMARCHY_BIN_DIR/omarchy" +REPEAT=5 + +show_help() { + cat <<'EOF' +Usage: + omarchy dev benchmark [--repeat=] + +Measure response times for common Omarchy CLI surfaces. + +Options: + --repeat= Number of times to run each case (default: 5) +EOF +} + +now_us() { + local now="${EPOCHREALTIME/./}" + printf '%s' "$now" +} + +format_ms() { + local us="$1" + printf '%d.%03d' "$(( us / 1000 ))" "$(( us % 1000 ))" +} + +run_case() { + local label="$1" + shift + local total_us=0 + local min_us=0 + local max_us=0 + local elapsed_us=0 + local start_us=0 + local end_us=0 + local status=0 + + for (( i = 1; i <= REPEAT; i++ )); do + start_us=$(now_us) + if "$@" >/dev/null; then + status=0 + else + status=$? + fi + end_us=$(now_us) + + if (( status != 0 )); then + printf '%-34s failed (exit %d)\n' "$label" "$status" + return "$status" + fi + + elapsed_us=$(( end_us - start_us )) + total_us=$(( total_us + elapsed_us )) + + if (( i == 1 || elapsed_us < min_us )); then + min_us=$elapsed_us + fi + + if (( elapsed_us > max_us )); then + max_us=$elapsed_us + fi + done + + printf '%-34s avg %8s ms min %8s ms max %8s ms\n' \ + "$label" \ + "$(format_ms "$(( total_us / REPEAT ))")" \ + "$(format_ms "$min_us")" \ + "$(format_ms "$max_us")" +} + +while (( $# > 0 )); do + case "$1" in + --repeat=*) + REPEAT="${1#*=}" + ;; + --help | -h) + show_help + exit 0 + ;; + *) + echo "Unknown option: $1" >&2 + show_help >&2 + exit 2 + ;; + esac + shift +done + +if [[ ! $REPEAT =~ ^[0-9]+$ ]] || (( REPEAT < 1 )); then + echo "--repeat must be a positive integer" >&2 + exit 2 +fi + +printf 'Omarchy CLI benchmark (%d runs each)\n\n' "$REPEAT" +run_case "omarchy" "$CLI" +run_case "omarchy --help" "$CLI" --help +run_case "omarchy commands" "$CLI" commands +run_case "omarchy commands --json" "$CLI" commands --json +run_case "omarchy commands --all --json" "$CLI" commands --all --json +run_case "omarchy theme set --help" "$CLI" theme set --help +run_case "omarchy screenshot --help" "$CLI" screenshot --help +run_case "omarchy restart --help" "$CLI" restart --help +run_case "omarchy theme current" "$CLI" theme current diff --git a/bin/omarchy-dev-bin-metadata b/bin/omarchy-dev-bin-metadata new file mode 100755 index 00000000..c63667b9 --- /dev/null +++ b/bin/omarchy-dev-bin-metadata @@ -0,0 +1,86 @@ +#!/bin/bash + +# omarchy:summary=Show Omarchy bin metadata fields and defaults +# omarchy:args=[--json] + +set -euo pipefail + +show_json() { + jq -n '{ + ok: true, + defaults: { + group: "first filename segment after omarchy-", + name: "remaining filename segments with dashes converted to spaces", + route: "omarchy ", + binary: "filename", + requires_sudo: false + }, + fields: [ + {name: "summary", required: true, type: "string", note: "One-line human and agent-facing description."}, + {name: "group", required: false, type: "string", note: "Only set when the route group should differ from the filename-derived group."}, + {name: "name", required: false, type: "string", note: "Only set when the route name should differ from the filename-derived name. May be empty for root commands."}, + {name: "args", required: false, type: "string", note: "Only set when the command accepts arguments."}, + {name: "examples", required: false, type: "string", note: "Pipe-separated examples."}, + {name: "aliases", required: false, type: "string", note: "Pipe-separated alternate routes, e.g. omarchy screenshot."}, + {name: "requires-sudo", required: false, type: "true", default: false, note: "Only include when true."} + ] + }' +} + +show_help() { + cat <<'EOF' +Omarchy bin metadata + +Metadata lives in the top comment block of each executable bin/omarchy-* file. +Keep it slim: define only fields that are required or override defaults. + +Required: + # omarchy:summary= + +Inferred defaults: + group first filename segment after omarchy- + name remaining filename segments, with dashes converted to spaces + route omarchy + binary filename + requires-sudo false + +Optional fields: + # omarchy:group= route override only + # omarchy:name= route override only; may be empty + # omarchy:args= only if the command accepts args + # omarchy:examples= | pipe-separated examples + # omarchy:aliases= | pipe-separated alternate routes + # omarchy:requires-sudo=true only when true + +Do not define: + binary inferred from filename + usage derived from route + args + false flags or empty args + +Examples: + # omarchy:summary=Restart Walker and related user services + + # omarchy:summary=Take a screenshot + # omarchy:group=capture + # omarchy:args=[smart|region|windows|fullscreen] [slurp|copy] [--editor=] + # omarchy:examples=omarchy screenshot | omarchy capture screenshot region + # omarchy:aliases=omarchy screenshot +EOF +} + +case "${1:-}" in +--json) + show_json + ;; +--help | -h) + show_help + ;; +"") + show_help + ;; +*) + echo "Unknown option: $1" >&2 + show_help >&2 + exit 2 + ;; +esac diff --git a/bin/omarchy-drive-info b/bin/omarchy-drive-info index 4943975d..88793c6a 100755 --- a/bin/omarchy-drive-info +++ b/bin/omarchy-drive-info @@ -1,6 +1,7 @@ #!/bin/bash -# Returns drive information about a given volumne, like /dev/nvme0, which is used by omarchy-drive-select. +# omarchy:summary=Print drive information such as size, model, and mount details +# omarchy:args= if (($# == 0)); then echo "Usage: omarchy-drive-info [/dev/drive]" diff --git a/bin/omarchy-drive-select b/bin/omarchy-drive-select index 14afcc22..117cde4d 100755 --- a/bin/omarchy-drive-select +++ b/bin/omarchy-drive-select @@ -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. +# omarchy:summary=Select a drive from a list with info that includes space and brand. Used by omarchy-drive-set-password. if (($# == 0)); then drives=$(lsblk -dpno NAME | grep -E '/dev/(sd|hd|vd|nvme|mmcblk|xv)') diff --git a/bin/omarchy-drive-set-password b/bin/omarchy-drive-set-password index baf4d1ba..3fdf9b08 100755 --- a/bin/omarchy-drive-set-password +++ b/bin/omarchy-drive-set-password @@ -1,11 +1,12 @@ #!/bin/bash -# Set a new encryption password for a drive selected. +# omarchy:summary=Set a new encryption password for a drive selected. +# omarchy:requires-sudo=true encrypted_drives=$(blkid -t TYPE=crypto_LUKS -o device) if [[ -n $encrypted_drives ]]; then - if (( $(wc -l << +# omarchy:examples=omarchy font list | omarchy font set "CaskaydiaMono Nerd Font" font_name="$1" diff --git a/bin/omarchy-haptic-touchpad b/bin/omarchy-haptic-touchpad index f0240116..a98bd90a 100755 --- a/bin/omarchy-haptic-touchpad +++ b/bin/omarchy-haptic-touchpad @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +# omarchy:summary=Run the Synaptics touchpad haptic feedback daemon + """Haptic feedback daemon for Synaptics touchpads with Manual Trigger. Monitors touchpad button press events and sends haptic pulses via HID diff --git a/bin/omarchy-hibernation-available b/bin/omarchy-hibernation-available index 32be61b6..701a8f72 100755 --- a/bin/omarchy-hibernation-available +++ b/bin/omarchy-hibernation-available @@ -1,6 +1,7 @@ #!/bin/bash -# Check if hibernation is supported +# omarchy:summary=Check if hibernation is supported + if [[ ! -f /sys/power/image_size ]]; then exit 1 fi diff --git a/bin/omarchy-hibernation-remove b/bin/omarchy-hibernation-remove index 2901a88a..49bad5bd 100755 --- a/bin/omarchy-hibernation-remove +++ b/bin/omarchy-hibernation-remove @@ -1,7 +1,7 @@ #!/bin/bash -# Removes hibernation setup: disables swap, removes swapfile, removes fstab entry, -# removes resume hook, and removes suspend-then-hibernate configuration. +# omarchy:summary=Remove hibernation setup including swap and boot resume settings +# omarchy:requires-sudo=true MKINITCPIO_CONF="/etc/mkinitcpio.conf.d/omarchy_resume.conf" diff --git a/bin/omarchy-hibernation-setup b/bin/omarchy-hibernation-setup index 482e5470..d8e32c94 100755 --- a/bin/omarchy-hibernation-setup +++ b/bin/omarchy-hibernation-setup @@ -1,14 +1,27 @@ #!/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. +# omarchy:summary=Set up hibernation with swap and boot resume configuration +# omarchy:requires-sudo=true +# omarchy:args=[--force] [--no-rebuild] + +FORCE=false +NO_REBUILD=false +for arg in "$@"; do + case "$arg" in + --force) FORCE=true ;; + --no-rebuild) NO_REBUILD=true ;; + esac +done 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 +# When --no-rebuild is set, the caller is responsible for the UKI rebuild +# (e.g. running before limine-mkinitcpio-hook is installed during initial +# install), so we only require limine-mkinitcpio when we'd invoke it ourselves. +if ! $NO_REBUILD && ! command -v limine-mkinitcpio &>/dev/null; then echo "Skipping hibernation setup (requires Limine bootloader)" exit 0 fi @@ -26,15 +39,14 @@ if [[ -f $MKINITCPIO_CONF ]] && grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; echo "Fixing empty resume_offset ($RESUME_OFFSET)" sudo sed -i "s/resume_offset=\"$/resume_offset=$RESUME_OFFSET\"/" "$RESUME_DROP_IN" sudo sed -i "s/resume_offset=\"$/resume_offset=$RESUME_OFFSET\"/" /etc/default/limine - sudo limine-mkinitcpio - sudo limine-update + $NO_REBUILD || sudo limine-mkinitcpio fi fi echo "Hibernation is already set up" exit 0 fi -if [[ $1 != "--force" ]]; then +if ! $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 @@ -105,13 +117,16 @@ if grep -q "\[s2idle\]" /sys/power/mem_sleep 2>/dev/null; then fi fi -# Regenerate initramfs and boot entry -echo "Regenerating initramfs..." -sudo limine-mkinitcpio -sudo limine-update +if ! $NO_REBUILD; then + # limine-mkinitcpio rebuilds initramfs/UKI for all kernels and updates the + # /boot/limine.conf entries via limine-entry-tool. The limine bootloader + # binary on the ESP doesn't change here, so we don't need limine-update + # (which would also re-deploy the binary and rebuild a second time). + echo "Regenerating initramfs..." + sudo limine-mkinitcpio + echo +fi -echo - -if [[ $1 != "--force" ]] && gum confirm "Reboot to enable hibernation?"; then +if ! $FORCE && ! $NO_REBUILD && gum confirm "Reboot to enable hibernation?"; then omarchy-system-reboot fi diff --git a/bin/omarchy-hook b/bin/omarchy-hook index fb670f02..85b5a180 100755 --- a/bin/omarchy-hook +++ b/bin/omarchy-hook @@ -1,6 +1,7 @@ #!/bin/bash -# Run a named hook, like post-update (available in ~/.config/omarchy/hooks/post-update). +# omarchy:summary=Run a named hook, like post-update (available in ~/.config/omarchy/hooks/post-update). +# omarchy:args=[name] [args...] set -e diff --git a/bin/omarchy-hw-asus-expertbook-b9406 b/bin/omarchy-hw-asus-expertbook-b9406 new file mode 100755 index 00000000..f44af543 --- /dev/null +++ b/bin/omarchy-hw-asus-expertbook-b9406 @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Detect ASUS ExpertBook B9406 series laptops on Intel Panther Lake. + +omarchy-hw-match "B9406" && omarchy-hw-intel-ptl diff --git a/bin/omarchy-hw-asus-rog b/bin/omarchy-hw-asus-rog index 6897d734..99e02525 100755 --- a/bin/omarchy-hw-asus-rog +++ b/bin/omarchy-hw-asus-rog @@ -1,6 +1,6 @@ #!/bin/bash -# Detect whether the computer is an Asus ROG machine. +# omarchy:summary=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 diff --git a/bin/omarchy-hw-dell-xps-oled b/bin/omarchy-hw-dell-xps-oled index 80141b8a..70163e95 100755 --- a/bin/omarchy-hw-dell-xps-oled +++ b/bin/omarchy-hw-dell-xps-oled @@ -1,6 +1,6 @@ #!/bin/bash -# Match Dell XPS systems with LG OLED panel on Intel Panther Lake (Xe3) GPU. +# omarchy:summary=Match Dell XPS systems with LG OLED panel on Intel Panther Lake (Xe3) GPU. omarchy-hw-match "XPS" \ && omarchy-hw-intel-ptl \ diff --git a/bin/omarchy-hw-external-monitors b/bin/omarchy-hw-external-monitors index b5dc967b..08ab52ff 100755 --- a/bin/omarchy-hw-external-monitors +++ b/bin/omarchy-hw-external-monitors @@ -1,7 +1,6 @@ #!/bin/bash -# Returns true when an external monitor is physically connected. -# Uses kernel DRM state so the result is independent of Hyprland's startup timing. +# omarchy:summary=Returns true when an external monitor is physically connected. for status in /sys/class/drm/card*-*/status; do [[ "$status" == *-eDP-*/status ]] && continue diff --git a/bin/omarchy-hw-framework16 b/bin/omarchy-hw-framework16 index cd746bb1..3f74fc98 100755 --- a/bin/omarchy-hw-framework16 +++ b/bin/omarchy-hw-framework16 @@ -1,6 +1,6 @@ #!/bin/bash -# Detect whether the computer is a Framework Laptop 16. +# omarchy:summary=Detect whether the computer is a Framework Laptop 16. [[ $(cat /sys/class/dmi/id/sys_vendor 2>/dev/null) == "Framework" ]] && omarchy-hw-match "Laptop 16" diff --git a/bin/omarchy-hw-hybrid-gpu b/bin/omarchy-hw-hybrid-gpu index dcd0a8fd..7a960c79 100755 --- a/bin/omarchy-hw-hybrid-gpu +++ b/bin/omarchy-hw-hybrid-gpu @@ -1,3 +1,9 @@ #!/bin/bash -(($(lspci | grep -cE 'VGA|3D|Display') >= 2)) +# omarchy:summary=Detect whether the system has an active hybrid GPU configuration + +if command -v supergfxctl &>/dev/null; then + supergfxctl -s 2>/dev/null | grep -qw Hybrid +else + (($(lspci | grep -cE 'VGA|3D|Display') >= 2)) +fi diff --git a/bin/omarchy-hw-intel b/bin/omarchy-hw-intel index 2dc37c08..f2a2b4c3 100755 --- a/bin/omarchy-hw-intel +++ b/bin/omarchy-hw-intel @@ -1,5 +1,5 @@ #!/bin/bash -# Detect whether the computer has an Intel CPU. +# omarchy:summary=Detect whether the computer has an Intel CPU. [[ $(grep -m1 "vendor_id" /proc/cpuinfo 2>/dev/null | cut -d: -f2 | tr -d ' ') == "GenuineIntel" ]] diff --git a/bin/omarchy-hw-intel-ptl b/bin/omarchy-hw-intel-ptl index 9750bd3b..0b80edaa 100755 --- a/bin/omarchy-hw-intel-ptl +++ b/bin/omarchy-hw-intel-ptl @@ -1,5 +1,5 @@ #!/bin/bash -# Detect whether the computer has an Intel Panther Lake GPU. +# omarchy:summary=Detect whether the computer has an Intel Panther Lake GPU. lspci | grep -iE 'vga|3d|display' | grep -qi 'panther lake' diff --git a/bin/omarchy-hw-match b/bin/omarchy-hw-match index c27875fa..318ca7e8 100755 --- a/bin/omarchy-hw-match +++ b/bin/omarchy-hw-match @@ -1,7 +1,7 @@ #!/bin/bash -# Match against the computer's DMI product name or product family (case-insensitive). -# Usage: omarchy-hw-match "XPS" or omarchy-hw-match "ThinkPad" +# omarchy:summary=Match against the computer's DMI product name or product family (case-insensitive). +# omarchy:args= grep -qi "$1" /sys/class/dmi/id/product_name 2>/dev/null || grep -qi "$1" /sys/class/dmi/id/product_family 2>/dev/null diff --git a/bin/omarchy-hw-nvidia-gsp b/bin/omarchy-hw-nvidia-gsp new file mode 100755 index 00000000..06af2a3e --- /dev/null +++ b/bin/omarchy-hw-nvidia-gsp @@ -0,0 +1,6 @@ +#!/bin/bash + +# omarchy:summary=Detect whether the computer has an NVIDIA GPU with GSP firmware (Turing or newer). + +# GTX 16xx, RTX 20xx-50xx, RTX Pro, Quadro RTX, datacenter A/H/T/L series. +lspci | grep -i 'nvidia' | grep -qE "GTX 16[0-9]{2}|RTX [2-5][0-9]{3}|RTX PRO [0-9]{4}|Quadro RTX|RTX A[0-9]{4}|A[1-9][0-9]{2}|H[1-9][0-9]{2}|T4|L[0-9]+" diff --git a/bin/omarchy-hw-nvidia-without-gsp b/bin/omarchy-hw-nvidia-without-gsp new file mode 100755 index 00000000..177e60b6 --- /dev/null +++ b/bin/omarchy-hw-nvidia-without-gsp @@ -0,0 +1,6 @@ +#!/bin/bash + +# omarchy:summary=Detect whether the computer has an NVIDIA GPU without GSP firmware (Maxwell/Pascal/Volta). + +# GTX 9xx/10xx, GT 10xx, Quadro P/M/GV, MX series, Titan X/Xp/V, Tesla V100. +lspci | grep -i 'nvidia' | grep -qE "GTX (9[0-9]{2}|10[0-9]{2})|GT 10[0-9]{2}|Quadro [PM][0-9]{3,4}|Quadro GV100|MX *[0-9]+|Titan (X|Xp|V)|Tesla V100" diff --git a/bin/omarchy-hw-recover-internal-monitor b/bin/omarchy-hw-recover-internal-monitor index 794cafea..2ff125e7 100755 --- a/bin/omarchy-hw-recover-internal-monitor +++ b/bin/omarchy-hw-recover-internal-monitor @@ -1,8 +1,6 @@ #!/bin/bash -# Clear the internal-monitor-disable toggle if no external display is connected. -# Runs before the graphical session so Hyprland doesn't block on having no output -# to render to when the user rebooted with the external unplugged. +# omarchy:summary=Clear the internal-monitor-disable toggle if no external display is connected. TOGGLE="$HOME/.local/state/omarchy/toggles/hypr/internal-monitor-disable.conf" diff --git a/bin/omarchy-hw-surface b/bin/omarchy-hw-surface index 2f642721..7bef0e7c 100755 --- a/bin/omarchy-hw-surface +++ b/bin/omarchy-hw-surface @@ -1,6 +1,6 @@ #!/bin/bash -# Detect whether the computer is a Microsoft Surface device. +# omarchy:summary=Detect whether the computer is a Microsoft Surface device. [[ $(cat /sys/class/dmi/id/sys_vendor 2>/dev/null) == "Microsoft Corporation" ]] && omarchy-hw-match "Surface" diff --git a/bin/omarchy-hw-touchpad b/bin/omarchy-hw-touchpad index a4d813e0..b5e4b777 100755 --- a/bin/omarchy-hw-touchpad +++ b/bin/omarchy-hw-touchpad @@ -1,4 +1,6 @@ #!/bin/bash +# omarchy:summary=Print the detected Hyprland touchpad or trackpad device name + device=$(hyprctl devices -j | jq -r '[.mice[] | .name | select(test("touchpad|trackpad"; "i"))] | first // empty') [[ -n $device ]] && echo "$device" diff --git a/bin/omarchy-hw-touchscreen b/bin/omarchy-hw-touchscreen new file mode 100755 index 00000000..337fd0df --- /dev/null +++ b/bin/omarchy-hw-touchscreen @@ -0,0 +1,6 @@ +#!/bin/bash + +# omarchy:summary=Print the detected Hyprland touchscreen or tablet device name + +device=$(hyprctl devices -j | jq -r '[.touch[]?.name, .tablets[]?.name] | first // empty') +[[ -n $device ]] && echo "$device" diff --git a/bin/omarchy-hw-vulkan b/bin/omarchy-hw-vulkan index 8d473a24..776bf254 100755 --- a/bin/omarchy-hw-vulkan +++ b/bin/omarchy-hw-vulkan @@ -1,6 +1,6 @@ #!/bin/bash -# Detect whether Vulkan is available. +# omarchy:summary=Detect whether Vulkan is available. [[ -d /usr/share/vulkan/icd.d ]] && find /usr/share/vulkan/icd.d -maxdepth 1 -name "*.json" -print -quit | grep -q . diff --git a/bin/omarchy-hyprland-active-window-transparency-toggle b/bin/omarchy-hyprland-active-window-transparency-toggle index 2412548d..81afc272 100755 --- a/bin/omarchy-hyprland-active-window-transparency-toggle +++ b/bin/omarchy-hyprland-active-window-transparency-toggle @@ -1,5 +1,5 @@ #!/bin/bash -# Toggles transparency for the currently focused window. +# omarchy:summary=Toggles transparency for the currently focused window. hyprctl dispatch setprop "address:$(hyprctl activewindow -j | jq -r '.address')" opaque toggle diff --git a/bin/omarchy-hyprland-monitor-focused b/bin/omarchy-hyprland-monitor-focused index 2b4b8eea..9dd2a264 100755 --- a/bin/omarchy-hyprland-monitor-focused +++ b/bin/omarchy-hyprland-monitor-focused @@ -1,5 +1,5 @@ #!/bin/bash -# Print the name of the currently focused Hyprland monitor. +# omarchy:summary=Print the name of the currently focused Hyprland monitor. hyprctl monitors -j | jq -r '.[] | select(.focused == true).name' diff --git a/bin/omarchy-hyprland-monitor-focused-apple b/bin/omarchy-hyprland-monitor-focused-apple new file mode 100755 index 00000000..1593c828 --- /dev/null +++ b/bin/omarchy-hyprland-monitor-focused-apple @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Return success if the focused Hyprland monitor is an Apple display. + +hyprctl monitors -j | jq -e '.[] | select(.focused == true) | select(.make == "Apple Computer Inc" and (.model | test("StudioDisplay|ProDisplayXDR")))' >/dev/null diff --git a/bin/omarchy-hyprland-monitor-internal b/bin/omarchy-hyprland-monitor-internal index 6936d2cf..29f101d4 100755 --- a/bin/omarchy-hyprland-monitor-internal +++ b/bin/omarchy-hyprland-monitor-internal @@ -1,6 +1,14 @@ #!/bin/bash +# omarchy:summary=Enable, disable, toggle, or recover the internal laptop display +# omarchy:args= + TOGGLE="internal-monitor-disable" +TOGGLE_FLAG="$HOME/.local/state/omarchy/toggles/hypr/$TOGGLE.conf" +MIRROR_TOGGLE="internal-monitor-mirror" + +# Get internal monitor name dynamically +INTERNAL=$(hyprctl monitors -j | jq -r '.[] | select(.name | contains("eDP")).name' | head -n 1) enable() { if omarchy-hyprland-toggle-enabled "$TOGGLE"; then @@ -9,14 +17,15 @@ enable() { } disable() { - if omarchy-hw-external-monitors; then - if omarchy-hyprland-toggle-disabled "$TOGGLE"; then - omarchy-hyprland-toggle --enabled-notification "󰍹 Laptop display disabled" "$TOGGLE" - fi - else + if ! omarchy-hw-external-monitors; then notify-send -u low "󰍹 Can't disable the only active display" exit 1 fi + if omarchy-hyprland-toggle-disabled "$TOGGLE" && omarchy-hyprland-toggle-disabled "$MIRROR_TOGGLE"; then + echo "monitor=$INTERNAL,disable" >"$TOGGLE_FLAG" + notify-send -u low "󰍹 Laptop display disabled" + hyprctl reload + fi } recover() { diff --git a/bin/omarchy-hyprland-monitor-internal-mirror b/bin/omarchy-hyprland-monitor-internal-mirror new file mode 100755 index 00000000..07a0ccad --- /dev/null +++ b/bin/omarchy-hyprland-monitor-internal-mirror @@ -0,0 +1,58 @@ +#!/bin/bash + +# omarchy:summary=Enable, disable, toggle, or recover mirroring the internal display to an external monitor +# omarchy:args= + +TOGGLE="internal-monitor-mirror" +TOGGLE_FLAG="$HOME/.local/state/omarchy/toggles/hypr/$TOGGLE.conf" +DISABLE_TOGGLE="internal-monitor-disable" + +# Get names dynamically +INTERNAL=$(hyprctl monitors -j | jq -r '.[] | select(.name | contains("eDP")).name' | head -n 1) +# Get the first available external monitor +EXTERNAL=$(hyprctl monitors -j | jq -r '.[] | select(.name | contains("eDP") | not).name' | head -n 1) + +enable() { + if [[ -z "$EXTERNAL" ]]; then + notify-send -u low "󰍹 No external monitors found for mirror" + exit 1 + fi + + if [[ -z "$INTERNAL" ]]; then + notify-send -u low "󰍹 No laptop monitor found to mirror" + exit 1 + fi + + if omarchy-hyprland-toggle-enabled "$DISABLE_TOGGLE"; then + omarchy-hyprland-toggle "$DISABLE_TOGGLE" + fi + + if omarchy-hyprland-toggle-disabled "$TOGGLE"; then + echo "monitor=$EXTERNAL, preferred, auto, 1, mirror, $INTERNAL" > "$TOGGLE_FLAG" + notify-send -u low "󰍹 Mirroring enabled ($EXTERNAL)" + hyprctl reload + fi +} + +disable() { + if omarchy-hyprland-toggle-enabled "$TOGGLE"; then + omarchy-hyprland-toggle --disabled-notification "󰍹 Extended mode restored" "$TOGGLE" + fi +} + +recover() { + if ! omarchy-hw-external-monitors && omarchy-hyprland-toggle-enabled "$TOGGLE"; then + omarchy-hyprland-toggle "$TOGGLE" + fi +} + +case "$1" in + on) enable ;; + off) disable ;; + toggle) if omarchy-hyprland-toggle-enabled "$TOGGLE"; then disable; else enable; fi ;; + recover) recover ;; + *) + echo "Usage: $(basename "$0") {on|off|toggle|recover}" >&2 + exit 1 + ;; +esac diff --git a/bin/omarchy-hyprland-monitor-scaling-cycle b/bin/omarchy-hyprland-monitor-scaling-cycle index 008dc864..32f61e50 100755 --- a/bin/omarchy-hyprland-monitor-scaling-cycle +++ b/bin/omarchy-hyprland-monitor-scaling-cycle @@ -1,6 +1,7 @@ #!/bin/bash -# Get the active monitor (the one with the cursor) +# omarchy:summary=Cycle scaling for the focused Hyprland monitor + 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') @@ -32,4 +33,15 @@ fi NEW_SCALE=${SCALES[$NEW_IDX]} hyprctl keyword monitor "$ACTIVE_MONITOR,${WIDTH}x${HEIGHT}@${REFRESH_RATE},auto,$NEW_SCALE" + +# Persist to monitors.conf if the user has a single generic catch-all line +# (ignoring disabled monitors), so the scale survives reboots. +MONITOR_CONF="$HOME/.config/hypr/monitors.conf" +if [[ -f $MONITOR_CONF ]]; then + mapfile -t ACTIVE_LINES < <(grep -E '^[[:space:]]*monitor=' "$MONITOR_CONF" | grep -vE 'disable[[:space:]]*$') + if [[ ${#ACTIVE_LINES[@]} -eq 1 ]] && [[ "${ACTIVE_LINES[0]}" =~ ^monitor=,preferred,auto, ]]; then + sed -i -E "s|^(monitor=,preferred,auto,).*|\\1${NEW_SCALE}|" "$MONITOR_CONF" + fi +fi + notify-send -u low "󰍹 Display scaling set to ${NEW_SCALE}x" diff --git a/bin/omarchy-hyprland-monitor-watch b/bin/omarchy-hyprland-monitor-watch index 470bf3de..7d0df494 100755 --- a/bin/omarchy-hyprland-monitor-watch +++ b/bin/omarchy-hyprland-monitor-watch @@ -1,7 +1,6 @@ #!/bin/bash -# Listen on Hyprland's event socket and recover the internal display whenever -# a monitor is removed. +# omarchy:summary=Watch Hyprland monitor events and recover monitor toggles when a monitor is removed SOCKET="$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" @@ -9,6 +8,7 @@ socat -U - "UNIX-CONNECT:$SOCKET" | while read -r event; do case "$event" in monitorremoved\>\>*|monitorremovedv2\>\>*) omarchy-hyprland-monitor-internal recover + omarchy-hyprland-monitor-internal-mirror recover ;; esac done diff --git a/bin/omarchy-hyprland-toggle b/bin/omarchy-hyprland-toggle index e272beed..363ac855 100755 --- a/bin/omarchy-hyprland-toggle +++ b/bin/omarchy-hyprland-toggle @@ -1,6 +1,7 @@ #!/bin/bash -# Toggle permanent Hyprland flags by copying them into a directory that's sourced entirely. +# omarchy:summary=Toggle permanent Hyprland flags by copying them into a directory that's sourced entirely. +# omarchy:args=[--enabled-notification ] [--disabled-notification ] ENABLED_NOTIFICATION="" DISABLED_NOTIFICATION="" diff --git a/bin/omarchy-hyprland-toggle-disabled b/bin/omarchy-hyprland-toggle-disabled index 4e526d09..51707491 100755 --- a/bin/omarchy-hyprland-toggle-disabled +++ b/bin/omarchy-hyprland-toggle-disabled @@ -1,5 +1,6 @@ #!/bin/bash -# Check if a Hyprland toggle is currently disabled (missing). +# omarchy:summary=Check if a Hyprland toggle is currently disabled (missing). +# omarchy:args= [[ ! -f "$HOME/.local/state/omarchy/toggles/hypr/$1.conf" ]] diff --git a/bin/omarchy-hyprland-toggle-enabled b/bin/omarchy-hyprland-toggle-enabled index 59a273a4..cdc4e718 100755 --- a/bin/omarchy-hyprland-toggle-enabled +++ b/bin/omarchy-hyprland-toggle-enabled @@ -1,5 +1,6 @@ #!/bin/bash -# Check if a Hyprland toggle is currently enabled. +# omarchy:summary=Check if a Hyprland toggle is currently enabled. +# omarchy:args= [[ -f "$HOME/.local/state/omarchy/toggles/hypr/$1.conf" ]] diff --git a/bin/omarchy-hyprland-window-close-all b/bin/omarchy-hyprland-window-close-all index e53fec6a..dbf0d758 100755 --- a/bin/omarchy-hyprland-window-close-all +++ b/bin/omarchy-hyprland-window-close-all @@ -1,6 +1,7 @@ #!/bin/bash -# Close all open windows +# omarchy:summary=Close all open windows + hyprctl clients -j | \ jq -r ".[].address" | \ xargs -I{} hyprctl dispatch closewindow address:{} diff --git a/bin/omarchy-hyprland-window-gaps-toggle b/bin/omarchy-hyprland-window-gaps-toggle index 082e4574..17f29587 100755 --- a/bin/omarchy-hyprland-window-gaps-toggle +++ b/bin/omarchy-hyprland-window-gaps-toggle @@ -1,5 +1,5 @@ #!/bin/bash -# Toggles the window gaps globally between no gaps and the default. +# omarchy:summary=Toggles the window gaps globally between no gaps and the default. omarchy-hyprland-toggle window-no-gaps diff --git a/bin/omarchy-hyprland-window-pop b/bin/omarchy-hyprland-window-pop index d1e8ef3c..05451076 100755 --- a/bin/omarchy-hyprland-window-pop +++ b/bin/omarchy-hyprland-window-pop @@ -1,19 +1,7 @@ #!/bin/bash -# 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. +# omarchy:summary=Toggle to pop-out a tile to stay fixed on a display basis. +# omarchy:args=[width height x y] width=${1:-1300} height=${2:-900} diff --git a/bin/omarchy-hyprland-window-single-square-aspect-toggle b/bin/omarchy-hyprland-window-single-square-aspect-toggle index 70615793..d600c408 100755 --- a/bin/omarchy-hyprland-window-single-square-aspect-toggle +++ b/bin/omarchy-hyprland-window-single-square-aspect-toggle @@ -1,6 +1,6 @@ #!/bin/bash -# Toggle single-window square aspect ratio. +# omarchy:summary=Toggle single-window square aspect ratio. omarchy-hyprland-toggle \ --enabled-notification " Enable single-window square aspect ratio" \ diff --git a/bin/omarchy-hyprland-workspace-layout-toggle b/bin/omarchy-hyprland-workspace-layout-toggle index 189a4694..4636e38e 100755 --- a/bin/omarchy-hyprland-workspace-layout-toggle +++ b/bin/omarchy-hyprland-workspace-layout-toggle @@ -1,6 +1,6 @@ #!/bin/bash -# Toggle the layout on the current active workspace between dwindle and scrolling +# omarchy:summary=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') diff --git a/bin/omarchy-install-chromium-google-account b/bin/omarchy-install-chromium-google-account index 71492056..515e067d 100755 --- a/bin/omarchy-install-chromium-google-account +++ b/bin/omarchy-install-chromium-google-account @@ -1,9 +1,9 @@ #!/bin/bash -# Allow Chromium to sign in to Google accounts by adding the correct -# oauth client id and secret to ~/.config/chromium-flags.conf. +# omarchy:summary=Allow Chromium to sign in to Google accounts by adding the required OAuth credentials if [[ -f ~/.config/chromium-flags.conf ]]; then + echo "Installing Chromium Google account support..." CONF=~/.config/chromium-flags.conf grep -qxF -- "--oauth2-client-id=77185425430.apps.googleusercontent.com" "$CONF" || diff --git a/bin/omarchy-install-dev-env b/bin/omarchy-install-dev-env index 99756a9e..263fd755 100755 --- a/bin/omarchy-install-dev-env +++ b/bin/omarchy-install-dev-env @@ -1,6 +1,10 @@ #!/bin/bash -# Install one of the supported development environments. Usually called via Install > Development > * in the Omarchy Menu. +# omarchy:summary=Install a supported development environment +# omarchy:name=dev-env +# omarchy:args= +# omarchy:examples=omarchy install dev-env ruby | omarchy install dev-env node +# omarchy:requires-sudo=true if [[ -z $1 ]]; then echo "Usage: omarchy-install-dev-env " >&2 diff --git a/bin/omarchy-install-docker-dbs b/bin/omarchy-install-docker-dbs index abfacdc7..26e850f7 100755 --- a/bin/omarchy-install-docker-dbs +++ b/bin/omarchy-install-docker-dbs @@ -1,7 +1,7 @@ #!/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. +# omarchy:summary=Install one of the supported databases in a Docker container with the suitable development options. +# omarchy:requires-sudo=true options=("MySQL" "PostgreSQL" "Redis" "MongoDB" "MariaDB" "MSSQL") @@ -13,6 +13,7 @@ fi if [[ -n $choices ]]; then for db in $choices; do + echo "Installing $db..." case $db in MySQL) sudo docker run -d --restart unless-stopped -p "127.0.0.1:3306:3306" --name=mysql8 -e MYSQL_ROOT_PASSWORD= -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:8.4 ;; PostgreSQL) sudo docker run -d --restart unless-stopped -p "127.0.0.1:5432:5432" --name=postgres18 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:18 ;; diff --git a/bin/omarchy-install-dropbox b/bin/omarchy-install-dropbox index 5b261563..4add3460 100755 --- a/bin/omarchy-install-dropbox +++ b/bin/omarchy-install-dropbox @@ -1,6 +1,6 @@ #!/bin/bash -# Install and start the Dropbox service. Must then be authenticated via the web. +# omarchy:summary=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 diff --git a/bin/omarchy-install-geforce-now b/bin/omarchy-install-gaming-geforce-now similarity index 81% rename from bin/omarchy-install-geforce-now rename to bin/omarchy-install-gaming-geforce-now index 4c941a9b..195c01ef 100755 --- a/bin/omarchy-install-geforce-now +++ b/bin/omarchy-install-gaming-geforce-now @@ -1,9 +1,10 @@ #!/bin/bash -# Install and launch Geforce Now. +# omarchy:summary=Install and launch Geforce Now. set -e +echo "Installing GeForce NOW..." omarchy-pkg-add flatpak cd /tmp diff --git a/bin/omarchy-install-gaming-gpu-lib32 b/bin/omarchy-install-gaming-gpu-lib32 new file mode 100755 index 00000000..419c44e0 --- /dev/null +++ b/bin/omarchy-install-gaming-gpu-lib32 @@ -0,0 +1,28 @@ +#!/bin/bash + +# omarchy:summary=Install lib32 graphics drivers (Vulkan + NVIDIA) for any detected GPUs. +# omarchy:requires-sudo=true + +set -e + +echo "Installing lib32 graphics drivers..." + +PACKAGES=() + +declare -A VULKAN_DRIVERS=( + [Intel]=lib32-vulkan-intel + [AMD]=lib32-vulkan-radeon +) +for vendor in "${!VULKAN_DRIVERS[@]}"; do + if lspci | grep -iE "(VGA|Display).*$vendor" >/dev/null; then + PACKAGES+=("${VULKAN_DRIVERS[$vendor]}") + fi +done + +if omarchy-hw-nvidia-gsp; then + PACKAGES+=(lib32-nvidia-utils) +elif omarchy-hw-nvidia-without-gsp; then + PACKAGES+=(lib32-nvidia-580xx-utils) +fi + +[[ ${#PACKAGES[@]} -gt 0 ]] && omarchy-pkg-add "${PACKAGES[@]}" diff --git a/bin/omarchy-install-gaming-heroic b/bin/omarchy-install-gaming-heroic new file mode 100755 index 00000000..df416a6c --- /dev/null +++ b/bin/omarchy-install-gaming-heroic @@ -0,0 +1,12 @@ +#!/bin/bash + +# omarchy:summary=Install Heroic Games Launcher (Epic, GOG, Amazon Prime Gaming) with graphics drivers. +# omarchy:requires-sudo=true + +set -e + +echo "Installing Heroic Games Launcher..." +omarchy-pkg-add heroic-games-launcher-bin +omarchy-install-gaming-gpu-lib32 + +setsid gtk-launch heroic >/dev/null 2>&1 & diff --git a/bin/omarchy-install-gaming-lutris b/bin/omarchy-install-gaming-lutris new file mode 100755 index 00000000..a9f2d11b --- /dev/null +++ b/bin/omarchy-install-gaming-lutris @@ -0,0 +1,23 @@ +#!/bin/bash + +# omarchy:summary=Install Lutris with Wine + DXVK for running Windows games (Battle.net, EA, Ubisoft Connect, etc.) +# omarchy:requires-sudo=true + +set -e + +echo "Installing Lutris..." +omarchy-pkg-add lutris umu-launcher wine-staging wine-mono wine-gecko winetricks python-protobuf +omarchy-install-gaming-gpu-lib32 + +# Lutris ships with `#!/usr/bin/env python3`, which resolves to mise's Python and +# fails to import the lutris module. Pin the shebang to the system Python. +sudo sed -i '/env python3/ c\#!/bin/python3' /usr/bin/lutris + +cat <<'EOF' + +Lutris will open and auto-fetch its DXVK and VKD3D runtimes in the background +(watch the bottom status bar). Once that finishes, click the + to add or install games. + +EOF + +setsid lutris >/dev/null 2>&1 & diff --git a/bin/omarchy-install-gaming-moonlight b/bin/omarchy-install-gaming-moonlight new file mode 100755 index 00000000..1fe77e68 --- /dev/null +++ b/bin/omarchy-install-gaming-moonlight @@ -0,0 +1,11 @@ +#!/bin/bash + +# omarchy:summary=Install Moonlight (NVIDIA GameStream / Sunshine client) for streaming games to this PC. +# omarchy:requires-sudo=true + +set -e + +echo "Installing Moonlight..." +omarchy-pkg-add moonlight-qt + +setsid gtk-launch com.moonlight_stream.Moonlight.desktop >/dev/null 2>&1 & diff --git a/bin/omarchy-install-gaming-retroarch b/bin/omarchy-install-gaming-retroarch new file mode 100755 index 00000000..b4685b04 --- /dev/null +++ b/bin/omarchy-install-gaming-retroarch @@ -0,0 +1,80 @@ +#!/bin/bash + +# omarchy:summary=Install RetroArch with the full libretro core set plus FBNeo and a ~/Games ROM directory. + +set -e + +echo "Installing RetroArch..." +omarchy-pkg-add \ + retroarch \ + retroarch-assets-glui retroarch-assets-ozone retroarch-assets-xmb \ + libretro-beetle-pce libretro-beetle-pce-fast libretro-beetle-psx libretro-beetle-psx-hw libretro-beetle-supergrafx \ + libretro-blastem \ + libretro-bsnes libretro-bsnes-hd libretro-bsnes2014 \ + libretro-core-info \ + libretro-desmume libretro-dolphin libretro-flycast \ + libretro-gambatte libretro-genesis-plus-gx \ + libretro-kronos \ + libretro-mame libretro-mame2016 libretro-melonds libretro-mesen libretro-mesen-s libretro-mgba libretro-mupen64plus-next \ + libretro-nestopia \ + libretro-overlays \ + libretro-parallel-n64 libretro-picodrive libretro-play libretro-ppsspp \ + libretro-sameboy libretro-scummvm libretro-shaders-slang libretro-snes9x \ + libretro-yabause \ + libretro-fbneo-git \ + libretro-database-git + +# Set up ~/Games for BIOS files and ROMs +mkdir -p "$HOME/Games/bios" "$HOME/Games/roms" + +CFG="$HOME/.config/retroarch/retroarch.cfg" +mkdir -p "$(dirname "$CFG")" +touch "$CFG" + +set_cfg() { + local key=$1 value=$2 + if grep -q "^$key = " "$CFG"; then + sed -i "s|^$key = .*|$key = \"$value\"|" "$CFG" + else + echo "$key = \"$value\"" >>"$CFG" + fi +} + +set_cfg rgui_browser_directory "$HOME/Games/roms" +set_cfg system_directory "$HOME/Games/bios" + +# Point at the cores and assets installed by pacman +set_cfg libretro_directory "/usr/lib/libretro" +set_cfg libretro_info_path "/usr/share/libretro/info" +set_cfg overlay_directory "/usr/share/libretro/overlays" +set_cfg osk_overlay_directory "/usr/share/libretro/overlays/keyboards" +set_cfg video_shader_dir "/usr/share/libretro/shaders/shaders_slang" + +# Point at the database, cheats, and cursors from libretro-database-git +set_cfg content_database_path "/usr/share/libretro/database/rdb" +set_cfg cheat_database_path "/usr/share/libretro/database/cht" +set_cfg cursor_directory "/usr/share/libretro/database/cursors" + +# Vulkan is required for slang shaders and unlocks hardware renderers in beetle-psx-hw, parallel-n64, dolphin +set_cfg video_driver "vulkan" + +# XMB is the classic PS3-style menu (vs. ozone/rgui/glui) +set_cfg menu_driver "xmb" + +# Default to crt-royale shader for that classic CRT look. The global preset is +# auto-loaded by RetroArch when auto_shaders_enable is true and no per-core/per-game +# preset takes precedence — setting video_shader alone in retroarch.cfg is not enough. +set_cfg video_shader_enable "true" +set_cfg auto_shaders_enable "true" +mkdir -p ~/.config/retroarch/config +echo '#reference "/usr/share/libretro/shaders/shaders_slang/crt/crt-royale.slangp"' \ + > ~/.config/retroarch/config/global.slangp + +# Hide Images and Video tabs in the main menu sidebar +set_cfg content_show_images "false" +set_cfg content_show_video "false" + +echo "" +echo "Put your roms and bios files in ~/Games. Then start RetroArch from the app launcher (Super + Space)." + +setsid nautilus "$HOME/Games" >/dev/null 2>&1 & diff --git a/bin/omarchy-install-gaming-steam b/bin/omarchy-install-gaming-steam new file mode 100755 index 00000000..20dce3b6 --- /dev/null +++ b/bin/omarchy-install-gaming-steam @@ -0,0 +1,15 @@ +#!/bin/bash + +# omarchy:summary=Install Steam and graphics drivers selected for this system +# omarchy:requires-sudo=true + +set -e + +echo "Installing Steam..." +omarchy-pkg-add steam +omarchy-install-gaming-gpu-lib32 + +echo "" +echo "Steam will start automatically now. This might take a while..." + +setsid gtk-launch steam >/dev/null 2>&1 & diff --git a/bin/omarchy-install-gaming-xbox-cloud b/bin/omarchy-install-gaming-xbox-cloud new file mode 100755 index 00000000..8622949d --- /dev/null +++ b/bin/omarchy-install-gaming-xbox-cloud @@ -0,0 +1,10 @@ +#!/bin/bash + +# omarchy:summary=Install Xbox Cloud Gaming as a web app and launch it. + +set -e + +echo "Installing Xbox Cloud Gaming..." +omarchy-webapp-install "Xbox Cloud Gaming" "https://www.xbox.com/en-US/play" "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/xbox.png" + +setsid omarchy-launch-webapp "https://www.xbox.com/en-US/play" >/dev/null 2>&1 & diff --git a/bin/omarchy-install-gaming-xbox-controllers b/bin/omarchy-install-gaming-xbox-controllers new file mode 100755 index 00000000..539d0297 --- /dev/null +++ b/bin/omarchy-install-gaming-xbox-controllers @@ -0,0 +1,37 @@ +#!/bin/bash + +# omarchy:summary=Install support for using Xbox controllers with Steam/RetroArch/etc. +# omarchy:requires-sudo=true + +set -e + +echo "Installing Xbox controller Bluetooth support..." + +# Install xpadneo to ensure controllers work out of the box +omarchy-pkg-add linux-headers xpadneo-dkms + +# Prevent xpad/xpadneo driver conflict +echo blacklist xpad | sudo tee /etc/modprobe.d/blacklist-xpad.conf >/dev/null +echo hid_xpadneo | sudo tee /etc/modules-load.d/xpadneo.conf >/dev/null + +# Ensure user is in the input group (controllers need it) +needs_reboot=false +if ! id -nG "$USER" | grep -qw input; then + sudo usermod -aG input "$USER" + needs_reboot=true +fi + +# Swap drivers in the running kernel so a reboot isn't needed otherwise +if lsmod | grep -q '^xpad '; then + sudo modprobe -r xpad 2>/dev/null || needs_reboot=true +fi + +if $needs_reboot; then + gum confirm "Reboot needed to finish setup. Reboot now?" && sudo reboot now + exit 0 +fi + +sudo modprobe hid_xpadneo + +echo "" +echo "Now you can pair your Xbox controller with Bluetooth using Super + Ctrl + B." diff --git a/bin/omarchy-install-helix b/bin/omarchy-install-helix new file mode 100755 index 00000000..97de51c2 --- /dev/null +++ b/bin/omarchy-install-helix @@ -0,0 +1,28 @@ +#!/bin/bash + +# Install Helix and configure it to use the current Omarchy theme. + +echo "Installing Helix..." +omarchy-pkg-add helix + +mkdir -p ~/.config/helix/themes + +# Symlink the rendered Omarchy theme so Helix tracks the active theme +ln -sf ~/.config/omarchy/current/theme/helix.toml ~/.config/helix/themes/omarchy.toml + +# Only seed a config.toml if the user does not already have one +if [[ ! -f ~/.config/helix/config.toml ]]; then + cat >~/.config/helix/config.toml <<'EOF' +theme = "omarchy" +EOF +fi + +# Ensure the symlink target exists for users whose current theme predates this template +if [[ ! -e ~/.config/omarchy/current/theme/helix.toml ]]; then + omarchy-theme-refresh +fi + +# Arch-based distros ship Helix as 'helix' rather than the upstream 'hx'. +if ! grep -q '^alias hx="helix"' ~/.bashrc 2>/dev/null; then + echo 'alias hx="helix"' >>~/.bashrc +fi diff --git a/bin/omarchy-install-nordvpn b/bin/omarchy-install-nordvpn index 7ed080d8..d275800d 100755 --- a/bin/omarchy-install-nordvpn +++ b/bin/omarchy-install-nordvpn @@ -1,6 +1,7 @@ #!/bin/bash -# Install the NordVPN service with optional GUI. +# omarchy:summary=Install the NordVPN service with optional GUI. +# omarchy:requires-sudo=true echo "Installing NordVPN..." omarchy-pkg-aur-add nordvpn-bin diff --git a/bin/omarchy-install-once b/bin/omarchy-install-once index 97d56752..9b5cf446 100755 --- a/bin/omarchy-install-once +++ b/bin/omarchy-install-once @@ -1,6 +1,7 @@ #!/bin/bash -# Install the ONCE service, enable its background service, and launch the TUI. +# omarchy:summary=Install the ONCE service, enable its background service, and launch the TUI. +# omarchy:requires-sudo=true echo "Installing ONCE..." omarchy-pkg-add once-bin diff --git a/bin/omarchy-install-steam b/bin/omarchy-install-steam deleted file mode 100755 index 2d3b7cd9..00000000 --- a/bin/omarchy-install-steam +++ /dev/null @@ -1,9 +0,0 @@ -#!/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 -setsid gtk-launch steam >/dev/null 2>&1 & diff --git a/bin/omarchy-install-tailscale b/bin/omarchy-install-tailscale index 4017eb80..1c37ba41 100755 --- a/bin/omarchy-install-tailscale +++ b/bin/omarchy-install-tailscale @@ -1,6 +1,7 @@ #!/bin/bash -# Install the Tailscale mesh VPN service and a web app for the Tailscale Admin Console. +# omarchy:summary=Install the Tailscale mesh VPN service and a web app for the Tailscale Admin Console. +# omarchy:requires-sudo=true echo -e "\nInstalling Tailscale..." omarchy-pkg-add tailscale diff --git a/bin/omarchy-install-terminal b/bin/omarchy-install-terminal index f52744f6..146e4167 100755 --- a/bin/omarchy-install-terminal +++ b/bin/omarchy-install-terminal @@ -1,6 +1,8 @@ #!/bin/bash -# Install one of the approved terminals and set it as the default for Omarchy (Super + Return etc). +# omarchy:summary=Install one of the approved terminals and set it as the default for Omarchy (Super + Return etc). +# omarchy:args= +# omarchy:requires-sudo=true if (($# == 0)); then echo "Usage: omarchy-install-terminal [alacritty|ghostty|kitty]" @@ -20,6 +22,8 @@ kitty) desktop_id="kitty.desktop" ;; ;; esac +echo "Installing $package..." + # Install package if omarchy-pkg-add $package; then # Copy custom desktop entry for alacritty with X-TerminalArg* keys diff --git a/bin/omarchy-install-vscode b/bin/omarchy-install-vscode index cd6a32b3..1850e779 100755 --- a/bin/omarchy-install-vscode +++ b/bin/omarchy-install-vscode @@ -1,6 +1,6 @@ #!/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. +# omarchy:summary=Install VS Code and configure Omarchy defaults for secrets, updates, and theme echo "Installing VSCode..." omarchy-pkg-add visual-studio-code-bin diff --git a/bin/omarchy-install-xbox-controllers b/bin/omarchy-install-xbox-controllers deleted file mode 100755 index c192e282..00000000 --- a/bin/omarchy-install-xbox-controllers +++ /dev/null @@ -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 diff --git a/bin/omarchy-launch-about b/bin/omarchy-launch-about index ee5dfdeb..cf9b4516 100755 --- a/bin/omarchy-launch-about +++ b/bin/omarchy-launch-about @@ -1,5 +1,5 @@ #!/bin/bash -# Launch the fastfetch TUI that gives information about the current system. +# omarchy:summary=Launch the fastfetch TUI that gives information about the current system. exec omarchy-launch-or-focus-tui "bash -c 'fastfetch; read -n 1 -s'" diff --git a/bin/omarchy-launch-audio b/bin/omarchy-launch-audio index b5e5e4c1..c3d2592c 100755 --- a/bin/omarchy-launch-audio +++ b/bin/omarchy-launch-audio @@ -1,5 +1,5 @@ #!/bin/bash -# Launch the Omarchy audio controls TUI (provided by wiremix). +# omarchy:summary=Launch the Omarchy audio controls TUI (provided by wiremix). omarchy-launch-or-focus-tui wiremix diff --git a/bin/omarchy-launch-bluetooth b/bin/omarchy-launch-bluetooth index 5e343308..8c450261 100755 --- a/bin/omarchy-launch-bluetooth +++ b/bin/omarchy-launch-bluetooth @@ -1,7 +1,6 @@ #!/bin/bash -# Launch the Omarchy bluetooth controls TUI (provided by bluetui). -# Also attempts to unblock bluetooth service if rfkill had blocked it. +# omarchy:summary=Launch the Omarchy bluetooth controls TUI (provided by bluetui). rfkill unblock bluetooth exec omarchy-launch-or-focus-tui bluetui diff --git a/bin/omarchy-launch-browser b/bin/omarchy-launch-browser index b4b3e289..fefc935e 100755 --- a/bin/omarchy-launch-browser +++ b/bin/omarchy-launch-browser @@ -1,7 +1,7 @@ #!/bin/bash -# Launch the default browser as determined by xdg-settings. -# Automatically converts --private into the correct flag for the given browser. +# omarchy:summary=Launch the default browser as determined by xdg-settings. +# omarchy:args=[url] 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) diff --git a/bin/omarchy-launch-editor b/bin/omarchy-launch-editor index 56afc614..9c3ec369 100755 --- a/bin/omarchy-launch-editor +++ b/bin/omarchy-launch-editor @@ -1,7 +1,7 @@ #!/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:summary=Launch the default editor as determined by $EDITOR (set via ~/.config/uwsm/default) (or nvim if missing). +# omarchy:args= omarchy-cmd-present "$EDITOR" || EDITOR=nvim diff --git a/bin/omarchy-launch-floating-terminal-with-presentation b/bin/omarchy-launch-floating-terminal-with-presentation index eac1cbb7..b0eaee72 100755 --- a/bin/omarchy-launch-floating-terminal-with-presentation +++ b/bin/omarchy-launch-floating-terminal-with-presentation @@ -1,7 +1,7 @@ #!/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. +# omarchy:summary=Launch a floating terminal with the Omarchy presentation wrapper +# omarchy:args= 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" diff --git a/bin/omarchy-launch-or-focus b/bin/omarchy-launch-or-focus index 85ab3d6c..44164bb5 100755 --- a/bin/omarchy-launch-or-focus +++ b/bin/omarchy-launch-or-focus @@ -1,7 +1,7 @@ #!/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. +# omarchy:summary=Launch an app or focus an existing window matching a pattern +# omarchy:args= if (($# == 0)); then echo "Usage: omarchy-launch-or-focus [window-pattern] [launch-command]" diff --git a/bin/omarchy-launch-or-focus-tui b/bin/omarchy-launch-or-focus-tui index bbbfeb5e..9b1858b3 100755 --- a/bin/omarchy-launch-or-focus-tui +++ b/bin/omarchy-launch-or-focus-tui @@ -1,7 +1,7 @@ #!/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. +# omarchy:summary=Launch a TUI or focus an existing terminal window for it +# omarchy:args= [args...] APP_ID="org.omarchy.$(basename "$1")" LAUNCH_COMMAND="omarchy-launch-tui $@" diff --git a/bin/omarchy-launch-or-focus-webapp b/bin/omarchy-launch-or-focus-webapp index c8f094e2..15191be2 100755 --- a/bin/omarchy-launch-or-focus-webapp +++ b/bin/omarchy-launch-or-focus-webapp @@ -1,7 +1,7 @@ #!/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. +# omarchy:summary=Launch or focus on a given web app identified by the window-pattern. +# omarchy:args= if (($# == 0)); then echo "Usage: omarchy-launch-or-focus-webapp [window-pattern] [url-and-flags...]" diff --git a/bin/omarchy-launch-screensaver b/bin/omarchy-launch-screensaver index b672c3e5..e3593ba5 100755 --- a/bin/omarchy-launch-screensaver +++ b/bin/omarchy-launch-screensaver @@ -1,8 +1,7 @@ #!/bin/bash -# Launch the Omarchy screensaver in the default terminal on the system with the correct font configuration. +# omarchy:summary=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 @@ -29,21 +28,21 @@ for m in $(hyprctl monitors -j | jq -r '.[] | .name'); do hyprctl dispatch exec -- \ alacritty --class=org.omarchy.screensaver \ --config-file ~/.local/share/omarchy/default/alacritty/screensaver.toml \ - -e omarchy-cmd-screensaver + -e omarchy-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 + -e omarchy-screensaver ;; *kitty*) hyprctl dispatch exec -- \ kitty --class=org.omarchy.screensaver \ --override font_size=18 \ --override window_padding_width=0 \ - -e omarchy-cmd-screensaver + -e omarchy-screensaver ;; *) notify-send -u low "✋ Screensaver only runs in Alacritty, Ghostty, or Kitty" diff --git a/bin/omarchy-launch-tui b/bin/omarchy-launch-tui index 3968ea65..ba64ad93 100755 --- a/bin/omarchy-launch-tui +++ b/bin/omarchy-launch-tui @@ -1,5 +1,6 @@ #!/bin/bash -# Launch the TUI command passed in as an argument in the default terminal with an org.omarchy.COMMAND app id for styling. +# omarchy:summary=Launch a TUI command in the default terminal with Omarchy styling +# omarchy:args= [args...] exec setsid uwsm-app -- xdg-terminal-exec --app-id=org.omarchy.$(basename $1) -e "$1" "${@:2}" diff --git a/bin/omarchy-launch-walker b/bin/omarchy-launch-walker index cda02c41..d6af04e1 100755 --- a/bin/omarchy-launch-walker +++ b/bin/omarchy-launch-walker @@ -1,8 +1,7 @@ #!/bin/bash -# Launch the Walker application launcher while ensuring that it's data provider (called elephant) is running first. +# omarchy:summary=Launch Walker and ensure its Elephant data provider is running -# Ensure elephant is running before launching walker if ! pgrep -x elephant > /dev/null; then setsid uwsm-app -- elephant & fi diff --git a/bin/omarchy-launch-webapp b/bin/omarchy-launch-webapp index 71606efa..6ee0f84a 100755 --- a/bin/omarchy-launch-webapp +++ b/bin/omarchy-launch-webapp @@ -1,6 +1,7 @@ #!/bin/bash -# Launch the passed in URL as a web app in the default browser (or chromium if the default doesn't support --app). +# omarchy:summary=Launch a URL as a web app in the default supported browser +# omarchy:args= browser=$(xdg-settings get default-web-browser) diff --git a/bin/omarchy-launch-wifi b/bin/omarchy-launch-wifi index 9af1fc82..e22b7083 100755 --- a/bin/omarchy-launch-wifi +++ b/bin/omarchy-launch-wifi @@ -1,7 +1,6 @@ #!/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. +# omarchy:summary=Launch the Omarchy wifi controls (provided by the Impala TUI). rfkill unblock wifi omarchy-launch-or-focus-tui impala diff --git a/bin/omarchy-menu b/bin/omarchy-menu index 4cd677c2..96e3839d 100755 --- a/bin/omarchy-menu +++ b/bin/omarchy-menu @@ -1,8 +1,6 @@ #!/bin/bash -# Launch the Omarchy Menu or takes a parameter to jump straight to a submenu. - -export PATH="$HOME/.local/share/omarchy/bin:$PATH" +# omarchy:summary=Launch the Omarchy Menu or takes a parameter to jump straight to a submenu. # Set to true when going directly to a submenu, so we can exit directly BACK_TO_EXIT=false @@ -105,9 +103,10 @@ show_trigger_menu() { } show_capture_menu() { - case $(menu "Capture" " Screenshot\n Screenrecord\n󰃉 Color") in - *Screenshot*) omarchy-cmd-screenshot ;; + case $(menu "Capture" " Screenshot\n Screenrecord\n󰴑 Text Extraction\n󰃉 Color") in + *Screenshot*) omarchy-capture-screenshot ;; *Screenrecord*) show_screenrecord_menu ;; + *Text*) omarchy-capture-text-extraction ;; *Color*) pkill hyprpicker || hyprpicker -a ;; *) back_to show_trigger_menu ;; esac @@ -141,18 +140,18 @@ show_webcam_select_menu() { } show_screenrecord_menu() { - omarchy-cmd-screenrecord --stop-recording && exit 0 + omarchy-capture-screenrecording --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 no audio") omarchy-capture-screenrecording ;; + *"With desktop audio") omarchy-capture-screenrecording --with-desktop-audio ;; + *"With desktop + microphone audio") omarchy-capture-screenrecording --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" + omarchy-capture-screenrecording --with-desktop-audio --with-microphone-audio --with-webcam --webcam-device="$device" ;; *) back_to show_capture_menu ;; esac @@ -160,31 +159,34 @@ show_screenrecord_menu() { show_share_menu() { case $(menu "Share" " Clipboard\n File \n Folder") in - *Clipboard*) omarchy-cmd-share clipboard ;; - *File*) terminal bash -c "omarchy-cmd-share file" ;; - *Folder*) terminal bash -c "omarchy-cmd-share folder" ;; + *Clipboard*) omarchy-menu-share clipboard ;; + *File*) terminal bash -c "omarchy-menu-share file" ;; + *Folder*) terminal bash -c "omarchy-menu-share folder" ;; *) back_to show_trigger_menu ;; esac } show_toggle_menu() { - local options="󱄄 Screensaver\n󰔎 Nightlight\n󱫖 Idle Lock\n󰍜 Top Bar\n󱂬 Workspace Layout\n Window Gaps\n 1-Window Ratio\n󰍹 Monitor Scaling\n" + local options="󱄄 Screensaver\n󰔎 Nightlight\n󱫖 Idle Lock\n󰂛 Notifications\n󰍜 Top Bar\n󱂬 Workspace Layout\n Window Gaps\n 1-Window Ratio\n󰍹 Monitor Scaling\n Direct Boot\n󰟵 Passwordless Sudo" case $(menu "Toggle" "$options") in *Screensaver*) omarchy-toggle-screensaver ;; *Nightlight*) omarchy-toggle-nightlight ;; *Idle*) omarchy-toggle-idle ;; + *Notifications*) omarchy-toggle-notification-silencing ;; *Bar*) omarchy-toggle-waybar ;; *Layout*) omarchy-hyprland-workspace-layout-toggle ;; *Ratio*) omarchy-hyprland-window-single-square-aspect-toggle ;; *Gaps*) omarchy-hyprland-window-gaps-toggle ;; *Scaling*) omarchy-hyprland-monitor-scaling-cycle ;; + *"Direct Boot"*) present_terminal omarchy-config-direct-boot ;; + *"Passwordless Sudo"*) present_terminal omarchy-sudo-passwordless ;; *) back_to show_trigger_menu ;; esac } show_hardware_menu() { - local options="󰛧 Laptop Display" + local options="󰛧 Laptop Display\n 󰍹 Mirror Display" if omarchy-hw-hybrid-gpu; then options="$options\n Hybrid GPU" @@ -194,17 +196,24 @@ show_hardware_menu() { options="$options\n󰟸 Touchpad" fi + if omarchy-hw-touchscreen; then + options="$options\n󰆽 Touchscreen" + fi + case $(menu "Toggle" "$options") in *Laptop*) omarchy-hyprland-monitor-internal toggle ;; + *Mirror*) omarchy-hyprland-monitor-internal-mirror toggle;; *Touchpad*) omarchy-toggle-touchpad ;; + *Touchscreen*) omarchy-toggle-touchscreen ;; *"Hybrid GPU"*) present_terminal omarchy-toggle-hybrid-gpu ;; *) back_to show_trigger_menu ;; esac } show_style_menu() { - case $(menu "Style" "󰸌 Theme\n Font\n Background\n Hyprland\n󱄄 Screensaver\n About") in + case $(menu "Style" "󰸌 Theme\n󰟵 Unlock\n Font\n Background\n Hyprland\n󱄄 Screensaver\n About") in *Theme*) show_theme_menu ;; + *Unlock*) omarchy-launch-walker -m menus:omarchyunlocks --width 800 --minheight 400 ;; *Font*) show_font_menu ;; *Background*) show_background_menu ;; *Hyprland*) open_in_editor ~/.config/hypr/looknfeel.conf ;; @@ -345,7 +354,7 @@ show_install_editor_menu() { *Cursor*) install_and_launch "Cursor" "cursor-bin" "cursor" ;; *Zed*) install_and_launch "Zed" "zed" "dev.zed.Zed" ;; *Sublime*) install_and_launch "Sublime Text" "sublime-text-4" "sublime_text" ;; - *Helix*) install "Helix" "helix" ;; + *Helix*) present_terminal omarchy-install-helix ;; *Emacs*) install "Emacs" "emacs-wayland" && systemctl --user enable --now emacs.service ;; *) show_install_menu ;; esac @@ -362,8 +371,8 @@ show_install_terminal_menu() { show_install_ai_menu() { ollama_pkg=$( - (command -v nvidia-smi &>/dev/null && echo ollama-cuda) || - (command -v rocminfo &>/dev/null && echo ollama-rocm) || + (omarchy-cmd-present nvidia-smi && echo ollama-cuda) || + (omarchy-cmd-present rocminfo && echo ollama-rocm) || echo ollama ) @@ -377,12 +386,16 @@ show_install_ai_menu() { } show_install_gaming_menu() { - case $(menu "Install" " Steam\n󰢹 NVIDIA GeForce NOW\n RetroArch [AUR]\n󰍳 Minecraft\n󰖺 Xbox Controller [AUR]") in - *Steam*) present_terminal omarchy-install-steam ;; - *GeForce*) present_terminal omarchy-install-geforce-now ;; - *RetroArch*) aur_install_and_launch "RetroArch" "retroarch retroarch-assets libretro libretro-fbneo" "com.libretro.RetroArch.desktop" ;; + case $(menu "Install" " Steam\n RetroArch\n󰍳 Minecraft\n󰢹 NVIDIA GeForce NOW\n Xbox Cloud Gaming\n󰖺 Xbox Controller (󰂯)\n󰍹 Moonlight (GameStream)\n Lutris (Battle.net)\n󱓟 Heroic (Epic Games)") in + *Steam*) present_terminal omarchy-install-gaming-steam ;; + *RetroArch*) present_terminal omarchy-install-gaming-retroarch ;; *Minecraft*) install_and_launch "Minecraft" "minecraft-launcher" "minecraft-launcher" ;; - *Xbox*) present_terminal omarchy-install-xbox-controllers ;; + *GeForce*) present_terminal omarchy-install-gaming-geforce-now ;; + *"Xbox Cloud"*) present_terminal omarchy-install-gaming-xbox-cloud ;; + *Xbox*) present_terminal omarchy-install-gaming-xbox-controllers ;; + *Lutris*) present_terminal omarchy-install-gaming-lutris ;; + *Heroic*) present_terminal omarchy-install-gaming-heroic ;; + *Moonlight*) present_terminal omarchy-install-gaming-moonlight ;; *) show_install_menu ;; esac } @@ -397,12 +410,12 @@ show_install_style_menu() { } show_install_font_menu() { - case $(menu "Install" " Cascadia Mono\n Meslo LG Mono\n Fira Code\n Victor Code\n Bistream Vera Mono\n Iosevka" "--width 350") in + case $(menu "Install" " Cascadia Mono\n Meslo LG Mono\n Fira Code\n Victor Code\n Bitstream Vera Mono\n Iosevka" "--width 350") in *Cascadia*) install_font "Cascadia Mono" "ttf-cascadia-mono-nerd" "CaskaydiaMono Nerd Font" ;; *Meslo*) install_font "Meslo LG Mono" "ttf-meslo-nerd" "MesloLGL Nerd Font" ;; *Fira*) install_font "Fira Code" "ttf-firacode-nerd" "FiraCode Nerd Font" ;; *Victor*) install_font "Victor Code" "ttf-victor-mono-nerd" "VictorMono Nerd Font" ;; - *Bistream*) install_font "Bistream Vera Code" "ttf-bitstream-vera-mono-nerd" "BitstromWera Nerd Font" ;; + *Bitstream*) install_font "Bitstream Vera Code" "ttf-bitstream-vera-mono-nerd" "BitstromWera Nerd Font" ;; *Iosevka*) install_font "Iosevka" "ttf-iosevka-nerd" "Iosevka Nerd Font Mono" ;; *) show_install_menu ;; esac @@ -455,11 +468,12 @@ show_install_elixir_menu() { } show_remove_menu() { - case $(menu "Remove" "󰣇 Package\n Web App\n TUI\n󰵮 Development\n󰏓 Preinstalls\n Dictation\n󰸌 Theme\n󰍲 Windows\n󰈷 Fingerprint\n Fido2") in + case $(menu "Remove" "󰣇 Package\n Web App\n TUI\n󰵮 Development\n Gaming\n󰏓 Preinstalls\n Dictation\n󰸌 Theme\n󰍲 Windows\n󰈷 Fingerprint\n Fido2") in *Package*) terminal omarchy-pkg-remove ;; *Web*) present_terminal omarchy-webapp-remove ;; *TUI*) present_terminal omarchy-tui-remove ;; *Development*) show_remove_development_menu ;; + *Gaming*) show_remove_gaming_menu ;; *Preinstalls*) present_terminal omarchy-remove-preinstalls ;; *Dictation*) present_terminal omarchy-voxtype-remove ;; *Theme*) present_terminal omarchy-theme-remove ;; @@ -470,6 +484,21 @@ show_remove_menu() { esac } +show_remove_gaming_menu() { + case $(menu "Remove" " Steam\n RetroArch\n󰍳 Minecraft\n󰢹 NVIDIA GeForce NOW\n Xbox Cloud Gaming\n󰖺 Xbox Controller (󰂯)\n󰍹 Moonlight (GameStream)\n Lutris (Battle.net)\n󱓟 Heroic (Epic Games)") in + *Steam*) present_terminal omarchy-remove-gaming-steam ;; + *RetroArch*) present_terminal omarchy-remove-gaming-retroarch ;; + *Minecraft*) present_terminal omarchy-remove-gaming-minecraft ;; + *GeForce*) present_terminal omarchy-remove-gaming-geforce-now ;; + *"Xbox Cloud"*) present_terminal omarchy-remove-gaming-xbox-cloud ;; + *Xbox*) present_terminal omarchy-remove-gaming-xbox-controllers ;; + *Moonlight*) present_terminal omarchy-remove-gaming-moonlight ;; + *Lutris*) present_terminal omarchy-remove-gaming-lutris ;; + *Heroic*) present_terminal omarchy-remove-gaming-heroic ;; + *) show_remove_menu ;; + esac +} + show_remove_development_menu() { case $(menu "Remove" "󰫏 Ruby on Rails\n JavaScript\n Go\n PHP\n Python\n Elixir\n Zig\n Rust\n Java\n .NET\n OCaml\n Clojure\n Scala") in *Rails*) present_terminal "omarchy-remove-dev-env ruby" ;; @@ -597,7 +626,7 @@ show_system_menu() { case $(menu "System" "$options") in *Screensaver*) omarchy-launch-screensaver force ;; - *Lock*) omarchy-lock-screen ;; + *Lock*) omarchy-system-lock ;; *Suspend*) systemctl suspend ;; *Hibernate*) systemctl hibernate ;; *Logout*) omarchy-system-logout ;; diff --git a/bin/omarchy-menu-keybindings b/bin/omarchy-menu-keybindings index 7aa0490a..d28474dc 100755 --- a/bin/omarchy-menu-keybindings +++ b/bin/omarchy-menu-keybindings @@ -1,6 +1,6 @@ #!/bin/bash -# Display Hyprland keybindings defined in your configuration using walker for an interactive search menu. +# omarchy:summary=Display Hyprland keybindings defined in your configuration using walker for an interactive search menu. declare -A KEYCODE_SYM_MAP diff --git a/bin/omarchy-cmd-share b/bin/omarchy-menu-share similarity index 79% rename from bin/omarchy-cmd-share rename to bin/omarchy-menu-share index 81535549..bb522686 100755 --- a/bin/omarchy-cmd-share +++ b/bin/omarchy-menu-share @@ -1,9 +1,13 @@ #!/bin/bash -# Share clipboard, file, or folder using LocalSend. Bound to Super + Ctrl + S by default. +# omarchy:summary=Share clipboard, files, or folders with LocalSend +# omarchy:group=share +# omarchy:name= +# omarchy:args= [path...] +# omarchy:examples=omarchy share clipboard | omarchy share file ~/Downloads/example.txt if (($# == 0)); then - echo "Usage: omarchy-cmd-share [clipboard|file|folder]" + echo "Usage: omarchy-menu-share [clipboard|file|folder]" exit 1 fi diff --git a/bin/omarchy-migrate b/bin/omarchy-migrate index 0e1ec2cc..4ba325be 100755 --- a/bin/omarchy-migrate +++ b/bin/omarchy-migrate @@ -1,8 +1,7 @@ #!/bin/bash -# Run all pending migrations to bring the system in line with the installed version. +# omarchy:summary=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" diff --git a/bin/omarchy-notification-dismiss b/bin/omarchy-notification-dismiss index 72964b84..ab515e72 100755 --- a/bin/omarchy-notification-dismiss +++ b/bin/omarchy-notification-dismiss @@ -1,6 +1,7 @@ #!/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. +# omarchy:summary=Dismiss a mako notification on the basis of its summary. Used by the first-run notifications to dismiss them after clicking for action. +# omarchy:args= if (($# == 0)); then echo "Usage: omarchy-notification-dismiss " diff --git a/bin/omarchy-npx-install b/bin/omarchy-npx-install index 2ec926d9..6c0101d6 100755 --- a/bin/omarchy-npx-install +++ b/bin/omarchy-npx-install @@ -1,10 +1,7 @@ #!/bin/bash -# Install an npx wrapper for a given npm package. -# Usage: omarchy-npx-install [command-name] -# -# If command-name is omitted, it defaults to the package name. -# Example: omarchy-npx-install opencode-ai opencode +# omarchy:summary=Install an npx wrapper for a given npm package. +# omarchy:args= [command-name] if [[ -z $1 ]]; then echo "Usage: omarchy-npx-install [command-name]" @@ -18,7 +15,55 @@ mkdir -p "$HOME/.local/bin" cat > "$HOME/.local/bin/$command" </dev/null + node_root="\$(mise where node@latest)" +fi + +node_bin="\$node_root/bin/node" +npx_bin="\$node_root/bin/npx" + +ensure_bin_runtime() { + local bin_path=\$1 + local shebang + + IFS= read -r shebang < "\$bin_path" + + if [[ \$shebang == "#!"*"/bun"* || \$shebang == "#!"*"/env bun"* ]]; then + if omarchy-cmd-missing bun; then + echo "Installing bun runtime for \$package..." + omarchy-pkg-add bun + hash -r + fi + fi +} + +exec_package_bin() { + local package_bin_path=\$1 + shift + + if [[ -n \$package_bin_path ]]; then + ensure_bin_runtime "\$package_bin_path" + PATH="\$node_root/bin:\$PATH" exec "\$package_bin_path" "\$@" + fi +} + +# Resolve the package bin inside npx, then run it with node@latest available for node shebangs. +# Some wrappers are aliases, e.g. playwright-cli wraps the playwright bin. +"\$node_bin" "\$npx_bin" --yes --prefer-online --package "\$package" -- true + +package_bin_path=\$("\$node_bin" "\$npx_bin" --yes --package "\$package" -- which "\$package" 2>/dev/null) +exec_package_bin "\$package_bin_path" "\$@" + +# Scoped packages like @openai/codex expose an unscoped bin like codex. +package_bin_path=\$("\$node_bin" "\$npx_bin" --yes --package "\$package" -- which "\$command" 2>/dev/null) +exec_package_bin "\$package_bin_path" "\$@" + +echo "Could not resolve npm bin for \$package / \$command" >&2 +exit 127 EOF chmod +x "$HOME/.local/bin/$command" diff --git a/bin/omarchy-pkg-add b/bin/omarchy-pkg-add index 15c803d4..5c18ae02 100755 --- a/bin/omarchy-pkg-add +++ b/bin/omarchy-pkg-add @@ -1,6 +1,11 @@ #!/bin/bash -# Add the named packages to the system if they're missing. Returns false if it couldn't be done. +# omarchy:summary=Install Arch packages if they are missing +# omarchy:group=install +# omarchy:name=package +# omarchy:args= +# omarchy:examples=omarchy install package jq ripgrep +# omarchy:requires-sudo=true if omarchy-pkg-missing "$@"; then sudo pacman -S --noconfirm --needed "$@" || exit 1 diff --git a/bin/omarchy-pkg-aur-accessible b/bin/omarchy-pkg-aur-accessible index 3800880e..fae95172 100755 --- a/bin/omarchy-pkg-aur-accessible +++ b/bin/omarchy-pkg-aur-accessible @@ -1,7 +1,6 @@ #!/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. +# omarchy:summary=Returns true if the AUR is up and available. 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 diff --git a/bin/omarchy-pkg-aur-add b/bin/omarchy-pkg-aur-add index 332a0f60..7a152be7 100755 --- a/bin/omarchy-pkg-aur-add +++ b/bin/omarchy-pkg-aur-add @@ -1,6 +1,7 @@ #!/bin/bash -# Add the named packages to the system from the AUR if they're missing. Returns false if it couldn't be done. +# omarchy:summary=Add the named packages to the system from the AUR if they're missing. Returns false if it couldn't be done. +# omarchy:args= if omarchy-pkg-missing "$@"; then yay -S --noconfirm --needed "$@" || exit 1 diff --git a/bin/omarchy-pkg-aur-install b/bin/omarchy-pkg-aur-install index 89340162..dcb7ba1e 100755 --- a/bin/omarchy-pkg-aur-install +++ b/bin/omarchy-pkg-aur-install @@ -1,6 +1,7 @@ #!/bin/bash -# Show a fuzzy-finder TUI for picking new AUR packages to install. +# omarchy:summary=Show a fuzzy-finder TUI for picking new AUR packages to install. +# omarchy:requires-sudo=true fzf_args=( --multi diff --git a/bin/omarchy-pkg-drop b/bin/omarchy-pkg-drop index 125c9c98..0cbbfca6 100755 --- a/bin/omarchy-pkg-drop +++ b/bin/omarchy-pkg-drop @@ -1,9 +1,16 @@ #!/bin/bash -# Remove all the named packages from the system if they're installed (otherwise ignore). +# omarchy:summary=Remove all the named packages from the system if they're installed (otherwise ignore). +# omarchy:args= +# omarchy:requires-sudo=true +installed=() for pkg in "$@"; do if pacman -Q "$pkg" &>/dev/null; then - sudo pacman -Rns --noconfirm "$pkg" + installed+=("$pkg") fi done + +if (( ${#installed[@]} > 0 )); then + sudo pacman -Rns --noconfirm "${installed[@]}" +fi diff --git a/bin/omarchy-pkg-install b/bin/omarchy-pkg-install index 8399da9c..15e5e288 100755 --- a/bin/omarchy-pkg-install +++ b/bin/omarchy-pkg-install @@ -1,6 +1,7 @@ #!/bin/bash -# Show a fuzzy-finder TUI for picking new Arch and OPR packages to install. +# omarchy:summary=Show a fuzzy-finder TUI for picking new Arch and OPR packages to install. +# omarchy:requires-sudo=true fzf_args=( --multi diff --git a/bin/omarchy-pkg-missing b/bin/omarchy-pkg-missing index c2bab7a7..c4059dff 100755 --- a/bin/omarchy-pkg-missing +++ b/bin/omarchy-pkg-missing @@ -1,6 +1,7 @@ #!/bin/bash -# Returns true if any of the named packages are missing from the system (or false if they're all there). +# omarchy:summary=Returns true if any of the named packages are missing from the system (or false if they're all there). +# omarchy:args= for pkg in "$@"; do if ! pacman -Q "$pkg" &>/dev/null; then diff --git a/bin/omarchy-pkg-present b/bin/omarchy-pkg-present index 03a5d9af..8c4340d6 100755 --- a/bin/omarchy-pkg-present +++ b/bin/omarchy-pkg-present @@ -1,6 +1,7 @@ #!/bin/bash -# Returns true if all of the named packages are installed on the system (or false if any of them are missing). +# omarchy:summary=Returns true if all of the named packages are installed on the system (or false if any of them are missing). +# omarchy:args= for pkg in "$@"; do pacman -Q "$pkg" &>/dev/null || exit 1 diff --git a/bin/omarchy-pkg-remove b/bin/omarchy-pkg-remove index 865c1354..486d3772 100755 --- a/bin/omarchy-pkg-remove +++ b/bin/omarchy-pkg-remove @@ -1,6 +1,7 @@ #!/bin/bash -# Show a fuzzy-finder TUI for picking packages installed on the system to be removed. +# omarchy:summary=Show a fuzzy-finder TUI for picking packages installed on the system to be removed. +# omarchy:requires-sudo=true fzf_args=( --multi diff --git a/bin/omarchy-plymouth-preview b/bin/omarchy-plymouth-preview new file mode 100755 index 00000000..88cc71df --- /dev/null +++ b/bin/omarchy-plymouth-preview @@ -0,0 +1,75 @@ +#!/bin/bash + +# omarchy:summary=Preview a Plymouth boot screen with custom colors and logo +# omarchy:args= + +# Render a Plymouth login-screen preview PNG by compositing the staged omarchy +# theme assets (recolored with the given text color) onto the background. + +if [[ $# -ne 4 ]]; then + echo "Usage: omarchy-plymouth-preview " >&2 + exit 1 +fi + +bg_hex="${1#\#}" +text_hex="${2#\#}" +logo_path="$3" +output_path="$4" + +if ! [[ $bg_hex =~ ^[0-9a-fA-F]{6}$ ]]; then + echo "Invalid background color: $1 (expected #RRGGBB)" >&2 + exit 1 +fi + +if ! [[ $text_hex =~ ^[0-9a-fA-F]{6}$ ]]; then + echo "Invalid text color: $2 (expected #RRGGBB)" >&2 + exit 1 +fi + +if [[ ! -f $logo_path ]]; then + echo "Logo file not found: $logo_path" >&2 + exit 1 +fi + +staging_dir=$(mktemp -d) +trap 'rm -rf "$staging_dir"' EXIT + +find ~/.local/share/omarchy/default/plymouth -maxdepth 1 -type f -exec cp -t "$staging_dir/" {} + +cp "$logo_path" "$staging_dir/logo.png" + +for asset in bullet.png entry.png lock.png; do + magick "$staging_dir/$asset" -channel RGB +level-colors "#$text_hex","#$text_hex" "$staging_dir/$asset" +done + +canvas_w=1920 +canvas_h=1080 + +logo_w=$(magick identify -format '%w' "$staging_dir/logo.png") +logo_h=$(magick identify -format '%h' "$staging_dir/logo.png") +entry_w=$(magick identify -format '%w' "$staging_dir/entry.png") +entry_h=$(magick identify -format '%h' "$staging_dir/entry.png") +lock_h=$(awk "BEGIN{print int($entry_h * 0.8)}") +lock_w=$(awk "BEGIN{print int(84 * $lock_h / 96)}") + +logo_x=$(( (canvas_w - logo_w) / 2 )) +logo_y=$(( (canvas_h - logo_h) / 2 )) +entry_x=$(( (canvas_w - entry_w) / 2 )) +entry_y=$(( logo_y + logo_h + 40 )) +lock_x=$(( entry_x - lock_w - 15 )) +lock_y=$(( entry_y + entry_h/2 - lock_h/2 )) +bullet_y=$(( entry_y + entry_h/2 - 4 )) + +bullet_args=() +for i in 0 1 2 3; do + bx=$(( entry_x + 20 + i * 12 )) + bullet_args+=( '(' "$staging_dir/bullet.png" -resize 7x7 ')' -geometry +${bx}+${bullet_y} -composite ) +done + +magick -size ${canvas_w}x${canvas_h} "xc:#$bg_hex" \ + "$staging_dir/logo.png" -geometry +${logo_x}+${logo_y} -composite \ + "$staging_dir/entry.png" -geometry +${entry_x}+${entry_y} -composite \ + \( "$staging_dir/lock.png" -resize ${lock_w}x${lock_h} \) -geometry +${lock_x}+${lock_y} -composite \ + "${bullet_args[@]}" \ + "$output_path" + +imv -f "$output_path" diff --git a/bin/omarchy-plymouth-reset b/bin/omarchy-plymouth-reset new file mode 100755 index 00000000..584c8417 --- /dev/null +++ b/bin/omarchy-plymouth-reset @@ -0,0 +1,17 @@ +#!/bin/bash + +# omarchy:summary=Restore the default Omarchy Plymouth boot theme and SDDM login screen +# omarchy:requires-sudo=true + +theme_dir="/usr/share/plymouth/themes/omarchy" + +sudo find ~/.local/share/omarchy/default/plymouth -maxdepth 1 -type f -exec cp -t "$theme_dir/" {} + +sudo plymouth-set-default-theme omarchy + +if omarchy-cmd-present limine-mkinitcpio; then + sudo limine-mkinitcpio +else + sudo mkinitcpio -P +fi + +omarchy-refresh-sddm diff --git a/bin/omarchy-plymouth-set b/bin/omarchy-plymouth-set new file mode 100755 index 00000000..46a4a9a8 --- /dev/null +++ b/bin/omarchy-plymouth-set @@ -0,0 +1,76 @@ +#!/bin/bash + +# omarchy:summary=Set the Plymouth boot theme colors and logo +# omarchy:args= +# omarchy:requires-sudo=true + +# Configure the Plymouth boot theme with a custom background color, text color, and logo. +# Stages the change in a temp dir, then commits the staged files to /usr/share and +# rebuilds the initramfs. Also syncs the SDDM login screen (the post-logout +# screen) with the same colors and logo so boot/login stay visually unified. + +if [[ $# -ne 3 ]]; then + echo "Usage: omarchy-plymouth-set " >&2 + exit 1 +fi + +bg_hex="${1#\#}" +text_hex="${2#\#}" +logo_path="$3" + +if ! [[ $bg_hex =~ ^[0-9a-fA-F]{6}$ ]]; then + echo "Invalid background color: $1 (expected #RRGGBB)" >&2 + exit 1 +fi + +if ! [[ $text_hex =~ ^[0-9a-fA-F]{6}$ ]]; then + echo "Invalid text color: $2 (expected #RRGGBB)" >&2 + exit 1 +fi + +if [[ ! -f $logo_path ]]; then + echo "Logo file not found: $logo_path" >&2 + exit 1 +fi + +bg_r=$(awk -v n=$((16#${bg_hex:0:2})) 'BEGIN{printf "%.3f", n/255}') +bg_g=$(awk -v n=$((16#${bg_hex:2:2})) 'BEGIN{printf "%.3f", n/255}') +bg_b=$(awk -v n=$((16#${bg_hex:4:2})) 'BEGIN{printf "%.3f", n/255}') + +theme_dir="/usr/share/plymouth/themes/omarchy" +staging_dir=$(mktemp -d) +trap 'rm -rf "$staging_dir"' EXIT + +find ~/.local/share/omarchy/default/plymouth -maxdepth 1 -type f -exec cp -t "$staging_dir/" {} + +cp "$logo_path" "$staging_dir/logo.png" + +sed -i \ + -e "s/^Window.SetBackgroundTopColor.*/Window.SetBackgroundTopColor($bg_r, $bg_g, $bg_b);/" \ + -e "s/^Window.SetBackgroundBottomColor.*/Window.SetBackgroundBottomColor($bg_r, $bg_g, $bg_b);/" \ + "$staging_dir/omarchy.script" + +for asset in bullet.png entry.png lock.png progress_bar.png; do + magick "$staging_dir/$asset" -channel RGB +level-colors "#$text_hex","#$text_hex" "$staging_dir/$asset" +done + +sudo cp -a "$staging_dir/." "$theme_dir/" +sudo plymouth-set-default-theme omarchy + +if omarchy-cmd-present limine-mkinitcpio; then + sudo limine-mkinitcpio +else + sudo mkinitcpio -P +fi + +# Sync the SDDM login screen with the same colors and logo. +sddm_dir="/usr/share/sddm/themes/omarchy" +sddm_template="$HOME/.local/share/omarchy/default/sddm/omarchy/Main.qml" + +sed \ + -e "s/#000000/#$bg_hex/g" \ + -e "s/#ffffff/#$text_hex/g" \ + -e 's|source: "logo.svg"|source: "logo.png"|' \ + "$sddm_template" | sudo tee "$sddm_dir/Main.qml" >/dev/null + +sudo cp "$logo_path" "$sddm_dir/logo.png" +sudo rm -f "$sddm_dir/logo.svg" diff --git a/bin/omarchy-plymouth-set-by-theme b/bin/omarchy-plymouth-set-by-theme new file mode 100755 index 00000000..d46d5668 --- /dev/null +++ b/bin/omarchy-plymouth-set-by-theme @@ -0,0 +1,26 @@ +#!/bin/bash + +# omarchy:summary=Set the Plymouth boot theme from an Omarchy theme +# omarchy:args= +# omarchy:requires-sudo=true + +# Resolve a theme by name and apply its unlock.png + colors.toml as the +# Plymouth boot screen via omarchy-plymouth-set. + +if [[ $# -ne 1 ]]; then + echo "Usage: omarchy-plymouth-set-by-theme " >&2 + exit 1 +fi + +theme=$1 + +if [[ -d ~/.config/omarchy/themes/$theme ]]; then + theme_dir=~/.config/omarchy/themes/$theme +else + theme_dir="$OMARCHY_PATH/themes/$theme" +fi + +bg=$(awk -F'"' '/^background/{print $2}' "$theme_dir/colors.toml") +text=$(awk -F'"' '/^foreground/{print $2}' "$theme_dir/colors.toml") + +exec omarchy-plymouth-set "$bg" "$text" "$theme_dir/unlock.png" diff --git a/bin/omarchy-powerprofiles-init b/bin/omarchy-powerprofiles-init index 5a94d05b..f2dcee1d 100755 --- a/bin/omarchy-powerprofiles-init +++ b/bin/omarchy-powerprofiles-init @@ -1,8 +1,6 @@ #!/bin/bash -# Set the correct power profile on boot based on current AC/battery state. -# The udev rules only fire on state *changes*, so without this, booting -# on AC leaves you in the default balanced mode. +# omarchy:summary=Set the correct power profile on boot based on current AC/battery state. if omarchy-battery-present && ! omarchy-ac-present; then omarchy-powerprofiles-set battery diff --git a/bin/omarchy-powerprofiles-list b/bin/omarchy-powerprofiles-list index d8717ce3..093f9c99 100755 --- a/bin/omarchy-powerprofiles-list +++ b/bin/omarchy-powerprofiles-list @@ -1,7 +1,6 @@ #!/bin/bash -# Returns a list of all the available power profiles on the system. -# Used by the Omarchy Menu under Setup > Power Profile. +# omarchy:summary=Returns a list of all the available power profiles on the system. powerprofilesctl list | awk '/^\s*[* ]\s*[a-zA-Z0-9\-]+:$/ { gsub(/^[*[:space:]]+|:$/,""); print }' | diff --git a/bin/omarchy-powerprofiles-set b/bin/omarchy-powerprofiles-set index 86c3ac0c..a7dd623d 100755 --- a/bin/omarchy-powerprofiles-set +++ b/bin/omarchy-powerprofiles-set @@ -1,13 +1,31 @@ #!/bin/bash -# Set the power profile to the requested level, falling back to balanced -# if the requested profile isn't available on this machine. -# -# Usage: omarchy-powerprofiles-set +# omarchy:summary=Set the power profile to the requested level, falling back to balanced +# omarchy:args=[autodetect|ac|battery] + +action="${1-}" + +# Auto-detect when called with no argument: treat any Mains or USB +# power-supply device reporting online=1 as "on AC". This handles +# USB-C only laptops where the legacy AC device may not fire udev +# events, and also avoids false negatives from per-port USB-C devices +# that are present-but-empty (online=0) while another port supplies power. +if [[ -z $action || $action == "autodetect" ]]; then + action=battery + for ps in /sys/class/power_supply/*; do + [[ -r $ps/online && -r $ps/type ]] || continue + type=$(cat "$ps/type") + [[ $type == "Mains" || $type == "USB" ]] || continue + if [[ $(cat "$ps/online") == "1" ]]; then + action=ac + break + fi + done +fi mapfile -t profiles < <(powerprofilesctl list | awk '/^\s*[* ]\s*[a-zA-Z0-9\-]+:$/ { gsub(/^[*[:space:]]+|:$/,""); print }') -case "$1" in +case "$action" in ac) # Prefer performance, fall back to balanced if [[ " ${profiles[*]} " == *" performance "* ]]; then @@ -19,4 +37,4 @@ case "$1" in battery) powerprofilesctl set balanced ;; -esac +esac \ No newline at end of file diff --git a/bin/omarchy-refresh-applications b/bin/omarchy-refresh-applications index 0c39e5bc..550d1c86 100755 --- a/bin/omarchy-refresh-applications +++ b/bin/omarchy-refresh-applications @@ -1,8 +1,7 @@ #!/bin/bash -# Ensure all default .desktop, web apps, and TUIs are installed. +# omarchy:summary=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/ gtk-update-icon-cache ~/.local/share/icons/hicolor &>/dev/null diff --git a/bin/omarchy-refresh-chromium b/bin/omarchy-refresh-chromium index e206f363..f8d13f73 100755 --- a/bin/omarchy-refresh-chromium +++ b/bin/omarchy-refresh-chromium @@ -1,6 +1,6 @@ #!/bin/bash -# Refresh the ~/.config/chromium-flags.conf file from the Omarchy defaults. +# omarchy:summary=Refresh the ~/.config/chromium-flags.conf file from the Omarchy defaults. CONFIG_FILE="$HOME/.config/chromium-flags.conf" INSTALL_GOOGLE_ACCOUNTS=false diff --git a/bin/omarchy-refresh-config b/bin/omarchy-refresh-config index b293206a..0e46925a 100755 --- a/bin/omarchy-refresh-config +++ b/bin/omarchy-refresh-config @@ -1,7 +1,7 @@ #!/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. +# omarchy:summary=Copies the named config from ~/.local/share/omarchy/config/X/Y/Z -> ~/.config/X/Y/Z. +# omarchy:args= config_file=$1 @@ -22,6 +22,8 @@ user_config_file="${HOME}/.config/$config_file" default_config_file="${HOME}/.local/share/omarchy/config/$config_file" backup_config_file="$user_config_file.bak.$(date +%s)" +mkdir -p "$(dirname "$user_config_file")" + if [[ -f $user_config_file ]]; then # Create preliminary backup cp -f "$user_config_file" "$backup_config_file" 2>/dev/null diff --git a/bin/omarchy-refresh-fastfetch b/bin/omarchy-refresh-fastfetch index 15587d3e..c7988b71 100755 --- a/bin/omarchy-refresh-fastfetch +++ b/bin/omarchy-refresh-fastfetch @@ -1,5 +1,5 @@ #!/bin/bash -# Overwrite the user config for fastfetch with the Omarchy default. +# omarchy:summary=Overwrite the user config for fastfetch with the Omarchy default. omarchy-refresh-config fastfetch/config.jsonc diff --git a/bin/omarchy-refresh-hypridle b/bin/omarchy-refresh-hypridle index c2ade21d..210e78bf 100755 --- a/bin/omarchy-refresh-hypridle +++ b/bin/omarchy-refresh-hypridle @@ -1,6 +1,6 @@ #!/bin/bash -# Overwrite the user config for hypridle with the Omarchy default and restart the service. +# omarchy:summary=Overwrite the user config for hypridle with the Omarchy default and restart the service. omarchy-refresh-config hypr/hypridle.conf omarchy-restart-hypridle diff --git a/bin/omarchy-refresh-hyprland b/bin/omarchy-refresh-hyprland index 49f484a0..58618014 100755 --- a/bin/omarchy-refresh-hyprland +++ b/bin/omarchy-refresh-hyprland @@ -1,6 +1,6 @@ #!/bin/bash -# Overwrite all the user configs in ~/.config/hypr with the Omarchy defaults. +# omarchy:summary=Overwrite all the user configs in ~/.config/hypr with the Omarchy defaults. omarchy-refresh-config hypr/autostart.conf omarchy-refresh-config hypr/bindings.conf diff --git a/bin/omarchy-refresh-hyprlock b/bin/omarchy-refresh-hyprlock index 7d8575fc..1a09c88f 100755 --- a/bin/omarchy-refresh-hyprlock +++ b/bin/omarchy-refresh-hyprlock @@ -1,5 +1,5 @@ #!/bin/bash -# Overwrite the user config for hyprlock with the Omarchy default. +# omarchy:summary=Overwrite the user config for hyprlock with the Omarchy default. omarchy-refresh-config hypr/hyprlock.conf diff --git a/bin/omarchy-refresh-hyprsunset b/bin/omarchy-refresh-hyprsunset index 1cbfc522..bb7de90a 100755 --- a/bin/omarchy-refresh-hyprsunset +++ b/bin/omarchy-refresh-hyprsunset @@ -1,6 +1,6 @@ #!/bin/bash -# Overwrite the user config for hyprsunset with the Omarchy default and restart the service. -# +# omarchy:summary=Overwrite the user config for hyprsunset with the Omarchy default and restart the service. + omarchy-refresh-config hypr/hyprsunset.conf omarchy-restart-hyprsunset diff --git a/bin/omarchy-refresh-limine b/bin/omarchy-refresh-limine index 61261634..b2b735cc 100755 --- a/bin/omarchy-refresh-limine +++ b/bin/omarchy-refresh-limine @@ -1,6 +1,7 @@ #!/bin/bash -# Overwrite the user config for the Limine bootloader and rebuild it. +# omarchy:summary=Overwrite the user config for the Limine bootloader and rebuild it. +# omarchy:requires-sudo=true if [[ -f /boot/EFI/Linux/omarchy_linux.efi ]] && [[ -f /boot/EFI/Linux/$(cat /etc/machine-id)_linux.efi ]]; then echo "Cleanup extra UKI" diff --git a/bin/omarchy-refresh-pacman b/bin/omarchy-refresh-pacman index f09b44fb..fce99ee5 100755 --- a/bin/omarchy-refresh-pacman +++ b/bin/omarchy-refresh-pacman @@ -1,9 +1,8 @@ #!/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. +# omarchy:summary=Overwrite the package configuration for /etc/pacman with the Omarchy default of using its dedicated mirrors and repositories, then update all packages. +# omarchy:requires-sudo=true -# 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 diff --git a/bin/omarchy-refresh-plymouth b/bin/omarchy-refresh-plymouth index bdff7c7f..5a9671d7 100755 --- a/bin/omarchy-refresh-plymouth +++ b/bin/omarchy-refresh-plymouth @@ -1,8 +1,9 @@ #!/bin/bash -# Overwrite the user config for the Plymouth drive decryption and boot sequence with the Omarchy default and rebuild it. +# omarchy:summary=Overwrite the user config for the Plymouth drive decryption and boot sequence with the Omarchy default and rebuild it. +# omarchy:requires-sudo=true -sudo cp ~/.local/share/omarchy/default/plymouth/* /usr/share/plymouth/themes/omarchy/ +sudo cp -r ~/.local/share/omarchy/default/plymouth/* /usr/share/plymouth/themes/omarchy/ sudo plymouth-set-default-theme omarchy if command -v limine-mkinitcpio &>/dev/null; then diff --git a/bin/omarchy-refresh-sddm b/bin/omarchy-refresh-sddm index 473bb3ee..9f2c51ad 100755 --- a/bin/omarchy-refresh-sddm +++ b/bin/omarchy-refresh-sddm @@ -1,6 +1,7 @@ #!/bin/bash -# Refresh the SDDM theme from default +# omarchy:summary=Refresh the SDDM theme from default +# omarchy:requires-sudo=true sudo rm -rf /usr/share/sddm/themes/omarchy sudo cp -r $OMARCHY_PATH/default/sddm/omarchy /usr/share/sddm/themes/omarchy diff --git a/bin/omarchy-refresh-swayosd b/bin/omarchy-refresh-swayosd index ab2fe56f..65820784 100755 --- a/bin/omarchy-refresh-swayosd +++ b/bin/omarchy-refresh-swayosd @@ -1,6 +1,6 @@ #!/bin/bash -# Overwrite the user configs for swayosd (controls on-screen feedback for changing volume/songs etc) with the Omarchy defaults and restart the service. +# omarchy:summary=Overwrite the user configs for swayosd (controls on-screen feedback for changing volume/songs etc) with the Omarchy defaults and restart the service. omarchy-refresh-config swayosd/config.toml omarchy-refresh-config swayosd/style.css diff --git a/bin/omarchy-refresh-tmux b/bin/omarchy-refresh-tmux index 560c7fd5..ba40b1c0 100755 --- a/bin/omarchy-refresh-tmux +++ b/bin/omarchy-refresh-tmux @@ -1,6 +1,6 @@ #!/bin/bash -# Overwrite the user tmux config with the Omarchy default and reload tmux. +# omarchy:summary=Overwrite the user tmux config with the Omarchy default and reload tmux. omarchy-refresh-config tmux/tmux.conf omarchy-restart-tmux diff --git a/bin/omarchy-refresh-walker b/bin/omarchy-refresh-walker index dd6900e1..2354144f 100755 --- a/bin/omarchy-refresh-walker +++ b/bin/omarchy-refresh-walker @@ -1,8 +1,7 @@ #!/bin/bash -# Overwrite the user configs for the Walker application launcher (which also powers the Omarchy Menu) and restart the services. +# omarchy:summary=Overwrite the user configs for the Walker application launcher (which also powers the Omarchy Menu) and restart the services. -# Ensure walker is set to autostart mkdir -p ~/.config/autostart/ cp $OMARCHY_PATH/default/walker/walker.desktop ~/.config/autostart/ @@ -17,5 +16,11 @@ omarchy-refresh-config walker/config.toml omarchy-refresh-config elephant/calc.toml omarchy-refresh-config elephant/desktopapplications.toml +# Link all elephant menus +mkdir -p ~/.config/elephant/menus +for menu in $OMARCHY_PATH/default/elephant/*.lua; do + ln -snf "$menu" ~/.config/elephant/menus/"$(basename "$menu")" +done + # Restart service omarchy-restart-walker diff --git a/bin/omarchy-refresh-waybar b/bin/omarchy-refresh-waybar index 1ea9f75c..62aebde4 100755 --- a/bin/omarchy-refresh-waybar +++ b/bin/omarchy-refresh-waybar @@ -1,6 +1,7 @@ #!/bin/bash -# Overwrite the user configs for the Waybar menu bar with the Omarchy defaults and restart the service. +# omarchy:summary=Reset Waybar config to Omarchy defaults +# omarchy:examples=omarchy refresh waybar omarchy-refresh-config waybar/config.jsonc omarchy-refresh-config waybar/style.css diff --git a/bin/omarchy-reinstall b/bin/omarchy-reinstall index df00c609..d214188a 100755 --- a/bin/omarchy-reinstall +++ b/bin/omarchy-reinstall @@ -1,4 +1,8 @@ #!/bin/bash + +# omarchy:summary=Reinstall Omarchy packages and reset default configs +# omarchy:requires-sudo=true + set -e # Attempt to reinstall all default Omarchy packages and reset all the default configs. diff --git a/bin/omarchy-reinstall-configs b/bin/omarchy-reinstall-configs index c27b1efa..8b073cf8 100755 --- a/bin/omarchy-reinstall-configs +++ b/bin/omarchy-reinstall-configs @@ -1,4 +1,8 @@ #!/bin/bash + +# omarchy:summary=Reset all Omarchy user configs to the defaults +# omarchy:requires-sudo=true + set -e # Overwrite all user configs with the Omarchy defaults. diff --git a/bin/omarchy-reinstall-git b/bin/omarchy-reinstall-git index 33c8b8cc..cbba15dd 100755 --- a/bin/omarchy-reinstall-git +++ b/bin/omarchy-reinstall-git @@ -1,4 +1,7 @@ #!/bin/bash + +# omarchy:summary=Reinstall the Omarchy source directory from git + set -e # Reinstall the Omarchy configuration directory from the git source. diff --git a/bin/omarchy-reinstall-pkgs b/bin/omarchy-reinstall-pkgs index d70d0643..dc64a1f3 100755 --- a/bin/omarchy-reinstall-pkgs +++ b/bin/omarchy-reinstall-pkgs @@ -1,4 +1,8 @@ #!/bin/bash + +# omarchy:summary=Reinstall all default Omarchy packages from the stable channel +# omarchy:requires-sudo=true + set -e # Reinstall all default Omarchy packages from the stable channel and downgrade any packages that are too new. diff --git a/bin/omarchy-remove-dev-env b/bin/omarchy-remove-dev-env index f25a5ff0..4551f1e1 100755 --- a/bin/omarchy-remove-dev-env +++ b/bin/omarchy-remove-dev-env @@ -1,7 +1,8 @@ #!/bin/bash -# Remove a development environment that was previously installed via omarchy-install-dev-env. -# Usage: omarchy-remove-dev-env +# omarchy:summary=Remove a development environment that was previously installed via omarchy-install-dev-env. +# omarchy:args= +# omarchy:requires-sudo=true if [[ -z $1 ]]; then echo "Usage: omarchy-remove-dev-env " >&2 diff --git a/bin/omarchy-remove-gaming-geforce-now b/bin/omarchy-remove-gaming-geforce-now new file mode 100755 index 00000000..9947ee10 --- /dev/null +++ b/bin/omarchy-remove-gaming-geforce-now @@ -0,0 +1,12 @@ +#!/bin/bash + +# omarchy:summary=Remove the GeForce NOW Flatpak app and its data. + +set -e + +if command -v flatpak >/dev/null && flatpak info com.nvidia.geforcenow &>/dev/null; then + flatpak uninstall -y --delete-data com.nvidia.geforcenow +fi + +echo "" +echo "GeForce NOW removed." diff --git a/bin/omarchy-remove-gaming-heroic b/bin/omarchy-remove-gaming-heroic new file mode 100755 index 00000000..7247c247 --- /dev/null +++ b/bin/omarchy-remove-gaming-heroic @@ -0,0 +1,17 @@ +#!/bin/bash + +# omarchy:summary=Remove Heroic Games Launcher and its game libraries, configs, and caches. +# omarchy:requires-sudo=true + +set -e + +omarchy-pkg-drop heroic-games-launcher-bin + +rm -rf \ + "$HOME/.config/heroic" \ + "$HOME/.local/share/heroic" \ + "$HOME/.cache/heroic" \ + "$HOME/Games/Heroic" + +echo "" +echo "Heroic and its data have been removed." diff --git a/bin/omarchy-remove-gaming-lutris b/bin/omarchy-remove-gaming-lutris new file mode 100755 index 00000000..18253890 --- /dev/null +++ b/bin/omarchy-remove-gaming-lutris @@ -0,0 +1,21 @@ +#!/bin/bash + +# omarchy:summary=Remove Lutris, Wine, umu-launcher, and all their configs and caches. +# omarchy:requires-sudo=true + +set -e + +omarchy-pkg-drop lutris wine-staging wine-mono wine-gecko winetricks python-protobuf umu-launcher + +rm -rf \ + "$HOME/.config/lutris" \ + "$HOME/.local/share/lutris" \ + "$HOME/.cache/lutris" \ + "$HOME/.local/share/umu" \ + "$HOME/.cache/umu" \ + "$HOME/.wine" \ + "$HOME/.cache/wine" \ + "$HOME/.cache/winetricks" + +echo "" +echo "Lutris, Wine, umu-launcher, and their configs have been removed." diff --git a/bin/omarchy-remove-gaming-minecraft b/bin/omarchy-remove-gaming-minecraft new file mode 100755 index 00000000..1e439213 --- /dev/null +++ b/bin/omarchy-remove-gaming-minecraft @@ -0,0 +1,17 @@ +#!/bin/bash + +# omarchy:summary=Remove the Minecraft launcher along with its worlds, mods, and caches. +# omarchy:requires-sudo=true + +set -e + +omarchy-pkg-drop minecraft-launcher + +rm -rf \ + "$HOME/.minecraft" \ + "$HOME/.config/Minecraft Launcher" \ + "$HOME/.local/share/minecraft-launcher" \ + "$HOME/.cache/minecraft" + +echo "" +echo "Minecraft and its data have been removed." diff --git a/bin/omarchy-remove-gaming-moonlight b/bin/omarchy-remove-gaming-moonlight new file mode 100755 index 00000000..9cb951de --- /dev/null +++ b/bin/omarchy-remove-gaming-moonlight @@ -0,0 +1,15 @@ +#!/bin/bash + +# omarchy:summary=Remove Moonlight and its configs and caches. +# omarchy:requires-sudo=true + +set -e + +omarchy-pkg-drop moonlight-qt + +rm -rf \ + "$HOME/.config/Moonlight Game Streaming Project" \ + "$HOME/.cache/Moonlight Game Streaming Project" + +echo "" +echo "Moonlight and its data have been removed." diff --git a/bin/omarchy-remove-gaming-retroarch b/bin/omarchy-remove-gaming-retroarch new file mode 100755 index 00000000..d3c101c8 --- /dev/null +++ b/bin/omarchy-remove-gaming-retroarch @@ -0,0 +1,33 @@ +#!/bin/bash + +# omarchy:summary=Remove RetroArch, all libretro cores, and its config/saves. Leaves ~/Games/roms and ~/Games/bios alone. +# omarchy:requires-sudo=true + +set -e + +omarchy-pkg-drop \ + retroarch \ + retroarch-assets-glui retroarch-assets-ozone retroarch-assets-xmb \ + libretro-beetle-pce libretro-beetle-pce-fast libretro-beetle-psx libretro-beetle-psx-hw libretro-beetle-supergrafx \ + libretro-blastem \ + libretro-bsnes libretro-bsnes-hd libretro-bsnes2014 \ + libretro-core-info \ + libretro-desmume libretro-dolphin libretro-flycast \ + libretro-gambatte libretro-genesis-plus-gx \ + libretro-kronos \ + libretro-mame libretro-mame2016 libretro-melonds libretro-mesen libretro-mesen-s libretro-mgba libretro-mupen64plus-next \ + libretro-nestopia \ + libretro-overlays \ + libretro-parallel-n64 libretro-picodrive libretro-play libretro-ppsspp \ + libretro-sameboy libretro-scummvm libretro-shaders-slang libretro-snes9x \ + libretro-yabause \ + libretro-fbneo-git + +rm -rf \ + "$HOME/.config/retroarch" \ + "$HOME/.local/share/retroarch" \ + "$HOME/.cache/retroarch" + +echo "" +echo "RetroArch and its cores have been removed." +echo "ROMs and BIOS files at ~/Games/roms and ~/Games/bios were left in place." diff --git a/bin/omarchy-remove-gaming-steam b/bin/omarchy-remove-gaming-steam new file mode 100755 index 00000000..1b20ec22 --- /dev/null +++ b/bin/omarchy-remove-gaming-steam @@ -0,0 +1,17 @@ +#!/bin/bash + +# omarchy:summary=Remove Steam and all of its game libraries, configs, and caches. +# omarchy:requires-sudo=true + +set -e + +omarchy-pkg-drop steam + +rm -rf \ + "$HOME/.steam" \ + "$HOME/.local/share/Steam" \ + "$HOME/.config/steam" \ + "$HOME/.cache/steam" + +echo "" +echo "Steam and its data have been removed." diff --git a/bin/omarchy-remove-gaming-xbox-cloud b/bin/omarchy-remove-gaming-xbox-cloud new file mode 100755 index 00000000..7a42d357 --- /dev/null +++ b/bin/omarchy-remove-gaming-xbox-cloud @@ -0,0 +1,7 @@ +#!/bin/bash + +# omarchy:summary=Remove the Xbox Cloud Gaming web app. + +set -e + +omarchy-webapp-remove "Xbox Cloud Gaming" diff --git a/bin/omarchy-remove-gaming-xbox-controllers b/bin/omarchy-remove-gaming-xbox-controllers new file mode 100755 index 00000000..d20af7e6 --- /dev/null +++ b/bin/omarchy-remove-gaming-xbox-controllers @@ -0,0 +1,13 @@ +#!/bin/bash + +# omarchy:summary=Remove the xpadneo Xbox controller driver and undo its module/blacklist config. +# omarchy:requires-sudo=true + +set -e + +omarchy-pkg-drop xpadneo-dkms + +sudo rm -f /etc/modprobe.d/blacklist-xpad.conf /etc/modules-load.d/xpadneo.conf + +echo "" +echo "Xbox controller support removed. Reboot to fully unload xpadneo and restore xpad." diff --git a/bin/omarchy-remove-preinstalls b/bin/omarchy-remove-preinstalls index 49f6a42b..fc5eae72 100755 --- a/bin/omarchy-remove-preinstalls +++ b/bin/omarchy-remove-preinstalls @@ -1,7 +1,6 @@ #!/bin/bash -# Remove preinstalled Omarchy applications (web apps, TUIs, and selected packages). -# This removes all web apps, TUIs, plus specific desktop applications. +# omarchy:summary=Remove preinstalled Omarchy applications (web apps, TUIs, and selected packages). if gum confirm "Are you sure you want to remove all preinstalled web apps, TUI wrappers, and desktop applications?"; then echo -e "Removing preinstalled Omarchy applications...\n" @@ -19,6 +18,7 @@ if gum confirm "Are you sure you want to remove all preinstalled web apps, TUI w omarchy-pkg-drop \ aether \ + cliamp \ typora \ spotify \ libreoffice-fresh \ diff --git a/bin/omarchy-restart-app b/bin/omarchy-restart-app index 78556e3e..d250650d 100755 --- a/bin/omarchy-restart-app +++ b/bin/omarchy-restart-app @@ -1,7 +1,7 @@ #!/bin/bash -# Restart an application by killing it and relaunching via uwsm. -# Usage: omarchy-restart-app [application-args...] +# omarchy:summary=Restart an application by killing it and relaunching via uwsm. +# omarchy:args= [application-args...] pkill -x $1 setsid uwsm-app -- "$@" >/dev/null 2>&1 & diff --git a/bin/omarchy-restart-bluetooth b/bin/omarchy-restart-bluetooth index 57530d10..b95f9904 100755 --- a/bin/omarchy-restart-bluetooth +++ b/bin/omarchy-restart-bluetooth @@ -1,6 +1,6 @@ #!/bin/bash -# Unblock and restart the bluetooth service. +# omarchy:summary=Unblock and restart the bluetooth service. echo -e "Unblocking bluetooth...\n" rfkill unblock bluetooth diff --git a/bin/omarchy-restart-btop b/bin/omarchy-restart-btop index 2de58537..16b6b98f 100755 --- a/bin/omarchy-restart-btop +++ b/bin/omarchy-restart-btop @@ -1,5 +1,5 @@ #!/bin/bash -# Reload btop configuration (used by the Omarchy theme switching). +# omarchy:summary=Reload btop configuration (used by the Omarchy theme switching). pkill -SIGUSR2 btop diff --git a/bin/omarchy-restart-helix b/bin/omarchy-restart-helix new file mode 100755 index 00000000..878cc6c9 --- /dev/null +++ b/bin/omarchy-restart-helix @@ -0,0 +1,7 @@ +#!/bin/bash + +# Reload Helix configuration (used by the Omarchy theme switching). + +if pgrep -x helix >/dev/null; then + pkill -USR1 helix +fi diff --git a/bin/omarchy-restart-hyprctl b/bin/omarchy-restart-hyprctl index d8362c9f..e6e2c317 100755 --- a/bin/omarchy-restart-hyprctl +++ b/bin/omarchy-restart-hyprctl @@ -1,5 +1,5 @@ #!/bin/bash -# Reload hyprland configuration (used by the Omarchy theme switching). +# omarchy:summary=Reload hyprland configuration (used by the Omarchy theme switching). hyprctl reload >/dev/null diff --git a/bin/omarchy-restart-hypridle b/bin/omarchy-restart-hypridle index 02186267..0ea7776c 100755 --- a/bin/omarchy-restart-hypridle +++ b/bin/omarchy-restart-hypridle @@ -1,5 +1,5 @@ #!/bin/bash -# Restart the hypridle service (used for idle detection and auto-lock). +# omarchy:summary=Restart the hypridle service (used for idle detection and auto-lock). omarchy-restart-app hypridle diff --git a/bin/omarchy-restart-hyprsunset b/bin/omarchy-restart-hyprsunset index c705ab53..5e8da60f 100755 --- a/bin/omarchy-restart-hyprsunset +++ b/bin/omarchy-restart-hyprsunset @@ -1,5 +1,5 @@ #!/bin/bash -# Restart the hyprsunset service (used for blue light filtering/night light). +# omarchy:summary=Restart the hyprsunset service (used for blue light filtering/night light). omarchy-restart-app hyprsunset diff --git a/bin/omarchy-restart-mako b/bin/omarchy-restart-mako index f681a405..3cb6a6a2 100755 --- a/bin/omarchy-restart-mako +++ b/bin/omarchy-restart-mako @@ -1,5 +1,5 @@ #!/bin/bash -# Reload mako configuration (used by the Omarchy theme switching). +# omarchy:summary=Reload mako configuration (used by the Omarchy theme switching). makoctl reload diff --git a/bin/omarchy-restart-opencode b/bin/omarchy-restart-opencode index 086eba9f..3b282248 100755 --- a/bin/omarchy-restart-opencode +++ b/bin/omarchy-restart-opencode @@ -1,6 +1,6 @@ #!/bin/bash -# Reload opencode configuration (used by the Omarchy theme switching). +# omarchy:summary=Reload opencode configuration (used by the Omarchy theme switching). if pgrep -x opencode >/dev/null; then killall -SIGUSR2 opencode diff --git a/bin/omarchy-restart-pipewire b/bin/omarchy-restart-pipewire index a222ad1e..14276bad 100755 --- a/bin/omarchy-restart-pipewire +++ b/bin/omarchy-restart-pipewire @@ -1,6 +1,6 @@ #!/bin/bash -# Restart the PipeWire audio service to fix audio issues or apply new configuration. +# omarchy:summary=Restart the PipeWire audio service to fix audio issues or apply new configuration. echo -e "Restarting pipewire audio service...\n" systemctl --user restart pipewire.service diff --git a/bin/omarchy-restart-swayosd b/bin/omarchy-restart-swayosd index b155bc2f..19f4e78d 100755 --- a/bin/omarchy-restart-swayosd +++ b/bin/omarchy-restart-swayosd @@ -1,3 +1,5 @@ #!/bin/bash +# omarchy:summary=Restart the SwayOSD server + omarchy-restart-app swayosd-server diff --git a/bin/omarchy-restart-terminal b/bin/omarchy-restart-terminal index 69ec8da2..d767879d 100755 --- a/bin/omarchy-restart-terminal +++ b/bin/omarchy-restart-terminal @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Reload supported terminal emulators after config changes + if [[ -f ~/.config/alacritty/alacritty.toml ]]; then touch ~/.config/alacritty/alacritty.toml fi diff --git a/bin/omarchy-restart-tmux b/bin/omarchy-restart-tmux index b1ce7603..539d5176 100755 --- a/bin/omarchy-restart-tmux +++ b/bin/omarchy-restart-tmux @@ -1,6 +1,6 @@ #!/bin/bash -# Restart tmux if running with the latest configuration +# omarchy:summary=Restart tmux if running with the latest configuration if pgrep -x tmux; then tmux source-file ~/.config/tmux/tmux.conf diff --git a/bin/omarchy-restart-trackpad b/bin/omarchy-restart-trackpad index 4e2d584a..45898dc3 100755 --- a/bin/omarchy-restart-trackpad +++ b/bin/omarchy-restart-trackpad @@ -1,11 +1,8 @@ #!/bin/bash -# Reset the trackpad by unbinding and rebinding its driver. -# Covers both driver paths: -# - i2c_hid_acpi (DesignWare I2C, e.g. XPS 14/16 Synaptics trackpad) -# - intel_quicki2c (THC Touch Host Controller) +# omarchy:summary=Reset the trackpad by unbinding and rebinding its driver. +# omarchy:requires-sudo=true -# Try i2c_hid_acpi path (DesignWare I2C trackpads) for dev in /sys/bus/i2c/drivers/i2c_hid_acpi/i2c-*; do [ -e "$dev" ] || continue I2C_DEVICE=$(basename "$dev") diff --git a/bin/omarchy-restart-walker b/bin/omarchy-restart-walker index fb1a9eae..b4326998 100755 --- a/bin/omarchy-restart-walker +++ b/bin/omarchy-restart-walker @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Restart Walker and related user services + restart_services() { if systemctl --user is-enabled elephant.service &>/dev/null; then systemctl --user restart elephant.service diff --git a/bin/omarchy-restart-waybar b/bin/omarchy-restart-waybar index 53b570ef..7c165f60 100755 --- a/bin/omarchy-restart-waybar +++ b/bin/omarchy-restart-waybar @@ -1,3 +1,6 @@ #!/bin/bash +# omarchy:summary=Restart Waybar +# omarchy:examples=omarchy restart waybar + omarchy-restart-app waybar diff --git a/bin/omarchy-restart-wifi b/bin/omarchy-restart-wifi index 5cf35dd3..1a177c33 100755 --- a/bin/omarchy-restart-wifi +++ b/bin/omarchy-restart-wifi @@ -1,6 +1,6 @@ #!/bin/bash -# Unblock and restart the Wi-Fi service. +# omarchy:summary=Unblock and restart the Wi-Fi service. echo -e "Unblocking wifi...\n" rfkill unblock wifi diff --git a/bin/omarchy-restart-xcompose b/bin/omarchy-restart-xcompose index c66bfe7a..c0676b1c 100755 --- a/bin/omarchy-restart-xcompose +++ b/bin/omarchy-restart-xcompose @@ -1,5 +1,5 @@ #!/bin/bash -# Restart the XCompose input method service (fcitx5) to apply new compose key settings. +# omarchy:summary=Restart the XCompose input method service (fcitx5) to apply new compose key settings. omarchy-restart-app fcitx5 --disable notificationitem diff --git a/bin/omarchy-cmd-screensaver b/bin/omarchy-screensaver similarity index 85% rename from bin/omarchy-cmd-screensaver rename to bin/omarchy-screensaver index 7dd64786..536ae0e3 100755 --- a/bin/omarchy-cmd-screensaver +++ b/bin/omarchy-screensaver @@ -1,6 +1,6 @@ #!/bin/bash -# Run the Omarchy screensaver using random effects from TTE. +# omarchy:summary=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 @@ -25,8 +25,7 @@ tty=$(tty 2>/dev/null) while true; do 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 & + --random-effect --no-eol --no-restore-cursor & while pgrep -t "${tty#/dev/}" -x tte >/dev/null; do if read -n1 -t 1 || ! screensaver_in_focus; then diff --git a/bin/omarchy-setup-dns b/bin/omarchy-setup-dns index 7a60b641..b62e0610 100755 --- a/bin/omarchy-setup-dns +++ b/bin/omarchy-setup-dns @@ -1,5 +1,9 @@ #!/bin/bash +# omarchy:summary=Configure the system DNS provider +# omarchy:args=[Cloudflare|Google|DHCP|Custom] +# omarchy:requires-sudo=true + lock_dns_to_resolved() { for file in /etc/systemd/network/*.network; do [[ -f $file ]] || continue @@ -33,8 +37,8 @@ case "$dns" in Cloudflare) sudo tee /etc/systemd/resolved.conf >/dev/null <<'EOF' [Resolve] -DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com -FallbackDNS=9.9.9.9 149.112.112.112 +DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com +FallbackDNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net DNSOverTLS=opportunistic EOF lock_dns_to_resolved @@ -43,8 +47,8 @@ EOF Google) sudo tee /etc/systemd/resolved.conf >/dev/null <<'EOF' [Resolve] -DNS=8.8.8.8#dns.google 8.8.4.4#dns.google -FallbackDNS=9.9.9.9 149.112.112.112 +DNS=8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google +FallbackDNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net DNSOverTLS=opportunistic EOF lock_dns_to_resolved @@ -70,7 +74,7 @@ Custom) sudo tee /etc/systemd/resolved.conf >/dev/null </dev/null)" == "2808" ]] || continue + [[ "$(cat "${v%idVendor}idProduct" 2>/dev/null)" == "a97a" ]] || continue + print_info "FocalTech FT9349 detected (B9406CAA) — using libfprint-git from OPR..." + # libfprint-git provides+conflicts libfprint; pacman -S --noconfirm + # defaults the conflict prompt to N and aborts. Pre-remove libfprint + # with -Rdd so the install goes silent. -Rdd (not omarchy-pkg-drop's + # -Rns) is required because fprintd requires libfprint; the dep is + # re-satisfied immediately by libfprint-git's provides=libfprint. + if omarchy-pkg-present libfprint; then + sudo pacman -Rdd --noconfirm libfprint + fi + omarchy-pkg-add libfprint-git + break + done + omarchy-pkg-add fprintd usbutils if ! check_fingerprint_hardware; then diff --git a/bin/omarchy-show-done b/bin/omarchy-show-done index 36f5aec2..60741076 100755 --- a/bin/omarchy-show-done +++ b/bin/omarchy-show-done @@ -1,7 +1,6 @@ #!/bin/bash -# Display a "Done!" message with a spinner and wait for user to press any key. -# Used by various install scripts to indicate completion. +# omarchy:summary=Display a "Done!" message with a spinner and wait for user to press any key. echo gum spin --spinner "globe" --title "Done! Press any key to close..." -- bash -c 'read -n 1 -s' diff --git a/bin/omarchy-show-logo b/bin/omarchy-show-logo index a6137c58..595bb487 100755 --- a/bin/omarchy-show-logo +++ b/bin/omarchy-show-logo @@ -1,7 +1,6 @@ #!/bin/bash -# Display the Omarchy logo in the terminal using green color. -# Used by various presentation scripts to show branding. +# omarchy:summary=Display the Omarchy logo in the terminal using green color. clear echo -e "\033[32m" diff --git a/bin/omarchy-snapshot b/bin/omarchy-snapshot index ee79512a..ce1bc9ca 100755 --- a/bin/omarchy-snapshot +++ b/bin/omarchy-snapshot @@ -1,5 +1,9 @@ #!/bin/bash +# omarchy:summary=Create or restore system snapshots with snapper +# omarchy:args= +# omarchy:requires-sudo=true + set -e COMMAND="$1" @@ -25,6 +29,7 @@ create) for config in "${CONFIGS[@]}"; do sudo snapper -c "$config" create -c number -d "$DESC" + sudo snapper -c "$config" cleanup number done echo ;; diff --git a/bin/omarchy-state b/bin/omarchy-state index ff5e3e87..2a294df4 100755 --- a/bin/omarchy-state +++ b/bin/omarchy-state @@ -1,8 +1,7 @@ #!/bin/bash -# Manage persistent state files for Omarchy toggles and settings. -# Usage: omarchy-state -# Used to track whether features like suspend, idle lock, etc are enabled or disabled. +# omarchy:summary=Manage persistent state files for Omarchy toggles and settings. +# omarchy:args= STATE_DIR="$HOME/.local/state/omarchy" mkdir -p "$STATE_DIR" diff --git a/bin/omarchy-sudo-keepalive b/bin/omarchy-sudo-keepalive index c475198b..1f77a196 100755 --- a/bin/omarchy-sudo-keepalive +++ b/bin/omarchy-sudo-keepalive @@ -1,8 +1,7 @@ #!/bin/bash -# Prompt for sudo once and keep the credential alive in the background. -# Source this script so the trap applies to the calling shell: -# source omarchy-sudo-keepalive +# omarchy:summary=Prompt for sudo once and keep the credential alive in the background. +# omarchy:requires-sudo=true sudo -v while true; do sudo -n true; sleep 60; done 2>/dev/null & diff --git a/bin/omarchy-sudo-passwordless-toggle b/bin/omarchy-sudo-passwordless similarity index 84% rename from bin/omarchy-sudo-passwordless-toggle rename to bin/omarchy-sudo-passwordless index 530a7dea..ad157ae9 100755 --- a/bin/omarchy-sudo-passwordless-toggle +++ b/bin/omarchy-sudo-passwordless @@ -1,19 +1,20 @@ #!/bin/bash -# Toggle passwordless sudo for the current user. -# Usage: omarchy-sudo-passwordless-toggle [MINUTES] -# First run: enables passwordless sudo for 15 minutes (after confirmation). -# Second run: disables it early. +# omarchy:summary=Toggle passwordless sudo for the current user. +# omarchy:args=[MINUTES] +# omarchy:requires-sudo=true NOPASSWD_FILE="/etc/sudoers.d/99-omarchy-nopasswd-${USER}" TIMER_NAME="omarchy-nopasswd-expire-${USER}" MINUTES=${1:-15} if [[ $1 && ! $1 =~ ^[0-9]+$ ]]; then - echo "Usage: omarchy-sudo-passwordless-toggle [MINUTES]" >&2 + echo "Usage: omarchy-sudo-passwordless [MINUTES]" >&2 exit 1 fi +echo "Toggle passwordless sudo..." + # Safety: if the file exists but the timer doesn't (e.g. after reboot), clean up if sudo test -f "$NOPASSWD_FILE" && ! systemctl is-active "${TIMER_NAME}.timer" &>/dev/null; then sudo rm "$NOPASSWD_FILE" @@ -33,7 +34,7 @@ if sudo test -f "$NOPASSWD_FILE"; then fi else echo "" - echo "⚠️WARNING: This will allow ANY process running as your user to" + echo "⚠️ WARNING: This will allow ANY process running as your user to" echo "execute ANY command as root WITHOUT a password for ${MINUTES} minutes." echo "" echo "This is useful for AI agents that need to run sudo commands," @@ -52,7 +53,7 @@ else echo "" echo "Passwordless sudo has been ENABLED. It will automatically disable in ${MINUTES} minutes." - echo "Note: if you restart before then, run omarchy-sudo-passwordless-toggle again to disable it." + echo "Note: if you restart before then, run omarchy-sudo-passwordless again to disable it." else echo "Aborted. No changes made." fi diff --git a/bin/omarchy-sudo-reset b/bin/omarchy-sudo-reset index 2c568469..56d91a8d 100755 --- a/bin/omarchy-sudo-reset +++ b/bin/omarchy-sudo-reset @@ -1,7 +1,5 @@ #!/bin/bash -# Reset the sudo lockout/faillock for the current user. -# This clears any failed authentication attempts that may have locked the user out. +# omarchy:summary=Reset the sudo lockout/faillock for the current user. -# Resetting sudo lockout for user su -c "faillock --reset --user $USER" diff --git a/bin/omarchy-swayosd-brightness b/bin/omarchy-swayosd-brightness index 8cc1f119..cf089a86 100755 --- a/bin/omarchy-swayosd-brightness +++ b/bin/omarchy-swayosd-brightness @@ -1,7 +1,7 @@ #!/bin/bash -# Display brightness level using SwayOSD on the current monitor. -# Usage: omarchy-swayosd-brightness +# omarchy:summary=Display brightness level using SwayOSD on the current monitor. +# omarchy:args= percent="$1" diff --git a/bin/omarchy-swayosd-client b/bin/omarchy-swayosd-client index e05beb4f..e8343aaa 100755 --- a/bin/omarchy-swayosd-client +++ b/bin/omarchy-swayosd-client @@ -1,5 +1,6 @@ #!/bin/bash -# Wrapper for swayosd-client that targets the currently focused monitor. +# omarchy:summary=Wrapper for swayosd-client that targets the currently focused monitor. +# omarchy:args= exec swayosd-client --monitor "$(omarchy-hyprland-monitor-focused)" "$@" diff --git a/bin/omarchy-swayosd-kbd-brightness b/bin/omarchy-swayosd-kbd-brightness index 729b7c4c..9252d475 100755 --- a/bin/omarchy-swayosd-kbd-brightness +++ b/bin/omarchy-swayosd-kbd-brightness @@ -1,7 +1,7 @@ #!/bin/bash -# Display keyboard brightness level using SwayOSD on the current monitor. -# Usage: omarchy-swayosd-kbd-brightness +# omarchy:summary=Display keyboard brightness level using SwayOSD on the current monitor. +# omarchy:args= percent="$1" diff --git a/bin/omarchy-lock-screen b/bin/omarchy-system-lock similarity index 69% rename from bin/omarchy-lock-screen rename to bin/omarchy-system-lock index df40b335..0ccd4d90 100755 --- a/bin/omarchy-lock-screen +++ b/bin/omarchy-system-lock @@ -1,8 +1,10 @@ #!/bin/bash -# Locks the system using hyprlock, but not before ensuring 1password has also been locked, and the screensaver stopped. +# omarchy:summary=Lock the screen +# omarchy:group=system +# omarchy:name=lock +# omarchy:examples=omarchy system lock -# Lock the screen pidof hyprlock || hyprlock & # Set keyboard layout to default (first layout) diff --git a/bin/omarchy-system-logout b/bin/omarchy-system-logout index bf70b861..c78f7485 100755 --- a/bin/omarchy-system-logout +++ b/bin/omarchy-system-logout @@ -1,9 +1,9 @@ #!/bin/bash -# Logout command that first closes all application windows (thus giving them a chance to save state), -# then stops the session, returning to the SDDM login screen. +# omarchy:summary=Log out after closing application windows +# omarchy:examples=omarchy logout | omarchy system logout +# omarchy:aliases=omarchy logout -# Schedule the session stop after closing windows (detached from terminal) nohup bash -c "sleep 2 && uwsm stop" >/dev/null 2>&1 & # Now close all windows diff --git a/bin/omarchy-system-reboot b/bin/omarchy-system-reboot index ec5f7cbc..661971bd 100755 --- a/bin/omarchy-system-reboot +++ b/bin/omarchy-system-reboot @@ -1,7 +1,8 @@ #!/bin/bash -# Reboot command that first closes all application windows (thus giving them a chance to save state). -# This is particularly helpful for applications like Chromium that otherwise won't shutdown cleanly. +# omarchy:summary=Reboot after closing application windows +# omarchy:examples=omarchy reboot | omarchy system reboot +# omarchy:aliases=omarchy reboot omarchy-state clear re*-required diff --git a/bin/omarchy-system-shutdown b/bin/omarchy-system-shutdown index be1a69d0..50e489ff 100755 --- a/bin/omarchy-system-shutdown +++ b/bin/omarchy-system-shutdown @@ -1,7 +1,8 @@ #!/bin/bash -# Shutdown command that first closes all application windows (thus giving them a chance to save state). -# This is particularly helpful for applications like Chromium that otherwise won't shutdown cleanly. +# omarchy:summary=Shut down after closing application windows +# omarchy:examples=omarchy shutdown | omarchy system shutdown +# omarchy:aliases=omarchy shutdown omarchy-state clear re*-required diff --git a/bin/omarchy-theme-bg-install b/bin/omarchy-theme-bg-install index 2ba2cb8b..60d23a7d 100755 --- a/bin/omarchy-theme-bg-install +++ b/bin/omarchy-theme-bg-install @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Open the current theme's user background folder + CURRENT_THEME_NAME=$(cat "$HOME/.config/omarchy/current/theme.name") THEME_USER_BACKGROUNDS="$HOME/.config/omarchy/backgrounds/$CURRENT_THEME_NAME" diff --git a/bin/omarchy-theme-bg-next b/bin/omarchy-theme-bg-next index 42f15340..e2d0bd4a 100755 --- a/bin/omarchy-theme-bg-next +++ b/bin/omarchy-theme-bg-next @@ -1,6 +1,7 @@ #!/bin/bash -# Cycles through the background images available +# omarchy:summary=Cycle to the next background for the current theme +# omarchy:examples=omarchy theme bg next THEME_NAME=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null) THEME_BACKGROUNDS_PATH="$HOME/.config/omarchy/current/theme/backgrounds/" diff --git a/bin/omarchy-theme-bg-set b/bin/omarchy-theme-bg-set index 45992612..4b069086 100755 --- a/bin/omarchy-theme-bg-set +++ b/bin/omarchy-theme-bg-set @@ -1,6 +1,8 @@ #!/bin/bash -# Sets the specified image as the current background +# omarchy:summary=Set the current background image +# omarchy:args= +# omarchy:examples=omarchy theme bg set ~/Pictures/wallpaper.png if [[ -z $1 ]]; then echo "Usage: omarchy-theme-bg-set " >&2 diff --git a/bin/omarchy-theme-colors-from-alacritty b/bin/omarchy-theme-colors-from-alacritty new file mode 100755 index 00000000..7c41b5ec --- /dev/null +++ b/bin/omarchy-theme-colors-from-alacritty @@ -0,0 +1,210 @@ +#!/bin/bash + +# omarchy:summary=Generate a theme's colors.toml from its alacritty.toml palette +# omarchy:args= + +set -e + +THEME_SOURCE="${1:-}" +COLORS_OUTPUT="$THEME_SOURCE/colors.toml" +ALACRITTY_FILE="$THEME_SOURCE/alacritty.toml" + +if [[ -z $THEME_SOURCE ]]; then + echo "Usage: omarchy-theme-colors-from-alacritty " >&2 + exit 1 +fi + +# Skip if colors.toml already exists in source theme +if [[ -f $COLORS_OUTPUT ]]; then + exit 0 +fi + +# Skip if no alacritty.toml to extract from +if [[ ! -f $ALACRITTY_FILE ]]; then + exit 0 +fi + +normalize_hex() { + local color="$1" + [[ -z $color ]] && return + color="${color#0x}" + color="${color#\#}" + if [[ $color =~ ^[0-9a-fA-F]{6}$ ]]; then + printf "#%s\n" "${color,,}" + fi +} + +extract_color_in_section() { + local section="$1" + local key="$2" + local color_hex="" + color_hex=$(awk -v section="$section" -v key="$key" ' + function trim(value) { + gsub(/^[ \t]+|[ \t]+$/, "", value) + return value + } + + function strip_comment(value, i, ch, out, in_single, in_double, prev) { + out = "" + in_single = 0 + in_double = 0 + prev = "" + + for (i = 1; i <= length(value); i++) { + ch = substr(value, i, 1) + + if (ch == "\"" && !in_single && prev != "\\") { + in_double = !in_double + } else if (ch == "'\''" && !in_double) { + in_single = !in_single + } + + if (ch == "#" && !in_single && !in_double) { + break + } + + out = out ch + prev = ch + } + + gsub(/[ \t]+$/, "", out) + return out + } + + /^[ \t]*\[/ { + in_section = ($0 ~ "^[ \\t]*\\[" section "\\][ \\t]*$") + next + } + + in_section { + line = $0 + line = strip_comment(line) + + split_pos = index(line, "=") + if (split_pos == 0) { + next + } + + current_key = trim(substr(line, 1, split_pos - 1)) + current_value = trim(substr(line, split_pos + 1)) + + if (current_key == key) { + gsub(/["'\''#]/, "", current_value) + sub(/^0[xX]/, "", current_value) + if (current_value ~ /^[0-9A-Fa-f]{6}$/) { + print current_value + exit + } + } + } + ' "$ALACRITTY_FILE") + + if [[ -n $color_hex && $color_hex =~ ^[0-9a-fA-F]{6}$ ]]; then + normalize_hex "$color_hex" + fi + + return 0 +} + +names=(black red green yellow blue magenta cyan white) + +# Extract normal colors (color0-7) +for i in {0..7}; do + name="${names[$i]}" + val=$(extract_color_in_section "colors.normal" "$name") + if [[ -z $val ]]; then + val=$(extract_color_in_section "colors" "normal.$name") + fi + + printf -v "color$i" "%s" "$val" +done + +# Validate we have all normal colors (required) +for c in color0 color1 color2 color3 color4 color5 color6 color7; do + if [[ -z ${!c} ]]; then + echo "Warning: Cannot extract all normal colors from $ALACRITTY_FILE, skipping generation" >&2 + exit 0 + fi +done + +# Extract bright colors (color8-15) +for i in {0..7}; do + normal="color$i" + bright="color$((i + 8))" + name="${names[$i]}" + + val=$(extract_color_in_section "colors.bright" "$name") + if [[ -z $val ]]; then + val=$(extract_color_in_section "colors" "bright.$name") + fi + + printf -v "$bright" "%s" "${val:-${!normal}}" +done + +# Extract primary colors +background=$(extract_color_in_section "colors.primary" "background") +foreground=$(extract_color_in_section "colors.primary" "foreground") + +if [[ -z $background ]]; then + background=$(extract_color_in_section "colors" "primary.background") +fi + +if [[ -z $foreground ]]; then + foreground=$(extract_color_in_section "colors" "primary.foreground") +fi + +# Extract cursor color (from [colors.cursor] section) +cursor=$(extract_color_in_section "colors.cursor" "cursor") + +if [[ -z $cursor ]]; then + cursor=$(extract_color_in_section "colors" "cursor.cursor") +fi + +# Extract selection colors +selection_background=$(extract_color_in_section "colors.selection" "background") + +if [[ -z $selection_background ]]; then + selection_background=$(extract_color_in_section "colors" "selection.background") +fi + +selection_foreground=$(extract_color_in_section "colors.selection" "text") + +if [[ -z $selection_foreground ]]; then + selection_foreground=$(extract_color_in_section "colors" "selection.text") +fi + +# Apply defaults +background=${background:-$color0} +foreground=${foreground:-$color7} +cursor=${cursor:-$foreground} +selection_background=${selection_background:-$foreground} +selection_foreground=${selection_foreground:-$background} +accent=$color4 + +mkdir -p "$THEME_SOURCE" + +cat > "$COLORS_OUTPUT" < +# omarchy:summary=Install a theme from a git repository +# omarchy:args=[git-repo-url] +# omarchy:examples=omarchy theme install https://github.com/example/omarchy-example-theme.git +# omarchy:examples=omarchy theme install git@github.com:example/omarchy-example-theme.git if [[ -z $1 ]]; then echo -e "\e[32mSee https://manuals.omamix.org/2/the-omarchy-manual/90/extra-themes\n\e[0m" - REPO_URL=$(gum input --placeholder="Git repo URL for theme" --header="") + REPO_URL=$(gum input --placeholder="Git repo URL (https or git@host:org/repo.git)" --header="") else REPO_URL="$1" fi @@ -15,7 +17,11 @@ if [[ -z $REPO_URL ]]; then fi THEMES_DIR="$HOME/.config/omarchy/themes" -THEME_NAME=$(basename "$REPO_URL" .git | sed -E 's/^omarchy-//; s/-theme$//' | tr '[:upper:]' '[:lower:]') + +# Strip user@host: prefix from scp-style SSH URLs so basename sees just the path +REPO_PATH="$REPO_URL" +[[ $REPO_PATH != *"://"* && $REPO_PATH == *:*/* ]] && REPO_PATH="${REPO_PATH#*:}" +THEME_NAME=$(basename "$REPO_PATH" .git | sed -E 's/^omarchy-//; s/-theme$//' | tr '[:upper:]' '[:lower:]') THEME_PATH="$THEMES_DIR/$THEME_NAME" # Remove existing theme if present diff --git a/bin/omarchy-theme-list b/bin/omarchy-theme-list index 08678288..0b901fc0 100755 --- a/bin/omarchy-theme-list +++ b/bin/omarchy-theme-list @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=List available themes +# omarchy:examples=omarchy theme list | omarchy theme set "Tokyo Night" + { find ~/.config/omarchy/themes/ -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%f\n' find "$OMARCHY_PATH/themes/" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' diff --git a/bin/omarchy-theme-refresh b/bin/omarchy-theme-refresh index e967f289..bbd79a31 100755 --- a/bin/omarchy-theme-refresh +++ b/bin/omarchy-theme-refresh @@ -1,6 +1,6 @@ #!/bin/bash -# Refresh the current theme from its templates. +# omarchy:summary=Refresh the current theme from its templates. THEME_NAME_PATH="$HOME/.config/omarchy/current/theme.name" diff --git a/bin/omarchy-theme-remove b/bin/omarchy-theme-remove index 98a81fa0..dac33cd4 100755 --- a/bin/omarchy-theme-remove +++ b/bin/omarchy-theme-remove @@ -1,7 +1,8 @@ #!/bin/bash -# omarchy-theme-remove: Remove a theme from Omarchy by name -# Usage: omarchy-theme-remove +# omarchy:summary=Remove a user-installed theme +# omarchy:args=[theme-name] +# omarchy:examples=omarchy theme remove "Tokyo Night" if [[ -z $1 ]]; then mapfile -t extra_themes < <(find ~/.config/omarchy/themes -mindepth 1 -maxdepth 1 -type d ! -xtype l -printf '%f\n') diff --git a/bin/omarchy-theme-set b/bin/omarchy-theme-set index 0c57455b..f231d11e 100755 --- a/bin/omarchy-theme-set +++ b/bin/omarchy-theme-set @@ -1,5 +1,9 @@ #!/bin/bash +# omarchy:summary=Apply an Omarchy theme +# omarchy:args= +# omarchy:examples=omarchy theme list | omarchy theme set "Tokyo Night" + if [[ -z $1 ]]; then echo "Usage: omarchy-theme-set " exit 1 @@ -25,6 +29,11 @@ mkdir -p "$NEXT_THEME_PATH" cp -r "$OMARCHY_THEMES_PATH/$THEME_NAME/"* "$NEXT_THEME_PATH/" 2>/dev/null cp -r "$USER_THEMES_PATH/$THEME_NAME/"* "$NEXT_THEME_PATH/" 2>/dev/null +# Generate colors.toml from alacritty.toml if theme is missing colors.toml +if [[ ! -f $NEXT_THEME_PATH/colors.toml && -f $NEXT_THEME_PATH/alacritty.toml ]]; then + omarchy-theme-colors-from-alacritty "$NEXT_THEME_PATH" +fi + # Generate dynamic configs omarchy-theme-set-templates @@ -48,6 +57,7 @@ omarchy-restart-hyprctl omarchy-restart-btop omarchy-restart-opencode omarchy-restart-mako +omarchy-restart-helix # Change app-specific themes omarchy-theme-set-gnome diff --git a/bin/omarchy-theme-set-browser b/bin/omarchy-theme-set-browser index 05c8fc96..e43f0634 100755 --- a/bin/omarchy-theme-set-browser +++ b/bin/omarchy-theme-set-browser @@ -1,8 +1,10 @@ #!/bin/bash +# omarchy:summary=Apply the current theme color to Chromium and Brave + CHROMIUM_THEME=~/.config/omarchy/current/theme/chromium.theme -if omarchy-cmd-present chromium || omarchy-cmd-present brave; then +if omarchy-cmd-present chromium || omarchy-cmd-present brave || omarchy-cmd-present brave-origin-beta; then if [[ -f $CHROMIUM_THEME ]]; then THEME_RGB_COLOR=$(<$CHROMIUM_THEME) THEME_HEX_COLOR=$(printf '#%02x%02x%02x' ${THEME_RGB_COLOR//,/ }) @@ -17,8 +19,12 @@ if omarchy-cmd-present chromium || omarchy-cmd-present brave; then pgrep -x chromium >/dev/null && chromium --refresh-platform-policy --no-startup-window &>/dev/null fi - if omarchy-cmd-present brave; then + # Brave and Brave Origin Beta share /etc/brave/policies, so a single write covers both + if omarchy-cmd-present brave || omarchy-cmd-present brave-origin-beta; then echo "{\"BrowserThemeColor\": \"$THEME_HEX_COLOR\", \"BrowserColorScheme\": \"device\"}" | tee "/etc/brave/policies/managed/color.json" >/dev/null - pgrep -x brave >/dev/null && brave --refresh-platform-policy --no-startup-window &>/dev/null + if pgrep -x brave >/dev/null; then + omarchy-cmd-present brave && brave --refresh-platform-policy --no-startup-window &>/dev/null + omarchy-cmd-present brave-origin-beta && brave-origin-beta --refresh-platform-policy --no-startup-window &>/dev/null + fi fi fi diff --git a/bin/omarchy-theme-set-gnome b/bin/omarchy-theme-set-gnome index da25b66a..66e3e204 100755 --- a/bin/omarchy-theme-set-gnome +++ b/bin/omarchy-theme-set-gnome @@ -1,6 +1,7 @@ #!/bin/bash -# Change gnome modes +# omarchy:summary=Apply the current theme to GNOME color mode and icon settings + if [[ -f ~/.config/omarchy/current/theme/light.mode ]]; then gsettings set org.gnome.desktop.interface color-scheme "prefer-light" gsettings set org.gnome.desktop.interface gtk-theme "Adwaita" diff --git a/bin/omarchy-theme-set-keyboard b/bin/omarchy-theme-set-keyboard index 6c237a8e..7fc9c7a5 100755 --- a/bin/omarchy-theme-set-keyboard +++ b/bin/omarchy-theme-set-keyboard @@ -1,4 +1,6 @@ #!/bin/bash +# omarchy:summary=Apply the current theme keyboard color to supported keyboards + omarchy-theme-set-keyboard-asus-rog omarchy-theme-set-keyboard-f16 diff --git a/bin/omarchy-theme-set-keyboard-asus-rog b/bin/omarchy-theme-set-keyboard-asus-rog index e0078ee4..971097e6 100755 --- a/bin/omarchy-theme-set-keyboard-asus-rog +++ b/bin/omarchy-theme-set-keyboard-asus-rog @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Apply the current theme keyboard color to ASUS ROG keyboards + ASUSCTL_THEME=~/.config/omarchy/current/theme/keyboard.rgb if omarchy-cmd-present asusctl; then diff --git a/bin/omarchy-theme-set-keyboard-f16 b/bin/omarchy-theme-set-keyboard-f16 index 1a30991e..466690d4 100755 --- a/bin/omarchy-theme-set-keyboard-f16 +++ b/bin/omarchy-theme-set-keyboard-f16 @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Apply the current theme keyboard color to Framework Laptop 16 keyboards + FRAMEWORK16_THEME=~/.config/omarchy/current/theme/keyboard.rgb if omarchy-cmd-present qmk_hid && [[ -f $FRAMEWORK16_THEME ]]; then diff --git a/bin/omarchy-theme-set-obsidian b/bin/omarchy-theme-set-obsidian index 420bd8c3..dd9468aa 100755 --- a/bin/omarchy-theme-set-obsidian +++ b/bin/omarchy-theme-set-obsidian @@ -1,6 +1,6 @@ #!/bin/bash -# Sync Omarchy theme to all Obsidian vaults +# omarchy:summary=Sync Omarchy theme to all Obsidian vaults CURRENT_THEME_DIR="$HOME/.config/omarchy/current/theme" diff --git a/bin/omarchy-theme-set-templates b/bin/omarchy-theme-set-templates index fde3ad18..f272ffff 100755 --- a/bin/omarchy-theme-set-templates +++ b/bin/omarchy-theme-set-templates @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Generate themed config files from Omarchy templates + TEMPLATES_DIR="$OMARCHY_PATH/default/themed" USER_TEMPLATES_DIR="$HOME/.config/omarchy/themed" NEXT_THEME_DIR="$HOME/.config/omarchy/current/next-theme" diff --git a/bin/omarchy-theme-set-vscode b/bin/omarchy-theme-set-vscode index bc9b5716..703b1563 100755 --- a/bin/omarchy-theme-set-vscode +++ b/bin/omarchy-theme-set-vscode @@ -1,6 +1,6 @@ #!/bin/bash -# Sync Omarchy theme to VS Code, VSCodium, and Cursor +# omarchy:summary=Sync Omarchy theme to VS Code, VSCodium, and Cursor VS_CODE_THEME="$HOME/.config/omarchy/current/theme/vscode.json" @@ -14,8 +14,8 @@ set_theme() { theme_name=$(jq -r '.name' "$VS_CODE_THEME") extension=$(jq -r '.extension' "$VS_CODE_THEME") - if [[ -n $extension ]] && ! "$editor_cmd" --list-extensions | grep -Fxq "$extension"; then - "$editor_cmd" --install-extension "$extension" >/dev/null + if [[ -n $extension ]] && ! "$editor_cmd" --list-extensions 2>/dev/null | grep -Fxq "$extension"; then + "$editor_cmd" --install-extension "$extension" >/dev/null 2>&1 fi mkdir -p "$(dirname "$settings_path")" diff --git a/bin/omarchy-theme-update b/bin/omarchy-theme-update index cfb823f4..a68cb176 100755 --- a/bin/omarchy-theme-update +++ b/bin/omarchy-theme-update @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Update user-installed git themes + for dir in ~/.config/omarchy/themes/*/; do if [[ -d $dir ]] && [[ ! -L ${dir%/} ]] && [[ -d $dir/.git ]]; then echo "Updating: $(basename "$dir")" diff --git a/bin/omarchy-toggle b/bin/omarchy-toggle index 7db467fa..f5eb1a3b 100755 --- a/bin/omarchy-toggle +++ b/bin/omarchy-toggle @@ -1,6 +1,7 @@ #!/bin/bash -# Toggle Omarchy features between enabled and disabled +# omarchy:summary=Toggle Omarchy features between enabled and disabled +# omarchy:args=[--enabled-notification ] [--disabled-notification ] ENABLED_NOTIFICATION="" DISABLED_NOTIFICATION="" diff --git a/bin/omarchy-toggle-enabled b/bin/omarchy-toggle-enabled index dd37c881..dd4f58c6 100755 --- a/bin/omarchy-toggle-enabled +++ b/bin/omarchy-toggle-enabled @@ -1,4 +1,6 @@ #!/bin/bash -# Check if a toggle is enabled (flag file exists) +# omarchy:summary=Check if a toggle is enabled (flag file exists) +# omarchy:args= + [[ -f "$HOME/.local/state/omarchy/toggles/$1" ]] diff --git a/bin/omarchy-toggle-hybrid-gpu b/bin/omarchy-toggle-hybrid-gpu index 4c573243..89b3ae8e 100755 --- a/bin/omarchy-toggle-hybrid-gpu +++ b/bin/omarchy-toggle-hybrid-gpu @@ -1,9 +1,8 @@ #!/bin/bash -# Toggle dedicated vs integrated GPU mode via supergfxd (for hybrid gpu laptops, like Asus G14). -# Requires reboot to take effect. +# omarchy:summary=Toggle dedicated vs integrated GPU mode via supergfxd (for hybrid gpu laptops, like Asus G14). +# omarchy:requires-sudo=true -# Ensure supergfxctl has been installed if omarchy-cmd-missing supergfxctl; then omarchy-pkg-add supergfxctl diff --git a/bin/omarchy-toggle-idle b/bin/omarchy-toggle-idle index a80eec45..622f1ab4 100755 --- a/bin/omarchy-toggle-idle +++ b/bin/omarchy-toggle-idle @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Toggle hypridle idle locking + if pgrep -x hypridle >/dev/null; then pkill -x hypridle notify-send -u low "󱫖 Stop locking computer when idle" diff --git a/bin/omarchy-toggle-nightlight b/bin/omarchy-toggle-nightlight index e05a1d45..c308b757 100755 --- a/bin/omarchy-toggle-nightlight +++ b/bin/omarchy-toggle-nightlight @@ -1,6 +1,8 @@ #!/bin/bash -# Default temperature values +# omarchy:summary=Toggle nightlight screen temperature +# omarchy:examples=omarchy toggle nightlight + ON_TEMP=4000 OFF_TEMP=6000 diff --git a/bin/omarchy-toggle-notification-silencing b/bin/omarchy-toggle-notification-silencing index 15ee7b5b..5e327ec2 100755 --- a/bin/omarchy-toggle-notification-silencing +++ b/bin/omarchy-toggle-notification-silencing @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Toggle notification do-not-disturb mode + makoctl mode -t do-not-disturb if makoctl mode | grep -q 'do-not-disturb'; then diff --git a/bin/omarchy-toggle-screensaver b/bin/omarchy-toggle-screensaver index 33e8d1bc..681c35ef 100755 --- a/bin/omarchy-toggle-screensaver +++ b/bin/omarchy-toggle-screensaver @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Toggle screensaver availability + omarchy-toggle \ --enabled-notification "󱄄 Screensaver disabled" \ --disabled-notification "󱄄 Screensaver enabled" \ diff --git a/bin/omarchy-toggle-suspend b/bin/omarchy-toggle-suspend index cd0d2191..c9ecac0a 100755 --- a/bin/omarchy-toggle-suspend +++ b/bin/omarchy-toggle-suspend @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Toggle suspend availability in the system menu + omarchy-toggle \ --enabled-notification "󰒲 Suspend removed from system menu" \ --disabled-notification "󰒲 Suspend now available in system menu" \ diff --git a/bin/omarchy-toggle-touchpad b/bin/omarchy-toggle-touchpad index 6c8428ca..06764dab 100755 --- a/bin/omarchy-toggle-touchpad +++ b/bin/omarchy-toggle-touchpad @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Enable, disable, or toggle the touchpad +# omarchy:args=[on|off|toggle] + STATE_CONF="$HOME/.local/state/omarchy/toggles/hypr/touchpad-disabled.conf" device="$(omarchy-hw-touchpad)" diff --git a/bin/omarchy-toggle-touchscreen b/bin/omarchy-toggle-touchscreen new file mode 100755 index 00000000..a0b5ccb0 --- /dev/null +++ b/bin/omarchy-toggle-touchscreen @@ -0,0 +1,32 @@ +#!/bin/bash + +# omarchy:summary=Enable, disable, or toggle the touch functionality of the screen +# omarchy:args=[on|off|toggle] + +STATE_CONF="$HOME/.local/state/omarchy/toggles/hypr/touchscreen-disabled.conf" + +device="$(omarchy-hw-touchscreen)" + +if [[ -z $device ]]; then + echo "No touchscreen device found" >&2 + exit 1 +fi + +enable() { + hyprctl keyword "device[$device]:enabled" true >/dev/null + rm -f "$STATE_CONF" + omarchy-swayosd-client --custom-icon device-support-touch-symbolic --custom-message "Touchscreen enabled" +} + +disable() { + hyprctl keyword "device[$device]:enabled" false >/dev/null + mkdir -p "$(dirname "$STATE_CONF")" + printf 'device {\n name = %s\n enabled = false\n}\n' "$device" > "$STATE_CONF" + omarchy-swayosd-client --custom-icon touch-disabled-symbolic --custom-message "Touchscreen disabled" +} + +case "${1:-toggle}" in + on) enable ;; + off) disable ;; + toggle) if [[ -f $STATE_CONF ]]; then enable; else disable; fi ;; +esac diff --git a/bin/omarchy-toggle-waybar b/bin/omarchy-toggle-waybar index 25762820..b441f011 100755 --- a/bin/omarchy-toggle-waybar +++ b/bin/omarchy-toggle-waybar @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Toggle Waybar visibility +# omarchy:examples=omarchy toggle waybar + omarchy-toggle waybar-off if pgrep -x waybar >/dev/null; then diff --git a/bin/omarchy-tui-install b/bin/omarchy-tui-install index 2d6397a2..d529b54f 100755 --- a/bin/omarchy-tui-install +++ b/bin/omarchy-tui-install @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Create a desktop launcher for a terminal UI app +# omarchy:args=[name command window-style icon-url] + set -e if (( $# != 4 )); then diff --git a/bin/omarchy-tui-remove b/bin/omarchy-tui-remove index 3b97df8c..369528e2 100755 --- a/bin/omarchy-tui-remove +++ b/bin/omarchy-tui-remove @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Remove terminal UI desktop launchers +# omarchy:args=[name...] + set -e ICON_DIR="$HOME/.local/share/applications/icons" diff --git a/bin/omarchy-tui-remove-all b/bin/omarchy-tui-remove-all index 8efe4d80..7f1c11f0 100755 --- a/bin/omarchy-tui-remove-all +++ b/bin/omarchy-tui-remove-all @@ -1,7 +1,6 @@ #!/bin/bash -# Remove all TUIs installed via omarchy-tui-install. -# Identifies TUIs by their Exec pattern (xdg-terminal-exec --app-id=TUI.). +# omarchy:summary=Remove all TUIs installed via omarchy-tui-install. set -e diff --git a/bin/omarchy-tz-select b/bin/omarchy-tz-select index 24003228..6ddb26c2 100755 --- a/bin/omarchy-tz-select +++ b/bin/omarchy-tz-select @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Select and set the system timezone +# omarchy:requires-sudo=true + timezone=$(timedatectl list-timezones | gum filter --height 20 --header "Set timezone") || exit 1 sudo timedatectl set-timezone "$timezone" echo "Timezone is now set to $timezone" diff --git a/bin/omarchy-update b/bin/omarchy-update index a9b2ba8d..f1ca5bc0 100755 --- a/bin/omarchy-update +++ b/bin/omarchy-update @@ -1,5 +1,10 @@ #!/bin/bash +# omarchy:summary=Update Omarchy and system packages +# omarchy:args=[-y] +# omarchy:examples=omarchy update | omarchy update -y +# omarchy:requires-sudo=true + set -e # Run the update inside a PTY so pacman/yay keep showing download progress diff --git a/bin/omarchy-update-analyze-logs b/bin/omarchy-update-analyze-logs index fb42e82e..1febd99d 100755 --- a/bin/omarchy-update-analyze-logs +++ b/bin/omarchy-update-analyze-logs @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Check the update log for known failure conditions + update_log="/tmp/omarchy-update.log" # Check for initramfs generation failure diff --git a/bin/omarchy-update-aur-pkgs b/bin/omarchy-update-aur-pkgs index 0dee5edf..4f496b33 100755 --- a/bin/omarchy-update-aur-pkgs +++ b/bin/omarchy-update-aur-pkgs @@ -1,6 +1,7 @@ #!/bin/bash -# Update AUR packages if any are installed +# omarchy:summary=Update AUR packages if any are installed + if pacman -Qem >/dev/null; then if omarchy-pkg-aur-accessible; then echo -e "\e[32m\nUpdate AUR packages\e[0m" diff --git a/bin/omarchy-update-available b/bin/omarchy-update-available index e5d19cf7..92c57adc 100755 --- a/bin/omarchy-update-available +++ b/bin/omarchy-update-available @@ -1,6 +1,7 @@ #!/bin/bash -# Get remote tag +# omarchy:summary=Get remote tag + latest_tag=$(git -C "$OMARCHY_PATH" ls-remote --tags origin | grep -v "{}" | awk '{print $2}' | sed 's#refs/tags/##' | sort -V | tail -n 1) if [[ -z $latest_tag ]]; then echo "Error: Could not retrieve latest tag." diff --git a/bin/omarchy-update-available-reset b/bin/omarchy-update-available-reset index 2f136cb0..d1e2ca4c 100755 --- a/bin/omarchy-update-available-reset +++ b/bin/omarchy-update-available-reset @@ -1,5 +1,6 @@ #!/bin/bash -# Ensure Waybar icon offering the available update is removed +# omarchy:summary=Ensure Waybar icon offering the available update is removed + pkill -RTMIN+7 waybar exit 0 diff --git a/bin/omarchy-update-branch b/bin/omarchy-update-branch index b10822cd..fa294b63 100755 --- a/bin/omarchy-update-branch +++ b/bin/omarchy-update-branch @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Switch Omarchy branches and update from the selected branch +# omarchy:args= + set -e if (($# == 0)); then diff --git a/bin/omarchy-update-confirm b/bin/omarchy-update-confirm index df3d8145..4ec37e85 100755 --- a/bin/omarchy-update-confirm +++ b/bin/omarchy-update-confirm @@ -1,6 +1,8 @@ #!/bin/bash -gum style --border normal --border-foreground 6 --padding "1 2" \ +# omarchy:summary=Prompt for confirmation before starting an update + +gum style --border normal --padding "1 2" \ "Ready to update?" \ "" \ "• You cannot stop the update once you start!" \ diff --git a/bin/omarchy-update-firmware b/bin/omarchy-update-firmware index d0613d82..f6dad359 100755 --- a/bin/omarchy-update-firmware +++ b/bin/omarchy-update-firmware @@ -1,7 +1,7 @@ #!/bin/bash -# Update system firmware using fwupd. Ensures the fwupd EFI binary is installed -# in the ESP so UEFI capsule updates work with the Limine bootloader. +# omarchy:summary=Update system firmware using fwupd. Ensures the fwupd EFI binary is installed +# omarchy:requires-sudo=true set -e echo -e "\e[32mUpdate Firmware\e[0m" diff --git a/bin/omarchy-update-git b/bin/omarchy-update-git index 04e428bb..5c64b624 100755 --- a/bin/omarchy-update-git +++ b/bin/omarchy-update-git @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Pull the latest Omarchy git changes + set -e echo -e "\e[32mUpdate Omarchy\e[0m" diff --git a/bin/omarchy-update-keyring b/bin/omarchy-update-keyring index 32bd3f22..74894f2b 100755 --- a/bin/omarchy-update-keyring +++ b/bin/omarchy-update-keyring @@ -1,6 +1,8 @@ #!/bin/bash -# Ensure we have the omarchy-keyring and it's populated +# omarchy:summary=Ensure the Omarchy keyring package is installed and populated +# omarchy:requires-sudo=true + if omarchy-pkg-missing omarchy-keyring || ! sudo pacman-key --list-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 &>/dev/null; then sudo pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org sudo pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571 diff --git a/bin/omarchy-update-orphan-pkgs b/bin/omarchy-update-orphan-pkgs index 3d7a3511..b1486867 100755 --- a/bin/omarchy-update-orphan-pkgs +++ b/bin/omarchy-update-orphan-pkgs @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Remove orphaned system packages after updates +# omarchy:requires-sudo=true + orphans=$(pacman -Qtdq || true) if [[ -n $orphans ]]; then echo -e "\e[32m\nRemove orphan system packages\e[0m" diff --git a/bin/omarchy-update-perform b/bin/omarchy-update-perform index d98b96c3..6e892610 100755 --- a/bin/omarchy-update-perform +++ b/bin/omarchy-update-perform @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Run the full Omarchy update pipeline +# omarchy:requires-sudo=true + set -e # Ensure screensaver/sleep doesn't set in during updates diff --git a/bin/omarchy-update-restart b/bin/omarchy-update-restart index 3a1bc4e2..2712cd39 100755 --- a/bin/omarchy-update-restart +++ b/bin/omarchy-update-restart @@ -1,8 +1,24 @@ #!/bin/bash +# omarchy:summary=Prompt for required reboot or service restarts after updates + echo -if find /usr/lib/modules -maxdepth 2 -name vmlinuz -newermt "$(uptime -s)" 2>/dev/null | grep -q .; then +running_kernel=$(uname -r) +kernel_updated=true + +for kernel in /usr/lib/modules/*/vmlinuz; do + if [[ -f $kernel ]] && pacman -Qo "$kernel" &>/dev/null; then + installed_kernel=$(basename "$(dirname "$kernel")") + + if [[ $installed_kernel == $running_kernel ]]; then + kernel_updated=false + break + fi + fi +done + +if [[ $kernel_updated == "true" ]]; then gum confirm "Linux kernel has been updated. Reboot?" && omarchy-system-reboot elif [[ -f $HOME/.local/state/omarchy/reboot-required ]]; then gum confirm "Updates require reboot. Ready?" && omarchy-system-reboot diff --git a/bin/omarchy-update-system-pkgs b/bin/omarchy-update-system-pkgs index 36a78418..6c6719f8 100755 --- a/bin/omarchy-update-system-pkgs +++ b/bin/omarchy-update-system-pkgs @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Update system packages with pacman +# omarchy:requires-sudo=true + set -e echo -e "\e[32m\nUpdate system packages\e[0m" diff --git a/bin/omarchy-update-time b/bin/omarchy-update-time index 14fc8b6f..c5e1d80b 100755 --- a/bin/omarchy-update-time +++ b/bin/omarchy-update-time @@ -1,4 +1,7 @@ #!/bin/bash +# omarchy:summary=Restart system time synchronization +# omarchy:requires-sudo=true + echo "Updating time..." sudo systemctl restart systemd-timesyncd diff --git a/bin/omarchy-update-without-idle b/bin/omarchy-update-without-idle index 20d1ef10..62a38fa4 100755 --- a/bin/omarchy-update-without-idle +++ b/bin/omarchy-update-without-idle @@ -1,5 +1,3 @@ #!/bin/bash -# No-op now that omarchy-update-perform is responsible for idle management. -# But this file can't be removed since it was referenced in old omarchy-update files, -# which would fail if this file is missing. +# omarchy:summary=No-op now that omarchy-update-perform is responsible for idle management. diff --git a/bin/omarchy-upload-log b/bin/omarchy-upload-log index c084f518..6d38eee8 100755 --- a/bin/omarchy-upload-log +++ b/bin/omarchy-upload-log @@ -1,6 +1,7 @@ #!/bin/bash -# Upload logs to 0x0.st +# omarchy:summary=Upload logs to 0x0.st +# omarchy:args= LOG_TYPE="${1:-install}" TEMP_LOG="/tmp/upload-log.txt" diff --git a/bin/omarchy-version b/bin/omarchy-version index 5ddc823f..da8b4974 100755 --- a/bin/omarchy-version +++ b/bin/omarchy-version @@ -1,2 +1,5 @@ #!/bin/bash + +# omarchy:summary=Print the installed Omarchy version + cat $OMARCHY_PATH/version diff --git a/bin/omarchy-version-branch b/bin/omarchy-version-branch index 43281d9a..898a71cd 100755 --- a/bin/omarchy-version-branch +++ b/bin/omarchy-version-branch @@ -1,3 +1,5 @@ #!/bin/bash +# omarchy:summary=Print the current Omarchy git branch + echo $(git -C "$OMARCHY_PATH" rev-parse --abbrev-ref HEAD) diff --git a/bin/omarchy-version-channel b/bin/omarchy-version-channel index 76233513..8a646cec 100755 --- a/bin/omarchy-version-channel +++ b/bin/omarchy-version-channel @@ -1,5 +1,7 @@ #!/bin/bash +# omarchy:summary=Print the active Omarchy mirror and package channel + if grep -q "https://stable-mirror.omarchy.org/" /etc/pacman.d/mirrorlist; then mirror="stable" elif grep -q "https://rc-mirror.omarchy.org/" /etc/pacman.d/mirrorlist; then diff --git a/bin/omarchy-version-pkgs b/bin/omarchy-version-pkgs index bc638110..9a37fb9a 100755 --- a/bin/omarchy-version-pkgs +++ b/bin/omarchy-version-pkgs @@ -1,3 +1,5 @@ #!/bin/bash +# omarchy:summary=Print when system packages were last upgraded + date -d "$(grep upgraded /var/log/pacman.log | tail -1 | sed -E 's/\[([^]]+)\].*/\1/')" "+%A, %B %d %Y at %H:%M" diff --git a/bin/omarchy-voxtype-config b/bin/omarchy-voxtype-config index 78a3254f..57665be4 100755 --- a/bin/omarchy-voxtype-config +++ b/bin/omarchy-voxtype-config @@ -1,4 +1,7 @@ #!/bin/bash + +# omarchy:summary=Open the Voxtype configuration file + set -e # Used by Voxtype waybar module to open config on right click diff --git a/bin/omarchy-voxtype-install b/bin/omarchy-voxtype-install index 6d2e1c42..9cb7af75 100755 --- a/bin/omarchy-voxtype-install +++ b/bin/omarchy-voxtype-install @@ -1,4 +1,8 @@ #!/bin/bash + +# omarchy:summary=Install and configure Voxtype dictation +# omarchy:requires-sudo=true + set -e # Install voxtype and configure it for use. diff --git a/bin/omarchy-voxtype-model b/bin/omarchy-voxtype-model index b58047d4..00ccb426 100755 --- a/bin/omarchy-voxtype-model +++ b/bin/omarchy-voxtype-model @@ -1,4 +1,7 @@ #!/bin/bash + +# omarchy:summary=Open Voxtype AI model setup + set -e omarchy-launch-floating-terminal-with-presentation "voxtype setup model" diff --git a/bin/omarchy-voxtype-remove b/bin/omarchy-voxtype-remove index b2083d15..4253f73d 100755 --- a/bin/omarchy-voxtype-remove +++ b/bin/omarchy-voxtype-remove @@ -1,4 +1,8 @@ #!/bin/bash + +# omarchy:summary=Remove Voxtype dictation and its configuration +# omarchy:requires-sudo=true + set -e # Remove voxtype and its configurations. diff --git a/bin/omarchy-voxtype-status b/bin/omarchy-voxtype-status index acab6f30..9576efaa 100755 --- a/bin/omarchy-voxtype-status +++ b/bin/omarchy-voxtype-status @@ -1,6 +1,7 @@ #!/bin/bash -# Clean up the voxtype --follow child when Waybar reloads +# omarchy:summary=Clean up the voxtype --follow child when Waybar reloads + trap 'kill 0' EXIT if omarchy-cmd-present voxtype; then diff --git a/bin/omarchy-webapp-handler-hey b/bin/omarchy-webapp-handler-hey index 37f4cf2d..b7c773d6 100755 --- a/bin/omarchy-webapp-handler-hey +++ b/bin/omarchy-webapp-handler-hey @@ -1,4 +1,8 @@ #!/bin/bash + +# omarchy:summary=Open HEY webmail and translate mailto links +# omarchy:args=[url] + url="$1" web_url="https://app.hey.com" diff --git a/bin/omarchy-webapp-handler-zoom b/bin/omarchy-webapp-handler-zoom index a27411ed..6692041f 100755 --- a/bin/omarchy-webapp-handler-zoom +++ b/bin/omarchy-webapp-handler-zoom @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Open Zoom web meetings from browser protocol links +# omarchy:args=[url] + url="$1" web_url="https://app.zoom.us/wc/home" diff --git a/bin/omarchy-webapp-install b/bin/omarchy-webapp-install index 264c7ea9..dbf00609 100755 --- a/bin/omarchy-webapp-install +++ b/bin/omarchy-webapp-install @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Create a desktop launcher for a web app +# omarchy:args=[name url icon [custom-exec] [mime-types]] + set -e ICON_DIR="$HOME/.local/share/applications/icons" diff --git a/bin/omarchy-webapp-remove b/bin/omarchy-webapp-remove index a54aba5c..d4db5270 100755 --- a/bin/omarchy-webapp-remove +++ b/bin/omarchy-webapp-remove @@ -1,5 +1,8 @@ #!/bin/bash +# omarchy:summary=Remove web app desktop launchers +# omarchy:args=[name...] + set -e ICON_DIR="$HOME/.local/share/applications/icons" @@ -41,3 +44,5 @@ for APP_NAME in "${APP_NAMES[@]}"; do rm -f "$ICON_DIR/$APP_NAME.png" echo "Removed $APP_NAME" done + +omarchy-restart-walker diff --git a/bin/omarchy-webapp-remove-all b/bin/omarchy-webapp-remove-all index d2006abc..142da29d 100755 --- a/bin/omarchy-webapp-remove-all +++ b/bin/omarchy-webapp-remove-all @@ -1,7 +1,6 @@ #!/bin/bash -# Remove all web apps installed via omarchy-webapp-install. -# Identifies web apps by their Exec pattern (omarchy-launch-webapp or omarchy-webapp-handler). +# omarchy:summary=Remove all web apps installed via omarchy-webapp-install. set -e @@ -33,4 +32,6 @@ if command -v update-desktop-database &>/dev/null; then update-desktop-database "$APP_DIR" &>/dev/null || true fi +omarchy-restart-walker + echo "Web apps removed successfully." diff --git a/bin/omarchy-wifi-powersave b/bin/omarchy-wifi-powersave index 9e1c5bbe..26810e52 100755 --- a/bin/omarchy-wifi-powersave +++ b/bin/omarchy-wifi-powersave @@ -1,4 +1,8 @@ #!/bin/bash + +# omarchy:summary=Set Wi-Fi power save mode on wireless interfaces +# omarchy:args= + for iface in /sys/class/net/*/wireless; do iface="$(basename "$(dirname "$iface")")" iw dev "$iface" set power_save "$1" 2>/dev/null diff --git a/bin/omarchy-windows-vm b/bin/omarchy-windows-vm index 70386213..ec918875 100755 --- a/bin/omarchy-windows-vm +++ b/bin/omarchy-windows-vm @@ -1,4 +1,9 @@ #!/bin/bash + +# omarchy:summary=Install, launch, stop, inspect, or remove the Windows VM +# omarchy:args= [options] +# omarchy:requires-sudo=true + COMPOSE_FILE="$HOME/.config/windows/docker-compose.yml" check_prerequisites() { diff --git a/config/brave-flags.conf b/config/brave-flags.conf index 88c8082b..57eba524 100644 --- a/config/brave-flags.conf +++ b/config/brave-flags.conf @@ -1,4 +1 @@ ---ozone-platform=wayland ---ozone-platform-hint=wayland ---enable-features=TouchpadOverscrollHistoryNavigation --load-extension=~/.local/share/omarchy/default/chromium/extensions/copy-url diff --git a/config/brave-origin-beta-flags.conf b/config/brave-origin-beta-flags.conf new file mode 120000 index 00000000..f3609ca7 --- /dev/null +++ b/config/brave-origin-beta-flags.conf @@ -0,0 +1 @@ +brave-flags.conf \ No newline at end of file diff --git a/config/chromium-flags.conf b/config/chromium-flags.conf index 88c8082b..c746fab6 100644 --- a/config/chromium-flags.conf +++ b/config/chromium-flags.conf @@ -1,4 +1,4 @@ --ozone-platform=wayland --ozone-platform-hint=wayland ---enable-features=TouchpadOverscrollHistoryNavigation +--enable-features=TouchpadOverscrollHistoryNavigation,VaapiVideoDecodeLinuxGL,VaapiVideoEncoder --load-extension=~/.local/share/omarchy/default/chromium/extensions/copy-url diff --git a/config/hypr/bindings.conf b/config/hypr/bindings.conf index 351fbe46..e7eb692d 100644 --- a/config/hypr/bindings.conf +++ b/config/hypr/bindings.conf @@ -7,10 +7,11 @@ bindd = SUPER ALT SHIFT, F, File manager (cwd), exec, uwsm-app -- nautilus --new bindd = SUPER SHIFT, B, Browser, exec, omarchy-launch-browser bindd = SUPER SHIFT ALT, B, Browser (private), exec, omarchy-launch-browser --private bindd = SUPER SHIFT, M, Music, exec, omarchy-launch-or-focus spotify +bindd = SUPER SHIFT ALT, M, Music TUI, exec, omarchy-launch-or-focus-tui cliamp bindd = SUPER SHIFT, N, Editor, exec, omarchy-launch-editor bindd = SUPER SHIFT, D, Docker, exec, omarchy-launch-tui lazydocker bindd = SUPER SHIFT, G, Signal, exec, omarchy-launch-or-focus ^signal$ "uwsm-app -- signal-desktop" -bindd = SUPER SHIFT, O, Obsidian, exec, omarchy-launch-or-focus ^obsidian$ "uwsm-app -- obsidian -disable-gpu --enable-wayland-ime" +bindd = SUPER SHIFT, O, Obsidian, exec, omarchy-launch-or-focus ^obsidian$ "uwsm-app -- obsidian" bindd = SUPER SHIFT, W, Typora, exec, uwsm-app -- typora --enable-wayland-ime bindd = SUPER SHIFT, SLASH, Passwords, exec, uwsm-app -- 1password @@ -34,6 +35,6 @@ bindd = SUPER SHIFT ALT, X, X Post, exec, omarchy-launch-webapp "https://x.com/c # bindd = SUPER, SPACE, Omarchy menu, exec, omarchy-menu # Logitech MX Keys -# bind = SUPER SHIFT, S, exec, omarchy-cmd-screenshot # Print Screen Button +# bind = SUPER SHIFT, S, exec, omarchy-capture-screenshot # Print Screen Button # bind = SUPER, H, exec, voxtype record toggle # Dictation Button # bind = SUPER, PERIOD, exec, omarchy-launch-walker -m symbols # Emoji Button diff --git a/config/hypr/hypridle.conf b/config/hypr/hypridle.conf index b7d17690..7d003275 100644 --- a/config/hypr/hypridle.conf +++ b/config/hypr/hypridle.conf @@ -1,5 +1,5 @@ general { - lock_cmd = omarchy-lock-screen # lock screen and 1password + lock_cmd = omarchy-system-lock # lock screen and 1password before_sleep_cmd = loginctl lock-session # lock before suspend. after_sleep_cmd = sleep 1 && hyprctl dispatch dpms on # delay for PAM readiness, then turn on display. inhibit_sleep = 3 # wait until screen is locked diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index ff272f9a..cf4f9ad0 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -1,4 +1,4 @@ -# Learn how to configure Hyprland: https://wiki.hyprland.org/Configuring/ +# Learn how to configure Hyprland: https://wiki.hypr.land/Configuring/ # Use defaults Omarchy defaults (but don't edit these directly!) source = ~/.local/share/omarchy/default/hypr/autostart.conf diff --git a/config/hypr/input.conf b/config/hypr/input.conf index 1dd2e075..36fb4403 100644 --- a/config/hypr/input.conf +++ b/config/hypr/input.conf @@ -1,5 +1,5 @@ # Control your input devices -# See https://wiki.hypr.land/Configuring/Variables/#input +# See https://wiki.hypr.land/Configuring/Basics/Variables/#input input { # Use multiple keyboard layouts and switch between them with Left Alt + Right Alt # kb_layout = us,dk,eu @@ -19,15 +19,15 @@ input { # Increase sensitivity for mouse/trackpad (default: 0) # sensitivity = 0.35 - # Turn off mouse acceleration (default: false) - # force_no_accel = true + # Turn off mouse acceleration (default: adaptive) + # accel_profile = flat touchpad { # Use natural (inverse) scrolling # natural_scroll = true # Use two-finger clicks for right-click instead of lower-right corner - # clickfinger_behavior = true + clickfinger_behavior = true # Control the speed of your scrolling scroll_factor = 0.4 @@ -45,7 +45,7 @@ windowrule = match:class (Alacritty|kitty), scroll_touchpad 1.5 windowrule = match:class com.mitchellh.ghostty, scroll_touchpad 0.2 # Enable touchpad gestures for changing workspaces -# See https://wiki.hyprland.org/Configuring/Gestures/ +# See https://wiki.hypr.land/Configuring/Advanced-and-Cool/Gestures/ # gesture = 3, horizontal, workspace # Enable touchpad gestures for moving focus (helpful on scrolling layout) diff --git a/config/hypr/looknfeel.conf b/config/hypr/looknfeel.conf index 2d2b7000..f4a2c00c 100644 --- a/config/hypr/looknfeel.conf +++ b/config/hypr/looknfeel.conf @@ -1,6 +1,6 @@ # Change the default Omarchy look'n'feel -# https://wiki.hyprland.org/Configuring/Variables/#general +# https://wiki.hypr.land/Configuring/Basics/Variables/#general general { # No gaps between windows or borders # gaps_in = 0 @@ -11,7 +11,7 @@ general { # layout = scrolling } -# https://wiki.hyprland.org/Configuring/Variables/#decoration +# https://wiki.hypr.land/Configuring/Basics/Variables/#decoration decoration { # Use round window corners # rounding = 8 @@ -21,13 +21,13 @@ decoration { # dim_strength = 0.15 } -# https://wiki.hyprland.org/Configuring/Variables/#animations +# https://wiki.hypr.land/Configuring/Basics/Variables/#animations animations { # Disable all animations # enabled = no } -# https://wiki.hypr.land/Configuring/Variables/#layout +# https://wiki.hypr.land/Configuring/Basics/Variables/#layout layout { # Avoid overly wide single-window layouts on wide screens # single_window_aspect_ratio = 1 1 diff --git a/config/hypr/monitors.conf b/config/hypr/monitors.conf index 01c9cde1..455c80fe 100644 --- a/config/hypr/monitors.conf +++ b/config/hypr/monitors.conf @@ -1,4 +1,4 @@ -# See https://wiki.hyprland.org/Configuring/Monitors/ +# See https://wiki.hypr.land/Configuring/Basics/Monitors/ # List current monitors and resolutions possible: hyprctl monitors # Format: monitor = [port], resolution, position, scale diff --git a/config/obsidian/user-flags.conf b/config/obsidian/user-flags.conf new file mode 100644 index 00000000..2f9cc082 --- /dev/null +++ b/config/obsidian/user-flags.conf @@ -0,0 +1,3 @@ +# Obsidian reads this file through the Arch package wrapper. +-disable-gpu +--enable-wayland-ime diff --git a/config/omarchy/extensions/menu.sh b/config/omarchy/extensions/menu.sh index 4ededf8e..f7d0b277 100644 --- a/config/omarchy/extensions/menu.sh +++ b/config/omarchy/extensions/menu.sh @@ -7,7 +7,7 @@ # # show_system_menu() { # case $(menu "System" " Lock\n󰐥 Shutdown") in -# *Lock*) omarchy-lock-screen ;; +# *Lock*) omarchy-system-lock ;; # *Shutdown*) omarchy-system-shutdown ;; # *) back_to show_main_menu ;; # esac diff --git a/config/waybar/config.jsonc b/config/waybar/config.jsonc index 8d857c69..cbf211c3 100644 --- a/config/waybar/config.jsonc +++ b/config/waybar/config.jsonc @@ -93,6 +93,7 @@ "tooltip-format-charging": "{power:>1.0f}W↑ {capacity}%", "interval": 5, "on-click": "omarchy-menu power", + "on-click-right": "notify-send -u low \"$(omarchy-battery-status)\"", "states": { "warning": 20, "critical": 10 @@ -137,7 +138,7 @@ "on-scroll-right": "" }, "custom/screenrecording-indicator": { - "on-click": "omarchy-cmd-screenrecord", + "on-click": "omarchy-capture-screenrecording", "exec": "$OMARCHY_PATH/default/waybar/indicators/screen-recording.sh", "signal": 8, "return-type": "json" diff --git a/default/bash/aliases b/default/bash/aliases index b3f6ad22..656d145f 100644 --- a/default/bash/aliases +++ b/default/bash/aliases @@ -48,7 +48,9 @@ alias cx='printf "\033[2J\033[3J\033[H" && claude --permission-mode bypassPermis alias d='docker' alias r='rails' alias t='tmux attach || tmux new -s Work' -alias i='tdl c cx' +alias ic='tdl c' +alias ix='tdl cx' +alias icx='tdl c cx' n() { if [ "$#" -eq 0 ]; then command nvim . ; else command nvim "$@"; fi; } # Git diff --git a/default/bash/completions b/default/bash/completions new file mode 100644 index 00000000..003d4f8c --- /dev/null +++ b/default/bash/completions @@ -0,0 +1,53 @@ +_omarchy_complete() { + COMPREPLY=() + local cur="${COMP_WORDS[COMP_CWORD]}" + + local omarchy_path bin_dir + omarchy_path=$(command -v omarchy 2>/dev/null) || return 0 + bin_dir=$(dirname -- "$(readlink -f -- "$omarchy_path" 2>/dev/null || printf '%s' "$omarchy_path")") + [[ -d $bin_dir ]] || return 0 + + local prefix="omarchy" + local i part + for ((i = 1; i < COMP_CWORD; i++)); do + part="${COMP_WORDS[i]}" + [[ -z $part || $part == -* ]] && continue + prefix+="-$part" + done + + local -A seen=() + local candidates=() + local file basename rest next + + shopt -s nullglob + for file in "$bin_dir/$prefix"-*; do + [[ -f $file && -x $file ]] || continue + basename="${file##*/}" + rest="${basename#"$prefix"-}" + next="${rest%%-*}" + if [[ -n $next && -z ${seen[$next]:-} ]]; then + seen[$next]=1 + candidates+=("$next") + fi + done + shopt -u nullglob + + if (( COMP_CWORD == 1 )); then + candidates+=("commands") + fi + + if [[ ${COMP_WORDS[1]:-} == "commands" ]] && (( COMP_CWORD >= 2 )); then + candidates+=("--all" "--json" "--markdown" "--check") + fi + + if (( ${#candidates[@]} > 0 )); then + local IFS=$'\n' + COMPREPLY=($(compgen -W "${candidates[*]}" -- "$cur")) + fi +} + +complete -F _omarchy_complete omarchy + +# Hide individual omarchy-* binaries from initial-word command completion; +# the unified `omarchy` dispatcher is the user-facing entry point. +complete -I -A command -X 'omarchy-*' diff --git a/default/bash/envs b/default/bash/envs index ea8510e6..a8d01dda 100644 --- a/default/bash/envs +++ b/default/bash/envs @@ -2,6 +2,10 @@ export SUDO_EDITOR="$EDITOR" export BAT_THEME=ansi +# Color man pages with bat +export MANROFFOPT="-c" +export MANPAGER="sh -c 'col -bx | bat -l man -p'" + # Duplicated from .config/uwsm/env so SSH works too export OMARCHY_PATH=$HOME/.local/share/omarchy export PATH=$OMARCHY_PATH/bin:$PATH:$HOME/.local/bin diff --git a/default/bash/fns/transcoding b/default/bash/fns/transcoding index 6f5b6a59..81ad0016 100644 --- a/default/bash/fns/transcoding +++ b/default/bash/fns/transcoding @@ -8,6 +8,11 @@ transcode-video-4K() { ffmpeg -i "$1" -c:v libx265 -preset slow -crf 24 -c:a aac -b:a 192k "${1%.*}-optimized.mp4" } +# Transcode a video to an animated GIF using a palette for accurate colors +transcode-video-gif() { + ffmpeg -i "$1" -vf "fps=10,scale=800:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" "${1%.*}.gif" +} + # Transcode any image to JPG image that's great for shrinking wallpapers img2jpg() { img="$1" diff --git a/default/bash/init b/default/bash/init index d2baba50..c3d8c97a 100644 --- a/default/bash/init +++ b/default/bash/init @@ -26,3 +26,5 @@ if command -v fzf &> /dev/null; then source /usr/share/fzf/key-bindings.bash fi fi + +source "$OMARCHY_PATH/default/bash/completions" diff --git a/default/elephant/omarchy_background_selector.lua b/default/elephant/omarchy_background_selector.lua index 7954266f..38bc2bf1 100644 --- a/default/elephant/omarchy_background_selector.lua +++ b/default/elephant/omarchy_background_selector.lua @@ -46,7 +46,7 @@ function GetEntries() for _, wallpaper_dir in ipairs(dirs) do local handle = io.popen( - "find " .. ShellEscape(wallpaper_dir) + "find -L " .. ShellEscape(wallpaper_dir) .. " -maxdepth 1 -type f \\( -name '*.jpg' -o -name '*.jpeg' -o -name '*.png' -o -name '*.gif' -o -name '*.bmp' -o -name '*.webp' \\) 2>/dev/null | sort" ) if handle then diff --git a/default/elephant/omarchy_unlocks.lua b/default/elephant/omarchy_unlocks.lua new file mode 100644 index 00000000..8aacaccd --- /dev/null +++ b/default/elephant/omarchy_unlocks.lua @@ -0,0 +1,92 @@ +-- +-- Dynamic Omarchy Unlocks Menu for Elephant/Walker +-- +-- A "Default" entry restores the omarchy-shipped Plymouth via +-- omarchy-plymouth-reset. After that, every theme that has a preview-unlock.png +-- appears as a customised unlock; picking one runs omarchy-plymouth-set-by-theme +-- . Both run in a floating terminal so sudo can prompt. +-- +Name = "omarchyunlocks" +NamePretty = "Omarchy Unlocks" +HideFromProviderlist = true +FixedOrder = true + +local function file_exists(path) + local f = io.open(path, "r") + if f then + f:close() + return true + end + return false +end + +local function shell_escape(s) + return "'" .. s:gsub("'", "'\\''") .. "'" +end + +function GetEntries() + local entries = {} + local home = os.getenv("HOME") + local user_themes_dir = home .. "/.config/omarchy/themes" + local omarchy_path = os.getenv("OMARCHY_PATH") or "" + local default_themes_dir = omarchy_path .. "/themes" + local default_preview = omarchy_path .. "/default/plymouth/preview-unlock.png" + + local seen_themes = {} + + local function process_themes_from_dir(themes_dir) + local handle = io.popen("find -L '" .. themes_dir .. "' -mindepth 1 -maxdepth 1 -type d 2>/dev/null") + if not handle then + return + end + + for theme_path in handle:lines() do + local theme_name = theme_path:match(".*/(.+)$") + + if theme_name and not seen_themes[theme_name] then + seen_themes[theme_name] = true + + local preview_path = theme_path .. "/preview-unlock.png" + + if file_exists(preview_path) then + local display_name = theme_name:gsub("_", " "):gsub("%-", " ") + display_name = display_name:gsub("(%a)([%w_']*)", function(first, rest) + return first:upper() .. rest:lower() + end) + display_name = display_name .. " " + + table.insert(entries, { + Text = display_name, + Preview = preview_path, + PreviewType = "file", + Actions = { + activate = "omarchy-launch-floating-terminal-with-presentation " + .. shell_escape("omarchy-plymouth-set-by-theme " .. shell_escape(theme_name)), + }, + }) + end + end + end + + handle:close() + end + + process_themes_from_dir(user_themes_dir) + process_themes_from_dir(default_themes_dir) + + -- Default entry last — restores the shipped Plymouth. + local default_entry = { + Text = "Default ", + Actions = { + activate = "omarchy-launch-floating-terminal-with-presentation " + .. shell_escape("omarchy-plymouth-reset"), + }, + } + if file_exists(default_preview) then + default_entry.Preview = default_preview + default_entry.PreviewType = "file" + end + table.insert(entries, default_entry) + + return entries +end diff --git a/default/hypr/apps.conf b/default/hypr/apps.conf index 777692cd..f64c6e39 100644 --- a/default/hypr/apps.conf +++ b/default/hypr/apps.conf @@ -3,6 +3,7 @@ source = ~/.local/share/omarchy/default/hypr/apps/1password.conf source = ~/.local/share/omarchy/default/hypr/apps/bitwarden.conf source = ~/.local/share/omarchy/default/hypr/apps/browser.conf source = ~/.local/share/omarchy/default/hypr/apps/hyprshot.conf +source = ~/.local/share/omarchy/default/hypr/apps/jetbrains.conf source = ~/.local/share/omarchy/default/hypr/apps/localsend.conf source = ~/.local/share/omarchy/default/hypr/apps/pip.conf source = ~/.local/share/omarchy/default/hypr/apps/qemu.conf diff --git a/default/hypr/apps/jetbrains.conf b/default/hypr/apps/jetbrains.conf new file mode 100644 index 00000000..b1eea6a0 --- /dev/null +++ b/default/hypr/apps/jetbrains.conf @@ -0,0 +1,6 @@ +# Disable mouse focus (see https://github.com/basecamp/omarchy/pull/5183#issuecomment-4189299971) +windowrule { + name = jetbrains-focus + no_follow_mouse = on + match:class = ^(jetbrains-.*)$ +} diff --git a/default/hypr/autostart.conf b/default/hypr/autostart.conf index 984b55a3..394a5f32 100644 --- a/default/hypr/autostart.conf +++ b/default/hypr/autostart.conf @@ -5,7 +5,7 @@ exec-once = uwsm-app -- fcitx5 --disable notificationitem exec-once = uwsm-app -- swaybg -i ~/.config/omarchy/current/background -m fill exec-once = uwsm-app -- swayosd-server exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 -exec-once = omarchy-cmd-first-run +exec-once = omarchy-first-run exec-once = omarchy-powerprofiles-init exec-once = uwsm-app -- omarchy-hyprland-monitor-watch diff --git a/default/hypr/bindings.conf b/default/hypr/bindings.conf index 20fee804..4daf95a0 100644 --- a/default/hypr/bindings.conf +++ b/default/hypr/bindings.conf @@ -8,7 +8,7 @@ bindd = SUPER, N, Neovim, exec, $terminal -e nvim bindd = SUPER, T, Top, exec, $terminal -e btop bindd = SUPER, D, Lazy Docker, exec, $terminal -e lazydocker bindd = SUPER, G, Messenger, exec, $messenger -bindd = SUPER, O, Obsidian, exec, obsidian -disable-gpu +bindd = SUPER, O, Obsidian, exec, obsidian bindd = SUPER, SLASH, Password manager, exec, $passwordManager source = ~/.local/share/omarchy/default/hypr/bindings/media.conf diff --git a/default/hypr/bindings/media.conf b/default/hypr/bindings/media.conf index c02872dc..d18f5aa5 100644 --- a/default/hypr/bindings/media.conf +++ b/default/hypr/bindings/media.conf @@ -2,9 +2,11 @@ bindeld = ,XF86AudioRaiseVolume, Volume up, exec, omarchy-swayosd-client --output-volume raise bindeld = ,XF86AudioLowerVolume, Volume down, exec, omarchy-swayosd-client --output-volume lower bindeld = ,XF86AudioMute, Mute, exec, omarchy-swayosd-client --output-volume mute-toggle -bindeld = ,XF86AudioMicMute, Mute microphone, exec, omarchy-cmd-mic-mute +bindeld = ,XF86AudioMicMute, Mute microphone, exec, omarchy-audio-input-mute bindeld = ,XF86MonBrightnessUp, Brightness up, exec, omarchy-brightness-display +5% bindeld = ,XF86MonBrightnessDown, Brightness down, exec, omarchy-brightness-display 5%- +bindeld = SHIFT, XF86MonBrightnessUp, Brightness maximum, exec, omarchy-brightness-display 100% +bindeld = SHIFT, XF86MonBrightnessDown, Brightness minimum, exec, omarchy-brightness-display 1% bindeld = ,XF86KbdBrightnessUp, Keyboard brightness up, exec, omarchy-brightness-keyboard up bindeld = ,XF86KbdBrightnessDown, Keyboard brightness down, exec, omarchy-brightness-keyboard down bindld = ,XF86KbdLightOnOff, Keyboard backlight cycle, exec, omarchy-brightness-keyboard cycle @@ -25,4 +27,4 @@ bindld = , XF86AudioPlay, Play, exec, omarchy-swayosd-client --playerctl play-pa bindld = , XF86AudioPrev, Previous track, exec, omarchy-swayosd-client --playerctl previous # Switch audio output with Super + Mute -bindld = SUPER, XF86AudioMute, Switch audio output, exec, omarchy-cmd-audio-switch +bindld = SUPER, XF86AudioMute, Switch audio output, exec, omarchy-audio-output-switch diff --git a/default/hypr/bindings/utilities.conf b/default/hypr/bindings/utilities.conf index 628a0aec..2b871c92 100644 --- a/default/hypr/bindings/utilities.conf +++ b/default/hypr/bindings/utilities.conf @@ -30,18 +30,15 @@ bindd = SUPER SHIFT ALT, COMMA, Restore last notification, exec, makoctl restore bindd = SUPER CTRL, I, Toggle locking on idle, exec, omarchy-toggle-idle bindd = SUPER CTRL, N, Toggle nightlight, exec, omarchy-toggle-nightlight bindd = SUPER CTRL, Delete, Toggle laptop display, exec, omarchy-hyprland-monitor-internal toggle -bindl = , switch:on:Lid Switch, exec, omarchy-hyprland-monitor-internal off +bindd = SUPER CTRL ALT, Delete, Toggle laptop display mirroring, exec, omarchy-hyprland-monitor-internal-mirror toggle +bindl = , switch:on:Lid Switch, exec, omarchy-hw-external-monitors && omarchy-hyprland-monitor-internal off bindl = , switch:off:Lid Switch, exec, omarchy-hyprland-monitor-internal on -# Control Apple Display brightness -bindd = CTRL, F1, Apple Display brightness down, exec, omarchy-brightness-display-apple -5000 -bindd = CTRL, F2, Apple Display brightness up, exec, omarchy-brightness-display-apple +5000 -bindd = SHIFT CTRL, F2, Apple Display full brightness, exec, omarchy-brightness-display-apple +60000 - # Captures -bindd = , PRINT, Screenshot, exec, omarchy-cmd-screenshot +bindd = , PRINT, Screenshot, exec, omarchy-capture-screenshot bindd = ALT, PRINT, Screenrecording, exec, omarchy-menu screenrecord bindd = SUPER, PRINT, Color picker, exec, pkill hyprpicker || hyprpicker -a +bindd = SUPER CTRL, PRINT, Extract text (OCR) from screenshot, exec, omarchy-capture-text-extraction # File sharing bindd = SUPER CTRL, S, Share, exec, omarchy-menu share @@ -59,9 +56,12 @@ bindd = SUPER CTRL, T, Activity, exec, omarchy-launch-tui btop # Dictation bindd = SUPER CTRL, X, Toggle dictation, exec, voxtype record toggle +bindd = , F9, Start dictation (push-to-talk), exec, voxtype record start +binddr = , F9, Stop dictation (push-to-talk), exec, voxtype record stop + # Zoom bindd = SUPER CTRL, Z, Zoom in, exec, hyprctl keyword cursor:zoom_factor $(hyprctl getoption cursor:zoom_factor -j | jq '.float + 1') bindd = SUPER CTRL ALT, Z, Reset zoom, exec, hyprctl keyword cursor:zoom_factor 1 # Lock system -bindd = SUPER CTRL, L, Lock system, exec, omarchy-lock-screen +bindd = SUPER CTRL, L, Lock system, exec, omarchy-system-lock diff --git a/default/hypr/envs.conf b/default/hypr/envs.conf index 85afc775..9210f594 100644 --- a/default/hypr/envs.conf +++ b/default/hypr/envs.conf @@ -1,3 +1,8 @@ +# GUM environment variables for styling purposes +# hyprlang noerror true +source = ~/.config/omarchy/current/theme/gum.env.conf +# hyprlang noerror false + # Cursor size env = XCURSOR_SIZE,24 env = HYPRCURSOR_SIZE,24 @@ -6,7 +11,6 @@ env = HYPRCURSOR_SIZE,24 env = GDK_BACKEND,wayland,x11,* env = QT_QPA_PLATFORM,wayland;xcb env = QT_STYLE_OVERRIDE,kvantum -env = SDL_VIDEODRIVER,wayland,x11 env = MOZ_ENABLE_WAYLAND,1 env = ELECTRON_OZONE_PLATFORM_HINT,wayland env = OZONE_PLATFORM,wayland diff --git a/default/hypr/input.conf b/default/hypr/input.conf index 74b2acab..14e9ccb6 100644 --- a/default/hypr/input.conf +++ b/default/hypr/input.conf @@ -1,4 +1,4 @@ -# https://wiki.hyprland.org/Configuring/Variables/#input +# https://wiki.hypr.land/Configuring/Basics/Variables/#input input { kb_layout = us kb_variant = diff --git a/default/hypr/looknfeel.conf b/default/hypr/looknfeel.conf index f735abda..ab2567c9 100644 --- a/default/hypr/looknfeel.conf +++ b/default/hypr/looknfeel.conf @@ -1,30 +1,30 @@ -# Refer to https://wiki.hyprland.org/Configuring/Variables/ +# Refer to https://wiki.hypr.land/Configuring/Basics/Variables/ # Variables $activeBorderColor = rgba(33ccffee) rgba(00ff99ee) 45deg $inactiveBorderColor = rgba(595959aa) -# https://wiki.hyprland.org/Configuring/Variables/#general +# https://wiki.hypr.land/Configuring/Basics/Variables/#general general { gaps_in = 5 gaps_out = 10 border_size = 2 - # https://wiki.hyprland.org/Configuring/Variables/#variable-types for info about colors + # https://wiki.hypr.land/Configuring/Basics/Variables/#variable-types for info about colors col.active_border = $activeBorderColor col.inactive_border = $inactiveBorderColor # Set to true enable resizing windows by clicking and dragging on borders and gaps resize_on_border = false - # Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on + # Please see https://wiki.hypr.land/Configuring/Advanced-and-Cool/Tearing/ before you turn this on allow_tearing = false layout = dwindle } -# https://wiki.hyprland.org/Configuring/Variables/#decoration +# https://wiki.hypr.land/Configuring/Basics/Variables/#decoration decoration { rounding = 0 @@ -35,7 +35,7 @@ decoration { color = rgba(1a1a1aee) } - # https://wiki.hyprland.org/Configuring/Variables/#blur + # https://wiki.hypr.land/Configuring/Basics/Variables/#blur blur { enabled = true size = 2 @@ -46,7 +46,7 @@ decoration { } } -# https://wiki.hypr.land/Configuring/Variables/#group +# https://wiki.hypr.land/Configuring/Basics/Variables/#group group { col.border_active = $activeBorderColor col.border_inactive = $inactiveBorderColor @@ -77,11 +77,11 @@ group { } -# https://wiki.hyprland.org/Configuring/Variables/#animations +# https://wiki.hypr.land/Configuring/Basics/Variables/#animations animations { enabled = yes, please :) - # Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more + # Default animations, see https://wiki.hypr.land/Configuring/Advanced-and-Cool/Animations/ for more bezier = easeOutQuint,0.23,1,0.32,1 bezier = easeInOutCubic,0.65,0.05,0.36,1 @@ -106,19 +106,19 @@ animations { animation = specialWorkspace, 1, 3, easeOutQuint, slidevert } -# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more +# See https://wiki.hypr.land/Configuring/Layouts/Dwindle-Layout/ for more dwindle { pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below preserve_split = true # You probably want this force_split = 2 # Always split on the right } -# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more +# See https://wiki.hypr.land/Configuring/Layouts/Master-Layout/ for more master { new_status = master } -# https://wiki.hyprland.org/Configuring/Variables/#misc +# https://wiki.hypr.land/Configuring/Basics/Variables/#misc misc { disable_hyprland_logo = true disable_splash_rendering = true @@ -128,7 +128,7 @@ misc { on_focus_under_fullscreen = 1 } -# https://wiki.hypr.land/Configuring/Variables/#cursor +# https://wiki.hypr.land/Configuring/Basics/Variables/#cursor cursor { hide_on_key_press = true warp_on_change_workspace = 1 @@ -138,10 +138,3 @@ cursor { binds { hide_special_on_workspace_change = true } - -# Style Gum confirm to match terminal theme -env = GUM_CONFIRM_PROMPT_FOREGROUND,6 # Cyan -env = GUM_CONFIRM_SELECTED_FOREGROUND,0 # Black -env = GUM_CONFIRM_SELECTED_BACKGROUND,2 # Green -env = GUM_CONFIRM_UNSELECTED_FOREGROUND,7 # White -env = GUM_CONFIRM_UNSELECTED_BACKGROUND,8 # Dark grey diff --git a/default/hypr/toggles/internal-monitor-disable.conf b/default/hypr/toggles/internal-monitor-disable.conf deleted file mode 100644 index f5458f94..00000000 --- a/default/hypr/toggles/internal-monitor-disable.conf +++ /dev/null @@ -1,2 +0,0 @@ -# Disable the internal laptop monitor -monitor=eDP-1,disable diff --git a/default/hypr/windows.conf b/default/hypr/windows.conf index 67a9a6a9..3ceca48f 100644 --- a/default/hypr/windows.conf +++ b/default/hypr/windows.conf @@ -1,4 +1,4 @@ -# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more +# See https://wiki.hypr.land/Configuring/Basics/Window-Rules/ for more # Hyprland 0.53+ syntax windowrule = suppress_event maximize, match:class .* diff --git a/default/limine/default.conf b/default/limine/default.conf index ff5ae56d..9beedcd4 100644 --- a/default/limine/default.conf +++ b/default/limine/default.conf @@ -3,7 +3,7 @@ TARGET_OS_NAME="Omarchy" ESP_PATH="/boot" KERNEL_CMDLINE[default]+="@@CMDLINE@@" -KERNEL_CMDLINE[default]+=" quiet splash" +KERNEL_CMDLINE[default]+=" quiet splash loglevel=0 systemd.show_status=false rd.udev.log_level=0 vt.global_cursor_default=0" ENABLE_UKI=yes CUSTOM_UKI_NAME="omarchy" diff --git a/default/limine/limine.conf b/default/limine/limine.conf index 9868fbc7..25947698 100644 --- a/default/limine/limine.conf +++ b/default/limine/limine.conf @@ -2,7 +2,9 @@ #timeout: 3 default_entry: 2 interface_branding: Omarchy Bootloader -interface_branding_color: 2 +interface_branding_color: 9ece6a +interface_help_color: 9ece6a +interface_help_color_bright: 9ece6a hash_mismatch_panic: no term_background: 1a1b26 diff --git a/default/omarchy-skill/SKILL.md b/default/omarchy-skill/SKILL.md index 46c11e73..db09dcd4 100644 --- a/default/omarchy-skill/SKILL.md +++ b/default/omarchy-skill/SKILL.md @@ -8,7 +8,7 @@ description: > monitors, gaps, borders, blur, opacity, waybar, walker, terminal config, themes, wallpaper, night light, idle, lock screen, screenshots, layer rules, workspace settings, display config, and user-facing omarchy commands. Excludes Omarchy - source development in ~/.local/share/omarchy/ and omarchy-dev-* workflows. + source development in ~/.local/share/omarchy/ and `omarchy dev` workflows. --- # Omarchy Skill @@ -29,19 +29,19 @@ It is not for contributing to Omarchy source code. - Window behavior, animations, opacity, blur, gaps, borders - Layer rules, workspace settings, display/monitor configuration - Themes, wallpapers, fonts, appearance changes -- User-facing `omarchy-*` commands (`omarchy-theme-*`, `omarchy-refresh-*`, `omarchy-restart-*`, etc.) +- User-facing `omarchy` commands (`omarchy theme ...`, `omarchy refresh ...`, `omarchy restart ...`, etc.) - Screenshots, screen recording, night light, idle behavior, lock screen **If you're about to edit a config file in ~/.config/ on this system, STOP and use this skill first.** -**Do NOT use this skill for Omarchy development tasks** (editing files in `~/.local/share/omarchy/`, creating migrations, or running `omarchy-dev-*` workflows). +**Do NOT use this skill for Omarchy development tasks** (editing files in `~/.local/share/omarchy/`, creating migrations, or running `omarchy dev ...` workflows). ## Critical Safety Rules **For end-user customization tasks, NEVER modify anything in `~/.local/share/omarchy/`** - but READING is safe and encouraged. This directory contains Omarchy's source files managed by git. Any changes will be: -- Lost on next `omarchy-update` +- Lost on next `omarchy update` - Cause conflicts with upstream - Break the system's update mechanism @@ -56,7 +56,7 @@ This directory contains Omarchy's source files managed by git. Any changes will ``` **Reading `~/.local/share/omarchy/` is SAFE and useful** - do it freely to: -- Understand how omarchy commands work: `cat $(which omarchy-theme-set)` +- Understand how omarchy commands work: `omarchy theme set --help` or `cat $(which omarchy-theme-set)` - See default configs before customizing: `cat ~/.local/share/omarchy/config/waybar/config.jsonc` - Check stock theme files to copy for customization - Reference default hyprland settings: `cat ~/.local/share/omarchy/default/hypr/*` @@ -84,34 +84,43 @@ Omarchy is built on: ## Command Discovery -Omarchy provides ~145 commands following `omarchy--` pattern. +Omarchy ships a single `omarchy` CLI that dispatches to all `omarchy-*` binaries via `omarchy `. Always prefer this form — it is self-documenting and stable. The underlying `omarchy-*` binaries still exist on `PATH` and remain safe to read for source. ```bash -# List all omarchy commands -compgen -c | grep -E '^omarchy-' | sort -u +# List every documented command and its summary +omarchy commands -# Find commands by category -compgen -c | grep -E '^omarchy-theme' -compgen -c | grep -E '^omarchy-restart' +# Show the commands inside a group +omarchy theme --help +omarchy refresh --help +omarchy restart --help + +# Show help for a specific command (does not execute it) +omarchy theme set --help + +# Machine-readable listing (binary, route, summary, args, aliases) +omarchy commands --json # Read a command's source to understand it cat $(which omarchy-theme-set) ``` -### Command Categories +### Command Groups -| Prefix | Purpose | Example | -|--------|---------|---------| -| `omarchy-refresh-*` | Reset config to defaults (backs up first) | `omarchy-refresh-waybar` | -| `omarchy-restart-*` | Restart a service/app | `omarchy-restart-waybar` | -| `omarchy-toggle-*` | Toggle feature on/off | `omarchy-toggle-nightlight` | -| `omarchy-theme-*` | Theme management | `omarchy-theme-set ` | -| `omarchy-install-*` | Install optional software | `omarchy-install-docker-dbs` | -| `omarchy-launch-*` | Launch apps | `omarchy-launch-browser` | -| `omarchy-cmd-*` | System commands | `omarchy-cmd-screenshot` | -| `omarchy-pkg-*` | Package management | `omarchy-pkg-install ` | -| `omarchy-setup-*` | Initial setup tasks | `omarchy-setup-fingerprint` | -| `omarchy-update-*` | System updates | `omarchy-update` | +Run `omarchy --help` for the full list. The most common groups: + +| Group | Purpose | Example | +|-------|---------|---------| +| `omarchy refresh` | Reset config to defaults (backs up first) | `omarchy refresh waybar` | +| `omarchy restart` | Restart a service/app | `omarchy restart waybar` | +| `omarchy toggle` | Toggle feature on/off | `omarchy toggle nightlight` | +| `omarchy theme` | Theme management | `omarchy theme set ` | +| `omarchy install` | Install optional software / packages | `omarchy install docker dbs` | +| `omarchy launch` | Launch apps | `omarchy launch browser` | +| `omarchy capture` | Screenshots and recordings | `omarchy capture screenshot` | +| `omarchy pkg` | Package management | `omarchy pkg install ` | +| `omarchy setup` | Initial setup tasks | `omarchy setup fingerprint` | +| `omarchy update` | System updates | `omarchy update` | ## Configuration Locations @@ -134,7 +143,9 @@ cat $(which omarchy-theme-set) **Key behaviors:** - Hyprland auto-reloads on config save (no restart needed for most changes) - Use `hyprctl reload` to force reload -- Use `omarchy-refresh-hyprland` to reset to defaults +- After ANY Hyprland config change, validate with `hyprctl reload` followed by `hyprctl configerrors` +- If `hyprctl configerrors` reports errors, address them and rerun validation until clean or until a real blocker is identified +- Use `omarchy refresh hyprland` to reset to defaults ### Waybar (Status Bar) @@ -144,9 +155,9 @@ cat $(which omarchy-theme-set) └── style.css # Styling ``` -**Waybar does NOT auto-reload.** You MUST run `omarchy-restart-waybar` after any config changes. +**Waybar does NOT auto-reload.** You MUST run `omarchy restart waybar` after any config changes. -**Commands:** `omarchy-restart-waybar`, `omarchy-refresh-waybar`, `omarchy-toggle-waybar` +**Commands:** `omarchy restart waybar`, `omarchy refresh waybar`, `omarchy toggle waybar` ### Terminals @@ -156,7 +167,7 @@ cat $(which omarchy-theme-set) ~/.config/ghostty/config ``` -**Command:** `omarchy-restart-terminal` +**Command:** `omarchy restart terminal` ### Other Configs @@ -185,10 +196,10 @@ cp ~/.config/hypr/bindings.conf ~/.config/hypr/bindings.conf.bak.$(date +%s) # 3. Make changes with Edit tool # 4. Apply changes -# - Hyprland: auto-reloads on save (no restart needed) -# - Waybar: MUST restart with omarchy-restart-waybar -# - Walker: MUST restart with omarchy-restart-walker -# - Terminals: MUST restart with omarchy-restart-terminal +# - Hyprland: auto-reloads on save, but MUST validate with `hyprctl reload` and `hyprctl configerrors` +# - Waybar: MUST restart with `omarchy restart waybar` +# - Walker: MUST restart with `omarchy restart walker` +# - Terminals: MUST restart with `omarchy restart terminal` ``` ### Pattern 2: Make a new theme @@ -196,7 +207,7 @@ cp ~/.config/hypr/bindings.conf ~/.config/hypr/bindings.conf.bak.$(date +%s) 1. Create a directory under ~/.config/omarchy/themes. 2. See how an existing theme is done via ~/.local/share/omarchy/themes/catppuccin. 3. Download a matching background (or several) from the internet and put them in ~/.config/omarchy/themes/[name-of-new-theme] -4. When done with the theme, run omarchy-theme-set "Name of new theme" +4. When done with the theme, run `omarchy theme set "Name of new theme"` ### Pattern 3: Use Hooks for Automation @@ -207,7 +218,7 @@ Create scripts in `~/.config/omarchy/hooks/` to run automatically on events: ~/.config/omarchy/hooks/ ├── theme-set # Runs after theme change (receives theme name as $1) ├── font-set # Runs after font change -└── post-update # Runs after omarchy-update +└── post-update # Runs after `omarchy update` ``` Example hook (`~/.config/omarchy/hooks/theme-set`): @@ -224,8 +235,8 @@ When customizations go wrong: ```bash # Reset specific config (creates backup automatically) -omarchy-refresh-waybar -omarchy-refresh-hyprland +omarchy refresh waybar +omarchy refresh hyprland # The refresh command: # 1. Backs up current config with timestamp @@ -238,12 +249,11 @@ omarchy-refresh-hyprland ### Themes ```bash -omarchy-theme-list # Show available themes -omarchy-theme-current # Show current theme -omarchy-theme-set # Apply theme (use "Tokyo Night" not "tokyo-night") -omarchy-theme-next # Cycle to next theme -omarchy-theme-bg-next # Cycle wallpaper -omarchy-theme-install # Install from git repo +omarchy theme list # Show available themes +omarchy theme current # Show current theme +omarchy theme set # Apply theme (use "Tokyo Night" not "tokyo-night") +omarchy theme bg next # Cycle wallpaper +omarchy theme install # Install from git repo ``` ### Keybindings @@ -255,11 +265,11 @@ bind = SUPER, Q, killactive bind = SUPER SHIFT, E, exit ``` -View current bindings: `omarchy-menu-keybindings --print` +View current bindings: `omarchy menu keybindings --print` **IMPORTANT: When re-binding an existing key:** -1. First check existing bindings: `omarchy-menu-keybindings --print` +1. First check existing bindings: `omarchy menu keybindings --print` 2. If the key is already bound, you MUST add an `unbind` directive BEFORE your new `bind` 3. Inform the user what the key was previously bound to @@ -297,43 +307,43 @@ Window rules go in `~/.config/hypr/hyprland.conf` or a sourced file. Always veri ### Fonts ```bash -omarchy-font-list # Available fonts -omarchy-font-current # Current font -omarchy-font-set # Change font +omarchy font list # Available fonts +omarchy font current # Current font +omarchy font set # Change font ``` ### System ```bash -omarchy-update # Full system update -omarchy-version # Show Omarchy version -omarchy-debug --no-sudo --print # Debug info (ALWAYS use these flags) -omarchy-lock-screen # Lock screen -omarchy-system-shutdown # Shutdown -omarchy-system-reboot # Reboot +omarchy update # Full system update +omarchy version # Show Omarchy version +omarchy debug --no-sudo --print # Debug info (ALWAYS use these flags) +omarchy system lock # Lock screen +omarchy system shutdown # Shutdown +omarchy system reboot # Reboot ``` -**IMPORTANT:** Always run `omarchy-debug` with `--no-sudo --print` flags to avoid interactive sudo prompts that will hang the terminal. +**IMPORTANT:** Always run `omarchy debug` with `--no-sudo --print` flags to avoid interactive sudo prompts that will hang the terminal. ## Troubleshooting ```bash # Get debug information (ALWAYS use these flags to avoid interactive prompts) -omarchy-debug --no-sudo --print +omarchy debug --no-sudo --print # Upload logs for support -omarchy-upload-log +omarchy upload log # Reset specific config to defaults -omarchy-refresh- +omarchy refresh # Refresh specific config file # config-file path is relative to ~/.config/ -# eg. omarchy-refresh-config hypr/hyprlock.conf will refresh ~/.config/hypr/hyprlock.conf -omarchy-refresh-config +# eg. `omarchy refresh config hypr/hyprlock.conf` will refresh ~/.config/hypr/hyprlock.conf +omarchy refresh config # Full reinstall of configs (nuclear option) -omarchy-reinstall +omarchy reinstall ``` ## Decision Framework @@ -344,23 +354,23 @@ When user requests system changes: 2. **Is it a config edit?** Edit in `~/.config/`, never `~/.local/share/omarchy/` 3. **Is it a theme customization?** Create a NEW custom theme directory 4. **Is it automation?** Use hooks in `~/.config/omarchy/hooks/` -5. **Is it a package install?** Use `omarchy-pkg-add` (or `omarchy-pkg-aur-add` for AUR-only packages) -6. **Unsure if command exists?** Search with `compgen -c | grep omarchy` +5. **Is it a package install?** Use `omarchy install package ` (or `omarchy pkg aur add ` for AUR-only packages) +6. **Unsure if command exists?** Run `omarchy commands` (or `omarchy --help` for one group) ## Out of Scope This skill intentionally does not cover Omarchy source development. Do not use this skill for: - Editing files in `~/.local/share/omarchy/` (`bin/`, `config/`, `default/`, `themes/`, `migrations/`, etc.) - Creating or editing migrations -- Running `omarchy-dev-*` commands +- Running `omarchy dev ...` commands ## Example Requests -- "Change my theme to catppuccin" -> `omarchy-theme-set catppuccin` +- "Change my theme to catppuccin" -> `omarchy theme set catppuccin` - "Add a keybinding for Super+E to open file manager" -> Check existing bindings first, add `unbind` if needed, then add `bind` in `~/.config/hypr/bindings.conf` - "Configure my external monitor" -> Edit `~/.config/hypr/monitors.conf` - "Make the window gaps smaller" -> Edit `~/.config/hypr/looknfeel.conf` -- "Set up night light to turn on at sunset" -> `omarchy-toggle-nightlight` or edit `~/.config/hypr/hyprsunset.conf` +- "Set up night light to turn on at sunset" -> `omarchy toggle nightlight` or edit `~/.config/hypr/hyprsunset.conf` - "Customize the catppuccin theme colors" -> Create `~/.config/omarchy/themes/catppuccin-custom/` by copying from stock, then edit - "Run a script every time I change themes" -> Create `~/.config/omarchy/hooks/theme-set` -- "Reset waybar to defaults" -> `omarchy-refresh-waybar` +- "Reset waybar to defaults" -> `omarchy refresh waybar` diff --git a/default/plymouth/logos/oma.png b/default/plymouth/logos/oma.png new file mode 100644 index 00000000..87d2cecb Binary files /dev/null and b/default/plymouth/logos/oma.png differ diff --git a/default/plymouth/omarchy.script b/default/plymouth/omarchy.script index df0c2982..581514d7 100644 --- a/default/plymouth/omarchy.script +++ b/default/plymouth/omarchy.script @@ -1,116 +1,105 @@ # Omarchy Plymouth Theme Script Window.SetBackgroundTopColor(0.101, 0.105, 0.149); -Window.SetBackgroundBottomColor(0.101, 0.105, 0.149); +Window.SetBackgroundBottomColor(0.101, 0.105, 0.149); logo.image = Image("logo.png"); logo.sprite = Sprite(logo.image); -logo.sprite.SetX (Window.GetWidth() / 2 - logo.image.GetWidth() / 2); -logo.sprite.SetY (Window.GetHeight() / 2 - logo.image.GetHeight() / 2); -logo.sprite.SetOpacity (1); +logo.sprite.SetX(Window.GetWidth() / 2 - logo.image.GetWidth() / 2); +logo.sprite.SetY(Window.GetHeight() / 2 - logo.image.GetHeight() / 2); +logo.sprite.SetOpacity(1); # Use these to adjust the progress bar timing global.fake_progress_limit = 0.7; # Target percentage for fake progress (0.0 to 1.0) global.fake_progress_duration = 15.0; # Duration in seconds to reach limit # Progress bar animation variables +global.animation_frame = 0; global.fake_progress = 0.0; global.real_progress = 0.0; -global.fake_progress_active = 0; # 0 / 1 boolean -global.animation_frame = 0; -global.fake_progress_start_time = 0; # Track when fake progress started +global.fake_progress_active = 0; +global.fake_progress_start_time = 0.0; # Track when fake progress started global.password_shown = 0; # Track if password dialog has been shown global.max_progress = 0.0; # Track the maximum progress reached to prevent backwards movement -fun refresh_callback () - { - global.animation_frame++; - - # Animate fake progress to limit over time with easing - if (global.fake_progress_active == 1) - { - # Calculate elapsed time since start - elapsed_time = global.animation_frame / 50.0; # Convert frames to seconds (50 FPS) - - # Calculate linear progress ratio (0 to 1) based on time - time_ratio = elapsed_time / global.fake_progress_duration; - if (time_ratio > 1.0) - time_ratio = 1.0; - - # Apply easing curve: ease-out quadratic - # Formula: 1 - (1 - x)^2 - eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio)); - - # Calculate fake progress based on eased ratio - global.fake_progress = eased_ratio * global.fake_progress_limit; - - # Update progress bar with fake progress - update_progress_bar(global.fake_progress); - } +fun refresh_callback() { + global.animation_frame++; + + # Animate fake progress to limit over time with easing + if (global.fake_progress_active == 1) { + # Calculate elapsed time since start + elapsed_time = global.animation_frame / 50.0; # Convert frames to seconds (50 FPS) + + # Calculate linear progress ratio (0 to 1) based on time + time_ratio = elapsed_time / global.fake_progress_duration; + if (time_ratio > 1.0) time_ratio = 1.0; + + # Apply easing curve: ease-out quadratic + # Formula: 1 - (1 - x)^2 + eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio)); + + # Calculate fake progress based on eased ratio + global.fake_progress = eased_ratio * global.fake_progress_limit; + + # Update progress bar with fake progress + update_progress_bar(global.fake_progress); } +} - -Plymouth.SetRefreshFunction (refresh_callback); +Plymouth.SetRefreshFunction(refresh_callback); #----------------------------------------- Helper Functions -------------------------------- -fun update_progress_bar(progress) - { - # Only update if progress is moving forward - if (progress > global.max_progress) - { - global.max_progress = progress; - width = Math.Int(progress_bar.original_image.GetWidth() * progress); - if (width < 1) width = 1; # Ensure minimum width of 1 pixel - - progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight()); - progress_bar.sprite.SetImage(progress_bar.image); - } - } +fun update_progress_bar(progress) { + # Only update if progress is moving forward + if (progress > global.max_progress) { + global.max_progress = progress; -fun show_progress_bar() - { - progress_box.sprite.SetOpacity(1); - progress_bar.sprite.SetOpacity(1); - } + width = Math.Int(progress_bar.original_image.GetWidth() * progress); + if (width < 1) width = 1; # Ensure minimum width of 1 pixel -fun hide_progress_bar() - { - progress_box.sprite.SetOpacity(0); - progress_bar.sprite.SetOpacity(0); + progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight()); + progress_bar.sprite.SetImage(progress_bar.image); } +} -fun show_password_dialog() - { - lock.sprite.SetOpacity(1); - entry.sprite.SetOpacity(1); - } +fun show_progress_bar() { + progress_box.sprite.SetOpacity(1); + progress_bar.sprite.SetOpacity(1); +} -fun hide_password_dialog() - { - lock.sprite.SetOpacity(0); - entry.sprite.SetOpacity(0); - for (index = 0; bullet.sprites[index]; index++) - bullet.sprites[index].SetOpacity(0); - } +fun hide_progress_bar() { + progress_box.sprite.SetOpacity(0); + progress_bar.sprite.SetOpacity(0); +} -fun start_fake_progress() - { - # Don't reset if we already have progress - if (global.max_progress == 0.0) - { - global.fake_progress = 0.0; - global.real_progress = 0.0; - update_progress_bar(0.0); - } - global.fake_progress_active = 1; - global.animation_frame = 0; - } +fun show_password_dialog() { + lock.sprite.SetOpacity(1); + entry.sprite.SetOpacity(1); +} -fun stop_fake_progress() - { - global.fake_progress_active = 0; +fun hide_password_dialog() { + lock.sprite.SetOpacity(0); + entry.sprite.SetOpacity(0); + + for (index = 0; bullet.sprites[index]; index++) { + bullet.sprites[index].SetOpacity(0); } +} + +fun start_fake_progress() { + global.fake_progress_active = 1; + + # Reset fake progress + global.animation_frame = 0; + global.max_progress = 0.0; + global.fake_progress = 0.0; + global.fake_progress_start_time = 0.0; +} + +fun stop_fake_progress() { + global.fake_progress_active = 0; +} #----------------------------------------- Dialogue -------------------------------- @@ -119,7 +108,7 @@ entry.image = Image("entry.png"); bullet.image = Image("bullet.png"); entry.sprite = Sprite(entry.image); -entry.x = Window.GetWidth()/2 - entry.image.GetWidth() / 2; +entry.x = Window.GetWidth() / 2 - entry.image.GetWidth() / 2; entry.y = logo.sprite.GetY() + logo.image.GetHeight() + 40; entry.sprite.SetPosition(entry.x, entry.y, 10001); entry.sprite.SetOpacity(0); @@ -133,65 +122,60 @@ lock_width = 84 * lock_scale; scaled_lock = lock.image.Scale(lock_width, lock_height); lock.sprite = Sprite(scaled_lock); lock.x = entry.x - lock_width - 15; -lock.y = entry.y + entry.image.GetHeight()/2 - lock_height/2; +lock.y = entry.y + entry.image.GetHeight() / 2 - lock_height / 2; lock.sprite.SetPosition(lock.x, lock.y, 10001); lock.sprite.SetOpacity(0); # Bullet array bullet.sprites = []; -fun display_normal_callback () - { - hide_password_dialog(); - - # Get current mode - mode = Plymouth.GetMode(); - - # Only show progress bar for boot and resume modes - if ((mode == "boot" || mode == "resume") && global.password_shown == 1) - { - show_progress_bar(); - start_fake_progress(); - } +fun display_normal_callback() { + hide_password_dialog(); + + # Get current mode + mode = Plymouth.GetMode(); + + # Only show progress bar for boot and resume modes + if ((mode == "boot" || mode == "resume") && global.password_shown == 1) { + show_progress_bar(); + start_fake_progress(); + } +} + +fun display_password_callback(prompt, bullets) { + global.password_shown = 1; # Mark that password dialog has been shown + + # Stop fake progress when password dialog appears + stop_fake_progress(); + hide_progress_bar(); + show_password_dialog(); + + # Clear all bullets first + for (index = 0; bullet.sprites[index]; index++) { + bullet.sprites[index].SetOpacity(0); } -fun display_password_callback (prompt, bullets) - { - global.password_shown = 1; # Mark that password dialog has been shown - - # Reset progress when password dialog appears - stop_fake_progress(); - hide_progress_bar(); - global.max_progress = 0.0; - global.fake_progress = 0.0; - global.real_progress = 0.0; - show_password_dialog(); - - # Clear all bullets first - for (index = 0; bullet.sprites[index]; index++) - bullet.sprites[index].SetOpacity(0); - - # Create and show bullets for current password (max 21) - max_bullets = 21; - bullets_to_show = bullets; - if (bullets_to_show > max_bullets) - bullets_to_show = max_bullets; - - for (index = 0; index < bullets_to_show; index++) - { - if (!bullet.sprites[index]) - { - # Scale bullet image to 7x7 pixels - scaled_bullet = bullet.image.Scale(7, 7); - bullet.sprites[index] = Sprite(scaled_bullet); - bullet.x = entry.x + 20 + index * (7 + 5); - bullet.y = entry.y + entry.image.GetHeight() / 2 - 3.5; - bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002); - } - bullet.sprites[index].SetOpacity(1); - } + # Create and show bullets for current password (max 21) + max_bullets = 21; + bullets_to_show = bullets; + if (bullets_to_show > max_bullets) { + bullets_to_show = max_bullets; } + for (index = 0; index < bullets_to_show; index++) { + if (!bullet.sprites[index]) { + # Scale bullet image to 7x7 pixels + scaled_bullet = bullet.image.Scale(7, 7); + bullet.sprites[index] = Sprite(scaled_bullet); + bullet.x = entry.x + 20 + index * (7 + 5); + bullet.y = entry.y + entry.image.GetHeight() / 2 - 3.5; + bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002); + } + + bullet.sprites[index].SetOpacity(1); + } +} + Plymouth.SetDisplayNormalFunction(display_normal_callback); Plymouth.SetDisplayPasswordFunction(display_password_callback); @@ -214,44 +198,38 @@ progress_bar.y = progress_box.y + (progress_box.image.GetHeight() - progress_bar progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1); progress_bar.sprite.SetOpacity(0); -fun progress_callback (duration, progress) - { - global.real_progress = progress; - - # If real progress is above limit, stop fake progress and use real progress - if (progress > global.fake_progress_limit) - { - stop_fake_progress(); - update_progress_bar(progress); - } +fun progress_callback(duration, progress) { + # Track when fake progress starts + # Needed because duration and progress freeze during drive decryption + if (global.fake_progress_start_time == 0.0) { + global.fake_progress_start_time = duration; } -Plymouth.SetBootProgressFunction(progress_callback); + global.real_progress = progress; -#----------------------------------------- Quit -------------------------------- - -fun quit_callback () -{ - logo.sprite.SetOpacity (1); + # Use real progress once its unfrozen and exceeds fake progress + if (duration > global.fake_progress_start_time && progress > global.fake_progress) { + stop_fake_progress(); + update_progress_bar(progress); + } } -Plymouth.SetQuitFunction(quit_callback); +Plymouth.SetBootProgressFunction(progress_callback); #----------------------------------------- Message -------------------------------- message_sprite = Sprite(); message_sprite.SetPosition(10, 10, 10000); -fun display_message_callback (text) -{ - my_image = Image.Text(text, 1, 1, 1); - message_sprite.SetImage(my_image); +fun display_message_callback(text) { + message = Image.Text(text, 1, 1, 1); + message_sprite.SetImage(message); + message_sprite.SetOpacity(1); } -fun hide_message_callback (text) -{ +fun hide_message_callback(text) { message_sprite.SetOpacity(0); } -Plymouth.SetDisplayMessageFunction (display_message_callback); -Plymouth.SetHideMessageFunction (hide_message_callback); +Plymouth.SetDisplayMessageFunction(display_message_callback); +Plymouth.SetHideMessageFunction(hide_message_callback); diff --git a/default/plymouth/preview-unlock.png b/default/plymouth/preview-unlock.png new file mode 100644 index 00000000..78c3e9c5 Binary files /dev/null and b/default/plymouth/preview-unlock.png differ diff --git a/default/themed/gum.env.conf.tpl b/default/themed/gum.env.conf.tpl new file mode 100644 index 00000000..179c08ff --- /dev/null +++ b/default/themed/gum.env.conf.tpl @@ -0,0 +1,137 @@ +# Gum Style (generic) Variables +env = FOREGROUND,#{{ foreground }} +env = BACKGROUND,#{{ background }} +env = BORDER_FOREGROUND,#{{ accent }} +env = BORDER_BACKGROUND,#{{ background }} + +# Gum Confirm Style Variables +env = GUM_CONFIRM_PROMPT_FOREGROUND,#{{ accent }} +env = GUM_CONFIRM_PROMPT_BACKGROUND,#{{ background }} +env = GUM_CONFIRM_SELECTED_FOREGROUND,#{{ selection_foreground }} +env = GUM_CONFIRM_SELECTED_BACKGROUND,#{{ selection_background }} +env = GUM_CONFIRM_UNSELECTED_FOREGROUND,#{{ foreground }} +env = GUM_CONFIRM_UNSELECTED_BACKGROUND,#{{ background }} + +# Gum Input Style Variables +env = GUM_INPUT_PROMPT_FOREGROUND,#{{ accent }} +env = GUM_INPUT_PROMPT_BACKGROUND,#{{ background }} +env = GUM_INPUT_PLACEHOLDER_FOREGROUND,#{{ color8 }} +env = GUM_INPUT_PLACEHOLDER_BACKGROUND,#{{ background }} +env = GUM_INPUT_CURSOR_FOREGROUND,#{{ cursor }} +env = GUM_INPUT_CURSOR_BACKGROUND,#{{ background }} +env = GUM_INPUT_HEADER_FOREGROUND,#{{ foreground }} +env = GUM_INPUT_HEADER_BACKGROUND,#{{ background }} + +# Gum Choose Style Variables +env = GUM_CHOOSE_CURSOR_FOREGROUND,#{{ cursor }} +env = GUM_CHOOSE_CURSOR_BACKGROUND,#{{ background }} +env = GUM_CHOOSE_HEADER_FOREGROUND,#{{ foreground }} +env = GUM_CHOOSE_HEADER_BACKGROUND,#{{ background }} +env = GUM_CHOOSE_ITEM_FOREGROUND,#{{ foreground }} +env = GUM_CHOOSE_ITEM_BACKGROUND,#{{ background }} +env = GUM_CHOOSE_SELECTED_FOREGROUND,#{{ selection_foreground }} +env = GUM_CHOOSE_SELECTED_BACKGROUND,#{{ selection_background }} + +# Gum Filter Style Variables +env = GUM_FILTER_PROMPT_FOREGROUND,#{{ accent }} +env = GUM_FILTER_PROMPT_BACKGROUND,#{{ background }} +env = GUM_FILTER_TEXT_FOREGROUND,#{{ foreground }} +env = GUM_FILTER_TEXT_BACKGROUND,#{{ background }} +env = GUM_FILTER_MATCH_FOREGROUND,#{{ accent }} +env = GUM_FILTER_CURSOR_TEXT_FOREGROUND,#{{ cursor }} +env = GUM_FILTER_CURSOR_TEXT_BACKGROUND,#{{ background }} +env = GUM_FILTER_SELECTED_FOREGROUND,#{{ selection_foreground }} +env = GUM_FILTER_SELECTED_BACKGROUND,#{{ selection_background }} +env = GUM_FILTER_INDICATOR_FOREGROUND,#{{ accent }} +env = GUM_FILTER_HEADER_FOREGROUND,#{{ foreground }} +env = GUM_FILTER_MATCH_BACKGROUND,#{{ background }} +env = GUM_FILTER_HEADER_BACKGROUND,#{{ background }} +env = GUM_FILTER_PLACEHOLDER_FOREGROUND,#{{ color8 }} +env = GUM_FILTER_PLACEHOLDER_BACKGROUND,#{{ background }} +env = GUM_FILTER_INDICATOR_BACKGROUND,#{{ background }} +env = GUM_FILTER_SELECTED_PREFIX_FOREGROUND,#{{ selection_foreground }} +env = GUM_FILTER_SELECTED_PREFIX_BACKGROUND,#{{ selection_background }} +env = GUM_FILTER_UNSELECTED_PREFIX_FOREGROUND,#{{ color8 }} +env = GUM_FILTER_UNSELECTED_PREFIX_BACKGROUND,#{{ background }} + +# Gum Table Style Variables +env = GUM_TABLE_HEADER_FOREGROUND,#{{ foreground }} +env = GUM_TABLE_HEADER_BACKGROUND,#{{ background }} +env = GUM_TABLE_CELL_FOREGROUND,#{{ foreground }} +env = GUM_TABLE_CELL_BACKGROUND,#{{ background }} +env = GUM_TABLE_BORDER_FOREGROUND,#{{ color8 }} +env = GUM_TABLE_BORDER_BACKGROUND,#{{ background }} +env = GUM_TABLE_SELECTED_FOREGROUND,#{{ selection_foreground }} +env = GUM_TABLE_SELECTED_BACKGROUND,#{{ selection_background }} + +# Gum Spin Style Variables +env = GUM_SPIN_SPINNER_FOREGROUND,#{{ accent }} +env = GUM_SPIN_SPINNER_BACKGROUND,#{{ background }} +env = GUM_SPIN_TITLE_FOREGROUND,#{{ foreground }} +env = GUM_SPIN_TITLE_BACKGROUND,#{{ background }} + +# Gum File Style Variables +env = GUM_FILE_CURSOR_FOREGROUND,#{{ cursor }} +env = GUM_FILE_CURSOR_BACKGROUND,#{{ background }} +env = GUM_FILE_SYMLINK_FOREGROUND,#{{ foreground }} +env = GUM_FILE_SYMLINK_BACKGROUND,#{{ background }} +env = GUM_FILE_DIRECTORY_FOREGROUND,#{{ foreground }} +env = GUM_FILE_DIRECTORY_BACKGROUND,#{{ background }} +env = GUM_FILE_FILE_FOREGROUND,#{{ foreground }} +env = GUM_FILE_FILE_BACKGROUND,#{{ background }} +env = GUM_FILE_PERMISSIONS_FOREGROUND,#{{ color8 }} +env = GUM_FILE_PERMISSIONS_BACKGROUND,#{{ background }} +env = GUM_FILE_SELECTED_FOREGROUND,#{{ selection_foreground }} +env = GUM_FILE_SELECTED_BACKGROUND,#{{ selection_background }} +env = GUM_FILE_FILE_SIZE_FOREGROUND,#{{ color8 }} +env = GUM_FILE_FILE_SIZE_BACKGROUND,#{{ background }} +env = GUM_FILE_HEADER_FOREGROUND,#{{ foreground }} +env = GUM_FILE_HEADER_BACKGROUND,#{{ background }} + +# Gum Pager Style Variables +env = GUM_PAGER_FOREGROUND,#{{ foreground }} +env = GUM_PAGER_BACKGROUND,#{{ background }} +env = GUM_PAGER_LINE_NUMBER_FOREGROUND,#{{ color8 }} +env = GUM_PAGER_LINE_NUMBER_BACKGROUND,#{{ background }} +env = GUM_PAGER_MATCH_FOREGROUND,#{{ accent }} +env = GUM_PAGER_MATCH_BACKGROUND,#{{ background }} +env = GUM_PAGER_MATCH_HIGH_FOREGROUND,#{{ accent }} +env = GUM_PAGER_MATCH_HIGH_BACKGROUND,#{{ background }} +env = GUM_PAGER_HELP_FOREGROUND,#{{ color8 }} +env = GUM_PAGER_HELP_BACKGROUND,#{{ background }} + +# Gum Write Style Variables +env = GUM_WRITE_BASE_FOREGROUND,#{{ foreground }} +env = GUM_WRITE_BASE_BACKGROUND,#{{ background }} +env = GUM_WRITE_CURSOR_LINE_NUMBER_FOREGROUND,#{{ color8 }} +env = GUM_WRITE_CURSOR_LINE_NUMBER_BACKGROUND,#{{ background }} +env = GUM_WRITE_CURSOR_LINE_FOREGROUND,#{{ foreground }} +env = GUM_WRITE_CURSOR_LINE_BACKGROUND,#{{ selection_background }} +env = GUM_WRITE_CURSOR_FOREGROUND,#{{ cursor }} +env = GUM_WRITE_CURSOR_BACKGROUND,#{{ background }} +env = GUM_WRITE_END_OF_BUFFER_FOREGROUND,#{{ color8 }} +env = GUM_WRITE_END_OF_BUFFER_BACKGROUND,#{{ background }} +env = GUM_WRITE_LINE_NUMBER_FOREGROUND,#{{ color8 }} +env = GUM_WRITE_LINE_NUMBER_BACKGROUND,#{{ background }} +env = GUM_WRITE_HEADER_FOREGROUND,#{{ foreground }} +env = GUM_WRITE_HEADER_BACKGROUND,#{{ background }} +env = GUM_WRITE_PLACEHOLDER_FOREGROUND,#{{ color8 }} +env = GUM_WRITE_PLACEHOLDER_BACKGROUND,#{{ background }} +env = GUM_WRITE_PROMPT_FOREGROUND,#{{ foreground }} +env = GUM_WRITE_PROMPT_BACKGROUND,#{{ background }} + +# Gum Log Style Variables +env = GUM_LOG_LEVEL_FOREGROUND,#{{ accent }} +env = GUM_LOG_LEVEL_BACKGROUND,#{{ background }} +env = GUM_LOG_TIME_FOREGROUND,#{{ color8 }} +env = GUM_LOG_TIME_BACKGROUND,#{{ background }} +env = GUM_LOG_PREFIX_FOREGROUND,#{{ foreground }} +env = GUM_LOG_PREFIX_BACKGROUND,#{{ background }} +env = GUM_LOG_MESSAGE_FOREGROUND,#{{ foreground }} +env = GUM_LOG_MESSAGE_BACKGROUND,#{{ background }} +env = GUM_LOG_KEY_FOREGROUND,#{{ foreground }} +env = GUM_LOG_KEY_BACKGROUND,#{{ background }} +env = GUM_LOG_VALUE_FOREGROUND,#{{ foreground }} +env = GUM_LOG_VALUE_BACKGROUND,#{{ background }} +env = GUM_LOG_SEPARATOR_FOREGROUND,#{{ color8 }} +env = GUM_LOG_SEPARATOR_BACKGROUND,#{{ background }} \ No newline at end of file diff --git a/default/themed/helix.toml.tpl b/default/themed/helix.toml.tpl new file mode 100644 index 00000000..90ba441c --- /dev/null +++ b/default/themed/helix.toml.tpl @@ -0,0 +1,132 @@ +# Syntax +"keyword" = "color5" +"keyword.control" = { fg = "color5", modifiers = ["italic"] } +"function" = "color4" +"function.builtin" = "color4" +"function.macro" = "color5" +"type" = "color3" +"type.builtin" = "color5" +"type.enum.variant" = "color6" +"constructor" = "color4" +"constant" = "color3" +"constant.builtin" = "color3" +"constant.numeric" = "color3" +"constant.character" = "color6" +"constant.character.escape" = "color5" +"string" = "color2" +"string.regexp" = "color5" +"string.special" = "color4" +"comment" = { fg = "color8", modifiers = ["italic"] } +"variable" = "foreground" +"variable.parameter" = { fg = "color5", modifiers = ["italic"] } +"variable.builtin" = "color1" +"variable.other.member" = "color4" +"label" = "color4" +"punctuation" = "color8" +"punctuation.special" = "color6" +"operator" = "color6" +"tag" = "color4" +"namespace" = { fg = "color3", modifiers = ["italic"] } +"special" = "color5" +"attribute" = "color3" + +# Markup +"markup.heading.1" = "color1" +"markup.heading.2" = "color3" +"markup.heading.3" = "color3" +"markup.heading.4" = "color2" +"markup.heading.5" = "color4" +"markup.heading.6" = "color5" +"markup.list" = "color6" +"markup.list.unchecked" = "color8" +"markup.list.checked" = "color2" +"markup.bold" = { fg = "color1", modifiers = ["bold"] } +"markup.italic" = { fg = "color1", modifiers = ["italic"] } +"markup.strikethrough" = { modifiers = ["crossed_out"] } +"markup.link.url" = { fg = "color4", modifiers = ["italic", "underlined"] } +"markup.link.text" = "color5" +"markup.link.label" = "color4" +"markup.raw" = "color2" +"markup.quote" = "color5" + +# Diff +"diff.plus" = "color2" +"diff.minus" = "color1" +"diff.delta" = "color4" + +# Leave the editor background transparent so the terminal background shows through +"ui.background" = { } + +"ui.linenr" = { fg = "color8" } +"ui.linenr.selected" = { fg = "foreground" } + +# Statusline uses an inverted band (background-color text on foreground-color +# background) to guarantee contrast across both light and dark Omarchy themes. +"ui.statusline" = { fg = "background", bg = "foreground" } +"ui.statusline.inactive" = { fg = "background", bg = "color8" } +"ui.statusline.normal" = { fg = "background", bg = "color4", modifiers = ["bold"] } +"ui.statusline.insert" = { fg = "background", bg = "color2", modifiers = ["bold"] } +"ui.statusline.select" = { fg = "background", bg = "color5", modifiers = ["bold"] } + +"ui.popup" = { fg = "foreground", bg = "background" } +"ui.window" = { fg = "color8" } +"ui.help" = { fg = "foreground", bg = "background" } + +"ui.bufferline" = { fg = "color8", bg = "background" } +"ui.bufferline.active" = { fg = "foreground", bg = "background", underline = { color = "color5", style = "line" } } + +"ui.text" = "foreground" +"ui.text.focus" = { fg = "foreground", bg = "color0", modifiers = ["bold"] } +"ui.text.inactive" = { fg = "color8" } +"ui.text.directory" = { fg = "color4" } + +"ui.virtual" = "color8" +"ui.virtual.ruler" = { bg = "color0" } +"ui.virtual.indent-guide" = "color8" +"ui.virtual.inlay-hint" = { fg = "color8" } +"ui.virtual.jump-label" = { fg = "color1", modifiers = ["bold"] } +"ui.virtual.whitespace" = "color8" + +"ui.selection" = { bg = "color0" } + +"ui.cursor" = { fg = "background", bg = "cursor" } +"ui.cursor.primary" = { fg = "background", bg = "cursor" } +"ui.cursor.match" = { fg = "color3", modifiers = ["bold"] } +"ui.cursor.primary.normal" = { fg = "background", bg = "cursor" } +"ui.cursor.primary.insert" = { fg = "background", bg = "color2" } +"ui.cursor.primary.select" = { fg = "background", bg = "color5" } + +"ui.cursorline.primary" = { bg = "color0" } + +"ui.highlight" = { bg = "color0", modifiers = ["bold"] } + +"ui.menu" = { fg = "foreground", bg = "background" } +"ui.menu.selected" = { fg = "background", bg = "foreground", modifiers = ["bold"] } + +"diagnostic.error" = { underline = { color = "color1", style = "curl" } } +"diagnostic.warning" = { underline = { color = "color3", style = "curl" } } +"diagnostic.info" = { underline = { color = "color4", style = "curl" } } +"diagnostic.hint" = { underline = { color = "color6", style = "curl" } } +"diagnostic.unnecessary" = { modifiers = ["dim"] } +"diagnostic.deprecated" = { modifiers = ["crossed_out"] } + +error = "color1" +warning = "color3" +info = "color4" +hint = "color6" + +[palette] +background = "{{ background }}" +foreground = "{{ foreground }}" +cursor = "{{ cursor }}" +selection_background = "{{ selection_background }}" +selection_foreground = "{{ selection_foreground }}" +color0 = "{{ color0 }}" +color1 = "{{ color1 }}" +color2 = "{{ color2 }}" +color3 = "{{ color3 }}" +color4 = "{{ color4 }}" +color5 = "{{ color5 }}" +color6 = "{{ color6 }}" +color7 = "{{ color7 }}" +color8 = "{{ color8 }}" diff --git a/default/walker/themes/omarchy-default/style.css b/default/walker/themes/omarchy-default/style.css index 0dc824fb..81ff4e00 100644 --- a/default/walker/themes/omarchy-default/style.css +++ b/default/walker/themes/omarchy-default/style.css @@ -78,6 +78,10 @@ child:selected .item-box * { color: @selected-text; } +child:selected { + background: alpha(@text, 0.07); +} + .item-box { padding-left: 14px; } @@ -114,3 +118,4 @@ child:selected .item-box * { .preview { } + diff --git a/default/wayland-sessions/omarchy.desktop b/default/wayland-sessions/omarchy.desktop new file mode 100644 index 00000000..760181af --- /dev/null +++ b/default/wayland-sessions/omarchy.desktop @@ -0,0 +1,6 @@ +[Desktop Entry] +Name=Omarchy (Hyprland uwsm) +Comment=Omarchy Hyprland session managed by uwsm +Exec=uwsm start -g -1 -e -D Hyprland hyprland.desktop +TryExec=uwsm +Type=Application diff --git a/install/config/all.sh b/install/config/all.sh index 69267195..bdd3f4ba 100644 --- a/install/config/all.sh +++ b/install/config/all.sh @@ -8,12 +8,14 @@ run_logged $OMARCHY_INSTALL/config/increase-sudo-tries.sh run_logged $OMARCHY_INSTALL/config/increase-lockout-limit.sh run_logged $OMARCHY_INSTALL/config/ssh-flakiness.sh run_logged $OMARCHY_INSTALL/config/increase-file-watchers.sh +run_logged $OMARCHY_INSTALL/config/increase-fd-limit.sh run_logged $OMARCHY_INSTALL/config/detect-keyboard-layout.sh run_logged $OMARCHY_INSTALL/config/xcompose.sh run_logged $OMARCHY_INSTALL/config/mise-work.sh run_logged $OMARCHY_INSTALL/config/fix-powerprofilesctl-shebang.sh run_logged $OMARCHY_INSTALL/config/docker.sh run_logged $OMARCHY_INSTALL/config/mimetypes.sh +run_logged $OMARCHY_INSTALL/config/user-dirs.sh run_logged $OMARCHY_INSTALL/config/nautilus-python.sh run_logged $OMARCHY_INSTALL/config/localdb.sh run_logged $OMARCHY_INSTALL/config/walker-elephant.sh @@ -43,12 +45,16 @@ run_logged $OMARCHY_INSTALL/config/hardware/intel/lpmd.sh run_logged $OMARCHY_INSTALL/config/hardware/intel/thermald.sh run_logged $OMARCHY_INSTALL/config/hardware/intel/ipu7-camera.sh run_logged $OMARCHY_INSTALL/config/hardware/intel/ptl-kernel.sh +run_logged $OMARCHY_INSTALL/config/hardware/intel/fred.sh run_logged $OMARCHY_INSTALL/config/hardware/intel/fix-wifi7-eht.sh run_logged $OMARCHY_INSTALL/config/hardware/dell/fix-xps-haptic-touchpad.sh +run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-asus-ptl-b9406-display.sh +run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-asus-ptl-b9406-touchpad.sh run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-audio-mixer.sh run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-mic.sh +run_logged $OMARCHY_INSTALL/config/hardware/asus/fix-z13-touchpad.sh run_logged $OMARCHY_INSTALL/config/hardware/framework/fix-f13-amd-audio-input.sh run_logged $OMARCHY_INSTALL/config/hardware/framework/qmk-hid.sh diff --git a/install/config/hardware/asus/fix-asus-ptl-b9406-display.sh b/install/config/hardware/asus/fix-asus-ptl-b9406-display.sh new file mode 100644 index 00000000..de03d286 --- /dev/null +++ b/install/config/hardware/asus/fix-asus-ptl-b9406-display.sh @@ -0,0 +1,21 @@ +# Display fixes for ASUS ExpertBook B9406 (Panther Lake / Xe3 iGPU). +# +# Panel Replay is Xe3-new, default-on in the xe driver, and has a broken +# exit/wake path on this eDP panel: the panel latches the last-presented +# frame in self-refresh and never wakes for subsequent atomic commits, so +# the screen only updates on a full modeset (e.g. a VT switch). The older +# xe.enable_psr=0 knob does not cover Panel Replay. +# +# The panel's EDID on eDP-1 reads as empty, so xe takes backlight type from +# VBT (which says PWM) but the panel actually wants DPCD AUX backlight. +# Without xe.enable_dpcd_backlight=1, intel_backlight sysfs writes succeed +# but produce no visible change; brightness is effectively binary. + +if omarchy-hw-asus-expertbook-b9406; then + sudo mkdir -p /etc/limine-entry-tool.d + cat </dev/null +# ASUS ExpertBook B9406 (Panther Lake / Xe3) display workarounds +KERNEL_CMDLINE[default]+=" xe.enable_panel_replay=0" +KERNEL_CMDLINE[default]+=" xe.enable_dpcd_backlight=1" +EOF +fi diff --git a/install/config/hardware/asus/fix-asus-ptl-b9406-touchpad.sh b/install/config/hardware/asus/fix-asus-ptl-b9406-touchpad.sh new file mode 100644 index 00000000..d39da070 --- /dev/null +++ b/install/config/hardware/asus/fix-asus-ptl-b9406-touchpad.sh @@ -0,0 +1,23 @@ +# Touchpad quirks for ASUS ExpertBook B9406 (Pixart 093A:4F05 on i2c-hid). +# +# The kernel produces perfect Precision Touchpad reports but libinput's +# jump-detection heuristic discards every motion event as "kernel bug: +# Touch jump detected and discarded" because the pad reports pressure +# values of 0-1, confusing the contact stability check. Button events +# still pass, so clicks register but motion does not. +# +# Mask the pressure axes with a quirks override, same pattern as the +# Asus UX302LA entry in libinput's shipped 50-system-asus.quirks. + +if omarchy-hw-asus-expertbook-b9406; then + sudo mkdir -p /etc/libinput + sudo tee /etc/libinput/asus-expertbook-b9406.quirks >/dev/null < /dev/null <<'EOF' +ACTION=="add|change", KERNEL=="event*", ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="1a30", ENV{ID_INPUT_TOUCHPAD}=="1", ENV{ID_INPUT_TOUCHPAD_INTEGRATION}="internal" +EOF + sudo udevadm control --reload-rules +fi diff --git a/install/config/hardware/fix-bcm43xx.sh b/install/config/hardware/fix-bcm43xx.sh index f6e0f18b..a788d6f9 100644 --- a/install/config/hardware/fix-bcm43xx.sh +++ b/install/config/hardware/fix-bcm43xx.sh @@ -2,7 +2,7 @@ # - BCM4360 (2013–2015 MacBooks) # - BCM4331 (2012, early 2013 MacBooks) -pci_info=$(lspci -nnv) +pci_info=$(lspci -nn) if (echo "$pci_info" | grep -q "14e4:43a0" || echo "$pci_info" | grep -q "14e4:4331"); then echo "BCM4360 / BCM4331 detected" diff --git a/install/config/hardware/intel/fred.sh b/install/config/hardware/intel/fred.sh new file mode 100644 index 00000000..c25e4c79 --- /dev/null +++ b/install/config/hardware/intel/fred.sh @@ -0,0 +1,18 @@ +# Enable Flexible Return and Event Delivery on Intel Panther Lake. + +DROP_IN="/etc/limine-entry-tool.d/intel-panther-lake-fred.conf" +DEFAULT_LIMINE="/etc/default/limine" + +if omarchy-hw-intel-ptl; then + if [[ ! -f $DROP_IN ]] || ! grep -q 'fred=on' "$DROP_IN"; then + sudo mkdir -p /etc/limine-entry-tool.d + cat </dev/null +# Intel Panther Lake FRED support +KERNEL_CMDLINE[default]+=" fred=on" +EOF + fi + + if [[ -f $DEFAULT_LIMINE ]] && ! grep -q 'fred=on' "$DEFAULT_LIMINE"; then + sudo tee -a "$DEFAULT_LIMINE" < "$DROP_IN" >/dev/null + fi +fi diff --git a/install/config/hardware/intel/ptl-kernel.sh b/install/config/hardware/intel/ptl-kernel.sh index 0e34def4..d914cf25 100644 --- a/install/config/hardware/intel/ptl-kernel.sh +++ b/install/config/hardware/intel/ptl-kernel.sh @@ -1,8 +1,8 @@ -# Install Panther Lake kernel for Intel Panther Lake systems +# Install Panther Lake kernel for Dell XPS Panther Lake systems # The linux-ptl kernel includes audio driver patches not yet in mainline. -if omarchy-hw-intel-ptl; then - echo "Detected Intel Panther Lake, installing PTL kernel..." +if omarchy-hw-match "XPS" && omarchy-hw-intel-ptl; then + echo "Detected Dell XPS Panther Lake, installing PTL kernel..." omarchy-pkg-add linux-ptl linux-ptl-headers for pkg in linux linux-headers; do @@ -10,8 +10,8 @@ if omarchy-hw-intel-ptl; then done sudo mkdir -p /etc/limine-entry-tool.d - cat </dev/null -# Only show Panther Lake kernel in boot menu + cat </dev/null +# Only show Panther Lake kernel in boot menu on Dell XPS Panther Lake BOOT_ORDER="linux-ptl*, *fallback, Snapshots" EOF fi diff --git a/install/config/hardware/nvidia.sh b/install/config/hardware/nvidia.sh index 5fb37232..dddcf7e4 100644 --- a/install/config/hardware/nvidia.sh +++ b/install/config/hardware/nvidia.sh @@ -1,15 +1,11 @@ -NVIDIA="$(lspci | grep -i 'nvidia')" - -if [[ -n $NVIDIA ]]; then +if lspci | grep -qi 'nvidia'; then # Check which kernel is installed and set appropriate headers package KERNEL_HEADERS="$(pacman -Qqs '^linux(-zen|-lts|-hardened)?$' | head -1)-headers" - # Turing+ (GTX 16xx, RTX 20xx-50xx, RTX Pro, Quadro RTX, datacenter A/H/T/L series) have GSP firmware - if echo "$NVIDIA" | grep -qE "GTX 16[0-9]{2}|RTX [2-5][0-9]{3}|RTX PRO [0-9]{4}|Quadro RTX|RTX A[0-9]{4}|A[1-9][0-9]{2}|H[1-9][0-9]{2}|T4|L[0-9]+"; then + if omarchy-hw-nvidia-gsp; then PACKAGES=(nvidia-open-dkms nvidia-utils lib32-nvidia-utils libva-nvidia-driver) GPU_ARCH="turing_plus" - # Maxwell (GTX 9xx), Pascal (GT/GTX 10xx, Quadro P, MX series), Volta (Titan V, Tesla V100, Quadro GV100) lack GSP - elif echo "$NVIDIA" | grep -qE "GTX (9[0-9]{2}|10[0-9]{2})|GT 10[0-9]{2}|Quadro [PM][0-9]{3,4}|Quadro GV100|MX *[0-9]+|Titan (X|Xp|V)|Tesla V100"; then + elif omarchy-hw-nvidia-without-gsp; then PACKAGES=(nvidia-580xx-dkms nvidia-580xx-utils lib32-nvidia-580xx-utils) GPU_ARCH="maxwell_pascal_volta" fi diff --git a/install/config/increase-fd-limit.sh b/install/config/increase-fd-limit.sh new file mode 100755 index 00000000..45f1e2ea --- /dev/null +++ b/install/config/increase-fd-limit.sh @@ -0,0 +1,11 @@ +# Raise soft file descriptor limit from systemd's default of 1024 to 65536 +# so dev tools (VS Code, Docker, dev servers, databases) get the headroom they need +sudo mkdir -p /etc/systemd/system.conf.d /etc/systemd/user.conf.d + +sudo tee /etc/systemd/system.conf.d/99-omarchy-nofile.conf >/dev/null <<'EOF' +[Manager] +DefaultLimitNOFILESoft=65536 +EOF + +sudo cp /etc/systemd/system.conf.d/99-omarchy-nofile.conf \ + /etc/systemd/user.conf.d/99-omarchy-nofile.conf diff --git a/install/config/powerprofilesctl-rules.sh b/install/config/powerprofilesctl-rules.sh index 9b5a71a6..0715a1c6 100644 --- a/install/config/powerprofilesctl-rules.sh +++ b/install/config/powerprofilesctl-rules.sh @@ -1,9 +1,11 @@ if omarchy-battery-present; then cat </dev/null sudo udevadm trigger --subsystem-match=power_supply 2>/dev/null fi diff --git a/install/config/theme.sh b/install/config/theme.sh index 0dab91ad..83e2b8dd 100644 --- a/install/config/theme.sh +++ b/install/config/theme.sh @@ -5,6 +5,14 @@ sudo ln -snf /usr/share/icons/Adwaita/symbolic/actions/go-next-symbolic.svg /usr # Setup user theme folder mkdir -p ~/.config/omarchy/themes +# Add managed policy directories for Chromium and Brave for theme changes. +# Must exist before the first omarchy-theme-set, which writes color.json into them. +sudo mkdir -p /etc/chromium/policies/managed +sudo chmod a+rw /etc/chromium/policies/managed + +sudo mkdir -p /etc/brave/policies/managed +sudo chmod a+rw /etc/brave/policies/managed + # Set initial theme omarchy-theme-set "Tokyo Night" rm -rf ~/.config/chromium/SingletonLock # otherwise archiso will own the chromium singleton @@ -16,12 +24,5 @@ ln -snf ~/.config/omarchy/current/theme/btop.theme ~/.config/btop/themes/current mkdir -p ~/.config/mako ln -snf ~/.config/omarchy/current/theme/mako.ini ~/.config/mako/config -# Add managed policy directories for Chromium and Brave for theme changes -sudo mkdir -p /etc/chromium/policies/managed -sudo chmod a+rw /etc/chromium/policies/managed - -sudo mkdir -p /etc/brave/policies/managed -sudo chmod a+rw /etc/brave/policies/managed - # Default Chromium to follow system appearance ("device") instead of dark echo '{"browser":{"theme":{"color_scheme":0,"color_scheme2":0}}}' | sudo tee /usr/lib/chromium/initial_preferences >/dev/null diff --git a/install/config/user-dirs.sh b/install/config/user-dirs.sh new file mode 100644 index 00000000..26d1adc2 --- /dev/null +++ b/install/config/user-dirs.sh @@ -0,0 +1,12 @@ +mkdir -p ~/Downloads ~/Pictures ~/Videos ~/.config/gtk-3.0 + +xdg-user-dirs-update --set TEMPLATES "$HOME" +xdg-user-dirs-update --set PUBLICSHARE "$HOME" +xdg-user-dirs-update --set DESKTOP "$HOME" + +rmdir ~/Templates ~/Public ~/Desktop 2>/dev/null || true + +touch ~/.config/gtk-3.0/bookmarks +for dir in Downloads Projects Pictures Videos; do + printf 'file://%s/%s %s\n' "$HOME" "$dir" "$dir" >>~/.config/gtk-3.0/bookmarks +done diff --git a/install/config/walker-elephant.sh b/install/config/walker-elephant.sh index ad071dc9..a06f8c39 100644 --- a/install/config/walker-elephant.sh +++ b/install/config/walker-elephant.sh @@ -28,3 +28,4 @@ EOF mkdir -p ~/.config/elephant/menus ln -snf $OMARCHY_PATH/default/elephant/omarchy_themes.lua ~/.config/elephant/menus/omarchy_themes.lua ln -snf $OMARCHY_PATH/default/elephant/omarchy_background_selector.lua ~/.config/elephant/menus/omarchy_background_selector.lua +ln -snf $OMARCHY_PATH/default/elephant/omarchy_unlocks.lua ~/.config/elephant/menus/omarchy_unlocks.lua diff --git a/install/first-run/firewall.sh b/install/first-run/firewall.sh index cc187dc2..96210c8b 100644 --- a/install/first-run/firewall.sh +++ b/install/first-run/firewall.sh @@ -8,6 +8,7 @@ sudo ufw allow 53317/tcp # Allow Docker containers to use DNS on host sudo ufw allow in proto udp from 172.16.0.0/12 to 172.17.0.1 port 53 comment 'allow-docker-dns' +sudo ufw allow in proto udp from 192.168.0.0/16 to 172.17.0.1 port 53 comment 'allow-docker-dns' # Turn on the firewall sudo ufw --force enable diff --git a/install/login/all.sh b/install/login/all.sh index 2c03df32..4d76d3f9 100644 --- a/install/login/all.sh +++ b/install/login/all.sh @@ -1,4 +1,5 @@ run_logged $OMARCHY_INSTALL/login/plymouth.sh run_logged $OMARCHY_INSTALL/login/default-keyring.sh run_logged $OMARCHY_INSTALL/login/sddm.sh +run_logged $OMARCHY_INSTALL/login/hibernation.sh run_logged $OMARCHY_INSTALL/login/limine-snapper.sh diff --git a/install/login/hibernation.sh b/install/login/hibernation.sh new file mode 100644 index 00000000..5983020d --- /dev/null +++ b/install/login/hibernation.sh @@ -0,0 +1,6 @@ +# Run before limine-snapper.sh so the resume hook + cmdline drop-ins are in +# place when `pacman -S limine-mkinitcpio-hook` triggers its single full UKI +# rebuild. The --no-rebuild flag tells the script to skip its own rebuild — +# limine-snapper's pacman install will produce a UKI that already includes +# hibernation. +omarchy-hibernation-setup --force --no-rebuild diff --git a/install/login/limine-snapper.sh b/install/login/limine-snapper.sh index d588f43f..ce9fffbb 100644 --- a/install/login/limine-snapper.sh +++ b/install/login/limine-snapper.sh @@ -1,6 +1,4 @@ if command -v limine &>/dev/null; then - sudo pacman -S --noconfirm --needed limine-snapper-sync limine-mkinitcpio-hook - sudo tee /etc/mkinitcpio.conf.d/omarchy_hooks.conf </dev/null HOOKS=(base udev plymouth keyboard autodetect microcode modconf kms keymap consolefont block encrypt filesystems fsck btrfs-overlayfs) EOF @@ -29,6 +27,10 @@ EOF CMDLINE=$(grep "^[[:space:]]*cmdline:" "$limine_config" | head -1 | sed 's/^[[:space:]]*cmdline:[[:space:]]*//') + # Write /etc/default/limine *before* installing limine-mkinitcpio-hook, whose + # post-transaction deploy hook runs limine-install and reads this file. Without + # it, ESP_PATH falls back to bootctl, which in a chroot prints a warning that + # gets captured as the path and trips a spurious "invalid ESP" error. sudo cp $OMARCHY_PATH/default/limine/default.conf /etc/default/limine sudo sed -i "s|@@CMDLINE@@|$CMDLINE|g" /etc/default/limine @@ -42,7 +44,8 @@ EOF sudo sed -i '/^ENABLE_UKI=/d; /^ENABLE_LIMINE_FALLBACK=/d' /etc/default/limine fi - # Remove the original config file if it's not /boot/limine.conf + # Remove the original config file if it's not /boot/limine.conf, so the deploy + # hook doesn't see conflicting configs on the same ESP. if [[ $limine_config != "/boot/limine.conf" ]] && [[ -f $limine_config ]]; then sudo rm "$limine_config" fi @@ -50,6 +53,8 @@ EOF # We overwrite the whole thing knowing the limine-update will add the entries for us sudo cp $OMARCHY_PATH/default/limine/limine.conf /boot/limine.conf + sudo pacman -S --noconfirm --needed limine-snapper-sync limine-mkinitcpio-hook + # Only snapshot root — /home is user data; rolling it back loses user work if ! sudo snapper list-configs 2>/dev/null | grep -q "root"; then sudo snapper -c root create-config / @@ -75,11 +80,17 @@ fi echo "mkinitcpio hooks re-enabled" -sudo limine-update - -# Verify that limine-update actually added boot entries +# Installing limine-mkinitcpio-hook above already triggered a full UKI rebuild +# (via 80-limine-efi-deploy.hook + 90-mkinitcpio-install.hook), which writes the +# boot entries into /boot/limine.conf. Only fall back to limine-update if those +# hooks didn't run for some reason — running it unconditionally rebuilds every +# UKI a second time. if ! grep -q "^/+" /boot/limine.conf; then - echo "Error: limine-update failed to add boot entries to /boot/limine.conf" >&2 + sudo limine-update +fi + +if ! grep -q "^/+" /boot/limine.conf; then + echo "Error: failed to add boot entries to /boot/limine.conf" >&2 exit 1 fi diff --git a/install/login/sddm.sh b/install/login/sddm.sh index a0366b3b..21696b48 100644 --- a/install/login/sddm.sh +++ b/install/login/sddm.sh @@ -2,16 +2,21 @@ omarchy-refresh-sddm # Setup SDDM login service +sudo mkdir -p /usr/local/share/wayland-sessions +sudo cp "$OMARCHY_PATH/default/wayland-sessions/omarchy.desktop" /usr/local/share/wayland-sessions/omarchy.desktop + sudo mkdir -p /etc/sddm.conf.d if [[ ! -f /etc/sddm.conf.d/autologin.conf ]]; then cat <>"$OBSIDIAN_FLAGS_FILE" + fi +fi + +if [[ -f ~/.config/hypr/bindings.conf ]]; then + sed -i '/Obsidian, exec/ { + s/ -disable-gpu//g + s/ --disable-gpu//g + s/ --enable-wayland-ime//g + s/"uwsm app -- obsidian/"uwsm-app -- obsidian/g + }' ~/.config/hypr/bindings.conf +fi diff --git a/migrations/1777017528.sh b/migrations/1777017528.sh new file mode 100644 index 00000000..7f340748 --- /dev/null +++ b/migrations/1777017528.sh @@ -0,0 +1,6 @@ +echo "Show battery status notification on right-click of the waybar battery icon" + +if ! grep -q 'omarchy-battery-status' ~/.config/waybar/config.jsonc; then + sed -i '/"on-click": "omarchy-menu power",/a\ "on-click-right": "notify-send -u low \\"$(omarchy-battery-status)\\"",' ~/.config/waybar/config.jsonc + omarchy-restart-waybar +fi diff --git a/migrations/1777072987.sh b/migrations/1777072987.sh new file mode 100644 index 00000000..e2d6080c --- /dev/null +++ b/migrations/1777072987.sh @@ -0,0 +1,7 @@ +echo "Fix disable-while-typing on ASUS ROG Flow Z13 detachable keyboard" + +source $OMARCHY_PATH/install/config/hardware/asus/fix-z13-touchpad.sh + +if [[ -f /etc/udev/rules.d/99-omarchy-asus-z13-touchpad.rules ]]; then + omarchy-state set reboot-required +fi diff --git a/migrations/1777098818.sh b/migrations/1777098818.sh new file mode 100644 index 00000000..a9de7e1b --- /dev/null +++ b/migrations/1777098818.sh @@ -0,0 +1,3 @@ +echo "Fix power profile auto-switching on USB-C only machines and ensure power-profiles-daemon is enabled" + +source "$OMARCHY_PATH/install/config/powerprofilesctl-rules.sh" diff --git a/migrations/1777145626.sh b/migrations/1777145626.sh new file mode 100644 index 00000000..b6518b5d --- /dev/null +++ b/migrations/1777145626.sh @@ -0,0 +1,3 @@ +echo "Install dosfstools for FAT filesystem utilities like fsck.fat and mkfs.fat" + +omarchy-pkg-add dosfstools diff --git a/migrations/1777282771.sh b/migrations/1777282771.sh new file mode 100644 index 00000000..b350376f --- /dev/null +++ b/migrations/1777282771.sh @@ -0,0 +1,5 @@ +echo "Allow Docker DNS from Docker's 192.168 address pool" + +if omarchy-cmd-present ufw && sudo ufw status | grep -q "Status: active"; then + sudo ufw allow in proto udp from 192.168.0.0/16 to 172.17.0.1 port 53 comment 'allow-docker-dns' +fi diff --git a/migrations/1777382905.sh b/migrations/1777382905.sh new file mode 100644 index 00000000..f524574f --- /dev/null +++ b/migrations/1777382905.sh @@ -0,0 +1,5 @@ +echo "Use interactive unlock (Plymouth) selector menu" + +mkdir -p ~/.config/elephant/menus +ln -snf $OMARCHY_PATH/default/elephant/omarchy_unlocks.lua ~/.config/elephant/menus/omarchy_unlocks.lua +omarchy-restart-walker diff --git a/migrations/1777396666.sh b/migrations/1777396666.sh new file mode 100644 index 00000000..ea8e4326 --- /dev/null +++ b/migrations/1777396666.sh @@ -0,0 +1,8 @@ +echo "Use Omarchy UWSM session without graphical.target startup wait" + +sudo mkdir -p /usr/local/share/wayland-sessions +sudo cp "$OMARCHY_PATH/default/wayland-sessions/omarchy.desktop" /usr/local/share/wayland-sessions/omarchy.desktop + +if [[ -f /etc/sddm.conf.d/autologin.conf ]]; then + sudo sed -i 's/^Session=hyprland-uwsm$/Session=omarchy/' /etc/sddm.conf.d/autologin.conf +fi diff --git a/migrations/1777450869.sh b/migrations/1777450869.sh new file mode 100644 index 00000000..6b1fcc8c --- /dev/null +++ b/migrations/1777450869.sh @@ -0,0 +1,9 @@ +echo "Hide shutdown console messages behind Plymouth" + +if [[ -f /etc/default/limine ]]; then + sudo sed -i 's/ quiet splash/ quiet splash loglevel=0 systemd.show_status=false rd.udev.log_level=0 vt.global_cursor_default=0/' /etc/default/limine + + if omarchy-cmd-present limine-mkinitcpio; then + sudo limine-mkinitcpio + fi +fi diff --git a/migrations/1777464602.sh b/migrations/1777464602.sh new file mode 100644 index 00000000..8c845442 --- /dev/null +++ b/migrations/1777464602.sh @@ -0,0 +1,8 @@ +echo "Update Waybar screen recording command" + +WAYBAR_CONFIG="$HOME/.config/waybar/config.jsonc" + +if [[ -f $WAYBAR_CONFIG ]] && grep -q 'omarchy-cmd-screenrecord' "$WAYBAR_CONFIG"; then + sed -i 's/omarchy-cmd-screenrecord/omarchy-capture-screenrecording/g' "$WAYBAR_CONFIG" + omarchy-restart-waybar +fi diff --git a/migrations/1777467659.sh b/migrations/1777467659.sh new file mode 100644 index 00000000..994c30bf --- /dev/null +++ b/migrations/1777467659.sh @@ -0,0 +1,6 @@ +echo "Rename lock screen command in Hypridle config" + +if grep -q 'omarchy-lock-screen' ~/.config/hypr/hypridle.conf; then + sed -i 's/omarchy-lock-screen/omarchy-system-lock/g' ~/.config/hypr/hypridle.conf + omarchy-restart-hypridle +fi diff --git a/migrations/1777546300.sh b/migrations/1777546300.sh new file mode 100644 index 00000000..fc40e222 --- /dev/null +++ b/migrations/1777546300.sh @@ -0,0 +1,9 @@ +echo "Enable FRED on Intel Panther Lake systems" + +DEFAULT_LIMINE="/etc/default/limine" + +if omarchy-hw-intel-ptl && [[ -f $DEFAULT_LIMINE ]] && ! grep -q 'fred=on' "$DEFAULT_LIMINE"; then + source "$OMARCHY_PATH/install/config/hardware/intel/fred.sh" + + sudo limine-update +fi diff --git a/migrations/1777570652.sh b/migrations/1777570652.sh new file mode 100644 index 00000000..5511fe27 --- /dev/null +++ b/migrations/1777570652.sh @@ -0,0 +1,10 @@ +echo "Update interface_ colors for limine 12 (palette index -> RRGGBB)" + +if [[ -f /boot/limine.conf ]]; then + sudo sed -i -E 's/^interface_branding_colou?r: 2$/interface_branding_color: 9ece6a/' /boot/limine.conf + sudo sed -i 's/^interface_branding_colour: /interface_branding_color: /' /boot/limine.conf + + sudo sed -i -E '/^interface_help_colou?r(_bright)?:/d' /boot/limine.conf + sudo sed -i '/^interface_branding_color:/a interface_help_color_bright: 9ece6a' /boot/limine.conf + sudo sed -i '/^interface_branding_color:/a interface_help_color: 9ece6a' /boot/limine.conf +fi diff --git a/migrations/1777572869.sh b/migrations/1777572869.sh new file mode 100644 index 00000000..b8ffd217 --- /dev/null +++ b/migrations/1777572869.sh @@ -0,0 +1,16 @@ +echo "Restore stock kernel on non-XPS Panther Lake systems" + +if omarchy-hw-intel-ptl && ! omarchy-hw-match "XPS"; then + omarchy-pkg-add linux linux-headers + + for pkg in linux-ptl linux-ptl-headers; do + sudo pacman -Rdd --noconfirm "$pkg" 2>/dev/null || true + done + + sudo rm -f /etc/limine-entry-tool.d/intel-panther-lake.conf + sudo rm -f /etc/limine-entry-tool.d/dell-xps-panther-lake.conf + + if omarchy-cmd-present limine-update; then + sudo limine-update + fi +fi diff --git a/migrations/1777578316.sh b/migrations/1777578316.sh new file mode 100644 index 00000000..d9e584c2 --- /dev/null +++ b/migrations/1777578316.sh @@ -0,0 +1,8 @@ +echo "Rename screen recording command" + +WAYBAR_CONFIG="$HOME/.config/waybar/config.jsonc" + +if [[ -f $WAYBAR_CONFIG ]] && grep -q 'omarchy-capture-screencording' "$WAYBAR_CONFIG"; then + sed -i 's/omarchy-capture-screencording/omarchy-capture-screenrecording/g' "$WAYBAR_CONFIG" + omarchy-restart-waybar +fi diff --git a/migrations/1777618046.sh b/migrations/1777618046.sh new file mode 100644 index 00000000..6c5c8f10 --- /dev/null +++ b/migrations/1777618046.sh @@ -0,0 +1,5 @@ +echo "Symlink Brave Origin Beta flags to brave-flags.conf so both browsers share configuration" + +if [[ ! -e ~/.config/brave-origin-beta-flags.conf ]]; then + ln -s brave-flags.conf ~/.config/brave-origin-beta-flags.conf +fi diff --git a/migrations/1777620904.sh b/migrations/1777620904.sh new file mode 100644 index 00000000..767c3c1e --- /dev/null +++ b/migrations/1777620904.sh @@ -0,0 +1,13 @@ +echo "Add cliamp music TUI player (Super+Shift+Alt+M)" + +if omarchy-pkg-missing cliamp; then + omarchy-pkg-add cliamp + + cp ~/.local/share/omarchy/applications/icons/Cliamp.png ~/.local/share/applications/icons/Cliamp.png + gtk-update-icon-cache ~/.local/share/icons/hicolor &>/dev/null + omarchy-tui-install "Cliamp" "cliamp" tile "$HOME/.local/share/applications/icons/Cliamp.png" + + if [[ -f ~/.config/hypr/bindings.conf ]] && ! grep -q "cliamp" ~/.config/hypr/bindings.conf; then + sed -i '/^bindd = SUPER SHIFT, M, Music, exec, omarchy-launch-or-focus spotify/a bindd = SUPER SHIFT ALT, M, Music TUI, exec, omarchy-launch-or-focus-tui cliamp' ~/.config/hypr/bindings.conf + fi +fi diff --git a/migrations/1777800806.sh b/migrations/1777800806.sh new file mode 100644 index 00000000..a57a0ae0 --- /dev/null +++ b/migrations/1777800806.sh @@ -0,0 +1,20 @@ +echo "Enable VAAPI hardware video decoding/encoding in Chromium and Brave for h265 and other codecs" + +add_flag() { + local file=$1 + local flag=$2 + + [[ -f $file ]] || return + grep -q "$flag" "$file" && return + + if grep -q "^--enable-features=" "$file"; then + sed -i "s/^--enable-features=\(.*\)$/--enable-features=\1,$flag/" "$file" + else + echo "--enable-features=$flag" >>"$file" + fi +} + +for conf in chromium-flags.conf brave-flags.conf; do + add_flag "$HOME/.config/$conf" "VaapiVideoDecodeLinuxGL" + add_flag "$HOME/.config/$conf" "VaapiVideoEncoder" +done diff --git a/migrations/1777813290.sh b/migrations/1777813290.sh new file mode 100644 index 00000000..e341c7a4 --- /dev/null +++ b/migrations/1777813290.sh @@ -0,0 +1,3 @@ +echo "Raise soft file descriptor limit so dev tools have headroom (takes effect after reboot)" + +bash $OMARCHY_PATH/install/config/increase-fd-limit.sh diff --git a/migrations/1777873457.sh b/migrations/1777873457.sh new file mode 100644 index 00000000..5c185abe --- /dev/null +++ b/migrations/1777873457.sh @@ -0,0 +1,3 @@ +echo "Install ghui (GitHub TUI) via npx wrapper" + +omarchy-npx-install @kitlangton/ghui ghui diff --git a/test/omarchy-cli-test.sh b/test/omarchy-cli-test.sh new file mode 100644 index 00000000..5763920a --- /dev/null +++ b/test/omarchy-cli-test.sh @@ -0,0 +1,260 @@ +#!/bin/bash + +set -euo pipefail + +ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) +CLI="$ROOT/bin/omarchy" +TMPDIR="" + +export PATH="$ROOT/bin:$PATH" + +pass() { + printf 'ok - %s\n' "$1" +} + +fail() { + printf 'not ok - %s\n' "$1" >&2 + exit 1 +} + +assert_output_contains() { + local description="$1" + local output="$2" + local expected="$3" + + if [[ $output != *"$expected"* ]]; then + printf 'Expected output to contain: %s\n' "$expected" >&2 + printf 'Actual output:\n%s\n' "$output" >&2 + fail "$description" + fi + + pass "$description" +} + +cleanup() { + [[ -n $TMPDIR && -d $TMPDIR ]] && rm -rf "$TMPDIR" +} +trap cleanup EXIT + +output=$("$CLI" --help) +assert_output_contains "main help renders" "$output" "Omarchy command center" +assert_output_contains "main help includes hardware group" "$output" "hw" +assert_output_contains "main help includes package group" "$output" "pkg" +if grep -Eq '^ [a-z0-9-]+[[:space:]].*\([0-9]+\)$' <<<"$output"; then + fail "main help does not show group counts" +fi +pass "main help does not show group counts" + +output=$("$CLI" commands) +assert_output_contains "commands lists documented commands" "$output" "omarchy theme set " + +"$CLI" commands --json | jq -e '.ok == true and (.commands | length >= 200)' >/dev/null +pass "commands --json is valid JSON with full bin coverage" + +"$CLI" commands --json | jq -e 'all(.commands[]; .summary != "undocumented")' >/dev/null +pass "all included commands have summaries" + +"$CLI" commands --json | jq -e 'all(.commands[]; has("binary") and has("filename_route") and has("routes") and (has("legacy") | not) and (has("usage") | not) and (has("visibility") | not) and (has("mutates") | not) and (has("interactive") | not))' >/dev/null +pass "JSON uses binary/routes and omits legacy/usage/extra metadata" + +"$CLI" commands --check >/dev/null +pass "commands --check passes" + +"$CLI" commands --all >/dev/null +pass "commands --all does not crash" + +"$CLI" commands --all --json | jq -e '.commands[] | select(.route == "omarchy hyprland window gaps toggle" and .summary != "undocumented")' >/dev/null +pass "fallback commands are inferred and documented" + +"$CLI" commands --all --json | jq -e '.commands[] | select(.route == "omarchy dev benchmark")' >/dev/null +pass "benchmark command is discoverable in all commands" + +"$CLI" commands --json | jq -e '.commands[] | select(.binary == "omarchy-pkg-add" and .route == "omarchy install package" and .filename_route == "omarchy pkg add" and (.routes | index("omarchy pkg add")))' >/dev/null +pass "JSON exposes canonical and filename-derived routes" + +"$CLI" commands --json | jq -e '.commands[] | select(.binary == "omarchy-refresh-pacman" and .requires_sudo == true)' >/dev/null +pass "sudo metadata marks sudo commands" + +output=$("$CLI" theme --help) +assert_output_contains "group help renders" "$output" "Theme commands" + +output=$("$CLI" install --help) +assert_output_contains "install group help renders" "$output" "omarchy install package " + +output=$("$CLI" install) +assert_output_contains "bare group renders help instead of picker" "$output" "Install commands" +assert_output_contains "bare group includes package route" "$output" "omarchy install package " + +output=$("$CLI" toggle) +assert_output_contains "bare root command with children renders help" "$output" "Toggle commands" +assert_output_contains "bare toggle help includes child route" "$output" "omarchy toggle waybar" + +output=$("$CLI" pkg --help) +assert_output_contains "package group includes pkg add fallback route" "$output" "omarchy pkg add " + +output=$("$CLI" restart --help) +assert_output_contains "restart group includes inferred commands" "$output" "omarchy restart btop" +assert_output_contains "restart group includes all restart commands" "$output" "omarchy restart wifi" + +output=$("$CLI" hw --help) +assert_output_contains "hardware group help renders" "$output" "omarchy hw asus rog" +assert_output_contains "hardware group includes touchpad" "$output" "omarchy hw touchpad" + +output=$("$CLI" menu --help) +assert_output_contains "menu group includes share fallback route" "$output" "omarchy menu share" + +output=$("$CLI" share) +assert_output_contains "bare required-arg alias renders CLI help" "$output" "Usage:" +assert_output_contains "bare share help uses canonical route" "$output" "omarchy share [path...]" + +output=$("$CLI" menu share) +assert_output_contains "bare required-arg filename route renders CLI help" "$output" "omarchy share [path...]" + +output=$("$CLI" branch set) +assert_output_contains "bare required-choice route renders CLI help" "$output" "omarchy branch set " + +CLI="$CLI" python3 <<'PY' +import json +import os +import subprocess +import sys + +cli = os.environ['CLI'] +commands = json.loads(subprocess.check_output([cli, 'commands', '--json'], text=True))['commands'] +by_group = {} +for command in commands: + binary = command['binary'] + stem = binary.removeprefix('omarchy-') + group = stem.split('-', 1)[0] + filename_route = 'omarchy ' + stem.replace('-', ' ') + by_group.setdefault(group, []).append((binary, filename_route, command['route'])) + +missing = [] +for group, rows in sorted(by_group.items()): + proc = subprocess.run([cli, group, '--help'], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output = proc.stdout + proc.stderr + if proc.returncode != 0: + missing.append((group, '', f'exit {proc.returncode}')) + continue + for binary, filename_route, canonical_route in rows: + if filename_route not in output and canonical_route not in output and binary not in output: + missing.append((group, binary, filename_route)) + +if missing: + for row in missing: + print('\t'.join(row), file=sys.stderr) + sys.exit(1) +PY +pass "every filename-derived group help represents its bins" + +output=$(timeout 5 "$CLI" theme set --help) +assert_output_contains "command help renders without executing" "$output" "Binary:" +assert_output_contains "theme set help names binary" "$output" "omarchy-theme-set" + +output=$(timeout 5 "$CLI" update --help) +assert_output_contains "mutating command help does not execute target" "$output" "omarchy-update" +assert_output_contains "root command help shows related child commands" "$output" "omarchy update perform" + +output=$("$CLI" screenshot --help) +assert_output_contains "root alias resolves to command help" "$output" "omarchy-capture-screenshot" + +"$CLI" commands --json | jq -e '.commands[] | select(.binary == "omarchy-capture-screenshot") | .aliases | index("omarchy screenshot")' >/dev/null +pass "aliases are included in JSON metadata" + +output=$("$CLI" pkg add --help) +assert_output_contains "fallback route resolves to curated metadata" "$output" "omarchy-pkg-add" +assert_output_contains "fallback route shows canonical route" "$output" "omarchy install package " + +output=$("$CLI" system reboot --help) +assert_output_contains "system command help is safe" "$output" "omarchy-system-reboot" + +output=$("$CLI" dev benchmark --repeat=1) +assert_output_contains "benchmark command runs" "$output" "Omarchy CLI benchmark" + +"$CLI" theme list >/dev/null +pass "safe dispatch works for theme list" + +"$CLI" theme current >/dev/null +pass "safe dispatch works for theme current" + +"$CLI" font list >/dev/null +pass "safe dispatch works for font list" + +"$CLI" font current >/dev/null +pass "safe dispatch works for font current" + +for binary in \ + omarchy-update \ + omarchy-theme-set \ + omarchy-capture-screenshot \ + omarchy-system-reboot \ + omarchy-pkg-add; do + [[ -x $ROOT/bin/$binary ]] || fail "binary is executable: $binary" + pass "binary is executable: $binary" +done + +while IFS= read -r binary_path; do + header=$(awk ' + NR == 1 && /^#!/ { next } + /^[[:space:]]*$/ { if (seen) print; next } + /^[[:space:]]*#/ { seen=1; print; next } + { exit } + ' "$binary_path") + + grep -q '^# omarchy:summary=' <<<"$header" || fail "metadata summary is present: $binary_path" + ! grep -q '^# omarchy:binary=' <<<"$header" || fail "metadata does not repeat inferred binary: $binary_path" + ! grep -q '^# omarchy:args=$' <<<"$header" || fail "metadata does not include empty args: $binary_path" + ! grep -Eq '^# omarchy:(legacy|usage|visibility|mutates|interactive)=' <<<"$header" || fail "metadata avoids removed fields: $binary_path" + ! grep -Eq '^# omarchy:requires-sudo=false$' <<<"$header" || fail "metadata omits false booleans: $binary_path" +done < <(find "$ROOT/bin" -maxdepth 1 -type f -executable -name 'omarchy-*' | sort) +pass "all executable bins have slim self-documenting metadata" + +TMPDIR=$(mktemp -d) +ln -s "$CLI" "$TMPDIR/omarchy" + +{ + printf '#!/bin/bash\n\n' + printf '# ordinary comments are fine\n' + printf '# omarchy:this malformed line should be ignored\n' + printf '# omarchy:group=weird\n' + printf '# omarchy:name=test\n' + printf '# omarchy:summary=Survives malformed metadata comments\n' + printf '# omarchy:made-up=value\n' + printf 'echo weird-ok\n' +} >"$TMPDIR/omarchy-weird-test" +chmod +x "$TMPDIR/omarchy-weird-test" + +{ + printf '#!/bin/bash\n\n' + printf '# a partial metadata header should not destroy fallback routing\n' + printf '# omarchy:summary=Partial metadata keeps inferred route\n' + printf '# omarchy:made-up=value\n' + printf 'echo partial-ok\n' +} >"$TMPDIR/omarchy-partial-meta-test" +chmod +x "$TMPDIR/omarchy-partial-meta-test" + +{ + printf '#!/bin/bash\n\n' + printf 'echo body-metadata-ok\n' + printf '# omarchy:group=wrong\n' + printf '# omarchy:name=wrong\n' +} >"$TMPDIR/omarchy-body-metadata-test" +chmod +x "$TMPDIR/omarchy-body-metadata-test" + +"$TMPDIR/omarchy" commands --all --json | jq -e '.commands[] | select(.route == "omarchy weird test" and .summary == "Survives malformed metadata comments")' >/dev/null +pass "unknown metadata values are non-fatal" + +"$TMPDIR/omarchy" commands --all --json | jq -e '.commands[] | select(.route == "omarchy partial meta test" and .summary == "Partial metadata keeps inferred route")' >/dev/null +pass "partial metadata keeps inferred fallback route" + +"$TMPDIR/omarchy" commands --all --json | jq -e '.commands[] | select(.route == "omarchy body metadata test" and .summary == "Run the body metadata test command")' >/dev/null +pass "metadata-looking comments after script body are ignored" + +output=$("$TMPDIR/omarchy" weird test) +assert_output_contains "temporary metadata command dispatches" "$output" "weird-ok" + +output=$("$TMPDIR/omarchy" partial meta test) +assert_output_contains "partial metadata command dispatches" "$output" "partial-ok" + +output=$("$TMPDIR/omarchy" body metadata test) +assert_output_contains "body metadata command dispatches by filename" "$output" "body-metadata-ok" diff --git a/themes/catppuccin-latte/backgrounds/omarchy.png b/themes/catppuccin-latte/backgrounds/omarchy.png new file mode 100644 index 00000000..8dd666ab Binary files /dev/null and b/themes/catppuccin-latte/backgrounds/omarchy.png differ diff --git a/themes/catppuccin-latte/preview-unlock.png b/themes/catppuccin-latte/preview-unlock.png new file mode 100644 index 00000000..a10534cc Binary files /dev/null and b/themes/catppuccin-latte/preview-unlock.png differ diff --git a/themes/catppuccin-latte/unlock.png b/themes/catppuccin-latte/unlock.png new file mode 100644 index 00000000..b209e93b Binary files /dev/null and b/themes/catppuccin-latte/unlock.png differ diff --git a/themes/catppuccin/backgrounds/omarchy.png b/themes/catppuccin/backgrounds/omarchy.png new file mode 100644 index 00000000..a4e90d76 Binary files /dev/null and b/themes/catppuccin/backgrounds/omarchy.png differ diff --git a/themes/catppuccin/preview-unlock.png b/themes/catppuccin/preview-unlock.png new file mode 100644 index 00000000..69974204 Binary files /dev/null and b/themes/catppuccin/preview-unlock.png differ diff --git a/themes/catppuccin/unlock.png b/themes/catppuccin/unlock.png new file mode 100644 index 00000000..14168e17 Binary files /dev/null and b/themes/catppuccin/unlock.png differ diff --git a/themes/ethereal/backgrounds/omarchy.png b/themes/ethereal/backgrounds/omarchy.png new file mode 100644 index 00000000..4354650f Binary files /dev/null and b/themes/ethereal/backgrounds/omarchy.png differ diff --git a/themes/ethereal/colors.toml b/themes/ethereal/colors.toml index 75cedec8..dbce1ae4 100644 --- a/themes/ethereal/colors.toml +++ b/themes/ethereal/colors.toml @@ -5,7 +5,7 @@ background = "#060B1E" selection_foreground = "#060B1E" selection_background = "#ffcead" -color0 = "#060B1E" +color0 = "#3C486D" color1 = "#ED5B5A" color2 = "#92a593" color3 = "#E9BB4F" diff --git a/themes/ethereal/preview-unlock.png b/themes/ethereal/preview-unlock.png new file mode 100644 index 00000000..7061587c Binary files /dev/null and b/themes/ethereal/preview-unlock.png differ diff --git a/themes/ethereal/unlock.png b/themes/ethereal/unlock.png new file mode 100644 index 00000000..136b6d59 Binary files /dev/null and b/themes/ethereal/unlock.png differ diff --git a/themes/everforest/backgrounds/omarchy.png b/themes/everforest/backgrounds/omarchy.png new file mode 100644 index 00000000..d759dde4 Binary files /dev/null and b/themes/everforest/backgrounds/omarchy.png differ diff --git a/themes/everforest/preview-unlock.png b/themes/everforest/preview-unlock.png new file mode 100644 index 00000000..be099bc1 Binary files /dev/null and b/themes/everforest/preview-unlock.png differ diff --git a/themes/everforest/unlock.png b/themes/everforest/unlock.png new file mode 100644 index 00000000..40e2cd80 Binary files /dev/null and b/themes/everforest/unlock.png differ diff --git a/themes/everforest/vscode.json b/themes/everforest/vscode.json index 02b107d0..c584417a 100644 --- a/themes/everforest/vscode.json +++ b/themes/everforest/vscode.json @@ -1,4 +1,4 @@ { "name": "Everforest Dark", - "extension": "sainnhe.everforest" + "extension": "reesew.everforest-theme" } diff --git a/themes/flexoki-light/colors.toml b/themes/flexoki-light/colors.toml index 44af88c4..1e3b8860 100644 --- a/themes/flexoki-light/colors.toml +++ b/themes/flexoki-light/colors.toml @@ -5,14 +5,14 @@ background = "#FFFCF0" selection_foreground = "#100F0F" selection_background = "#CECDC3" -color0 = "#100F0F" +color0 = "#DAD8CE" color1 = "#D14D41" color2 = "#879A39" color3 = "#D0A215" color4 = "#205EA6" color5 = "#CE5D97" color6 = "#3AA99F" -color7 = "#FFFCF0" +color7 = "#B7B5AC" color8 = "#100F0F" color9 = "#D14D41" color10 = "#879A39" @@ -20,4 +20,4 @@ color11 = "#D0A215" color12 = "#4385BE" color13 = "#CE5D97" color14 = "#3AA99F" -color15 = "#FFFCF0" +color15 = "#CECDC3" diff --git a/themes/flexoki-light/preview-unlock.png b/themes/flexoki-light/preview-unlock.png new file mode 100644 index 00000000..024241b2 Binary files /dev/null and b/themes/flexoki-light/preview-unlock.png differ diff --git a/themes/flexoki-light/unlock.png b/themes/flexoki-light/unlock.png new file mode 100644 index 00000000..f160bb55 Binary files /dev/null and b/themes/flexoki-light/unlock.png differ diff --git a/themes/gruvbox/backgrounds/omarchy.png b/themes/gruvbox/backgrounds/omarchy.png new file mode 100644 index 00000000..a6feebe6 Binary files /dev/null and b/themes/gruvbox/backgrounds/omarchy.png differ diff --git a/themes/gruvbox/preview-unlock.png b/themes/gruvbox/preview-unlock.png new file mode 100644 index 00000000..9b09d6cd Binary files /dev/null and b/themes/gruvbox/preview-unlock.png differ diff --git a/themes/gruvbox/unlock.png b/themes/gruvbox/unlock.png new file mode 100644 index 00000000..777a7fb8 Binary files /dev/null and b/themes/gruvbox/unlock.png differ diff --git a/themes/hackerman/backgrounds/omarchy.png b/themes/hackerman/backgrounds/omarchy.png new file mode 100644 index 00000000..eb91c8b0 Binary files /dev/null and b/themes/hackerman/backgrounds/omarchy.png differ diff --git a/themes/hackerman/colors.toml b/themes/hackerman/colors.toml index 56aec2a9..517ff366 100644 --- a/themes/hackerman/colors.toml +++ b/themes/hackerman/colors.toml @@ -5,7 +5,7 @@ background = "#0B0C16" selection_foreground = "#0B0C16" selection_background = "#ddf7ff" -color0 = "#0B0C16" +color0 = "#3E4058" color1 = "#50f872" color2 = "#4fe88f" color3 = "#50f7d4" diff --git a/themes/hackerman/preview-unlock.png b/themes/hackerman/preview-unlock.png new file mode 100644 index 00000000..7d42ff6e Binary files /dev/null and b/themes/hackerman/preview-unlock.png differ diff --git a/themes/hackerman/unlock.png b/themes/hackerman/unlock.png new file mode 100644 index 00000000..80793337 Binary files /dev/null and b/themes/hackerman/unlock.png differ diff --git a/themes/kanagawa/backgrounds/omarchy.png b/themes/kanagawa/backgrounds/omarchy.png new file mode 100644 index 00000000..c4560ce3 Binary files /dev/null and b/themes/kanagawa/backgrounds/omarchy.png differ diff --git a/themes/kanagawa/preview-unlock.png b/themes/kanagawa/preview-unlock.png new file mode 100644 index 00000000..cef402b7 Binary files /dev/null and b/themes/kanagawa/preview-unlock.png differ diff --git a/themes/kanagawa/unlock.png b/themes/kanagawa/unlock.png new file mode 100644 index 00000000..a83180f7 Binary files /dev/null and b/themes/kanagawa/unlock.png differ diff --git a/themes/lumon/backgrounds/omarchy.png b/themes/lumon/backgrounds/omarchy.png new file mode 100644 index 00000000..8c194e6e Binary files /dev/null and b/themes/lumon/backgrounds/omarchy.png differ diff --git a/themes/lumon/preview-unlock.png b/themes/lumon/preview-unlock.png new file mode 100644 index 00000000..a2f9e581 Binary files /dev/null and b/themes/lumon/preview-unlock.png differ diff --git a/themes/lumon/unlock.png b/themes/lumon/unlock.png new file mode 100644 index 00000000..18c566bb Binary files /dev/null and b/themes/lumon/unlock.png differ diff --git a/themes/matte-black/backgrounds/omarchy.png b/themes/matte-black/backgrounds/omarchy.png new file mode 100644 index 00000000..b34300c1 Binary files /dev/null and b/themes/matte-black/backgrounds/omarchy.png differ diff --git a/themes/matte-black/preview-unlock.png b/themes/matte-black/preview-unlock.png new file mode 100644 index 00000000..e23b4665 Binary files /dev/null and b/themes/matte-black/preview-unlock.png differ diff --git a/themes/matte-black/unlock.png b/themes/matte-black/unlock.png new file mode 100644 index 00000000..1a60e709 Binary files /dev/null and b/themes/matte-black/unlock.png differ diff --git a/themes/miasma/backgrounds/omarchy.png b/themes/miasma/backgrounds/omarchy.png new file mode 100644 index 00000000..08d8b9a5 Binary files /dev/null and b/themes/miasma/backgrounds/omarchy.png differ diff --git a/themes/miasma/preview-unlock.png b/themes/miasma/preview-unlock.png new file mode 100644 index 00000000..d3d0254e Binary files /dev/null and b/themes/miasma/preview-unlock.png differ diff --git a/themes/miasma/unlock.png b/themes/miasma/unlock.png new file mode 100644 index 00000000..5d07e9be Binary files /dev/null and b/themes/miasma/unlock.png differ diff --git a/themes/nord/backgrounds/omarchy.png b/themes/nord/backgrounds/omarchy.png new file mode 100644 index 00000000..f8b19601 Binary files /dev/null and b/themes/nord/backgrounds/omarchy.png differ diff --git a/themes/nord/preview-unlock.png b/themes/nord/preview-unlock.png new file mode 100644 index 00000000..d002326f Binary files /dev/null and b/themes/nord/preview-unlock.png differ diff --git a/themes/nord/unlock.png b/themes/nord/unlock.png new file mode 100644 index 00000000..e6b204be Binary files /dev/null and b/themes/nord/unlock.png differ diff --git a/themes/osaka-jade/backgrounds/omarchy.png b/themes/osaka-jade/backgrounds/omarchy.png new file mode 100644 index 00000000..8f691c61 Binary files /dev/null and b/themes/osaka-jade/backgrounds/omarchy.png differ diff --git a/themes/osaka-jade/preview-unlock.png b/themes/osaka-jade/preview-unlock.png new file mode 100644 index 00000000..8db51932 Binary files /dev/null and b/themes/osaka-jade/preview-unlock.png differ diff --git a/themes/osaka-jade/unlock.png b/themes/osaka-jade/unlock.png new file mode 100644 index 00000000..ca4ac8c4 Binary files /dev/null and b/themes/osaka-jade/unlock.png differ diff --git a/themes/retro-82/backgrounds/omarchy.png b/themes/retro-82/backgrounds/omarchy.png new file mode 100644 index 00000000..477cad10 Binary files /dev/null and b/themes/retro-82/backgrounds/omarchy.png differ diff --git a/themes/retro-82/preview-unlock.png b/themes/retro-82/preview-unlock.png new file mode 100644 index 00000000..1df397a2 Binary files /dev/null and b/themes/retro-82/preview-unlock.png differ diff --git a/themes/retro-82/unlock.png b/themes/retro-82/unlock.png new file mode 100644 index 00000000..b7216ca1 Binary files /dev/null and b/themes/retro-82/unlock.png differ diff --git a/themes/ristretto/backgrounds/0-launch.png b/themes/ristretto/backgrounds/0-launch.png new file mode 100644 index 00000000..3c191940 Binary files /dev/null and b/themes/ristretto/backgrounds/0-launch.png differ diff --git a/themes/ristretto/backgrounds/omarchy.png b/themes/ristretto/backgrounds/omarchy.png new file mode 100644 index 00000000..f1182f69 Binary files /dev/null and b/themes/ristretto/backgrounds/omarchy.png differ diff --git a/themes/ristretto/preview-unlock.png b/themes/ristretto/preview-unlock.png new file mode 100644 index 00000000..ec51c946 Binary files /dev/null and b/themes/ristretto/preview-unlock.png differ diff --git a/themes/ristretto/unlock.png b/themes/ristretto/unlock.png new file mode 100644 index 00000000..f865bc5a Binary files /dev/null and b/themes/ristretto/unlock.png differ diff --git a/themes/rose-pine/backgrounds/omarchy.png b/themes/rose-pine/backgrounds/omarchy.png new file mode 100644 index 00000000..14f6e8a3 Binary files /dev/null and b/themes/rose-pine/backgrounds/omarchy.png differ diff --git a/themes/rose-pine/preview-unlock.png b/themes/rose-pine/preview-unlock.png new file mode 100644 index 00000000..d087e423 Binary files /dev/null and b/themes/rose-pine/preview-unlock.png differ diff --git a/themes/rose-pine/unlock.png b/themes/rose-pine/unlock.png new file mode 100644 index 00000000..892ea41e Binary files /dev/null and b/themes/rose-pine/unlock.png differ diff --git a/themes/tokyo-night/backgrounds/4-oma-cityscape.jpg b/themes/tokyo-night/backgrounds/4-oma-cityscape.jpg new file mode 100644 index 00000000..f57916bb Binary files /dev/null and b/themes/tokyo-night/backgrounds/4-oma-cityscape.jpg differ diff --git a/themes/tokyo-night/backgrounds/5-oma.jpg b/themes/tokyo-night/backgrounds/5-oma.jpg new file mode 100644 index 00000000..3b85cd0d Binary files /dev/null and b/themes/tokyo-night/backgrounds/5-oma.jpg differ diff --git a/themes/tokyo-night/backgrounds/omarchy.png b/themes/tokyo-night/backgrounds/omarchy.png new file mode 100644 index 00000000..0f520903 Binary files /dev/null and b/themes/tokyo-night/backgrounds/omarchy.png differ diff --git a/themes/tokyo-night/preview-unlock.png b/themes/tokyo-night/preview-unlock.png new file mode 100644 index 00000000..bb4897a7 Binary files /dev/null and b/themes/tokyo-night/preview-unlock.png differ diff --git a/themes/tokyo-night/unlock.png b/themes/tokyo-night/unlock.png new file mode 100644 index 00000000..f5544419 Binary files /dev/null and b/themes/tokyo-night/unlock.png differ diff --git a/themes/vantablack/backgrounds/omarchy.png b/themes/vantablack/backgrounds/omarchy.png new file mode 100644 index 00000000..4bf3789d Binary files /dev/null and b/themes/vantablack/backgrounds/omarchy.png differ diff --git a/themes/vantablack/colors.toml b/themes/vantablack/colors.toml index e3b2267d..45b8213e 100644 --- a/themes/vantablack/colors.toml +++ b/themes/vantablack/colors.toml @@ -11,7 +11,7 @@ selection_foreground = "#000000" selection_background = "#ffffff" # Normal colors (ANSI 0-7) -color0 = "#000000" +color0 = "#404040" color1 = "#a4a4a4" color2 = "#b6b6b6" color3 = "#cecece" @@ -21,7 +21,7 @@ color6 = "#b0b0b0" color7 = "#ececec" # Bright colors (ANSI 8-15) -color8 = "#fdfdfd" +color8 = "#5c5c5c" color9 = "#a4a4a4" color10 = "#b6b6b6" color11 = "#cecece" diff --git a/themes/vantablack/preview-unlock.png b/themes/vantablack/preview-unlock.png new file mode 100644 index 00000000..b2cd593c Binary files /dev/null and b/themes/vantablack/preview-unlock.png differ diff --git a/themes/vantablack/unlock.png b/themes/vantablack/unlock.png new file mode 100644 index 00000000..87d2cecb Binary files /dev/null and b/themes/vantablack/unlock.png differ diff --git a/themes/white/backgrounds/omarchy.png b/themes/white/backgrounds/omarchy.png new file mode 100644 index 00000000..9b5cd0c0 Binary files /dev/null and b/themes/white/backgrounds/omarchy.png differ diff --git a/themes/white/colors.toml b/themes/white/colors.toml index de6cce97..e6e072ea 100644 --- a/themes/white/colors.toml +++ b/themes/white/colors.toml @@ -11,7 +11,7 @@ selection_foreground = "#ffffff" selection_background = "#1a1a1a" # Normal colors (ANSI 0-7) -color0 = "#ffffff" +color0 = "#c0c0c0" color1 = "#2a2a2a" color2 = "#3a3a3a" color3 = "#4a4a4a" diff --git a/themes/white/preview-unlock.png b/themes/white/preview-unlock.png new file mode 100644 index 00000000..71bce653 Binary files /dev/null and b/themes/white/preview-unlock.png differ diff --git a/themes/white/unlock.png b/themes/white/unlock.png new file mode 100644 index 00000000..87d2cecb Binary files /dev/null and b/themes/white/unlock.png differ diff --git a/version b/version index 40c341bd..7c69a55d 100644 --- a/version +++ b/version @@ -1 +1 @@ -3.6.0 +3.7.0