From ede7e4288bb0e144009b283103d317d2b430796a Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Wed, 1 Oct 2025 12:03:13 -0400 Subject: [PATCH] feat: Updates launch-webapp script, reformats keybinds, and removes uneeded scripts now that launch-webapp is more robust. --- env/.config/ghostty/config | 1 + env/.config/hypr/keybinds.conf | 84 ++++++++++----------- env/.config/hypr/windows.conf | 5 +- env/.local/scripts/launch-or-focus-webapp | 34 --------- env/.local/scripts/launch-webapp | 91 +++++++++++++++++------ env/.local/scripts/proton-pass-manager | 30 -------- 6 files changed, 112 insertions(+), 133 deletions(-) delete mode 100755 env/.local/scripts/launch-or-focus-webapp delete mode 100755 env/.local/scripts/proton-pass-manager diff --git a/env/.config/ghostty/config b/env/.config/ghostty/config index 6f9751d..681a953 100644 --- a/env/.config/ghostty/config +++ b/env/.config/ghostty/config @@ -24,6 +24,7 @@ quit-after-last-window-closed-delay = 5m # macos-icon = custom-style keybind = ctrl+shift+t=toggle_quick_terminal +keybind = ctrl+l=clear_screen # Splits keybind = super+j=goto_split:down diff --git a/env/.config/hypr/keybinds.conf b/env/.config/hypr/keybinds.conf index eb25284..c27a916 100644 --- a/env/.config/hypr/keybinds.conf +++ b/env/.config/hypr/keybinds.conf @@ -9,60 +9,60 @@ $HYPER = ALT SHIFT SUPER CTRL # See https://wiki.hyprland.org/Configuring/Keywords/ -$terminal = ghostty -$browser = zen-browser +$terminal = uwsm app -- ghostty +$browser = uwsm app -- zen-browser $fileManager = $terminal -e yazi -$fileBrowser = nautilus -$menu = walker +$fileBrowser = uwsm app -- nautilus +$menu = uwsm app -- walker $scripts = ~/.local/scripts $pwa = $scripts/launch-webapp -$launchOrFocusWebapp = $scripts/launch-or-focus-webapp $tmuxSessionator = $scripts/tmux-sessionator -$clipboardHistory = $terminal --class=com.ghostty.float -e $scripts/uninstall-desktop-app +$clipboardHistory = $terminal --class=com.ghostty.clipse -e clipse $uninstallDesktop = $terminal --class=com.ghostty.float -e $scripts/uninstall-desktop-app -$housecallPro = $pwa "https://pro.housecallpro.com/app/calendar_new" +$housecallPro = https://pro.housecallpro.com/app/calendar_new # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more -###################################################### +####################################################################################### # Apps / hyprland controls # # These should in general use the $mainMod prefix -###################################################### -# MOD # KEY # DESC # Action # -###################################################### +####################################################################################### +# MOD # KEY # DESC # Action # +####################################################################################### -bindd = $mainMod, Space, Application launcher, exec, $menu -bindd = $mainMod, Return, New terminal, exec, $terminal -bindd = $mainMod SHIFT, Return, New floating terminal, exec, $terminal --class=com.ghostty.float -bindd = $mainMod, A, Chat-gpt [a]i, exec, $pwa "https://chatgpt.com" --class com.chromium.chatgpt -bindd = $mainMod, B, New [b]rowser, exec, $browser -bindd = $mainMod SHIFT, B, New private [b]rowser, exec, $browser --private-window -bindd = $mainMod, C, [C]onfig folder in tmux session, exec, $terminal -e $tmuxSessionator ~/.config -bindd = $mainMod, D, [D]ispatch app, exec, $housecallPro -bindd = $mainMod SHIFT, D, Show [d]esktop / hide all windows, exec, $scripts/toggle-desktop -bindd = $mainMod, E, [E]mail - personal, exec, $pwa "https://mail.proton.me" -bindd = $mainMod SHIFT, E, [E]mail - work, exec, uwsm app -- thunderbird -bindd = $mainMod, F, [F]ile manager - terminal, exec, $fileManager -bindd = $mainMod SHIFT, F, [F]ile manager - application, exec, $fileBrowser -bindd = $mainMod, G, [G]itea, exec, $pwa "https://git.housh.dev" -bindd = $mainMod, H, Focus window - left, movefocus, l # move window focus using vim keys -bindd = $mainMod SHIFT, H, Workspace - back, workspace, -1 -bindd = $mainMod, J, Focus window - down, movefocus, d # move window focus using vim keys -bindd = $mainMod, K, Focus window - up, movefocus, u # move window focus using vim keys -bindd = $mainMod, L, Focus window - right, movefocus, r # move window focus using vim keys -bindd = $mainMod SHIFT, L, Workspace - forward, workspace, +1 -bindd = $mainMod, M, [M]usic - apple, exec, $pwa "https://music.apple.com" -bindd = $mainMod SHIFT, M, [M]enu bar - toggle visible, exec, ~/.local/scripts/toggle-waybar -bindd = $mainMod, P, [P]assword manager, exec, ~/.local/scripts/proton-pass-manager -bindd = $mainMod SHIFT, P, Toggle [p]seudo window mode, pseudo, # dwindle -bindd = $mainMod SHIFT, R, [R]estart menu bar, exec, ~/.local/scripts/waybar-restart -bindd = $mainMod, S, Toggle [s]pecial workspace, togglespecialworkspace, magic # use $windowMod S to send window to the special workspace -bindd = $mainMod, Y, [Y]ouTube, exec, $pwa "https://youtube.com" -bindd = $mainMod, U, [U]nifi, exec, $pwa "https://unifi.ui.com" -bindd = $mainMod SHIFT, U, [U]ninstall desktop app, exec, $uninstallDesktop -bindd = $mainMod, V, Clipboard history, exec, $clipboardHistory -bindd = $mainMod, W, Close current window, killactive, +bindd = $mainMod, Space, Application launcher, exec, $menu +bindd = $mainMod, Return, New terminal, exec, $terminal +bindd = $mainMod SHIFT, Return, New floating terminal, exec, $terminal --class=com.ghostty.float +bindd = $mainMod, A, Chat-gpt [a]i - launch / focus, exec, $pwa --focus "https://chatgpt.com" +bindd = $mainMod, A, Chat-gpt [a]i - new window, exec, $pwa "https://chatgpt.com" +bindd = $mainMod, B, New [b]rowser, exec, $browser +bindd = $mainMod SHIFT, B, New private [b]rowser, exec, $browser --private-window +bindd = $mainMod, C, [C]onfig folder in tmux session, exec, $terminal -e $tmuxSessionator ~/.config +bindd = $mainMod, D, [D]ispatch app - special workspace, exec, $pwa --special dispatch $housecallPro +bindd = $mainMod SHIFT, D, [D]ispatch app - new window, exec, $pwa $housecallPro +bindd = $mainMod, E, [E]mail - personal, exec, $pwa --focus "https://mail.proton.me" +bindd = $mainMod SHIFT, E, [E]mail - work, exec, uwsm app -- thunderbird +bindd = $mainMod, F, [F]ile manager - terminal, exec, $fileManager +bindd = $mainMod SHIFT, F, [F]ile manager - application, exec, $fileBrowser +bindd = $mainMod, G, [G]itea, exec, $pwa "https://git.housh.dev" +bindd = $mainMod, H, Focus window - left, movefocus, l # move window focus using vim keys +bindd = $mainMod SHIFT, H, Workspace - back, workspace, -1 +bindd = $mainMod, J, Focus window - down, movefocus, d # move window focus using vim keys +bindd = $mainMod, K, Focus window - up, movefocus, u # move window focus using vim keys +bindd = $mainMod, L, Focus window - right, movefocus, r # move window focus using vim keys +bindd = $mainMod SHIFT, L, Workspace - forward, workspace, +1 +bindd = $mainMod, M, [M]usic - apple, exec, $pwa --focus "https://music.apple.com" +bindd = $mainMod SHIFT, M, [M]enu bar - toggle visible, exec, $scripts/toggle-waybar +bindd = $mainMod, P, [P]assword manager, exec, $pwa --special pass "https://pass.proton.me" +bindd = $mainMod SHIFT, P, Toggle [p]seudo window mode, pseudo, # dwindle +bindd = $mainMod SHIFT, R, [R]estart menu bar, exec, $scripts/waybar-restart +bindd = $mainMod, S, Toggle [s]pecial workspace, togglespecialworkspace, magic # use $windowMod S to send window to the special workspace +bindd = $mainMod, Y, [Y]ouTube, exec, $pwa "https://youtube.com" +bindd = $mainMod, U, [U]nifi, exec, $pwa "https://unifi.ui.com" +bindd = $mainMod SHIFT, U, [U]ninstall desktop app, exec, $uninstallDesktop +bindd = $mainMod, V, Clipboard history, exec, $clipboardHistory +bindd = $mainMod, W, Close current window, killactive, # Switch to workspaces with mainMod + [0-9] bindd = $mainMod, 1, Switch to workspace [1], workspace, 1 diff --git a/env/.config/hypr/windows.conf b/env/.config/hypr/windows.conf index 19b62f7..3e51418 100644 --- a/env/.config/hypr/windows.conf +++ b/env/.config/hypr/windows.conf @@ -13,10 +13,6 @@ windowrule = size 800 600, tag:floating-window # Force windows to be a floating window windowrule = tag +floating-window, class:^(blueberry.py|org.gnome.Nautilus|com.ghostty.float)$ -# windowrule = float, class:.*pass.proton.me.* -# windowrule = center, class:.*pass.proton.me.* -# windowrule = size 1200 800, class:.*pass.proton.me.* -# # Force to stay focused when visible. windowrule = stayfocused, class:(blueberry.py) windowrule = stayfocused, class:Pinentry.gtk @@ -40,3 +36,4 @@ windowrule = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned workspace = special:hidden, invisible workspace = special:pass, class:.*pass.proton.me.* +workspace = special:dispatch, class:.*pro.housecallpro.com.* diff --git a/env/.local/scripts/launch-or-focus-webapp b/env/.local/scripts/launch-or-focus-webapp deleted file mode 100755 index 14ba846..0000000 --- a/env/.local/scripts/launch-or-focus-webapp +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -# Launch a web app or focus if it's already open. - -if [[ $# == 0 ]]; then - echo "Usage: launch-or-focus-webapp " - exit 1 -fi - -SCRIPTS="${SCRIPTS}" - -if [[ -z $SCRIPTS ]]; then - echo "scripts directory not set" - echo "using ~/.local/scripts" - SCRIPTS=~/.local/scripts -fi - -url=$1 - -# parse domain pattern from the url -pattern=${url#https:\/\/} # removing leading 'https://' -pattern=${pattern#http:\/\/} # removing leading 'http://' -pattern=${pattern%%/*} # removing everything after '/' that's left (which should leave us with the domain) - -window=$(hyprctl clients -j | jq -r ".[] | select((.class | contains(\"$pattern\"))) | .address") - -echo "Pattern: \"$pattern\"" -echo "Window: \"$window\"" - -if [[ -n $window ]]; then - hyprctl dispatch focuswindow "address:$window" -else - eval exec "$SCRIPTS/launch-webapp $url" -fi diff --git a/env/.local/scripts/launch-webapp b/env/.local/scripts/launch-webapp index 85c0f2f..cb15ce5 100755 --- a/env/.local/scripts/launch-webapp +++ b/env/.local/scripts/launch-webapp @@ -1,17 +1,42 @@ #!/usr/bin/env bash # Adapted from https://github.com/basecamp/omarchy/tree/master?tab=readme-ov-file -# -# Launch a web application, can handle "singleton" applications in special -# workspaces using the '--special ' option, focus an existing window -# matching the url using '--focus' option, or always launch a new instance -# if only the url is passed in. -# + +usage() { + cat < [ARGS...] + +OPTIONS: + + -f | --focus: If a window exists matching the url's domain, focus it + instead of launching new window. + -s | --special : Launch in the special workspace name, or toggle the special + workspace. + -h | --help: Show this help page. + +NOTES: + +Any extra arguments after the url get passed directly to the browser invocation. + +Using the '--special' flag is useful for apps that you want to have a "summoning" like behavior. +Upon first launch the application will be opened and the special workspace will be shown. +Calling it again will keep the application open in the special workspace but hide the workspace. +Further calls will not open another instance of the application, but will toggle the visiblity +of the special workspace. + +EOF +} browser="chromium.desktop" special="" special_flag="0" focus_flag="0" +help_flag="0" url="" args=() SCRIPTS="${SCRIPTS}" @@ -29,6 +54,8 @@ while [[ $# -gt 0 ]]; do special=$1 elif [[ $1 =~ ^--focus ]] || [[ $1 =~ ^-f ]]; then focus_flag="1" + elif [[ $1 =~ ^--help ]] || [[ $1 =~ ^-h ]]; then + help_flag="1" elif [[ -z $url ]]; then url=$1 else @@ -37,65 +64,83 @@ while [[ $# -gt 0 ]]; do shift done +# Early out if help flag was supplied. +if [[ $help_flag == "1" ]]; then + usage && exit 0 +fi + launch() { exec setsid uwsm app -- $(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$browser 2>/dev/null | head -1) --app="$1" "$2" } +# Strips url down to just the domain, so that we can match window classes. pattern() { pattern=${url/#https:\/\//} pattern=${pattern/#http:\/\//} - pattern=${pattern%/*} + pattern=${pattern%%/*} echo $pattern } getWindowProp() { - echo $(hyprctl clients -j | jq -r ".[] | select((.class | contains(\"$(pattern)\"))) | .$1") + echo $(hyprctl clients -j | jq -r ".[] | select((.class | contains(\"$(pattern)\"))) | .$1" | head -n 1) +} + +log() { + echo "[$($SCRIPTS/isosec)] - $1" >>/tmp/launch-webapp.log +} + +fail() { + echo -e "\n\e[31m[Error]: $1\e[0m" + log "[Error]: $1" } handleSpecial() { local window_addr=$(getWindowProp address) local window_workspace=$(getWindowProp workspace.id) + local active_workspace=$(hyprctl activeworkspace -j | jq -r ".id") local special_workspace_id=$(hyprctl workspaces -j | jq -r ".[] | select(.name | contains(\"$special\")) | .id") - echo "Window: address: $window_addr workspace: $window_workspace" - echo "Special workspace: $special_workspace_id" + log "Window: address: $window_addr workspace: $window_workspace" + log "Special workspace: $special id: $special_workspace_id" + log "Active workspace: $active_workspace" # Check if we don't have a window address, or if the window is not on the expected special workspace. if [[ -z $window_addr ]] || ([[ -n $window_workspace ]] && [[ $window_workspace != $special_workspace_id ]]); then - echo "No window, launching..." + log "No window, launching..." hyprctl dispatch togglespecialworkspace $special launch $url $args else - echo "We have a window, toggling special workspace" - hyprctl dispatch togglespecialworkspace pass + log "We have a window, toggling special workspace" + hyprctl dispatch togglespecialworkspace $special fi } +################################################## +# MAIN +################################################## + if [[ -z $url ]]; then - # TODO: Usage message. - echo "Must supply a url." - exit 1 + fail "Must supply a url." && usage && exit 1 fi if [[ $special_flag == "1" ]]; then - echo "Handling special workspace..." + log "Handling special workspace..." if [[ -z $special ]]; then - echo "Must supply special workspace name." - exit 1 + fail "Must supply special workspace name." && exit 1 fi - handleSpecial - exit 0 + handleSpecial && exit 0 fi window_addr="" if [[ $focus_flag == "1" ]]; then - echo "Received focus flag, checking for window address." + log "Received focus flag, checking for window address." window_addr=$(getWindowProp address) - echo "addr: $window_addr" + log "Window address: $window_addr" fi if [[ -n $window_addr ]]; then + log "No window address launching..." hyprctl dispatch focuswindow "address:$window_addr" exit 0 fi diff --git a/env/.local/scripts/proton-pass-manager b/env/.local/scripts/proton-pass-manager deleted file mode 100755 index 17f7001..0000000 --- a/env/.local/scripts/proton-pass-manager +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -# Manages the proton pass web application. If the app is not open then -# it will launch the app (which has a workspace rule that put's it into a -# special workspace). If the app is open then it will toggle the special -# workspace. This allows the application to not close and be able to hide -# and show it quickly using the same keybind that would launch it. - -SCRIPTS="${SCRIPTS}" - -if [[ -z $SCRIPTS ]]; then - echo "scripts directory not set" - echo "using ~/.local/scripts" - SCRIPTS=~/.local/scripts -fi - -pattern="pass.proton.me" -url="https://$pattern" - -# Get the window address if it exists. -window_addr=$(hyprctl clients -j | jq -r ".[] | select((.class | contains(\"$pattern\"))) | .address") - -if [[ -z $window_addr ]]; then - echo "No window, launching..." - hyprctl dispatch togglespecialworkspace pass - eval exec $SCRIPTS/launch-webapp $url -else - echo "We have a window, toggling special workspace" - hyprctl dispatch togglespecialworkspace pass -fi