diff --git a/default/foot/foot.desktop b/applications/foot.desktop similarity index 100% rename from default/foot/foot.desktop rename to applications/foot.desktop diff --git a/bin/omarchy-battery-status b/bin/omarchy-battery-status index 0390df1f..88c336b2 100755 --- a/bin/omarchy-battery-status +++ b/bin/omarchy-battery-status @@ -21,7 +21,7 @@ time_remaining=$(omarchy-battery-remaining-time) capacity=$(omarchy-battery-capacity) if [[ $state == "charging" ]]; then - echo "󰁹 Battery ${percentage}% · ${time_remaining} to full ·  ${power_rate}W / ${capacity}Wh" + echo "Battery ${percentage}% · ${time_remaining} to full ·  ${power_rate}W / ${capacity}Wh" else - echo "󰁹 Battery ${percentage}% · ${time_remaining} left ·  ${power_rate}W / ${capacity}Wh" + echo "Battery ${percentage}% · ${time_remaining} left ·  ${power_rate}W / ${capacity}Wh" fi diff --git a/bin/omarchy-hibernation-remove b/bin/omarchy-hibernation-remove index 49bad5bd..f06396b5 100755 --- a/bin/omarchy-hibernation-remove +++ b/bin/omarchy-hibernation-remove @@ -44,11 +44,6 @@ if grep -Fq "$SWAP_FILE" /etc/fstab; then sudo sed -i '/^# Btrfs swapfile for system hibernation$/d' /etc/fstab fi -# Remove suspend-then-hibernate configuration -echo "Removing suspend-then-hibernate configuration" -sudo rm -f /etc/systemd/logind.conf.d/lid.conf -sudo rm -f /etc/systemd/sleep.conf.d/hibernate.conf - # Remove mkinitcpio resume hook echo "Removing resume hook" sudo rm "$MKINITCPIO_CONF" diff --git a/bin/omarchy-install-service-sunshine b/bin/omarchy-install-service-sunshine new file mode 100755 index 00000000..9aef4f31 --- /dev/null +++ b/bin/omarchy-install-service-sunshine @@ -0,0 +1,92 @@ +#!/bin/bash + +# omarchy:summary=Install Sunshine and open Moonlight streaming ports for LAN and Tailscale. +# omarchy:requires-sudo=true + +set -e + +TCP_PORTS=(47984 47989 48010) +UDP_PORTS=(5353 47998 47999 48000 48002 48010) +PRIVATE_CIDRS=(10.0.0.0/8 172.16.0.0/12 192.168.0.0/16) +UFW_COMMENT="omarchy-sunshine" +SUNSHINE_ADMIN_APP="Sunshine Admin" +SUNSHINE_ADMIN_URL="https://localhost:47990" +SUNSHINE_ADMIN_EXEC="omarchy-launch-webapp $SUNSHINE_ADMIN_URL --ignore-certificate-errors" +SUNSHINE_ICON_SOURCE="/usr/share/sunshine/web/images/logo-sunshine-45.png" +SUNSHINE_ICON_NAME="Sunshine Admin.png" +WEBAPP_ICON_DIR="$HOME/.local/share/applications/icons" +HYPR_AUTOSTART_FILE="$HOME/.config/hypr/autostart.lua" +HYPR_AUTOSTART_ENTRY='o.launch_on_start("sunshine")' + +open_ufw_port_for_private_lans() { + local proto="$1" + local port="$2" + local cidr + + for cidr in "${PRIVATE_CIDRS[@]}"; do + sudo ufw allow in proto "$proto" from "$cidr" to any port "$port" comment "$UFW_COMMENT" + done +} + +open_ufw_port_for_tailscale() { + local proto="$1" + local port="$2" + + if ip link show tailscale0 >/dev/null 2>&1; then + sudo ufw allow in on tailscale0 to any port "$port" proto "$proto" comment "$UFW_COMMENT" + fi +} + +open_ufw_ports() { + local port + + if omarchy-cmd-missing ufw; then + echo "UFW is not installed; skipping Sunshine firewall rules." + return + fi + + for port in "${TCP_PORTS[@]}"; do + open_ufw_port_for_private_lans tcp "$port" + open_ufw_port_for_tailscale tcp "$port" + done + + for port in "${UDP_PORTS[@]}"; do + open_ufw_port_for_private_lans udp "$port" + open_ufw_port_for_tailscale udp "$port" + done + + sudo ufw reload +} + +install_admin_webapp() { + mkdir -p "$WEBAPP_ICON_DIR" + cp "$SUNSHINE_ICON_SOURCE" "$WEBAPP_ICON_DIR/$SUNSHINE_ICON_NAME" + omarchy-webapp-install "$SUNSHINE_ADMIN_APP" "$SUNSHINE_ADMIN_URL" "$SUNSHINE_ICON_NAME" "$SUNSHINE_ADMIN_EXEC" + omarchy-restart-walker +} + +enable_hyprland_autostart() { + mkdir -p "$(dirname "$HYPR_AUTOSTART_FILE")" + touch "$HYPR_AUTOSTART_FILE" + + if ! grep -Fxq "$HYPR_AUTOSTART_ENTRY" "$HYPR_AUTOSTART_FILE"; then + printf '\n%s\n' "$HYPR_AUTOSTART_ENTRY" >>"$HYPR_AUTOSTART_FILE" + fi +} + +echo "Installing Sunshine..." +omarchy-pkg-add sunshine +systemctl --user enable --now sunshine + +echo "Opening Sunshine firewall ports..." +open_ufw_ports + +echo "Installing Sunshine admin web app..." +install_admin_webapp +$SUNSHINE_ADMIN_EXEC >/dev/null 2>&1 & + +echo "Enabling Sunshine autostart..." +enable_hyprland_autostart + +echo "" +echo "Sunshine has been installed and its Moonlight streaming ports are open for private LANs and Tailscale." diff --git a/bin/omarchy-install-terminal b/bin/omarchy-install-terminal index 2fb040dd..a32a7a33 100755 --- a/bin/omarchy-install-terminal +++ b/bin/omarchy-install-terminal @@ -30,10 +30,10 @@ if omarchy-pkg-add $package; then # Copy custom desktop entries with X-TerminalArg* keys if [[ $package == "alacritty" ]]; then mkdir -p ~/.local/share/applications - cp "$OMARCHY_PATH/applications/$desktop_id" ~/.local/share/applications/ + cp "$OMARCHY_PATH/default/alacritty/$desktop_id" ~/.local/share/applications/ elif [[ $package == "foot" ]]; then mkdir -p ~/.local/share/applications - cp "$OMARCHY_PATH/default/foot/$desktop_id" ~/.local/share/applications/ + cp "$OMARCHY_PATH/applications/$desktop_id" ~/.local/share/applications/ fi # Copy default config for optional terminals when missing diff --git a/bin/omarchy-launch-browser b/bin/omarchy-launch-browser index fefc935e..f1076e79 100755 --- a/bin/omarchy-launch-browser +++ b/bin/omarchy-launch-browser @@ -6,7 +6,7 @@ default_browser=$(xdg-settings get default-web-browser) browser_exec=$(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$default_browser 2>/dev/null | head -1) -if $browser_exec --help | grep -q MOZ_LOG; then +if $browser_exec --help 2>/dev/null | grep -q MOZ_LOG; then private_flag="--private-window" elif [[ $browser_exec =~ edge ]]; then private_flag="--inprivate" @@ -14,4 +14,6 @@ else private_flag="--incognito" fi -exec setsid uwsm-app -- "$browser_exec" "${@/--private/$private_flag}" +systemd-run --user --quiet --collect --unit="omarchy-browser-$(date +%s%N)" \ + --property=StandardOutput=null --property=StandardError=null \ + uwsm-app -- "$browser_exec" "${@/--private/$private_flag}" diff --git a/bin/omarchy-launch-nautilus b/bin/omarchy-launch-nautilus new file mode 100755 index 00000000..0b10b7b2 --- /dev/null +++ b/bin/omarchy-launch-nautilus @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Launch Files + +exec setsid uwsm-app -- nautilus --new-window diff --git a/bin/omarchy-launch-nautilus-cwd b/bin/omarchy-launch-nautilus-cwd new file mode 100755 index 00000000..ae9a0d88 --- /dev/null +++ b/bin/omarchy-launch-nautilus-cwd @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Launch Files in the active terminal's current directory + +exec setsid uwsm-app -- nautilus --new-window "$(omarchy-cmd-terminal-cwd)" diff --git a/bin/omarchy-launch-terminal b/bin/omarchy-launch-terminal new file mode 100755 index 00000000..a07a1dde --- /dev/null +++ b/bin/omarchy-launch-terminal @@ -0,0 +1,6 @@ +#!/bin/bash + +# omarchy:summary=Launch a terminal in the active terminal's current directory +# omarchy:args=[command...] + +exec setsid uwsm-app -- xdg-terminal-exec --dir="$(omarchy-cmd-terminal-cwd)" "$@" diff --git a/bin/omarchy-launch-terminal-tmux b/bin/omarchy-launch-terminal-tmux new file mode 100755 index 00000000..2b70179c --- /dev/null +++ b/bin/omarchy-launch-terminal-tmux @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Launch or attach to the Work tmux session in a terminal + +exec omarchy-launch-terminal bash -c "tmux attach || tmux new -s Work" diff --git a/bin/omarchy-menu-keybindings b/bin/omarchy-menu-keybindings index ddaa6106..78435e76 100755 --- a/bin/omarchy-menu-keybindings +++ b/bin/omarchy-menu-keybindings @@ -187,7 +187,7 @@ hl = setmetatable({ end, }) -local config = (os.getenv("HOME") or "") .. "/.config/hypr/hyprland.lua" +local config = os.getenv("HOME") .. "/.config/hypr/hyprland.lua" local file = io.open(config, "r") if file then diff --git a/bin/omarchy-notification-battery b/bin/omarchy-notification-battery new file mode 100755 index 00000000..3b0dcad7 --- /dev/null +++ b/bin/omarchy-notification-battery @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Show the current battery status notification + +omarchy-notification-send -g 󰁹 -u low "$(omarchy-battery-status)" diff --git a/bin/omarchy-notification-time b/bin/omarchy-notification-time new file mode 100755 index 00000000..6963f373 --- /dev/null +++ b/bin/omarchy-notification-time @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Show the current time and date notification + +omarchy-notification-send -g  -u low "$(date +"%A %H:%M · %d %B %Y · Week %V")" diff --git a/bin/omarchy-notification-weather b/bin/omarchy-notification-weather new file mode 100755 index 00000000..5b4d17bd --- /dev/null +++ b/bin/omarchy-notification-weather @@ -0,0 +1,5 @@ +#!/bin/bash + +# omarchy:summary=Show the current weather notification + +omarchy-notification-send -g $(omarchy-weather-icon) -u low "$(omarchy-weather-status)" diff --git a/bin/omarchy-refresh-applications b/bin/omarchy-refresh-applications index a4315f8f..6cc0e473 100755 --- a/bin/omarchy-refresh-applications +++ b/bin/omarchy-refresh-applications @@ -11,8 +11,8 @@ mkdir -p ~/.local/share/applications cp ~/.local/share/omarchy/applications/*.desktop ~/.local/share/applications/ cp ~/.local/share/omarchy/applications/hidden/*.desktop ~/.local/share/applications/ -if omarchy-cmd-present foot; then - cp ~/.local/share/omarchy/default/foot/foot.desktop ~/.local/share/applications/ +if omarchy-cmd-present alacritty; then + cp ~/.local/share/omarchy/default/alacritty/alacritty.desktop ~/.local/share/applications/ fi # Refresh the webapps, TUIs, and npx wrappers diff --git a/bin/omarchy-refresh-hyprland b/bin/omarchy-refresh-hyprland index 1ebd1ab3..999efa6b 100755 --- a/bin/omarchy-refresh-hyprland +++ b/bin/omarchy-refresh-hyprland @@ -9,4 +9,5 @@ omarchy-refresh-config hypr/input.lua omarchy-refresh-config hypr/looknfeel.lua omarchy-refresh-config hypr/hyprland.lua omarchy-refresh-config hypr/monitors.lua +bash "$OMARCHY_PATH/install/config/omarchy-toggles.sh" bash "$OMARCHY_PATH/install/config/detect-keyboard-layout.sh" diff --git a/bin/omarchy-reinstall-git b/bin/omarchy-reinstall-git index 308d67c8..c62797c1 100755 --- a/bin/omarchy-reinstall-git +++ b/bin/omarchy-reinstall-git @@ -6,6 +6,6 @@ set -e # Reinstall the Omarchy configuration directory from the git source. -git clone "https://github.com/basecamp/omarchy.git" ~/.local/share/omarchy-new >/dev/null +git clone --depth=1 --branch master "https://github.com/basecamp/omarchy.git" ~/.local/share/omarchy-new >/dev/null mv $OMARCHY_PATH ~/.local/share/omarchy-old mv ~/.local/share/omarchy-new $OMARCHY_PATH diff --git a/bin/omarchy-remove-service-sunshine b/bin/omarchy-remove-service-sunshine new file mode 100755 index 00000000..83457978 --- /dev/null +++ b/bin/omarchy-remove-service-sunshine @@ -0,0 +1,69 @@ +#!/bin/bash + +# omarchy:summary=Remove Sunshine and close Omarchy-managed Moonlight streaming ports. +# omarchy:requires-sudo=true + +set -e + +TCP_PORTS=(47984 47989 48010) +UDP_PORTS=(5353 47998 47999 48000 48002 48010) +PRIVATE_CIDRS=(10.0.0.0/8 172.16.0.0/12 192.168.0.0/16) +SUNSHINE_ADMIN_APP="Sunshine Admin" +HYPR_AUTOSTART_FILE="$HOME/.config/hypr/autostart.lua" +HYPR_AUTOSTART_ENTRY='o.launch_on_start("sunshine")' + +delete_ufw_rule() { + sudo ufw --force delete "$@" 2>/dev/null || true +} + +close_ufw_port_for_private_lans() { + local proto="$1" + local port="$2" + local cidr + + for cidr in "${PRIVATE_CIDRS[@]}"; do + delete_ufw_rule allow in proto "$proto" from "$cidr" to any port "$port" + done +} + +close_ufw_port_for_tailscale() { + local proto="$1" + local port="$2" + + delete_ufw_rule allow in on tailscale0 to any port "$port" proto "$proto" +} + +close_ufw_ports() { + local port + + if omarchy-cmd-missing ufw; then + return + fi + + for port in "${TCP_PORTS[@]}"; do + close_ufw_port_for_private_lans tcp "$port" + close_ufw_port_for_tailscale tcp "$port" + done + + for port in "${UDP_PORTS[@]}"; do + close_ufw_port_for_private_lans udp "$port" + close_ufw_port_for_tailscale udp "$port" + done + + sudo ufw reload +} + +disable_hyprland_autostart() { + if [[ -f $HYPR_AUTOSTART_FILE ]]; then + sed -i "\|^$HYPR_AUTOSTART_ENTRY$|d" "$HYPR_AUTOSTART_FILE" + fi +} + +systemctl --user disable --now sunshine 2>/dev/null || true +omarchy-pkg-drop sunshine +omarchy-webapp-remove "$SUNSHINE_ADMIN_APP" 2>/dev/null || true +disable_hyprland_autostart +close_ufw_ports + +echo "" +echo "Sunshine has been removed and its Omarchy-managed Moonlight streaming ports have been closed." diff --git a/bin/omarchy-swayosd-brightness b/bin/omarchy-swayosd-brightness index 8a1e852d..3a533085 100755 --- a/bin/omarchy-swayosd-brightness +++ b/bin/omarchy-swayosd-brightness @@ -12,4 +12,4 @@ progress="$(awk -v p="$percent" 'BEGIN{printf "%.2f", p/100}')" omarchy-swayosd-client \ --custom-icon display-brightness-symbolic \ --custom-progress "$progress" \ - --custom-progress-text "${percent}%" + --custom-progress-text "$(printf '%3d%%' "$percent")" diff --git a/bin/omarchy-update-git b/bin/omarchy-update-git index c3e63008..420ee379 100755 --- a/bin/omarchy-update-git +++ b/bin/omarchy-update-git @@ -9,7 +9,8 @@ echo -e "\e[32mUpdate Omarchy\e[0m" omarchy-update-time # Suppress Hyprland config errors while git updates default config files mid-pull -hyprctl eval 'hl.config({ debug = { suppress_errors = true } })' &>/dev/null || hyprctl keyword debug:suppress_errors true &>/dev/null || true +hyprctl keyword debug:suppress_errors true &>/dev/null || true +hyprctl eval 'hl.config({ debug = { suppress_errors = true } })' &>/dev/null || true git -C $OMARCHY_PATH pull --autostash git -C $OMARCHY_PATH --no-pager diff --check || git -C $OMARCHY_PATH reset --merge diff --git a/bin/omarchy-update-restart b/bin/omarchy-update-restart index 2712cd39..763d6b65 100755 --- a/bin/omarchy-update-restart +++ b/bin/omarchy-update-restart @@ -4,6 +4,10 @@ echo +confirm_reboot() { + gum confirm "$1" && { omarchy-system-reboot; exit 0; } +} + running_kernel=$(uname -r) kernel_updated=true @@ -19,14 +23,14 @@ for kernel in /usr/lib/modules/*/vmlinuz; do done if [[ $kernel_updated == "true" ]]; then - gum confirm "Linux kernel has been updated. Reboot?" && omarchy-system-reboot + confirm_reboot "Linux kernel has been updated. Reboot?" elif [[ -f $HOME/.local/state/omarchy/reboot-required ]]; then - gum confirm "Updates require reboot. Ready?" && omarchy-system-reboot + confirm_reboot "Updates require reboot. Ready?" fi running_hyprland=$(readlink /proc/$(pgrep -x Hyprland)/exe 2>/dev/null) if [[ $running_hyprland == *"(deleted)"* ]]; then - gum confirm "Hyprland has been updated. Reboot?" && omarchy-system-reboot + confirm_reboot "Hyprland has been updated. Reboot?" fi for file in "$HOME"/.local/state/omarchy/restart-*-required; do diff --git a/bin/omarchy-voxtype-remove b/bin/omarchy-voxtype-remove index 4253f73d..3ca45703 100755 --- a/bin/omarchy-voxtype-remove +++ b/bin/omarchy-voxtype-remove @@ -11,12 +11,11 @@ if omarchy-cmd-present voxtype; then echo "Uninstall Voxtype to remove dictation." # Remove services - systemctl --user stop voxtype.service 2>/dev/null || true - rm -f ~/.config/systemd/user/voxtype* + systemctl --user disable --now voxtype.service 2>/dev/null || true systemctl --user daemon-reload # Remove packages and configs - omarchy-pkg-drop wtype voxtype-bin + omarchy-pkg-drop voxtype-bin rm -rf ~/.config/voxtype rm -rf ~/.local/share/voxtype else diff --git a/bin/omarchy-weather-status b/bin/omarchy-weather-status index b2552b82..f0cf0741 100755 --- a/bin/omarchy-weather-status +++ b/bin/omarchy-weather-status @@ -14,4 +14,4 @@ place=${place%%,*} place=${place^} temperature=${temperature#+} -echo "$(omarchy-weather-icon) $place · Temp $temperature · Wind $wind" +echo "$place · Temp $temperature · Wind $wind" diff --git a/config/hypr/.luarc.json b/config/hypr/.luarc.json index ff0e3599..afb4466c 100644 --- a/config/hypr/.luarc.json +++ b/config/hypr/.luarc.json @@ -6,6 +6,6 @@ "checkThirdParty": false }, "diagnostics": { - "globals": ["hl"] + "globals": ["hl", "o"] } } diff --git a/config/hypr/autostart.lua b/config/hypr/autostart.lua index 5f444bb1..de1a69a1 100644 --- a/config/hypr/autostart.lua +++ b/config/hypr/autostart.lua @@ -1,4 +1,2 @@ -- Extra autostart processes. --- hl.on("hyprland.start", function() --- hl.exec_cmd("uwsm-app -- my-service") --- end) +-- o.launch_on_start("my-service") diff --git a/config/hypr/hyprland.lua b/config/hypr/hyprland.lua index af2ce6db..6836e3cc 100644 --- a/config/hypr/hyprland.lua +++ b/config/hypr/hyprland.lua @@ -1,32 +1,14 @@ -- Learn how to configure Hyprland: https://wiki.hypr.land/Configuring/Start/ -local home = os.getenv("HOME") or "" +-- Load user modules from ~/.config and Omarchy defaults from $OMARCHY_PATH. +package.path = os.getenv("HOME") + .. "/.config/?.lua;" + .. (os.getenv("OMARCHY_PATH") or (os.getenv("HOME") .. "/.local/share/omarchy")) + .. "/?.lua;" + .. package.path --- Hyprland recommends require() for split Lua configs. These two roots let us --- load user modules from ~/.config and Omarchy defaults from $OMARCHY_PATH. -package.path = home .. "/.config/?.lua;" .. (os.getenv("OMARCHY_PATH") or (home .. "/.local/share/omarchy")) .. "/?.lua;" .. package.path - -local paths = require("default.hypr.paths") - --- Use Omarchy defaults, but don't edit these directly. -require("default.hypr.autostart") -require("default.hypr.bindings.media") -require("default.hypr.bindings.clipboard") -require("default.hypr.bindings.tiling-v2") -require("default.hypr.bindings.utilities") -require("default.hypr.envs") -require("default.hypr.looknfeel") -require("default.hypr.input") -require("default.hypr.windows") - --- Current theme overrides. -do - local theme = io.open(paths.config_home .. "/omarchy/current/theme/hyprland.lua", "r") - if theme then - theme:close() - require("omarchy.current.theme.hyprland") - end -end +-- All Omarchy default setups +require("default.hypr.omarchy") -- Change your own setup in these files and override defaults. require("hypr.monitors") @@ -39,4 +21,4 @@ require("hypr.autostart") require("default.hypr.toggles") -- Add any other personal Hyprland configuration below. --- hl.window_rule({ match = { class = "qemu" }, workspace = "5" }) +-- o.window("qemu", { workspace = "5" }) diff --git a/config/hypr/input.lua b/config/hypr/input.lua index d3ef0d20..03e32bde 100644 --- a/config/hypr/input.lua +++ b/config/hypr/input.lua @@ -43,8 +43,8 @@ hl.config({ }) -- Scroll nicely in the terminal. -hl.window_rule({ match = { class = "(Alacritty|kitty|foot)" }, scroll_touchpad = 1.5 }) -hl.window_rule({ match = { class = "com.mitchellh.ghostty" }, scroll_touchpad = 0.2 }) +o.window("(Alacritty|kitty|foot)", { scroll_touchpad = 1.5 }) +o.window("com.mitchellh.ghostty", { scroll_touchpad = 0.2 }) -- Enable touchpad gestures for changing workspaces. -- See https://wiki.hypr.land/Configuring/Advanced-and-Cool/Gestures/ diff --git a/config/tmux/tmux.conf b/config/tmux/tmux.conf index 40293937..53990431 100644 --- a/config/tmux/tmux.conf +++ b/config/tmux/tmux.conf @@ -13,6 +13,10 @@ bind -T copy-mode-vi v send -X begin-selection bind -T copy-mode-vi y send -X copy-selection-and-cancel # Pane Controls +bind -n M-Enter split-window -v -c "#{pane_current_path}" +bind -n M-S-Enter split-window -h -c "#{pane_current_path}" +bind -n M-Escape kill-pane + bind h split-window -v -c "#{pane_current_path}" bind v split-window -h -c "#{pane_current_path}" bind x kill-pane diff --git a/config/uwsm/default b/config/uwsm/default index 946fbe5f..92836d0c 100644 --- a/config/uwsm/default +++ b/config/uwsm/default @@ -3,6 +3,9 @@ # Install other terminals via Install > Terminal export TERMINAL=xdg-terminal-exec +# Used by terminal programs (like gh) to open URLs detached from the terminal process tree +export BROWSER=omarchy-launch-browser + # Use code for VSCode export EDITOR=nvim diff --git a/applications/Alacritty.desktop b/default/alacritty/Alacritty.desktop similarity index 100% rename from applications/Alacritty.desktop rename to default/alacritty/Alacritty.desktop diff --git a/default/hypr/apps/1password.lua b/default/hypr/apps/1password.lua index 0cb083b4..d57bf651 100644 --- a/default/hypr/apps/1password.lua +++ b/default/hypr/apps/1password.lua @@ -1,2 +1 @@ -hl.window_rule({ match = { class = "^(1[p|P]assword)$" }, no_screen_share = true }) -hl.window_rule({ match = { class = "^(1[p|P]assword)$" }, tag = "+floating-window" }) +o.window("^(1[p|P]assword)$", { no_screen_share = true, tag = "+floating-window" }) diff --git a/default/hypr/apps/bitwarden.lua b/default/hypr/apps/bitwarden.lua index 817d78ab..ec2e7bf6 100644 --- a/default/hypr/apps/bitwarden.lua +++ b/default/hypr/apps/bitwarden.lua @@ -1,6 +1,6 @@ -hl.window_rule({ match = { class = "^(Bitwarden)$" }, no_screen_share = true }) -hl.window_rule({ match = { class = "^(Bitwarden)$" }, tag = "+floating-window" }) +o.window("^(Bitwarden)$", { no_screen_share = true, tag = "+floating-window" }) --- Bitwarden Chrome Extension. -hl.window_rule({ match = { class = "chrome-nngceckbapebfimnlniiiahkandclblb-Default" }, no_screen_share = true }) -hl.window_rule({ match = { class = "chrome-nngceckbapebfimnlniiiahkandclblb-Default" }, tag = "+floating-window" }) +o.window("chrome-nngceckbapebfimnlniiiahkandclblb-Default", { + no_screen_share = true, + tag = "+floating-window", +}) diff --git a/default/hypr/apps/browser.lua b/default/hypr/apps/browser.lua index 4fc73a33..06bb1905 100644 --- a/default/hypr/apps/browser.lua +++ b/default/hypr/apps/browser.lua @@ -1,19 +1,12 @@ --- Browser types. -hl.window_rule({ match = { class = "((google-)?[cC]hrom(e|ium)|[bB]rave-browser|[mM]icrosoft-edge|Vivaldi-stable|helium)" }, tag = "+chromium-based-browser" }) -hl.window_rule({ match = { class = "([fF]irefox|zen|librewolf)" }, tag = "+firefox-based-browser" }) -hl.window_rule({ match = { tag = "chromium-based-browser" }, tag = "-default-opacity" }) -hl.window_rule({ match = { tag = "firefox-based-browser" }, tag = "-default-opacity" }) +-- Browser tags and styling. +o.window("((google-)?[cC]hrom(e|ium)|[bB]rave-browser|[mM]icrosoft-edge|Vivaldi-stable|helium)", { tag = "+chromium-based-browser" }) +o.window("([fF]irefox|zen|librewolf)", { tag = "+firefox-based-browser" }) +o.window({ tag = "chromium-based-browser" }, { tag = "-default-opacity", tile = true, opacity = "1.0 0.97" }) +o.window({ tag = "firefox-based-browser" }, { tag = "-default-opacity", opacity = "1.0 0.97" }) -- Video apps: remove chromium browser tag so they don't get opacity applied. -hl.window_rule({ match = { class = "(chrome-youtube.com__-Default|chrome-app.zoom.us__wc_home-Default)" }, tag = "-chromium-based-browser" }) -hl.window_rule({ match = { class = "(chrome-youtube.com__-Default|chrome-app.zoom.us__wc_home-Default)" }, tag = "-default-opacity" }) +o.window("(chrome-youtube.com__-Default|chrome-app.zoom.us__wc_home-Default)", { tag = "-chromium-based-browser" }) +o.window("(chrome-youtube.com__-Default|chrome-app.zoom.us__wc_home-Default)", { tag = "-default-opacity" }) --- Force chromium-based browsers into a tile to deal with --app bug. -hl.window_rule({ match = { tag = "chromium-based-browser" }, tile = true }) - --- Only a subtle opacity change, but not for video sites. -hl.window_rule({ match = { tag = "chromium-based-browser" }, opacity = "1.0 0.97" }) -hl.window_rule({ match = { tag = "firefox-based-browser" }, opacity = "1.0 0.97" }) - --- Hide the screen-sharing notification bar (the "Hide" button on it is broken on Wayland). -hl.window_rule({ match = { title = ".*is sharing.*" }, workspace = "special silent" }) +-- Hide screen sharing notification windows. +o.window({ title = ".*is sharing.*" }, { workspace = "special silent" }) diff --git a/default/hypr/apps/davinci-resolve.lua b/default/hypr/apps/davinci-resolve.lua index 637d51bd..ba81e12c 100644 --- a/default/hypr/apps/davinci-resolve.lua +++ b/default/hypr/apps/davinci-resolve.lua @@ -1,2 +1,2 @@ --- Focus floating DaVinci Resolve dialog windows. -hl.window_rule({ match = { class = ".*[Rr]esolve.*", float = true }, stay_focused = true }) +-- DaVinci Resolve dialog focus handling. +o.window(".*[Rr]esolve.*", { float = true, stay_focused = true }) diff --git a/default/hypr/apps/geforce.lua b/default/hypr/apps/geforce.lua index feb7e885..d89db006 100644 --- a/default/hypr/apps/geforce.lua +++ b/default/hypr/apps/geforce.lua @@ -1,5 +1 @@ -hl.window_rule({ - name = "geforce", - match = { class = "GeForceNOW" }, - idle_inhibit = "fullscreen", -}) +o.window("GeForceNOW", { idle_inhibit = "fullscreen" }) diff --git a/default/hypr/apps/jetbrains.lua b/default/hypr/apps/jetbrains.lua index f48d150f..678e823e 100644 --- a/default/hypr/apps/jetbrains.lua +++ b/default/hypr/apps/jetbrains.lua @@ -1,6 +1,2 @@ -- Disable mouse focus (see https://github.com/basecamp/omarchy/pull/5183#issuecomment-4189299971). -hl.window_rule({ - name = "jetbrains-focus", - match = { class = "^(jetbrains-.*)$" }, - no_follow_mouse = true, -}) +o.window("^(jetbrains-.*)$", { no_follow_mouse = true }) diff --git a/default/hypr/apps/localsend.lua b/default/hypr/apps/localsend.lua index e670fd7f..6e7ec132 100644 --- a/default/hypr/apps/localsend.lua +++ b/default/hypr/apps/localsend.lua @@ -1,4 +1,3 @@ -- Float LocalSend and fzf file picker. -hl.window_rule({ match = { class = "(Share|localsend)" }, float = true }) -hl.window_rule({ match = { class = "(Share|localsend)" }, center = true }) -hl.window_rule({ match = { class = "localsend" }, size = { 1100, 700 } }) +o.window("(Share|localsend)", { float = true, center = true }) +o.window("localsend", { size = { 1100, 700 } }) diff --git a/default/hypr/apps/moonlight.lua b/default/hypr/apps/moonlight.lua index 2774d77c..d7f3489e 100644 --- a/default/hypr/apps/moonlight.lua +++ b/default/hypr/apps/moonlight.lua @@ -1,6 +1 @@ -hl.window_rule({ - name = "moonlight", - match = { class = "com.moonlight_stream.Moonlight" }, - fullscreen = true, - idle_inhibit = "fullscreen", -}) +o.window("com.moonlight_stream.Moonlight", { fullscreen = true, idle_inhibit = "fullscreen" }) diff --git a/default/hypr/apps/pip.lua b/default/hypr/apps/pip.lua index 6158fa9b..d7d4e12f 100644 --- a/default/hypr/apps/pip.lua +++ b/default/hypr/apps/pip.lua @@ -1,10 +1,12 @@ -- Picture-in-picture overlays. -hl.window_rule({ match = { title = "(Picture.?in.?[Pp]icture)" }, tag = "+pip" }) -hl.window_rule({ match = { tag = "pip" }, tag = "-default-opacity" }) -hl.window_rule({ match = { tag = "pip" }, float = true }) -hl.window_rule({ match = { tag = "pip" }, pin = true }) -hl.window_rule({ match = { tag = "pip" }, size = { 600, 338 } }) -hl.window_rule({ match = { tag = "pip" }, keep_aspect_ratio = true }) -hl.window_rule({ match = { tag = "pip" }, border_size = 0 }) -hl.window_rule({ match = { tag = "pip" }, opacity = "1 1" }) -hl.window_rule({ match = { tag = "pip" }, move = { "(monitor_w-window_w-40)", "(monitor_h*0.04)" } }) +o.window({ title = "(Picture.?in.?[Pp]icture)" }, { tag = "+pip" }) +o.window({ tag = "pip" }, { + tag = "-default-opacity", + float = true, + pin = true, + size = { 600, 338 }, + keep_aspect_ratio = true, + border_size = 0, + opacity = "1 1", + move = { "(monitor_w-window_w-40)", "(monitor_h*0.04)" }, +}) diff --git a/default/hypr/apps/qemu.lua b/default/hypr/apps/qemu.lua index e9334c1c..c919bcec 100644 --- a/default/hypr/apps/qemu.lua +++ b/default/hypr/apps/qemu.lua @@ -1,2 +1 @@ -hl.window_rule({ match = { class = "qemu" }, tag = "-default-opacity" }) -hl.window_rule({ match = { class = "qemu" }, opacity = "1 1" }) +o.window("qemu", { tag = "-default-opacity", opacity = "1 1" }) diff --git a/default/hypr/apps/retroarch.lua b/default/hypr/apps/retroarch.lua index 01b3f8b5..0bc8a218 100644 --- a/default/hypr/apps/retroarch.lua +++ b/default/hypr/apps/retroarch.lua @@ -1,4 +1,6 @@ -hl.window_rule({ match = { class = "com.libretro.RetroArch" }, fullscreen = true }) -hl.window_rule({ match = { class = "com.libretro.RetroArch" }, tag = "-default-opacity" }) -hl.window_rule({ match = { class = "com.libretro.RetroArch" }, opacity = "1 1" }) -hl.window_rule({ match = { class = "com.libretro.RetroArch" }, idle_inhibit = "fullscreen" }) +o.window("com.libretro.RetroArch", { + fullscreen = true, + tag = "-default-opacity", + opacity = "1 1", + idle_inhibit = "fullscreen", +}) diff --git a/default/hypr/apps/steam.lua b/default/hypr/apps/steam.lua index 05bb75d8..152aff64 100644 --- a/default/hypr/apps/steam.lua +++ b/default/hypr/apps/steam.lua @@ -1,8 +1,4 @@ --- Float Steam. -hl.window_rule({ match = { class = "steam" }, float = true }) -hl.window_rule({ match = { class = "steam", title = "Steam" }, center = true }) -hl.window_rule({ match = { class = "steam.*" }, tag = "-default-opacity" }) -hl.window_rule({ match = { class = "steam.*" }, opacity = "1 1" }) -hl.window_rule({ match = { class = "steam", title = "Steam" }, size = { 1100, 700 } }) -hl.window_rule({ match = { class = "steam", title = "Friends List" }, size = { 460, 800 } }) -hl.window_rule({ match = { class = "steam" }, idle_inhibit = "fullscreen" }) +o.window("steam", { float = true, idle_inhibit = "fullscreen" }) +o.window({ class = "steam", title = "Steam" }, { center = true, size = { 1100, 700 } }) +o.window("steam.*", { tag = "-default-opacity", opacity = "1 1" }) +o.window({ class = "steam", title = "Friends List" }, { size = { 460, 800 } }) diff --git a/default/hypr/apps/telegram.lua b/default/hypr/apps/telegram.lua index e1509516..ff0f03a6 100644 --- a/default/hypr/apps/telegram.lua +++ b/default/hypr/apps/telegram.lua @@ -1,2 +1,2 @@ -- Prevent Telegram from stealing focus on new messages. -hl.window_rule({ match = { class = "org.telegram.desktop" }, focus_on_activate = false }) +o.window("org.telegram.desktop", { focus_on_activate = false }) diff --git a/default/hypr/apps/terminals.lua b/default/hypr/apps/terminals.lua index 0a1d403e..4d90a636 100644 --- a/default/hypr/apps/terminals.lua +++ b/default/hypr/apps/terminals.lua @@ -1,4 +1,3 @@ -- Define terminal tag to style them uniformly. -hl.window_rule({ match = { class = "(Alacritty|kitty|com.mitchellh.ghostty|foot)" }, tag = "+terminal" }) -hl.window_rule({ match = { tag = "terminal" }, tag = "-default-opacity" }) -hl.window_rule({ match = { tag = "terminal" }, opacity = "0.97 0.9" }) +o.window("(Alacritty|kitty|com.mitchellh.ghostty|foot)", { tag = "+terminal" }) +o.window({ tag = "terminal" }, { tag = "-default-opacity", opacity = "0.97 0.9" }) diff --git a/default/hypr/apps/typora.lua b/default/hypr/apps/typora.lua index a8af36a3..4249db4c 100644 --- a/default/hypr/apps/typora.lua +++ b/default/hypr/apps/typora.lua @@ -1,2 +1,2 @@ --- Float Typora print dialog. -hl.window_rule({ match = { class = "^Typora$", title = "^Print$" }, float = true, center = true }) +-- Typora print dialog. +o.window({ class = "^Typora$", title = "^Print$" }, { float = true, center = true }) diff --git a/default/hypr/apps/webcam-overlay.lua b/default/hypr/apps/webcam-overlay.lua index 42f7acde..3e92ae8e 100644 --- a/default/hypr/apps/webcam-overlay.lua +++ b/default/hypr/apps/webcam-overlay.lua @@ -1,6 +1,8 @@ --- Webcam overlay for screen recording. -hl.window_rule({ match = { title = "WebcamOverlay" }, float = true }) -hl.window_rule({ match = { title = "WebcamOverlay" }, pin = true }) -hl.window_rule({ match = { title = "WebcamOverlay" }, no_initial_focus = true }) -hl.window_rule({ match = { title = "WebcamOverlay" }, no_dim = true }) -hl.window_rule({ match = { title = "WebcamOverlay" }, move = { "(monitor_w-window_w-40)", "(monitor_h-window_h-40)" } }) +-- Webcam overlay window. +o.window({ title = "WebcamOverlay" }, { + float = true, + pin = true, + no_initial_focus = true, + no_dim = true, + move = { "(monitor_w-window_w-40)", "(monitor_h-window_h-40)" }, +}) diff --git a/default/hypr/bindings/clipboard.lua b/default/hypr/bindings/clipboard.lua index bc30414f..415b71f6 100644 --- a/default/hypr/bindings/clipboard.lua +++ b/default/hypr/bindings/clipboard.lua @@ -10,7 +10,7 @@ local function send_shortcut_once(mods, key) end end -hl.bind("SUPER + C", send_shortcut_once("CTRL", "Insert"), { description = "Universal copy" }) -hl.bind("SUPER + V", send_shortcut_once("SHIFT", "Insert"), { description = "Universal paste" }) -hl.bind("SUPER + X", send_shortcut_once("CTRL", "X"), { description = "Universal cut" }) -hl.bind("SUPER + CTRL + V", hl.dsp.exec_cmd("omarchy-launch-walker -m clipboard"), { description = "Clipboard manager" }) +o.bind("SUPER + C", "Universal copy", send_shortcut_once("CTRL", "Insert")) +o.bind("SUPER + V", "Universal paste", send_shortcut_once("SHIFT", "Insert")) +o.bind("SUPER + X", "Universal cut", send_shortcut_once("CTRL", "X")) +o.bind("SUPER + CTRL + V", "Clipboard manager", { omarchy = "walker -m clipboard" }) diff --git a/default/hypr/bindings/media.lua b/default/hypr/bindings/media.lua index 9b6a54be..5c2b3ccd 100644 --- a/default/hypr/bindings/media.lua +++ b/default/hypr/bindings/media.lua @@ -1,29 +1,29 @@ -- Volume, brightness, keyboard backlight, and touchpad controls. -hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("omarchy-swayosd-client --output-volume raise"), { locked = true, repeating = true, description = "Volume up" }) -hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("omarchy-swayosd-client --output-volume lower"), { locked = true, repeating = true, description = "Volume down" }) -hl.bind("XF86AudioMute", hl.dsp.exec_cmd("omarchy-swayosd-client --output-volume mute-toggle"), { locked = true, repeating = true, description = "Mute" }) -hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("omarchy-audio-input-mute"), { locked = true, repeating = true, description = "Mute microphone" }) -hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("omarchy-brightness-display +5%"), { locked = true, repeating = true, description = "Brightness up" }) -hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("omarchy-brightness-display 5%-"), { locked = true, repeating = true, description = "Brightness down" }) -hl.bind("SHIFT + XF86MonBrightnessUp", hl.dsp.exec_cmd("omarchy-brightness-display 100%"), { locked = true, repeating = true, description = "Brightness maximum" }) -hl.bind("SHIFT + XF86MonBrightnessDown", hl.dsp.exec_cmd("omarchy-brightness-display 1%"), { locked = true, repeating = true, description = "Brightness minimum" }) -hl.bind("XF86KbdBrightnessUp", hl.dsp.exec_cmd("omarchy-brightness-keyboard up"), { locked = true, repeating = true, description = "Keyboard brightness up" }) -hl.bind("XF86KbdBrightnessDown", hl.dsp.exec_cmd("omarchy-brightness-keyboard down"), { locked = true, repeating = true, description = "Keyboard brightness down" }) -hl.bind("XF86KbdLightOnOff", hl.dsp.exec_cmd("omarchy-brightness-keyboard cycle"), { locked = true, description = "Keyboard backlight cycle" }) -hl.bind("XF86TouchpadToggle", hl.dsp.exec_cmd("omarchy-toggle-touchpad"), { locked = true, description = "Toggle touchpad" }) -hl.bind("XF86TouchpadOn", hl.dsp.exec_cmd("omarchy-toggle-touchpad on"), { locked = true, description = "Enable touchpad" }) -hl.bind("XF86TouchpadOff", hl.dsp.exec_cmd("omarchy-toggle-touchpad off"), { locked = true, description = "Disable touchpad" }) +o.bind("XF86AudioRaiseVolume", "Volume up", "omarchy-swayosd-client --output-volume raise", { locked = true, repeating = true }) +o.bind("XF86AudioLowerVolume", "Volume down", "omarchy-swayosd-client --output-volume lower", { locked = true, repeating = true }) +o.bind("XF86AudioMute", "Mute", "omarchy-swayosd-client --output-volume mute-toggle", { locked = true, repeating = true }) +o.bind("XF86AudioMicMute", "Mute microphone", "omarchy-audio-input-mute", { locked = true, repeating = true }) +o.bind("XF86MonBrightnessUp", "Brightness up", "omarchy-brightness-display +5%", { locked = true, repeating = true }) +o.bind("XF86MonBrightnessDown", "Brightness down", "omarchy-brightness-display 5%-", { locked = true, repeating = true }) +o.bind("SHIFT + XF86MonBrightnessUp", "Brightness maximum", "omarchy-brightness-display 100%", { locked = true, repeating = true }) +o.bind("SHIFT + XF86MonBrightnessDown", "Brightness minimum", "omarchy-brightness-display 1%", { locked = true, repeating = true }) +o.bind("XF86KbdBrightnessUp", "Keyboard brightness up", "omarchy-brightness-keyboard up", { locked = true, repeating = true }) +o.bind("XF86KbdBrightnessDown", "Keyboard brightness down", "omarchy-brightness-keyboard down", { locked = true, repeating = true }) +o.bind("XF86KbdLightOnOff", "Keyboard backlight cycle", "omarchy-brightness-keyboard cycle", { locked = true }) +o.bind("XF86TouchpadToggle", "Toggle touchpad", "omarchy-toggle-touchpad", { locked = true }) +o.bind("XF86TouchpadOn", "Enable touchpad", "omarchy-toggle-touchpad on", { locked = true }) +o.bind("XF86TouchpadOff", "Disable touchpad", "omarchy-toggle-touchpad off", { locked = true }) -- Precise volume and brightness controls. -hl.bind("ALT + XF86AudioRaiseVolume", hl.dsp.exec_cmd("omarchy-swayosd-client --output-volume +1"), { locked = true, repeating = true, description = "Volume up precise" }) -hl.bind("ALT + XF86AudioLowerVolume", hl.dsp.exec_cmd("omarchy-swayosd-client --output-volume -1"), { locked = true, repeating = true, description = "Volume down precise" }) -hl.bind("ALT + XF86MonBrightnessUp", hl.dsp.exec_cmd("omarchy-brightness-display +1%"), { locked = true, repeating = true, description = "Brightness up precise" }) -hl.bind("ALT + XF86MonBrightnessDown", hl.dsp.exec_cmd("omarchy-brightness-display 1%-"), { locked = true, repeating = true, description = "Brightness down precise" }) +o.bind("ALT + XF86AudioRaiseVolume", "Volume up precise", "omarchy-swayosd-client --output-volume +1", { locked = true, repeating = true }) +o.bind("ALT + XF86AudioLowerVolume", "Volume down precise", "omarchy-swayosd-client --output-volume -1", { locked = true, repeating = true }) +o.bind("ALT + XF86MonBrightnessUp", "Brightness up precise", "omarchy-brightness-display +1%", { locked = true, repeating = true }) +o.bind("ALT + XF86MonBrightnessDown", "Brightness down precise", "omarchy-brightness-display 1%-", { locked = true, repeating = true }) -- Media controls. -hl.bind("XF86AudioNext", hl.dsp.exec_cmd("omarchy-swayosd-client --playerctl next"), { locked = true, description = "Next track" }) -hl.bind("XF86AudioPause", hl.dsp.exec_cmd("omarchy-swayosd-client --playerctl play-pause"), { locked = true, description = "Pause" }) -hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("omarchy-swayosd-client --playerctl play-pause"), { locked = true, description = "Play" }) -hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("omarchy-swayosd-client --playerctl previous"), { locked = true, description = "Previous track" }) +o.bind("XF86AudioNext", "Next track", "omarchy-swayosd-client --playerctl next", { locked = true }) +o.bind("XF86AudioPause", "Pause", "omarchy-swayosd-client --playerctl play-pause", { locked = true }) +o.bind("XF86AudioPlay", "Play", "omarchy-swayosd-client --playerctl play-pause", { locked = true }) +o.bind("XF86AudioPrev", "Previous track", "omarchy-swayosd-client --playerctl previous", { locked = true }) -hl.bind("SUPER + XF86AudioMute", hl.dsp.exec_cmd("omarchy-audio-output-switch"), { locked = true, description = "Switch audio output" }) +o.bind("SUPER + XF86AudioMute", "Switch audio output", "omarchy-audio-output-switch", { locked = true }) diff --git a/default/hypr/bindings/tiling-v2.lua b/default/hypr/bindings/tiling-v2.lua index 8a12b78b..04022b2e 100644 --- a/default/hypr/bindings/tiling-v2.lua +++ b/default/hypr/bindings/tiling-v2.lua @@ -1,93 +1,93 @@ -hl.bind("SUPER + W", hl.dsp.window.close(), { description = "Close window" }) -hl.bind("CTRL + ALT + DELETE", hl.dsp.exec_cmd("omarchy-hyprland-window-close-all"), { description = "Close all windows" }) +o.bind("SUPER + W", "Close window", hl.dsp.window.close()) +o.bind("CTRL + ALT + DELETE", "Close all windows", "omarchy-hyprland-window-close-all") -hl.bind("SUPER + J", hl.dsp.layout("togglesplit"), { description = "Toggle window split" }) -hl.bind("SUPER + P", hl.dsp.window.pseudo(), { description = "Pseudo window" }) -hl.bind("SUPER + T", hl.dsp.window.float({ action = "toggle" }), { description = "Toggle window floating/tiling" }) -hl.bind("SUPER + F", hl.dsp.window.fullscreen({ mode = "fullscreen" }), { description = "Full screen" }) -hl.bind("SUPER + CTRL + F", hl.dsp.window.fullscreen_state({ internal = 0, client = 2 }), { description = "Tiled full screen" }) -hl.bind("SUPER + ALT + F", hl.dsp.window.fullscreen({ mode = "maximized" }), { description = "Full width" }) -hl.bind("SUPER + O", hl.dsp.exec_cmd("omarchy-hyprland-window-pop"), { description = "Pop window out (float & pin)" }) -hl.bind("SUPER + L", hl.dsp.exec_cmd("omarchy-hyprland-workspace-layout-toggle"), { description = "Toggle workspace layout" }) +o.bind("SUPER + J", "Toggle window split", hl.dsp.layout("togglesplit")) +o.bind("SUPER + P", "Pseudo window", hl.dsp.window.pseudo()) +o.bind("SUPER + T", "Toggle window floating/tiling", hl.dsp.window.float({ action = "toggle" })) +o.bind("SUPER + F", "Full screen", hl.dsp.window.fullscreen({ mode = "fullscreen" })) +o.bind("SUPER + CTRL + F", "Tiled full screen", hl.dsp.window.fullscreen_state({ internal = 0, client = 2 })) +o.bind("SUPER + ALT + F", "Full width", hl.dsp.window.fullscreen({ mode = "maximized" })) +o.bind("SUPER + O", "Pop window out (float & pin)", "omarchy-hyprland-window-pop") +o.bind("SUPER + L", "Toggle workspace layout", "omarchy-hyprland-workspace-layout-toggle") -hl.bind("SUPER + LEFT", hl.dsp.focus({ direction = "l" }), { description = "Focus on left window" }) -hl.bind("SUPER + RIGHT", hl.dsp.focus({ direction = "r" }), { description = "Focus on right window" }) -hl.bind("SUPER + UP", hl.dsp.focus({ direction = "u" }), { description = "Focus on above window" }) -hl.bind("SUPER + DOWN", hl.dsp.focus({ direction = "d" }), { description = "Focus on below window" }) +o.bind("SUPER + LEFT", "Focus on left window", hl.dsp.focus({ direction = "l" })) +o.bind("SUPER + RIGHT", "Focus on right window", hl.dsp.focus({ direction = "r" })) +o.bind("SUPER + UP", "Focus on above window", hl.dsp.focus({ direction = "u" })) +o.bind("SUPER + DOWN", "Focus on below window", hl.dsp.focus({ direction = "d" })) for workspace = 1, 10 do local key = "code:" .. tostring(workspace + 9) - hl.bind("SUPER + " .. key, hl.dsp.focus({ workspace = tostring(workspace) }), { description = "Switch to workspace " .. workspace }) - hl.bind("SUPER + SHIFT + " .. key, hl.dsp.window.move({ workspace = tostring(workspace) }), { description = "Move window to workspace " .. workspace }) - hl.bind("SUPER + SHIFT + ALT + " .. key, hl.dsp.window.move({ workspace = tostring(workspace), follow = false }), { description = "Move window silently to workspace " .. workspace }) + o.bind("SUPER + " .. key, "Switch to workspace " .. workspace, hl.dsp.focus({ workspace = tostring(workspace) })) + o.bind("SUPER + SHIFT + " .. key, "Move window to workspace " .. workspace, hl.dsp.window.move({ workspace = tostring(workspace) })) + o.bind("SUPER + SHIFT + ALT + " .. key, "Move window silently to workspace " .. workspace, hl.dsp.window.move({ workspace = tostring(workspace), follow = false })) end -hl.bind("SUPER + S", hl.dsp.workspace.toggle_special("scratchpad"), { description = "Toggle scratchpad" }) -hl.bind("SUPER + ALT + S", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false }), { description = "Move window to scratchpad" }) +o.bind("SUPER + S", "Toggle scratchpad", hl.dsp.workspace.toggle_special("scratchpad")) +o.bind("SUPER + ALT + S", "Move window to scratchpad", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false })) -hl.bind("SUPER + TAB", hl.dsp.focus({ workspace = "e+1" }), { description = "Next workspace" }) -hl.bind("SUPER + SHIFT + TAB", hl.dsp.focus({ workspace = "e-1" }), { description = "Previous workspace" }) -hl.bind("SUPER + CTRL + TAB", hl.dsp.focus({ workspace = "previous" }), { description = "Former workspace" }) +o.bind("SUPER + TAB", "Next workspace", hl.dsp.focus({ workspace = "e+1" })) +o.bind("SUPER + SHIFT + TAB", "Previous workspace", hl.dsp.focus({ workspace = "e-1" })) +o.bind("SUPER + CTRL + TAB", "Former workspace", hl.dsp.focus({ workspace = "previous" })) -hl.bind("SUPER + SHIFT + ALT + LEFT", hl.dsp.workspace.move({ monitor = "l" }), { description = "Move workspace to left monitor" }) -hl.bind("SUPER + SHIFT + ALT + RIGHT", hl.dsp.workspace.move({ monitor = "r" }), { description = "Move workspace to right monitor" }) -hl.bind("SUPER + SHIFT + ALT + UP", hl.dsp.workspace.move({ monitor = "u" }), { description = "Move workspace to up monitor" }) -hl.bind("SUPER + SHIFT + ALT + DOWN", hl.dsp.workspace.move({ monitor = "d" }), { description = "Move workspace to down monitor" }) +o.bind("SUPER + SHIFT + ALT + LEFT", "Move workspace to left monitor", hl.dsp.workspace.move({ monitor = "l" })) +o.bind("SUPER + SHIFT + ALT + RIGHT", "Move workspace to right monitor", hl.dsp.workspace.move({ monitor = "r" })) +o.bind("SUPER + SHIFT + ALT + UP", "Move workspace to up monitor", hl.dsp.workspace.move({ monitor = "u" })) +o.bind("SUPER + SHIFT + ALT + DOWN", "Move workspace to down monitor", hl.dsp.workspace.move({ monitor = "d" })) -hl.bind("SUPER + SHIFT + LEFT", hl.dsp.window.swap({ direction = "l" }), { description = "Swap window to the left" }) -hl.bind("SUPER + SHIFT + RIGHT", hl.dsp.window.swap({ direction = "r" }), { description = "Swap window to the right" }) -hl.bind("SUPER + SHIFT + UP", hl.dsp.window.swap({ direction = "u" }), { description = "Swap window up" }) -hl.bind("SUPER + SHIFT + DOWN", hl.dsp.window.swap({ direction = "d" }), { description = "Swap window down" }) +o.bind("SUPER + SHIFT + LEFT", "Swap window to the left", hl.dsp.window.swap({ direction = "l" })) +o.bind("SUPER + SHIFT + RIGHT", "Swap window to the right", hl.dsp.window.swap({ direction = "r" })) +o.bind("SUPER + SHIFT + UP", "Swap window up", hl.dsp.window.swap({ direction = "u" })) +o.bind("SUPER + SHIFT + DOWN", "Swap window down", hl.dsp.window.swap({ direction = "d" })) -hl.bind("ALT + TAB", hl.dsp.window.cycle_next(), { description = "Focus on next window" }) -hl.bind("ALT + SHIFT + TAB", hl.dsp.window.cycle_next({ next = false }), { description = "Focus on previous window" }) -hl.bind("ALT + TAB", hl.dsp.window.bring_to_top(), { description = "Reveal active window on top" }) -hl.bind("ALT + SHIFT + TAB", hl.dsp.window.bring_to_top(), { description = "Reveal active window on top" }) +o.bind("ALT + TAB", "Focus on next window", hl.dsp.window.cycle_next()) +o.bind("ALT + SHIFT + TAB", "Focus on previous window", hl.dsp.window.cycle_next({ next = false })) +o.bind("ALT + TAB", "Reveal active window on top", hl.dsp.window.bring_to_top()) +o.bind("ALT + SHIFT + TAB", "Reveal active window on top", hl.dsp.window.bring_to_top()) -hl.bind("CTRL + ALT + TAB", hl.dsp.focus({ monitor = "+1" }), { description = "Focus on next monitor" }) -hl.bind("CTRL + ALT + SHIFT + TAB", hl.dsp.focus({ monitor = "-1" }), { description = "Focus on previous monitor" }) +o.bind("CTRL + ALT + TAB", "Focus on next monitor", hl.dsp.focus({ monitor = "+1" })) +o.bind("CTRL + ALT + SHIFT + TAB", "Focus on previous monitor", hl.dsp.focus({ monitor = "-1" })) -hl.bind("SUPER + code:20", hl.dsp.window.resize({ x = -100, y = 0, relative = true }), { description = "Expand window left" }) -hl.bind("SUPER + code:21", hl.dsp.window.resize({ x = 100, y = 0, relative = true }), { description = "Shrink window left" }) -hl.bind("SUPER + SHIFT + code:20", hl.dsp.window.resize({ x = 0, y = -100, relative = true }), { description = "Shrink window up" }) -hl.bind("SUPER + SHIFT + code:21", hl.dsp.window.resize({ x = 0, y = 100, relative = true }), { description = "Expand window down" }) +o.bind("SUPER + code:20", "Expand window left", hl.dsp.window.resize({ x = -100, y = 0, relative = true })) +o.bind("SUPER + code:21", "Shrink window left", hl.dsp.window.resize({ x = 100, y = 0, relative = true })) +o.bind("SUPER + SHIFT + code:20", "Shrink window up", hl.dsp.window.resize({ x = 0, y = -100, relative = true })) +o.bind("SUPER + SHIFT + code:21", "Expand window down", hl.dsp.window.resize({ x = 0, y = 100, relative = true })) -hl.bind("SUPER + ALT + code:20", hl.dsp.window.resize({ x = -25, y = 0, relative = true }), { description = "Expand window left a little" }) -hl.bind("SUPER + ALT + code:21", hl.dsp.window.resize({ x = 25, y = 0, relative = true }), { description = "Shrink window left a little" }) -hl.bind("SUPER + SHIFT + ALT + code:20", hl.dsp.window.resize({ x = 0, y = -25, relative = true }), { description = "Shrink window up a little" }) -hl.bind("SUPER + SHIFT + ALT + code:21", hl.dsp.window.resize({ x = 0, y = 25, relative = true }), { description = "Expand window down a little" }) +o.bind("SUPER + ALT + code:20", "Expand window left a little", hl.dsp.window.resize({ x = -25, y = 0, relative = true })) +o.bind("SUPER + ALT + code:21", "Shrink window left a little", hl.dsp.window.resize({ x = 25, y = 0, relative = true })) +o.bind("SUPER + SHIFT + ALT + code:20", "Shrink window up a little", hl.dsp.window.resize({ x = 0, y = -25, relative = true })) +o.bind("SUPER + SHIFT + ALT + code:21", "Expand window down a little", hl.dsp.window.resize({ x = 0, y = 25, relative = true })) -hl.bind("SUPER + CTRL + code:20", hl.dsp.window.resize({ x = -300, y = 0, relative = true }), { description = "Expand window left a lot" }) -hl.bind("SUPER + CTRL + code:21", hl.dsp.window.resize({ x = 300, y = 0, relative = true }), { description = "Shrink window left a lot" }) -hl.bind("SUPER + CTRL + SHIFT + code:20", hl.dsp.window.resize({ x = 0, y = -300, relative = true }), { description = "Shrink window up a lot" }) -hl.bind("SUPER + CTRL + SHIFT + code:21", hl.dsp.window.resize({ x = 0, y = 300, relative = true }), { description = "Expand window down a lot" }) +o.bind("SUPER + CTRL + code:20", "Expand window left a lot", hl.dsp.window.resize({ x = -300, y = 0, relative = true })) +o.bind("SUPER + CTRL + code:21", "Shrink window left a lot", hl.dsp.window.resize({ x = 300, y = 0, relative = true })) +o.bind("SUPER + CTRL + SHIFT + code:20", "Shrink window up a lot", hl.dsp.window.resize({ x = 0, y = -300, relative = true })) +o.bind("SUPER + CTRL + SHIFT + code:21", "Expand window down a lot", hl.dsp.window.resize({ x = 0, y = 300, relative = true })) -hl.bind("SUPER + mouse_down", hl.dsp.focus({ workspace = "e+1" }), { description = "Scroll active workspace forward" }) -hl.bind("SUPER + mouse_up", hl.dsp.focus({ workspace = "e-1" }), { description = "Scroll active workspace backward" }) +o.bind("SUPER + mouse_down", "Scroll active workspace forward", hl.dsp.focus({ workspace = "e+1" })) +o.bind("SUPER + mouse_up", "Scroll active workspace backward", hl.dsp.focus({ workspace = "e-1" })) -hl.bind("SUPER + mouse:272", hl.dsp.window.drag(), { mouse = true, description = "Move window" }) -hl.bind("SUPER + mouse:273", hl.dsp.window.resize(), { mouse = true, description = "Resize window" }) +o.bind("SUPER + mouse:272", "Move window", hl.dsp.window.drag(), { mouse = true }) +o.bind("SUPER + mouse:273", "Resize window", hl.dsp.window.resize(), { mouse = true }) -hl.bind("SUPER + G", hl.dsp.group.toggle(), { description = "Toggle window grouping" }) -hl.bind("SUPER + ALT + G", hl.dsp.window.move({ out_of_group = true }), { description = "Move active window out of group" }) +o.bind("SUPER + G", "Toggle window grouping", hl.dsp.group.toggle()) +o.bind("SUPER + ALT + G", "Move active window out of group", hl.dsp.window.move({ out_of_group = true })) -hl.bind("SUPER + ALT + LEFT", hl.dsp.window.move({ into_group = "l" }), { description = "Move window to group on left" }) -hl.bind("SUPER + ALT + RIGHT", hl.dsp.window.move({ into_group = "r" }), { description = "Move window to group on right" }) -hl.bind("SUPER + ALT + UP", hl.dsp.window.move({ into_group = "u" }), { description = "Move window to group on top" }) -hl.bind("SUPER + ALT + DOWN", hl.dsp.window.move({ into_group = "d" }), { description = "Move window to group on bottom" }) +o.bind("SUPER + ALT + LEFT", "Move window to group on left", hl.dsp.window.move({ into_group = "l" })) +o.bind("SUPER + ALT + RIGHT", "Move window to group on right", hl.dsp.window.move({ into_group = "r" })) +o.bind("SUPER + ALT + UP", "Move window to group on top", hl.dsp.window.move({ into_group = "u" })) +o.bind("SUPER + ALT + DOWN", "Move window to group on bottom", hl.dsp.window.move({ into_group = "d" })) -hl.bind("SUPER + ALT + TAB", hl.dsp.group.next(), { description = "Next window in group" }) -hl.bind("SUPER + ALT + SHIFT + TAB", hl.dsp.group.prev(), { description = "Previous window in group" }) +o.bind("SUPER + ALT + TAB", "Next window in group", hl.dsp.group.next()) +o.bind("SUPER + ALT + SHIFT + TAB", "Previous window in group", hl.dsp.group.prev()) -hl.bind("SUPER + CTRL + LEFT", hl.dsp.group.prev(), { description = "Move grouped window focus left" }) -hl.bind("SUPER + CTRL + RIGHT", hl.dsp.group.next(), { description = "Move grouped window focus right" }) +o.bind("SUPER + CTRL + LEFT", "Move grouped window focus left", hl.dsp.group.prev()) +o.bind("SUPER + CTRL + RIGHT", "Move grouped window focus right", hl.dsp.group.next()) -hl.bind("SUPER + ALT + mouse_down", hl.dsp.group.next(), { description = "Next window in group" }) -hl.bind("SUPER + ALT + mouse_up", hl.dsp.group.prev(), { description = "Previous window in group" }) +o.bind("SUPER + ALT + mouse_down", "Next window in group", hl.dsp.group.next()) +o.bind("SUPER + ALT + mouse_up", "Previous window in group", hl.dsp.group.prev()) for index = 1, 5 do - hl.bind("SUPER + ALT + code:" .. tostring(index + 9), hl.dsp.group.active({ index = index }), { description = "Switch to group window " .. index }) + o.bind("SUPER + ALT + code:" .. tostring(index + 9), "Switch to group window " .. index, hl.dsp.group.active({ index = index })) end -hl.bind("SUPER + code:61", hl.dsp.exec_cmd("omarchy-hyprland-monitor-scaling-cycle"), { description = "Cycle monitor scaling" }) -hl.bind("SUPER + ALT + code:61", hl.dsp.exec_cmd("omarchy-hyprland-monitor-scaling-cycle --reverse"), { description = "Cycle monitor scaling backwards" }) +o.bind("SUPER + code:61", "Cycle monitor scaling", "omarchy-hyprland-monitor-scaling-cycle") +o.bind("SUPER + ALT + code:61", "Cycle monitor scaling backwards", "omarchy-hyprland-monitor-scaling-cycle --reverse") diff --git a/default/hypr/helpers.lua b/default/hypr/helpers.lua new file mode 100644 index 00000000..ee78252e --- /dev/null +++ b/default/hypr/helpers.lua @@ -0,0 +1,103 @@ +-- Shared helpers for Hyprland Lua configuration. + +o = o or {} + +local function shell_quote(value) + return "'" .. tostring(value):gsub("'", "'\\''") .. "'" +end + +local function command_from(value, description) + if type(value) ~= "table" then + return value + end + + if value.omarchy then + return "omarchy-launch-" .. value.omarchy + elseif value.focus and value.launch then + return o.launch_sole(value.focus, value.launch) + elseif value.launch then + return o.launch(value.launch) + elseif value.webapp then + if value.focus then + return o.launch_webapp_sole(description, value.webapp) + else + return o.launch_webapp(value.webapp) + end + elseif value.tui then + if value.focus then + return "omarchy-launch-or-focus-tui " .. shell_quote(value.tui) + else + return "omarchy-launch-tui " .. shell_quote(value.tui) + end + end + + return value +end + +function o.bind(keys, description, dispatcher, options) + local opts = options or {} + + if description then + opts.description = description + end + + dispatcher = command_from(dispatcher, description) + + if type(dispatcher) == "string" then + dispatcher = hl.dsp.exec_cmd(dispatcher) + end + + hl.bind(keys, dispatcher, opts) +end + +function o.launch(command) + return "uwsm-app -- " .. command +end + +function o.exec_on_start(command) + hl.on("hyprland.start", function() + hl.exec_cmd(command) + end) +end + +function o.launch_on_start(command) + o.exec_on_start(o.launch(command)) +end + +function o.launch_webapp(url) + return "omarchy-launch-webapp " .. shell_quote(url) +end + +function o.launch_webapp_sole(name, url) + return "omarchy-launch-or-focus-webapp " .. shell_quote(name) .. " " .. shell_quote(url) +end + +function o.launch_sole(match, command) + return "omarchy-launch-or-focus " .. shell_quote(match) .. " " .. shell_quote(o.launch(command)) +end + +function o.bind_menu(keys, description, menu, options) + o.bind(keys, description, menu and ("omarchy-menu " .. menu) or "omarchy-menu", options) +end + +function o.bind_toggle(keys, description, toggle, options) + o.bind(keys, description, "omarchy-toggle-" .. toggle, options) +end + +function o.notify(message) + return "notify-send -u low " .. shell_quote(message) +end + +function o.window(match, rules) + rules.match = rules.match or {} + + if type(match) == "string" then + rules.match.class = match + else + for key, value in pairs(match) do + rules.match[key] = value + end + end + + hl.window_rule(rules) +end diff --git a/default/hypr/omarchy.lua b/default/hypr/omarchy.lua new file mode 100644 index 00000000..f5087b8d --- /dev/null +++ b/default/hypr/omarchy.lua @@ -0,0 +1,24 @@ +-- Omarchy Hyprland setup: helpers, defaults, and current theme overrides. + +require("default.hypr.helpers") + +-- Use Omarchy defaults, but don't edit these directly. +require("default.hypr.autostart") +require("default.hypr.bindings.media") +require("default.hypr.bindings.clipboard") +require("default.hypr.bindings.tiling-v2") +require("default.hypr.bindings.utilities") +require("default.hypr.envs") +require("default.hypr.looknfeel") +require("default.hypr.input") +require("default.hypr.windows") + +-- Current theme overrides. +do + local paths = require("default.hypr.paths") + local theme = io.open(paths.config_home .. "/omarchy/current/theme/hyprland.lua", "r") + if theme then + theme:close() + require("omarchy.current.theme.hyprland") + end +end diff --git a/default/hypr/paths.lua b/default/hypr/paths.lua index 4671cf64..4e2d2428 100644 --- a/default/hypr/paths.lua +++ b/default/hypr/paths.lua @@ -2,7 +2,7 @@ -- Lua files loaded with require() have separate local scopes, so modules that -- need these paths import this table instead of repeating os.getenv() lookups. -local home = os.getenv("HOME") or "" +local home = os.getenv("HOME") return { home = home, diff --git a/default/hypr/plain-bindings.lua b/default/hypr/plain-bindings.lua index 8656d6d7..5f132a84 100644 --- a/default/hypr/plain-bindings.lua +++ b/default/hypr/plain-bindings.lua @@ -4,10 +4,10 @@ require("default.hypr.bindings.tiling-v2") require("default.hypr.bindings.utilities") -- Application bindings without Omarchy's preinstalled web apps, TUIs, or desktop apps. -hl.bind("SUPER + RETURN", hl.dsp.exec_cmd([[uwsm-app -- xdg-terminal-exec --dir="$(omarchy-cmd-terminal-cwd)"]]), { description = "Terminal" }) -hl.bind("SUPER + SHIFT + RETURN", hl.dsp.exec_cmd("omarchy-launch-browser"), { description = "Browser" }) -hl.bind("SUPER + SHIFT + F", hl.dsp.exec_cmd("uwsm-app -- nautilus --new-window"), { description = "File manager" }) -hl.bind("SUPER + ALT + SHIFT + F", hl.dsp.exec_cmd([[uwsm-app -- nautilus --new-window "$(omarchy-cmd-terminal-cwd)"]]), { description = "File manager (cwd)" }) -hl.bind("SUPER + SHIFT + B", hl.dsp.exec_cmd("omarchy-launch-browser"), { description = "Browser" }) -hl.bind("SUPER + SHIFT + ALT + B", hl.dsp.exec_cmd("omarchy-launch-browser --private"), { description = "Browser (private)" }) -hl.bind("SUPER + SHIFT + N", hl.dsp.exec_cmd("omarchy-launch-editor"), { description = "Editor" }) +o.bind("SUPER + RETURN", "Terminal", { omarchy = "terminal" }) +o.bind("SUPER + SHIFT + RETURN", "Browser", { omarchy = "browser" }) +o.bind("SUPER + SHIFT + F", "File manager", { omarchy = "nautilus" }) +o.bind("SUPER + ALT + SHIFT + F", "File manager (cwd)", { omarchy = "nautilus-cwd" }) +o.bind("SUPER + SHIFT + B", "Browser", { omarchy = "browser" }) +o.bind("SUPER + SHIFT + ALT + B", "Browser (private)", { omarchy = "browser --private" }) +o.bind("SUPER + SHIFT + N", "Editor", { omarchy = "editor" }) diff --git a/default/hypr/windows.lua b/default/hypr/windows.lua index 342ddbcb..d2dd282c 100644 --- a/default/hypr/windows.lua +++ b/default/hypr/windows.lua @@ -1,9 +1,9 @@ -- See https://wiki.hypr.land/Configuring/Basics/Window-Rules/ -hl.window_rule({ match = { class = ".*" }, suppress_event = "maximize" }) +o.window(".*", { suppress_event = "maximize" }) -- Tag all windows for default opacity (apps can override with -default-opacity tag). -hl.window_rule({ match = { class = ".*" }, tag = "+default-opacity" }) +o.window(".*", { tag = "+default-opacity" }) -- Fix some dragging issues with XWayland. hl.window_rule({ @@ -22,4 +22,4 @@ hl.window_rule({ require("default.hypr.apps") -- Apply default opacity after apps have had a chance to opt out. -hl.window_rule({ match = { tag = "default-opacity" }, opacity = "0.97 0.9" }) +o.window({ tag = "default-opacity" }, { opacity = "0.97 0.9" }) diff --git a/default/quickshell/omarchy-shell/plugins/image-picker/ImagePicker.qml b/default/quickshell/omarchy-shell/plugins/image-picker/ImagePicker.qml index 4633145b..7a0b5d60 100644 --- a/default/quickshell/omarchy-shell/plugins/image-picker/ImagePicker.qml +++ b/default/quickshell/omarchy-shell/plugins/image-picker/ImagePicker.qml @@ -38,11 +38,12 @@ Item { property color background: "#101315" property color foreground: "#cacccc" property int expandedWidth: 768 + property int expandedHeight: 475 property int sliceWidth: 108 property int sliceHeight: 432 property int sliceSpacing: -30 property int skewOffset: 28 - property int bottomChromeHeight: showLabels ? (filterable ? 104 : 74) : 30 + property int bottomChromeHeight: showLabels ? (filterable ? 104 : 74) : (filterable ? 60 : 30) function fileUrl(path) { return "file://" + path.split("/").map(encodeURIComponent).join("/") @@ -66,8 +67,8 @@ Item { } function currentPath() { - if (imageModel.count === 0 || !itemMatches(selectedIndex)) return "" - return imageModel.get(selectedIndex).filePath + if (imageArray.length === 0 || !itemMatches(selectedIndex)) return "" + return imageArray[selectedIndex].filePath } function nameForPath(path) { @@ -86,19 +87,19 @@ Item { } function itemMatches(index) { - if (index < 0 || index >= imageModel.count) return false + if (index < 0 || index >= imageArray.length) return false if (!filterText) return true - var path = imageModel.get(index).filePath + var path = imageArray[index].filePath var needle = filterText.toLowerCase() return nameForPath(path).toLowerCase().indexOf(needle) !== -1 || labelForPath(path).toLowerCase().indexOf(needle) !== -1 } function matchingCount() { - if (!filterText) return imageModel.count + if (!filterText) return imageArray.length var count = 0 - for (var i = 0; i < imageModel.count; i++) { + for (var i = 0; i < imageArray.length; i++) { if (itemMatches(i)) count++ } @@ -106,7 +107,7 @@ Item { } function firstMatchingIndex() { - for (var i = 0; i < imageModel.count; i++) { + for (var i = 0; i < imageArray.length; i++) { if (itemMatches(i)) return i } @@ -131,9 +132,9 @@ Item { } function select(index, immediate) { - if (imageModel.count === 0) return + if (imageArray.length === 0) return if (index < 0) index = 0 - else if (index >= imageModel.count) index = imageModel.count - 1 + else if (index >= imageArray.length) index = imageArray.length - 1 if (!itemMatches(index)) return if (index === selectedIndex && immediate !== true) return @@ -141,19 +142,16 @@ Item { } function selectAdjacent(direction) { - if (!filterText) { - select(selectedIndex + direction) - return - } + var count = imageArray.length + if (count === 0) return - var index = selectedIndex + direction - while (index >= 0 && index < imageModel.count) { + var index = selectedIndex + for (var i = 0; i < count; i++) { + index = (index + direction + count) % count if (itemMatches(index)) { select(index) return } - - index += direction } } @@ -225,15 +223,27 @@ Item { } function loadRows(rows) { + var newImages = [] + var seen = {} var paths = rows.split("\n") for (var i = 0; i < paths.length; i++) { var row = paths[i] if (!row) continue var columns = row.split("\t") - root.addImage(columns[0], columns[1]) + var path = columns[0] + if (!path) continue + var fileName = path.split("/").pop() + if (seen[fileName]) continue + seen[fileName] = true + newImages.push({ + filePath: path, + fileName: fileName, + thumbnailPath: columns[1] || path + }) } + root.imageArray = newImages root.select(root.selectedImageIndex(), true) root.imagesLoaded = true root.opened = true @@ -258,7 +268,7 @@ Item { colorsFile = nextColorsFile || (Quickshell.env("HOME") + "/.config/omarchy/current/theme/image-picker-colors.json") if (nextColorsRaw) loadColors(nextColorsRaw) - imageModel.clear() + imageArray = [] selectedIndex = 0 imagesLoaded = false opened = false @@ -270,23 +280,11 @@ Item { } } - ListModel { id: imageModel } - - function addImage(path, thumbnailPath) { - if (!path) return - var fileName = path.split("/").pop() - - for (var i = imageModel.count - 1; i >= 0; i--) { - if (imageModel.get(i).fileName === fileName) - imageModel.remove(i) - } - - imageModel.append({ filePath: path, fileName: fileName, thumbnailPath: thumbnailPath || path }) - } + property var imageArray: [] function selectedImageIndex() { - for (var i = 0; i < imageModel.count; i++) { - if (imageModel.get(i).filePath === selectedImage) + for (var i = 0; i < imageArray.length; i++) { + if (imageArray[i].filePath === selectedImage) return i } @@ -420,7 +418,7 @@ Item { Item { id: card width: Math.min(parent.width - 80, root.expandedWidth + 13 * (root.sliceWidth + root.sliceSpacing) + 40) - height: root.sliceHeight + 30 + root.bottomChromeHeight + height: root.expandedHeight + 30 + root.bottomChromeHeight anchors.centerIn: parent MouseArea { anchors.fill: parent; onClicked: {} } @@ -470,14 +468,16 @@ Item { Component.onCompleted: forceActiveFocus() Repeater { - model: imageModel + model: root.imageArray.length delegate: Item { id: item required property int index - required property string filePath - required property string fileName - required property string thumbnailPath + + readonly property var imageData: root.imageArray[index] + readonly property string filePath: imageData ? imageData.filePath : "" + readonly property string fileName: imageData ? imageData.fileName : "" + readonly property string thumbnailPath: imageData ? imageData.thumbnailPath : "" readonly property bool matched: root.itemMatches(index) readonly property int relativeIndex: root.filteredPosition(index) - root.selectedFilteredPosition() @@ -487,7 +487,8 @@ Item { visible: nearby x: selected ? carousel.previewX : (relativeIndex < 0 ? carousel.previewX + relativeIndex * carousel.itemStep : carousel.previewX + root.expandedWidth + root.sliceSpacing + (relativeIndex - 1) * carousel.itemStep) width: selected ? root.expandedWidth : root.sliceWidth - height: carousel.height + height: selected ? root.expandedHeight : root.sliceHeight + y: selected ? 0 : (root.expandedHeight - root.sliceHeight) / 2 z: selected ? 100 : 50 - Math.min(Math.abs(relativeIndex), 40) readonly property real skAbs: Math.abs(root.skewOffset) @@ -518,25 +519,6 @@ Item { } } - Shape { - x: item.selected ? 4 : 2 - y: item.selected ? 10 : 5 - width: item.width - height: item.height - opacity: item.selected ? 0.5 : 0.32 - antialiasing: true - preferredRendererType: Shape.CurveRenderer - ShapePath { - fillColor: root.background - strokeColor: "transparent" - startX: item.topLeft; startY: 0 - PathLine { x: item.topRight; y: 0 } - PathLine { x: item.bottomRight; y: item.height } - PathLine { x: item.bottomLeft; y: item.height } - PathLine { x: item.topLeft; y: 0 } - } - } - Item { anchors.fill: parent layer.enabled: true @@ -553,7 +535,7 @@ Item { anchors.fill: parent source: item.nearby ? root.fileUrl(item.thumbnailPath) : "" fillMode: Image.PreserveAspectCrop - asynchronous: false + asynchronous: true cache: true smooth: true } @@ -561,7 +543,6 @@ Item { Rectangle { anchors.fill: parent color: root.withAlpha(root.background, item.selected ? 0 : 0.42) - Behavior on color { ColorAnimation { duration: 120 } } } } @@ -608,14 +589,14 @@ Item { } Text { - visible: root.filterable + visible: root.filterable && root.filterText anchors.top: selectedLabel.bottom anchors.topMargin: 8 anchors.horizontalCenter: carousel.horizontalCenter width: root.expandedWidth - text: root.filterText ? ("Filter: " + root.filterText + " (" + root.matchingCount() + ")") : "Type to filter" + text: root.filterText color: root.foreground - opacity: root.filterText ? 0.85 : 0.55 + opacity: 0.85 style: Text.Outline styleColor: root.withAlpha(root.background, 0.7) font.pixelSize: 14 diff --git a/default/themed/gum_env.lua.tpl b/default/themed/gum_env.lua.tpl index aa607d87..5df3f6fc 100644 --- a/default/themed/gum_env.lua.tpl +++ b/default/themed/gum_env.lua.tpl @@ -1,137 +1,137 @@ -- Gum Style (generic) Variables -hl.env("FOREGROUND", "#{{ foreground }}") -hl.env("BACKGROUND", "#{{ background }}") -hl.env("BORDER_FOREGROUND", "#{{ accent }}") -hl.env("BORDER_BACKGROUND", "#{{ background }}") +hl.env("FOREGROUND", "{{ foreground }}") +hl.env("BACKGROUND", "{{ background }}") +hl.env("BORDER_FOREGROUND", "{{ accent }}") +hl.env("BORDER_BACKGROUND", "{{ background }}") -- Gum Confirm Style Variables -hl.env("GUM_CONFIRM_PROMPT_FOREGROUND", "#{{ accent }}") -hl.env("GUM_CONFIRM_PROMPT_BACKGROUND", "#{{ background }}") -hl.env("GUM_CONFIRM_SELECTED_FOREGROUND", "#{{ selection_foreground }}") -hl.env("GUM_CONFIRM_SELECTED_BACKGROUND", "#{{ selection_background }}") -hl.env("GUM_CONFIRM_UNSELECTED_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_CONFIRM_UNSELECTED_BACKGROUND", "#{{ background }}") +hl.env("GUM_CONFIRM_PROMPT_FOREGROUND", "{{ accent }}") +hl.env("GUM_CONFIRM_PROMPT_BACKGROUND", "{{ background }}") +hl.env("GUM_CONFIRM_SELECTED_FOREGROUND", "{{ selection_foreground }}") +hl.env("GUM_CONFIRM_SELECTED_BACKGROUND", "{{ selection_background }}") +hl.env("GUM_CONFIRM_UNSELECTED_FOREGROUND", "{{ foreground }}") +hl.env("GUM_CONFIRM_UNSELECTED_BACKGROUND", "{{ background }}") -- Gum Input Style Variables -hl.env("GUM_INPUT_PROMPT_FOREGROUND", "#{{ accent }}") -hl.env("GUM_INPUT_PROMPT_BACKGROUND", "#{{ background }}") -hl.env("GUM_INPUT_PLACEHOLDER_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_INPUT_PLACEHOLDER_BACKGROUND", "#{{ background }}") -hl.env("GUM_INPUT_CURSOR_FOREGROUND", "#{{ cursor }}") -hl.env("GUM_INPUT_CURSOR_BACKGROUND", "#{{ background }}") -hl.env("GUM_INPUT_HEADER_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_INPUT_HEADER_BACKGROUND", "#{{ background }}") +hl.env("GUM_INPUT_PROMPT_FOREGROUND", "{{ accent }}") +hl.env("GUM_INPUT_PROMPT_BACKGROUND", "{{ background }}") +hl.env("GUM_INPUT_PLACEHOLDER_FOREGROUND", "{{ color8 }}") +hl.env("GUM_INPUT_PLACEHOLDER_BACKGROUND", "{{ background }}") +hl.env("GUM_INPUT_CURSOR_FOREGROUND", "{{ cursor }}") +hl.env("GUM_INPUT_CURSOR_BACKGROUND", "{{ background }}") +hl.env("GUM_INPUT_HEADER_FOREGROUND", "{{ foreground }}") +hl.env("GUM_INPUT_HEADER_BACKGROUND", "{{ background }}") -- Gum Choose Style Variables -hl.env("GUM_CHOOSE_CURSOR_FOREGROUND", "#{{ accent }}") -hl.env("GUM_CHOOSE_CURSOR_BACKGROUND", "#{{ background }}") -hl.env("GUM_CHOOSE_HEADER_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_CHOOSE_HEADER_BACKGROUND", "#{{ background }}") -hl.env("GUM_CHOOSE_ITEM_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_CHOOSE_ITEM_BACKGROUND", "#{{ background }}") -hl.env("GUM_CHOOSE_SELECTED_FOREGROUND", "#{{ selection_foreground }}") -hl.env("GUM_CHOOSE_SELECTED_BACKGROUND", "#{{ selection_background }}") +hl.env("GUM_CHOOSE_CURSOR_FOREGROUND", "{{ accent }}") +hl.env("GUM_CHOOSE_CURSOR_BACKGROUND", "{{ background }}") +hl.env("GUM_CHOOSE_HEADER_FOREGROUND", "{{ foreground }}") +hl.env("GUM_CHOOSE_HEADER_BACKGROUND", "{{ background }}") +hl.env("GUM_CHOOSE_ITEM_FOREGROUND", "{{ foreground }}") +hl.env("GUM_CHOOSE_ITEM_BACKGROUND", "{{ background }}") +hl.env("GUM_CHOOSE_SELECTED_FOREGROUND", "{{ selection_foreground }}") +hl.env("GUM_CHOOSE_SELECTED_BACKGROUND", "{{ selection_background }}") -- Gum Filter Style Variables -hl.env("GUM_FILTER_PROMPT_FOREGROUND", "#{{ accent }}") -hl.env("GUM_FILTER_PROMPT_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILTER_TEXT_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_FILTER_TEXT_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILTER_MATCH_FOREGROUND", "#{{ accent }}") -hl.env("GUM_FILTER_CURSOR_TEXT_FOREGROUND", "#{{ cursor }}") -hl.env("GUM_FILTER_CURSOR_TEXT_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILTER_SELECTED_FOREGROUND", "#{{ selection_foreground }}") -hl.env("GUM_FILTER_SELECTED_BACKGROUND", "#{{ selection_background }}") -hl.env("GUM_FILTER_INDICATOR_FOREGROUND", "#{{ accent }}") -hl.env("GUM_FILTER_HEADER_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_FILTER_MATCH_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILTER_HEADER_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILTER_PLACEHOLDER_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_FILTER_PLACEHOLDER_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILTER_INDICATOR_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILTER_SELECTED_PREFIX_FOREGROUND", "#{{ selection_foreground }}") -hl.env("GUM_FILTER_SELECTED_PREFIX_BACKGROUND", "#{{ selection_background }}") -hl.env("GUM_FILTER_UNSELECTED_PREFIX_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_FILTER_UNSELECTED_PREFIX_BACKGROUND", "#{{ background }}") +hl.env("GUM_FILTER_PROMPT_FOREGROUND", "{{ accent }}") +hl.env("GUM_FILTER_PROMPT_BACKGROUND", "{{ background }}") +hl.env("GUM_FILTER_TEXT_FOREGROUND", "{{ foreground }}") +hl.env("GUM_FILTER_TEXT_BACKGROUND", "{{ background }}") +hl.env("GUM_FILTER_MATCH_FOREGROUND", "{{ accent }}") +hl.env("GUM_FILTER_CURSOR_TEXT_FOREGROUND", "{{ cursor }}") +hl.env("GUM_FILTER_CURSOR_TEXT_BACKGROUND", "{{ background }}") +hl.env("GUM_FILTER_SELECTED_FOREGROUND", "{{ selection_foreground }}") +hl.env("GUM_FILTER_SELECTED_BACKGROUND", "{{ selection_background }}") +hl.env("GUM_FILTER_INDICATOR_FOREGROUND", "{{ accent }}") +hl.env("GUM_FILTER_HEADER_FOREGROUND", "{{ foreground }}") +hl.env("GUM_FILTER_MATCH_BACKGROUND", "{{ background }}") +hl.env("GUM_FILTER_HEADER_BACKGROUND", "{{ background }}") +hl.env("GUM_FILTER_PLACEHOLDER_FOREGROUND", "{{ color8 }}") +hl.env("GUM_FILTER_PLACEHOLDER_BACKGROUND", "{{ background }}") +hl.env("GUM_FILTER_INDICATOR_BACKGROUND", "{{ background }}") +hl.env("GUM_FILTER_SELECTED_PREFIX_FOREGROUND", "{{ selection_foreground }}") +hl.env("GUM_FILTER_SELECTED_PREFIX_BACKGROUND", "{{ selection_background }}") +hl.env("GUM_FILTER_UNSELECTED_PREFIX_FOREGROUND", "{{ color8 }}") +hl.env("GUM_FILTER_UNSELECTED_PREFIX_BACKGROUND", "{{ background }}") -- Gum Table Style Variables -hl.env("GUM_TABLE_HEADER_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_TABLE_HEADER_BACKGROUND", "#{{ background }}") -hl.env("GUM_TABLE_CELL_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_TABLE_CELL_BACKGROUND", "#{{ background }}") -hl.env("GUM_TABLE_BORDER_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_TABLE_BORDER_BACKGROUND", "#{{ background }}") -hl.env("GUM_TABLE_SELECTED_FOREGROUND", "#{{ selection_foreground }}") -hl.env("GUM_TABLE_SELECTED_BACKGROUND", "#{{ selection_background }}") +hl.env("GUM_TABLE_HEADER_FOREGROUND", "{{ foreground }}") +hl.env("GUM_TABLE_HEADER_BACKGROUND", "{{ background }}") +hl.env("GUM_TABLE_CELL_FOREGROUND", "{{ foreground }}") +hl.env("GUM_TABLE_CELL_BACKGROUND", "{{ background }}") +hl.env("GUM_TABLE_BORDER_FOREGROUND", "{{ color8 }}") +hl.env("GUM_TABLE_BORDER_BACKGROUND", "{{ background }}") +hl.env("GUM_TABLE_SELECTED_FOREGROUND", "{{ selection_foreground }}") +hl.env("GUM_TABLE_SELECTED_BACKGROUND", "{{ selection_background }}") -- Gum Spin Style Variables -hl.env("GUM_SPIN_SPINNER_FOREGROUND", "#{{ accent }}") -hl.env("GUM_SPIN_SPINNER_BACKGROUND", "#{{ background }}") -hl.env("GUM_SPIN_TITLE_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_SPIN_TITLE_BACKGROUND", "#{{ background }}") +hl.env("GUM_SPIN_SPINNER_FOREGROUND", "{{ accent }}") +hl.env("GUM_SPIN_SPINNER_BACKGROUND", "{{ background }}") +hl.env("GUM_SPIN_TITLE_FOREGROUND", "{{ foreground }}") +hl.env("GUM_SPIN_TITLE_BACKGROUND", "{{ background }}") -- Gum File Style Variables -hl.env("GUM_FILE_CURSOR_FOREGROUND", "#{{ cursor }}") -hl.env("GUM_FILE_CURSOR_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILE_SYMLINK_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_FILE_SYMLINK_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILE_DIRECTORY_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_FILE_DIRECTORY_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILE_FILE_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_FILE_FILE_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILE_PERMISSIONS_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_FILE_PERMISSIONS_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILE_SELECTED_FOREGROUND", "#{{ selection_foreground }}") -hl.env("GUM_FILE_SELECTED_BACKGROUND", "#{{ selection_background }}") -hl.env("GUM_FILE_FILE_SIZE_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_FILE_FILE_SIZE_BACKGROUND", "#{{ background }}") -hl.env("GUM_FILE_HEADER_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_FILE_HEADER_BACKGROUND", "#{{ background }}") +hl.env("GUM_FILE_CURSOR_FOREGROUND", "{{ cursor }}") +hl.env("GUM_FILE_CURSOR_BACKGROUND", "{{ background }}") +hl.env("GUM_FILE_SYMLINK_FOREGROUND", "{{ foreground }}") +hl.env("GUM_FILE_SYMLINK_BACKGROUND", "{{ background }}") +hl.env("GUM_FILE_DIRECTORY_FOREGROUND", "{{ foreground }}") +hl.env("GUM_FILE_DIRECTORY_BACKGROUND", "{{ background }}") +hl.env("GUM_FILE_FILE_FOREGROUND", "{{ foreground }}") +hl.env("GUM_FILE_FILE_BACKGROUND", "{{ background }}") +hl.env("GUM_FILE_PERMISSIONS_FOREGROUND", "{{ color8 }}") +hl.env("GUM_FILE_PERMISSIONS_BACKGROUND", "{{ background }}") +hl.env("GUM_FILE_SELECTED_FOREGROUND", "{{ selection_foreground }}") +hl.env("GUM_FILE_SELECTED_BACKGROUND", "{{ selection_background }}") +hl.env("GUM_FILE_FILE_SIZE_FOREGROUND", "{{ color8 }}") +hl.env("GUM_FILE_FILE_SIZE_BACKGROUND", "{{ background }}") +hl.env("GUM_FILE_HEADER_FOREGROUND", "{{ foreground }}") +hl.env("GUM_FILE_HEADER_BACKGROUND", "{{ background }}") -- Gum Pager Style Variables -hl.env("GUM_PAGER_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_PAGER_BACKGROUND", "#{{ background }}") -hl.env("GUM_PAGER_LINE_NUMBER_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_PAGER_LINE_NUMBER_BACKGROUND", "#{{ background }}") -hl.env("GUM_PAGER_MATCH_FOREGROUND", "#{{ accent }}") -hl.env("GUM_PAGER_MATCH_BACKGROUND", "#{{ background }}") -hl.env("GUM_PAGER_MATCH_HIGH_FOREGROUND", "#{{ accent }}") -hl.env("GUM_PAGER_MATCH_HIGH_BACKGROUND", "#{{ background }}") -hl.env("GUM_PAGER_HELP_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_PAGER_HELP_BACKGROUND", "#{{ background }}") +hl.env("GUM_PAGER_FOREGROUND", "{{ foreground }}") +hl.env("GUM_PAGER_BACKGROUND", "{{ background }}") +hl.env("GUM_PAGER_LINE_NUMBER_FOREGROUND", "{{ color8 }}") +hl.env("GUM_PAGER_LINE_NUMBER_BACKGROUND", "{{ background }}") +hl.env("GUM_PAGER_MATCH_FOREGROUND", "{{ accent }}") +hl.env("GUM_PAGER_MATCH_BACKGROUND", "{{ background }}") +hl.env("GUM_PAGER_MATCH_HIGH_FOREGROUND", "{{ accent }}") +hl.env("GUM_PAGER_MATCH_HIGH_BACKGROUND", "{{ background }}") +hl.env("GUM_PAGER_HELP_FOREGROUND", "{{ color8 }}") +hl.env("GUM_PAGER_HELP_BACKGROUND", "{{ background }}") -- Gum Write Style Variables -hl.env("GUM_WRITE_BASE_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_WRITE_BASE_BACKGROUND", "#{{ background }}") -hl.env("GUM_WRITE_CURSOR_LINE_NUMBER_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_WRITE_CURSOR_LINE_NUMBER_BACKGROUND", "#{{ background }}") -hl.env("GUM_WRITE_CURSOR_LINE_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_WRITE_CURSOR_LINE_BACKGROUND", "#{{ selection_background }}") -hl.env("GUM_WRITE_CURSOR_FOREGROUND", "#{{ cursor }}") -hl.env("GUM_WRITE_CURSOR_BACKGROUND", "#{{ background }}") -hl.env("GUM_WRITE_END_OF_BUFFER_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_WRITE_END_OF_BUFFER_BACKGROUND", "#{{ background }}") -hl.env("GUM_WRITE_LINE_NUMBER_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_WRITE_LINE_NUMBER_BACKGROUND", "#{{ background }}") -hl.env("GUM_WRITE_HEADER_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_WRITE_HEADER_BACKGROUND", "#{{ background }}") -hl.env("GUM_WRITE_PLACEHOLDER_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_WRITE_PLACEHOLDER_BACKGROUND", "#{{ background }}") -hl.env("GUM_WRITE_PROMPT_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_WRITE_PROMPT_BACKGROUND", "#{{ background }}") +hl.env("GUM_WRITE_BASE_FOREGROUND", "{{ foreground }}") +hl.env("GUM_WRITE_BASE_BACKGROUND", "{{ background }}") +hl.env("GUM_WRITE_CURSOR_LINE_NUMBER_FOREGROUND", "{{ color8 }}") +hl.env("GUM_WRITE_CURSOR_LINE_NUMBER_BACKGROUND", "{{ background }}") +hl.env("GUM_WRITE_CURSOR_LINE_FOREGROUND", "{{ foreground }}") +hl.env("GUM_WRITE_CURSOR_LINE_BACKGROUND", "{{ selection_background }}") +hl.env("GUM_WRITE_CURSOR_FOREGROUND", "{{ cursor }}") +hl.env("GUM_WRITE_CURSOR_BACKGROUND", "{{ background }}") +hl.env("GUM_WRITE_END_OF_BUFFER_FOREGROUND", "{{ color8 }}") +hl.env("GUM_WRITE_END_OF_BUFFER_BACKGROUND", "{{ background }}") +hl.env("GUM_WRITE_LINE_NUMBER_FOREGROUND", "{{ color8 }}") +hl.env("GUM_WRITE_LINE_NUMBER_BACKGROUND", "{{ background }}") +hl.env("GUM_WRITE_HEADER_FOREGROUND", "{{ foreground }}") +hl.env("GUM_WRITE_HEADER_BACKGROUND", "{{ background }}") +hl.env("GUM_WRITE_PLACEHOLDER_FOREGROUND", "{{ color8 }}") +hl.env("GUM_WRITE_PLACEHOLDER_BACKGROUND", "{{ background }}") +hl.env("GUM_WRITE_PROMPT_FOREGROUND", "{{ foreground }}") +hl.env("GUM_WRITE_PROMPT_BACKGROUND", "{{ background }}") -- Gum Log Style Variables -hl.env("GUM_LOG_LEVEL_FOREGROUND", "#{{ accent }}") -hl.env("GUM_LOG_LEVEL_BACKGROUND", "#{{ background }}") -hl.env("GUM_LOG_TIME_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_LOG_TIME_BACKGROUND", "#{{ background }}") -hl.env("GUM_LOG_PREFIX_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_LOG_PREFIX_BACKGROUND", "#{{ background }}") -hl.env("GUM_LOG_MESSAGE_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_LOG_MESSAGE_BACKGROUND", "#{{ background }}") -hl.env("GUM_LOG_KEY_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_LOG_KEY_BACKGROUND", "#{{ background }}") -hl.env("GUM_LOG_VALUE_FOREGROUND", "#{{ foreground }}") -hl.env("GUM_LOG_VALUE_BACKGROUND", "#{{ background }}") -hl.env("GUM_LOG_SEPARATOR_FOREGROUND", "#{{ color8 }}") -hl.env("GUM_LOG_SEPARATOR_BACKGROUND", "#{{ background }}") +hl.env("GUM_LOG_LEVEL_FOREGROUND", "{{ accent }}") +hl.env("GUM_LOG_LEVEL_BACKGROUND", "{{ background }}") +hl.env("GUM_LOG_TIME_FOREGROUND", "{{ color8 }}") +hl.env("GUM_LOG_TIME_BACKGROUND", "{{ background }}") +hl.env("GUM_LOG_PREFIX_FOREGROUND", "{{ foreground }}") +hl.env("GUM_LOG_PREFIX_BACKGROUND", "{{ background }}") +hl.env("GUM_LOG_MESSAGE_FOREGROUND", "{{ foreground }}") +hl.env("GUM_LOG_MESSAGE_BACKGROUND", "{{ background }}") +hl.env("GUM_LOG_KEY_FOREGROUND", "{{ foreground }}") +hl.env("GUM_LOG_KEY_BACKGROUND", "{{ background }}") +hl.env("GUM_LOG_VALUE_FOREGROUND", "{{ foreground }}") +hl.env("GUM_LOG_VALUE_BACKGROUND", "{{ background }}") +hl.env("GUM_LOG_SEPARATOR_FOREGROUND", "{{ color8 }}") +hl.env("GUM_LOG_SEPARATOR_BACKGROUND", "{{ background }}") diff --git a/install/omarchy-base.packages b/install/omarchy-base.packages index 34dd56ff..79b875dc 100644 --- a/install/omarchy-base.packages +++ b/install/omarchy-base.packages @@ -4,7 +4,6 @@ 1password-beta 1password-cli aether -alacritty alsa-utils asdcontrol avahi @@ -39,6 +38,7 @@ fcitx5-qt fd ffmpegthumbnailer fontconfig +foot fzf github-cli gnome-calculator diff --git a/migrations/1755340533.sh b/migrations/1755340533.sh deleted file mode 100644 index b94ec59c..00000000 --- a/migrations/1755340533.sh +++ /dev/null @@ -1,5 +0,0 @@ -echo "Add .config/brave-flags.conf by default to ensure Brave runs under Wayland" - -if [[ ! -f ~/.config/brave-flags.conf ]]; then - cp $OMARCHY_PATH/config/brave-flags.conf ~/.config/ -fi diff --git a/migrations/1756153445.sh b/migrations/1756153445.sh deleted file mode 100644 index 63441e2f..00000000 --- a/migrations/1756153445.sh +++ /dev/null @@ -1,10 +0,0 @@ -echo "Checking and correcting Snapper configs if needed" -if command -v snapper &>/dev/null; then - if ! sudo snapper list-configs 2>/dev/null | grep -q "root"; then - sudo snapper -c root create-config / - fi - - if ! sudo snapper list-configs 2>/dev/null | grep -q "home"; then - sudo snapper -c home create-config /home - fi -fi diff --git a/migrations/1757515650.sh b/migrations/1757515650.sh deleted file mode 100644 index 0087257a..00000000 --- a/migrations/1757515650.sh +++ /dev/null @@ -1,2 +0,0 @@ -echo "Update plymouth theme to avoid freetype2 issue that broke the styled login screen" -omarchy-refresh-plymouth diff --git a/migrations/1757861484.sh b/migrations/1757861484.sh deleted file mode 100644 index fa4cec99..00000000 --- a/migrations/1757861484.sh +++ /dev/null @@ -1,3 +0,0 @@ -echo "Add a blurred background to the lock screen" - -omarchy-refresh-hyprlock diff --git a/migrations/1758564460.sh b/migrations/1758564460.sh deleted file mode 100644 index f0b10693..00000000 --- a/migrations/1758564460.sh +++ /dev/null @@ -1,2 +0,0 @@ -echo "Enable fast shutdown" -source $OMARCHY_PATH/install/config/fast-shutdown.sh diff --git a/migrations/1761569743.sh b/migrations/1761569743.sh deleted file mode 100644 index 976df478..00000000 --- a/migrations/1761569743.sh +++ /dev/null @@ -1,9 +0,0 @@ -echo "Add default Ctrl+P binding for imv; backup existing config if present" - -if [[ -f ~/.config/imv/config ]]; then - cp ~/.config/imv/config ~/.config/imv/config.bak.$(date +%s) -else - mkdir -p ~/.config/imv -fi - -cp ~/.local/share/omarchy/config/imv/config ~/.config/imv/config diff --git a/migrations/1761897226.sh b/migrations/1761897226.sh index 34dbc1fd..e72f2a8a 100644 --- a/migrations/1761897226.sh +++ b/migrations/1761897226.sh @@ -1,3 +1,4 @@ echo "Install Copy URL extension for Brave" -omarchy-refresh-config brave-flags.conf +mkdir -p ~/.config +cp "$OMARCHY_PATH/config/chromium-flags.conf" ~/.config/brave-flags.conf diff --git a/migrations/1762352101.sh b/migrations/1762352101.sh deleted file mode 100644 index 9b69745a..00000000 --- a/migrations/1762352101.sh +++ /dev/null @@ -1,5 +0,0 @@ -echo "Increase Walker limit on how many entries can be shown to 256" - -if ! grep -q "max_results" ~/.config/walker/config.toml; then - sed -i '/^\[providers\]$/a max_results = 256' ~/.config/walker/config.toml -fi diff --git a/migrations/1762802472.sh b/migrations/1762802472.sh deleted file mode 100644 index 95856362..00000000 --- a/migrations/1762802472.sh +++ /dev/null @@ -1,4 +0,0 @@ -echo "Update imv config with new keybindings" - -mkdir -p ~/.config/imv -cp $OMARCHY_PATH/config/imv/config ~/.config/imv/ diff --git a/migrations/1763393133.sh b/migrations/1763393133.sh deleted file mode 100644 index f84cf74d..00000000 --- a/migrations/1763393133.sh +++ /dev/null @@ -1,6 +0,0 @@ -echo "Link new theme picker config" - -mkdir -p ~/.config/elephant/menus -ln -snf $OMARCHY_PATH/default/elephant/omarchy_themes.lua ~/.config/elephant/menus/omarchy_themes.lua -sed -i '/"menus",/d' ~/.config/walker/config.toml -omarchy-restart-walker diff --git a/migrations/1763743755.sh b/migrations/1763743755.sh deleted file mode 100644 index db73b86e..00000000 --- a/migrations/1763743755.sh +++ /dev/null @@ -1,3 +0,0 @@ -echo "Refresh Walker config to ensure compatibility with latest version" - -omarchy-refresh-walker diff --git a/migrations/1765739892.sh b/migrations/1765739892.sh deleted file mode 100644 index 845270b3..00000000 --- a/migrations/1765739892.sh +++ /dev/null @@ -1,7 +0,0 @@ -if omarchy-cmd-present btrfs && omarchy-cmd-present snapper; then - echo "Adjust snapper space limits & enable btrfs quota" - - sudo sed -i 's/^SPACE_LIMIT="0.5"/SPACE_LIMIT="0.3"/' /etc/snapper/configs/{root,home} 2>/dev/null - sudo sed -i 's/^FREE_LIMIT="0.2"/FREE_LIMIT="0.3"/' /etc/snapper/configs/{root,home} 2>/dev/null - sudo btrfs quota enable / -fi diff --git a/migrations/1767414310.sh b/migrations/1767414310.sh deleted file mode 100644 index a0f3fbe2..00000000 --- a/migrations/1767414310.sh +++ /dev/null @@ -1,3 +0,0 @@ -echo "Use correct idle-timer sensitive timeouts for lock screen" - -sed -i 's/timeout = 300/timeout = 151/' ~/.config/hypr/hypridle.conf diff --git a/migrations/1767478141.sh b/migrations/1767478141.sh deleted file mode 100644 index 96d25cf8..00000000 --- a/migrations/1767478141.sh +++ /dev/null @@ -1,3 +0,0 @@ -echo "Add Omarchy AI skill for assistance tailoring the system" - -source $OMARCHY_PATH/install/config/omarchy-ai-skill.sh diff --git a/migrations/1769566732.sh b/migrations/1769566732.sh deleted file mode 100644 index f2df93c0..00000000 --- a/migrations/1769566732.sh +++ /dev/null @@ -1,3 +0,0 @@ -echo "Set power profile based on source switching (AC or Battery)" - -source $OMARCHY_PATH/install/config/powerprofilesctl-rules.sh diff --git a/migrations/1770811646.sh b/migrations/1770811646.sh deleted file mode 100644 index efb50931..00000000 --- a/migrations/1770811646.sh +++ /dev/null @@ -1,3 +0,0 @@ -echo "Disable WiFi power save on AC power" - -source $OMARCHY_PATH/install/config/wifi-powersave-rules.sh diff --git a/migrations/1771618300.sh b/migrations/1771618300.sh deleted file mode 100644 index 28794966..00000000 --- a/migrations/1771618300.sh +++ /dev/null @@ -1,2 +0,0 @@ -echo "Turn off keyboard backlight when idle" -cp $OMARCHY_PATH/config/hypr/hypridle.conf ~/.config/hypr/hypridle.conf diff --git a/migrations/1773017819.sh b/migrations/1773017819.sh deleted file mode 100644 index b4a1d36e..00000000 --- a/migrations/1773017819.sh +++ /dev/null @@ -1,3 +0,0 @@ -echo "Add LocalSend entry to Nautilus context menu" - -source $OMARCHY_PATH/install/config/nautilus-python.sh diff --git a/migrations/1775946416.sh b/migrations/1775946416.sh deleted file mode 100644 index 8e537976..00000000 --- a/migrations/1775946416.sh +++ /dev/null @@ -1,9 +0,0 @@ -echo "Set Chromium appearance mode to device (follow system) by default" - -echo '{"browser":{"theme":{"color_scheme":0}}}' | sudo tee /usr/lib/chromium/initial_preferences >/dev/null - -# Update existing Chromium profiles to use "device" instead of "dark" -PREFS="$HOME/.config/chromium/Default/Preferences" -if [[ -f "$PREFS" ]] && command -v jq &>/dev/null; then - jq '.browser.theme.color_scheme = 0' "$PREFS" > "$PREFS.tmp" && mv "$PREFS.tmp" "$PREFS" -fi diff --git a/migrations/1777467659.sh b/migrations/1777467659.sh deleted file mode 100644 index 994c30bf..00000000 --- a/migrations/1777467659.sh +++ /dev/null @@ -1,6 +0,0 @@ -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/1778516505.sh b/migrations/1778516505.sh index 6f8acf62..b0c94023 100644 --- a/migrations/1778516505.sh +++ b/migrations/1778516505.sh @@ -1,3 +1,3 @@ -echo "Install npm package wrappers" +echo "Install npm package wrappers using pnpm with 5-day security lag" source "$OMARCHY_PATH/install/packaging/npm.sh" diff --git a/migrations/1778752973.sh b/migrations/1778752973.sh new file mode 100644 index 00000000..ed1facc8 --- /dev/null +++ b/migrations/1778752973.sh @@ -0,0 +1,26 @@ +echo "Add Alt+Enter split and Alt+Escape close keybindings to tmux" + +tmux_config="$HOME/.config/tmux/tmux.conf" + +if [[ -f $tmux_config ]]; then + changed=0 + + if ! grep -qxF 'bind -n M-Enter split-window -v -c "#{pane_current_path}"' "$tmux_config"; then + printf '\nbind -n M-Enter split-window -v -c "#{pane_current_path}"\n' >>"$tmux_config" + changed=1 + fi + + if ! grep -qxF 'bind -n M-S-Enter split-window -h -c "#{pane_current_path}"' "$tmux_config"; then + printf 'bind -n M-S-Enter split-window -h -c "#{pane_current_path}"\n' >>"$tmux_config" + changed=1 + fi + + if ! grep -qxF 'bind -n M-Escape kill-pane' "$tmux_config"; then + printf 'bind -n M-Escape kill-pane\n' >>"$tmux_config" + changed=1 + fi + + if (( changed )); then + omarchy-restart-tmux + fi +fi diff --git a/migrations/1778847256.sh b/migrations/1778847256.sh new file mode 100644 index 00000000..8f4a8b15 --- /dev/null +++ b/migrations/1778847256.sh @@ -0,0 +1,3 @@ +echo "Refresh theme files to pick up Hyprland changes" + +omarchy-theme-refresh diff --git a/migrations/1778847558.sh b/migrations/1778847558.sh new file mode 100644 index 00000000..9494ba7e --- /dev/null +++ b/migrations/1778847558.sh @@ -0,0 +1,3 @@ +echo "Refresh Hyprland Lua language server config" + +omarchy-refresh-config hypr/.luarc.json diff --git a/migrations/1778851263.sh b/migrations/1778851263.sh new file mode 100644 index 00000000..3b3a4fe7 --- /dev/null +++ b/migrations/1778851263.sh @@ -0,0 +1,11 @@ +echo "Set BROWSER to Omarchy browser launcher for detached terminal URL opens" + +if [[ -f ~/.config/uwsm/default ]]; then + if grep -q '^export BROWSER=' ~/.config/uwsm/default; then + sed -i 's|^export BROWSER=.*|export BROWSER=omarchy-launch-browser|' ~/.config/uwsm/default + else + printf '\n# Used by terminal programs (like gh) to open URLs detached from the terminal process tree\nexport BROWSER=omarchy-launch-browser\n' >> ~/.config/uwsm/default + fi +else + omarchy-refresh-config uwsm/default +fi diff --git a/themes/kanagawa/hyprland.lua b/themes/kanagawa/hyprland.lua index b03145b6..5b619e0c 100644 --- a/themes/kanagawa/hyprland.lua +++ b/themes/kanagawa/hyprland.lua @@ -15,4 +15,4 @@ hl.config({ }) -- Kanagawa backdrop is too strong for default opacity. -hl.window_rule({ match = { tag = "terminal" }, opacity = "0.98 0.95" }) +o.window({ tag = "terminal" }, { opacity = "0.98 0.95" }) diff --git a/version b/version index 19811903..8ec49576 100644 --- a/version +++ b/version @@ -1 +1 @@ -3.8.0 +4.0.0.alpha