feat: Renames launch-or to just launch, generalizes it to also handle special workspaces, integrates launch-webapp script to use it, and updates keybinds that reference the script.

This commit is contained in:
2025-10-03 20:06:47 -04:00
parent cedb6d8ab7
commit 4d4b8c9945
4 changed files with 160 additions and 148 deletions

View File

@@ -35,16 +35,16 @@ bindd = $mainMod, SPACE, Application launcher, exec,
bindd = $mainMod, RETURN, New terminal, exec, $terminal
bindd = $mainMod SHIFT, RETURN, New floating terminal, exec, $terminal --class=com.ghostty.float
bindd = $mainMod, TAB, Focus previous workspace, workspace, previous
bindd = $mainMod, A, [A]i - launch / focus, exec, $pwa --focus "https://chatgpt.com"
bindd = $mainMod, A, [A]i - launch / focus, exec, $pwa --or-focus "https://chatgpt.com"
bindd = $mainMod SHIFT, A, [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]alendar, exec, $pwa --focus "https://www.icloud.com/calendar"
bindd = $mainMod, C, [C]alendar, exec, $pwa --or-focus "https://www.icloud.com/calendar"
bindd = $mainMod SHIFT, 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, $scripts/launch-or --focus thunderbird uwsm app -- thunderbird
bindd = $mainMod, E, [E]mail - personal, exec, $pwa --or-focus "https://mail.proton.me"
bindd = $mainMod SHIFT, E, [E]mail - work, exec, $scripts/launch --or-focus thunderbird 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"
@@ -61,10 +61,10 @@ bindd = $mainMod, P, [P]assword manager, exec,
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 --focus "https://youtube.com"
bindd = $mainMod, Y, [Y]ouTube, exec, $pwa --or-focus "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, $scripts/launch-or --close $clipboardHistory
bindd = $mainMod, V, Clipboard history, exec, $scripts/launch --or-close $clipboardHistory
bindd = $mainMod, W, Close current window, killactive,
bindd = $mainMod SHIFT, W, Close all windows in active workspace, exec, $scripts/close-windows --active-workspace

125
env/.local/scripts/launch vendored Executable file
View File

@@ -0,0 +1,125 @@
#!/usr/bin/env bash
usage() {
cat <<EOF
Launch or focus / close a window based on pattern contained within the window
class name. (Default is to focus the window).
This is used in keybinds and by other scripts as a general entrypoint for managing applications.
USAGE:
$ $(basename ${BASH_SOURCE[0]}) [OPTIONS] PATTERN [LAUNCH_CMD...]
OPTIONS:
-f | --or-focus: Focus the window matching the pattern, if it exists.
-c | --or-close: Close the window matching the pattern, if it exists.
-s | --special <name>: Launch or toggle a special workspace.
-h | --help: Show this help page.
NOTES:
Passing both a '--close' and '--focus' flag will result in an error if a window is found matching
the pattern.
If the special option is passed then we will not attempt to close a window. If the script is
invoked with the special option set, we check if there is a window matching the pattern, if there
is and the currently active window is on the same workspace passed in to the special option, then
we toggle the workspace closed. This allows the same keybind to be used to launch an application
in a special workspace as well as toggle the workspace closed.
EOF
}
action="focuswindow"
close_flag="0"
focus_flag="0"
launch_cmd=()
pattern=""
special_flag="0"
special=""
while [[ $# -gt 0 ]]; do
if [[ $1 == "-c" ]] || [[ $1 == "--or-close" ]]; then
close_flag="1"
action="closewindow"
elif [[ $1 == "-f" ]] || [[ $1 == "--or-focus" ]]; then
focus_flag="1"
action="focuswindow"
elif [[ $1 == "-s" ]] || [[ $1 == "--special" ]]; then
shift
special_flag="1"
special=$1
elif [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then
usage && exit 0
elif [[ -z $pattern ]]; then
pattern=$1
else
launch_cmd+=("$1")
fi
shift
done
toggle_special() {
if [[ -z $special ]]; then
echo "[ERROR]: No name supplied for special workspace."
exit 1
fi
hyprctl dispatch togglespecialworkspace $special
}
################################################################################
# MAIN
################################################################################
if [[ -z $pattern ]]; then
echo "[ERROR]: Must supply a pattern to match the window class."
usage && exit 1
elif [[ -z $launch_cmd ]]; then
echo "[ERROR]: Must supply a launch command to match the window class."
usage && exit 1
fi
# Get first window matching the pattern.
address=$(hyprctl clients -j | jq -r ".[] | select(.class | contains(\"$pattern\")) | .address")
echo "Pattern: $pattern"
echo "Address: $address"
# Check if we found a window address.
if [[ -n $address ]]; then
# Get the workspace name of the active window.
active_window_workspace=$(hyprctl activewindow -j | jq -r '.workspace.name')
echo "Active window workspace: $active_window_workspace"
# Check if we have special flag and active window is on the special workspace. If so
# we just toggle the special workspace. This keeps "special" apps alive, but closes and / opens
# the special workspace when invoked.
if [[ $special_flag == "1" ]] && [[ $active_window_workspace =~ $special ]]; then
toggle_special && exit 0
fi
# Check if both close and focus flags were passed, so we don't do the
# wrong thing.
if [[ $focus_flag == "1" ]] && [[ $close_flag == "1" ]]; then
echo "[ERROR]: Both focus and close flag were passed."
exit 1
fi
# We didn't have the special flag, so dispatch the command (focus or close).
echo "Found window, dispatching action: $action"
hyprctl dispatch $action "address:$address"
else
# We did not find an address matching the pattern.
#
# Toggle a special workspace, if applicable before launching.
if [[ $special_flag == "1" ]]; then
toggle_special
fi
echo "Launching..."
echo "'${launch_cmd[@]}'"
eval exec ${launch_cmd[@]}
fi

View File

@@ -1,61 +0,0 @@
#!/usr/bin/env bash
usage() {
cat <<EOF
Launch or focus / close a window based on pattern contained within the window
class name. (Default is to focus the window).
USAGE:
$ $(basename ${BASH_SOURCE[0]}) [OPTIONS] PATTERN [LAUNCH_CMD...]
OPTIONS:
-f | --focus: Focus the window matching the pattern, if it exists.
-c | --close: Close the window matching the pattern, if it exists.
-h | --help: Show this help page.
EOF
}
action="focuswindow"
pattern=""
launch_cmd=()
while [[ $# -gt 0 ]]; do
if [[ $1 == "-c" ]] || [[ $1 == "--close" ]]; then
action="closewindow"
elif [[ $1 == "-f" ]] || [[ $1 == "--focus" ]]; then
action="focuswindow"
elif [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then
usage && exit 0
elif [[ -z $pattern ]]; then
pattern=$1
else
launch_cmd+=("$1")
fi
shift
done
if [[ -z $pattern ]]; then
echo "[ERROR]: Must supply a pattern to match the window class."
usage && exit 1
elif [[ -z $launch_cmd ]]; then
echo "[ERROR]: Must supply a launch command to match the window class."
usage && exit 1
fi
address=$(hyprctl clients -j | jq -r ".[] | select(.class | contains(\"$pattern\")) | .address")
echo "Pattern: $pattern"
echo "Address: $address"
if [[ -n $address ]]; then
echo "Found window, dispatching action: $action"
hyprctl dispatch $action "address:$address"
else
echo "Launching..."
echo "'${launch_cmd[@]}'"
eval exec ${launch_cmd[@]}
fi

View File

@@ -5,7 +5,8 @@
usage() {
cat <<EOF
Launches a url as a web application.
Launches a url as a web application. This script relys on the 'launch-or' script. This
essentially just generates the pattern and launch command to pass into that script.
USAGE:
@@ -13,7 +14,7 @@ USAGE:
OPTIONS:
-f | --focus: If a window exists matching the url's domain, focus it
-f | --or-focus: If a window exists matching the url's domain, focus it
instead of launching new window.
-s | --special <name>: Launch in the special workspace name, or toggle the special
workspace.
@@ -21,7 +22,13 @@ OPTIONS:
NOTES:
Any extra arguments after the url get passed directly to the browser invocation.
Any extra arguments after '--' get passed directly to the browser invocation.
$ launch-webapp https://example.com -- --some-random-flag-for-browser=1
Any options passed in prior to the '--' get sent to the 'launch-or' script, so you can pass
options that are not specifically shown here, but the ones shown would be the most commonly
used, so they are documented here.
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.
@@ -33,12 +40,9 @@ EOF
}
browser="chromium.desktop"
special=""
special_flag="0"
focus_flag="0"
help_flag="0"
url=""
args=()
launch_args=()
app_args=""
SCRIPTS="${SCRIPTS}"
if [[ -z $SCRIPTS ]]; then
@@ -49,30 +53,22 @@ fi
while [[ $# -gt 0 ]]; do
if [[ $1 =~ ^--special ]] || [[ $1 =~ ^-s ]]; then
shift
special_flag="1"
special=$1
elif [[ $1 =~ ^--focus ]] || [[ $1 =~ ^-f ]]; then
focus_flag="1"
launch_args+=("$1")
launch_args+=("$2")
shift # Second shift get's handled below
elif [[ $1 =~ ^--help ]] || [[ $1 =~ ^-h ]]; then
help_flag="1"
elif [[ -z $url ]]; then
usage && exit 0
elif [[ -z $url ]] && [[ ! $1 =~ ^- ]]; then
url=$1
elif [[ $1 == "--" ]]; then
shift
break
else
args+=($1)
launch_args+=("$1")
fi
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:\/\//}
@@ -81,68 +77,20 @@ pattern() {
echo $pattern
}
getWindowProp() {
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")
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
log "No window, launching..."
hyprctl dispatch togglespecialworkspace $special
launch $url $args
else
log "We have a window, toggling special workspace"
hyprctl dispatch togglespecialworkspace $special
fi
}
##################################################
# MAIN
##################################################
if [[ -z $url ]]; then
fail "Must supply a url." && usage && exit 1
echo "[ERROR]: Must supply a url." && usage && exit 1
fi
if [[ $special_flag == "1" ]]; then
log "Handling special workspace..."
if [[ -z $special ]]; then
fail "Must supply special workspace name." && exit 1
fi
handleSpecial && exit 0
fi
# Any left over args after "--"
app_args="$@"
window_addr=""
echo "URL: $url"
echo "Launch args: ${launch_args[@]}"
echo "App args: ${app_args}"
if [[ $focus_flag == "1" ]]; then
log "Received focus flag, checking for window address."
window_addr=$(getWindowProp address)
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
launch $url $args
$SCRIPTS/launch "${launch_args[@]}" "$(pattern)" \
setsid uwsm app -- $(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$browser 2>/dev/null | head -1) --app="$url" "$app_args"