7 Commits

11 changed files with 493 additions and 365 deletions

View File

@@ -1,7 +1,14 @@
#!/usr/bin/env bash
set -e
set -o nounset
set -o pipefail
SCRIPTS=${SCRIPTS:-$HOME/.local/scripts}
THIS_FILE=${BASH_SOURCE[0]}
LOG_LABEL=$(basename "$THIS_FILE")
THIS=$(basename "$THIS_FILE")
LOG_FILE=${LOG_FILE:-"/tmp/$LOG_LABEL.log"}
usage() {
cat <<EOF
@@ -52,7 +59,6 @@ launch_cmd=()
pattern=""
special_flag="0"
special=""
SCRIPTS=${SCRIPTS:-$HOME/.local/scripts}
while [[ $# -gt 0 ]]; do
if [[ $1 == "-c" ]] || [[ $1 == "--or-close" ]]; then
@@ -114,7 +120,7 @@ launch_application() {
# Setup logging file and label
source "$SCRIPTS/hypr/logging"
setup-logging "/tmp/$THIS.log" "$THIS"
setup-logging "$LOG_FILE" "$LOG_LABEL"
if [[ -z $pattern ]]; then
log --error "Must supply a pattern to match the window class."

View File

@@ -1,8 +1,11 @@
#! /usr/bin/env bash
# Adapted from https://github.com/basecamp/omarchy/tree/master?tab=readme-ov-file
SCRIPTS="${SCRIPTS:-$HOME/.local/scripts}"
THIS_FILE=${BASH_SOURCE[0]}
LOG_LABEL=$(basename "$THIS_FILE")
THIS=$(basename "$THIS_FILE")
LOG_FILE=${LOG_FILE:-"/tmp/$LOG_LABEL.log"}
usage() {
cat <<EOF
@@ -45,7 +48,6 @@ browser="chromium.desktop"
url=""
launch_args=()
app_args=""
SCRIPTS="${SCRIPTS:-$HOME/.local/scripts}"
while [[ $# -gt 0 ]]; do
if [[ $1 =~ ^--special ]] || [[ $1 =~ ^-s ]]; then
@@ -83,7 +85,7 @@ log() {
# setup logging file and label
source "$SCRIPTS/hypr/logging"
setup-logging "/tmp/$THIS.log" "$THIS"
setup-logging "$LOG_FILE" "$LOG_LABEL"
if [[ -z $url ]]; then
log --error "Must supply a url." && usage && exit 1

View File

@@ -27,10 +27,13 @@
# log --warning "My warning message."
# log --error "My error message."
#
set -e
set -o nounset
set -o pipefail
LOG_FILE=(${LOG_FILE:-})
LOG_INVOCATION_ID=${LOG_INVOCATION_ID:-}
LOG_LABEL=${LOG_LABEL:-()}
LOG_FILE=${LOG_FILE:-""}
LOG_INVOCATION_ID=${LOG_INVOCATION_ID:-""}
LOG_LABEL=${LOG_LABEL:-""}
# Run in dry run mode, which just prints to the console and does
# not log to the files.
LOG_ENABLE_DRY_RUN=${LOG_ENABLE_DRY_RUN:-"0"}
@@ -104,14 +107,23 @@ logging() {
if [[ $LOG_ENABLE_DRY_RUN == "0" ]]; then
# Loop over log files logging message to each file.
for i in "${!LOG_FILE[@]}"; do
prefix="[id: $LOG_INVOCATION_ID][time: $($SCRIPTS/isosec)][label: ${LOG_LABEL[i]}][source: $source_file] : "
m="$prefix $msg"
echo -e "$m" >>${LOG_FILE[i]}
local file=${LOG_FILE[i]}
local id=$LOG_INVOCATION_ID
local label=${LOG_LABEL[i]:-"$LOG_LABEL"}
local time=$("$SCRIPTS/isosec")
if [[ -z $file ]] || [[ -z $id ]] || [[ -z $label ]]; then
echo "Loggging not properly setup."
exit 1
fi
local prefix="[id: $id][time: $time][source: \e[32m$source_file\e[0m][\e[34m$label\e[0m] :"
local m="$prefix $msg"
echo -e "$m" >>"$file"
done
# Also log errors and warning messages to the console.
if [[ $error_flag == "1" ]] || [[ $warn_flag == "1" ]]; then
echo -e "[id: $LOG_INVOCATION_ID]$msg"
echo -e "[id: $id]$msg"
fi
else
# Dry run mode, so just log to the console
@@ -141,14 +153,19 @@ setup-logging() {
exit 1
fi
LOG_FILE+=("$file")
# Only add files that aren't already in the LOG_FILE.
if [[ ! $LOG_FILE =~ $file ]]; then
LOG_FILE+=("$file")
fi
LOG_INVOCATION_ID=${LOG_INVOCATION_ID:-$RANDOM}
if [[ -n $LOG_LABEL ]]; then
if [[ -n $LOG_LABEL ]] && [[ ! $LOG_LABEL =~ $label ]]; then
LOG_LABEL+=("${LOG_LABEL[@]}=>$label")
else
elif [[ ! $LOG_LABEL =~ $label ]]; then
LOG_LABEL+=("$label")
fi
export LOG_FILE
export LOG_LABEL
export LOG_INVOCATION_ID

View File

@@ -1,7 +1,9 @@
#!/usr/bin/env bash
THIS_FILE=${BASH_SOURCE[0]}
THIS=$(basename "$THIS_FILE")
LOG_LABEL=$(basename $THIS_FILE)
LOG_FILE=${LOG_FILE:-/tmp/$LOG_LABEL.log}
THIS=${THIS:-$LOG_LABEL}
usage() {
cat <<EOF
@@ -42,7 +44,7 @@ log() {
}
source "$SCRIPTS/hypr/logging"
setup-logging "/tmp/$THIS.log" "$THIS"
setup-logging "$LOG_FILE" "$LOG_LABEL"
if [[ -z target_workspace ]]; then
log --error "Must supply a workpsace to switch to."

View File

@@ -1,5 +1,9 @@
#!/usr/bin/env bash
set -e
set -o nounset
set -o pipefail
THIS_FILE=${BASH_SOURCE[0]}
LOG_LABEL=$(basename "$THIS_FILE")
# Allows script name to be set when called from a parent script or defaults to filename.
@@ -98,6 +102,10 @@ close() {
fi
}
################################################################################
# MAIN
################################################################################
# Setup logging file and label
source "$SCRIPTS/hypr/logging"
setup-logging "$LOG_LABEL"

View File

@@ -0,0 +1,84 @@
#!/usr/bin/env bash
set -e
set -o nounset
set -o pipefail
SCRIPTS=${SCRIPTS:-$HOME/.local/scripts}
THIS_FILE=${BASH_SOURCE[0]}
LOG_LABEL=$(basename "$THIS_FILE")
THIS=${THIS:-$LOG_LABEL}
LOG_FILE=${LOG_FILE:-"/tmp/$LOG_LABEL.log"}
usage() {
cat <<EOF
Focuses a window, properly handling windows in special workspaces. If no address is supplied,
then we will read address from stdin.
USAGE:
$ $THIS <flags> <address>
FLAGS:
-h | --help: Show this help page.
EOF
}
# Logging utility function, use in place of echo.
log() {
logging log --source "$THIS_FILE" "$@"
}
# Prevent hyprctl dispatch calls from printing to the console.
hypr_dispatch() {
hyprctl dispatch "$@" >/dev/null 2>&1
return $?
}
focus_window() {
local address=$1
log "Focusing window, selection: $address"
local name=$(hyprctl clients -j | jq -r ".[] | select(.address == \"$address\") | .workspace.name")
local active_workspace=$(hyprctl activewindow -j | jq -r ".workspace.name")
log "Window workspace: '$name', active workspace: '$active_workspace'"
if [[ $name =~ ^special ]] && [[ ! $active_workspace == $name ]]; then
log "Toggling special workspace prior to focusing window."
name="${name#special:*}"
hypr_dispatch togglespecialworkspace $name
fi
hypr_dispatch focuswindow "address:$address"
}
################################################################################
# MAIN
################################################################################
# Setup logging file and label.
source "$SCRIPTS/hypr/logging"
setup-logging "$LOG_FILE" "$LOG_LABEL"
address=""
while [[ $# -gt 0 ]]; do
if [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then
usage && exit 0
else
address=$1
fi
shift
done
if [[ -z $address ]]; then
log "Reading address from stdin."
# If an address not supplied then read from stdin, which allows us to pipe the address into
# this command.
read -p "Window address: " address
fi
if [[ -z $address ]]; then
log --error "No address supplied." && exit 1
fi
focus_window $address && exit $?

View File

@@ -7,18 +7,18 @@ set -o pipefail
SCRIPTS=${SCRIPTS:-$HOME/.local/scripts}
THIS_FILE=${BASH_SOURCE[0]}
LOG_LABEL=$(basename "$THIS_FILE")
LOG_FILE=${LOG_FILE:-"/tmp/$LOG_LABEL.log"}
THIS=${THIS:-$LOG_LABEL}
address=""
move_silent_flag="0"
should_go_back="0"
if [[ $# == 1 ]]; then
address="$1"
else
# If an address not supplied then read from stdin, which allows us to pipe into
# If an address not supplied then read from stdin, which allows us to pipe the address into
# this command.
read -r address
read -p "Window address: " address
fi
# Logging utility function, use in place of echo.
@@ -42,19 +42,6 @@ hypr_dispatch() {
return $?
}
focus_window() {
log "Focusing window, selection: $address"
local name=$(hyprctl clients -j | jq -r ".[] | select(.address == \"$address\") | .workspace.name")
local active_workspace=$(hyprctl activewindow -j | jq -r ".workspace.name")
log "Window workspace: '$name', active workspace: '$active_workspace'"
if [[ $name =~ ^special ]] && [[ ! $active_workspace == $name ]]; then
log "Toggling special workspace prior to focusing window."
name="${name#special:*}"
hypr_dispatch togglespecialworkspace $name
fi
hypr_dispatch focuswindow "address:$address"
}
parse_workspace_id() {
local workspace_name=""
read -r workspace_name
@@ -91,6 +78,67 @@ move_to_workspace() {
xargs -I{} hyprctl dispatch "$action" "{},address:$address" >/dev/null 2>&1
return $?
}
make_selection() {
log "Prompting for window action..."
local choices=(
"Focus the selected window.:Focus window"
"Close the selected window.:Close window"
"Close the selected window and go back to the window list.:Close window and back"
"Move the selected window to another workspace, focusing the window.\n\nA workspace picker will be presented to choose which workspace to move to.:Move to workspace"
"Move the selected window to another workspace, without focusing the window.\n\nA workspace picker will be presented to choose which workspace to move to.:Move to workspace - silent"
"Copy the window address to the system clipboard:Copy to clipboard"
"Move back to window picker and reload windows.:Back"
"Quit:Quit"
)
local preview_action="$SCRIPTS/hypr/preview-stats window $address \"{title, workspace, address}\""
local choice=$(
printf "%s\n" "${choices[@]}" |
fzf --style=full --footer="$(action_footer)" \
--delimiter=':' --with-nth=2 \
--header="What should we do with the selected window?" \
--preview-label="[ Description ]" \
--preview="echo -e {1}; echo -e '\n\n\e[35mSelected Window:\e[0m'; $preview_action;"
)
# Exit if non-zero code returned from making selection.
[[ $? -gt 0 ]] && log --error "Unexpected fzf status: $?" && exit $?
# Set choice to just the action portion.
choice="${choice#*:}"
echo "$choice"
}
# Set appropriate flags based on the choice and perform the action on the window address.
handle_selection() {
local resp="done"
local choice=""
read -r choice
log "Action Choice: $choice"
if [[ $choice == "Quit" ]]; then
log "Quitting..."
elif [[ $choice == "Close window" ]]; then
log "Closing window..."
"$SCRIPTS/hypr/close-windows" "$address"
elif [[ $choice == "Close window and back" ]]; then
log "Closing window and setting should go back flag."
"$SCRIPTS/hypr/close-windows" "$address"
resp="back:close"
elif [[ $choice == "Copy to clipboard" ]]; then
log "Copied window address to the clipboard."
echo $address | wl-copy
elif [[ $choice == "Focus window" ]]; then
"$SCRIPTS/hypr/utils/windows/focus-window" $address
elif [[ $choice == "Move to workspace" ]]; then
move_to_workspace
elif [[ $choice == "Move to workspace - silent" ]]; then
move_silent_flag="1"
move_to_workspace
resp="back"
elif [[ $choice == "Back" ]]; then
resp="back"
fi
echo "$resp"
}
@@ -100,65 +148,13 @@ move_to_workspace() {
# Setup logging file and label.
source "$SCRIPTS/hypr/logging"
setup-logging "$LOG_LABEL"
setup-logging "$LOG_FILE" "$LOG_LABEL"
if [[ -z $address ]]; then
log --error "Address not set."
exit 1
fi
log "Prompting for window action..."
choices=(
"Focus the selected window.:Focus window"
"Close the selected window.:Close window"
"Close the selected window and go back to the window list.:Close window and back"
"Move the selected window to another workspace, focusing the window.\n\nA workspace picker will be presented to choose which workspace to move to.:Move to workspace"
"Move the selected window to another workspace, without focusing the window.\n\nA workspace picker will be presented to choose which workspace to move to.:Move to workspace - silent"
"Copy the window address to the system clipboard:Copy to clipboard"
"Move back to window picker and reload windows.:Back"
"Quit:Quit"
)
preview_action="$SCRIPTS/hypr/preview-stats window $address \"{title, workspace, address}\""
choice=$(
printf "%s\n" "${choices[@]}" |
fzf --style=full --footer="$(action_footer)" \
--delimiter=':' --with-nth=2 \
--header="What should we do with the selected window?" \
--preview-label="[ Description ]" \
--preview="echo -e {1}; echo -e '\n\n\e[35mSelected Window:\e[0m'; $preview_action;"
)
if [[ $? -gt 0 ]]; then
log --error "Unexpected fzf status: $?"
exit $?
fi
# Set choice to just the action portion.
choice="${choice#*:}"
log "Action Choice: $choice"
# Set appropriate flags based on the choice and perform the action on the window address.
if [[ $choice == "Quit" ]]; then
exit 0
elif [[ $choice == "Close window" ]]; then
"$SCRIPTS/hypr/close-windows" "$address"
elif [[ $choice == "Close window and back" ]]; then
"$SCRIPTS/hypr/close-windows" "$address"
should_go_back="1"
elif [[ $choice == "Copy to clipboard" ]]; then
echo $address | wl-copy
elif [[ $choice == "Focus window" ]]; then
focus_window
elif [[ $choice == "Move to workspace" ]]; then
move_to_workspace
elif [[ $choice == "Move to workspace - silent" ]]; then
move_silent_flag="1"
move_to_workspace
elif [[ $choice == "Back" ]]; then
should_go_back="1"
fi
# TODO: Maybe we just echo out a 'back' message.
if [[ $should_go_back == "1" ]]; then
exit 69
fi
res=$(make_selection | handle_selection)
log "Action result: $res"
echo "$res"

View File

@@ -0,0 +1,113 @@
#!/usr/bin/env bash
set -e
set -o nounset
set -o pipefail
SCRIPTS=${SCRIPTS:-$HOME/.local/scripts}
THIS_FILE=${BASH_SOURCE[0]}
LOG_LABEL=$(basename "$THIS_FILE")
THIS=${THIS:-$LOG_LABEL}
LOG_FILE=${LOG_FILE:-"/tmp/$LOG_LABEL.log"}
address=""
width=""
height=""
usage() {
cat <<EOF
Utility for toggling a windows floating property.
If no address is supplied and '--active' flag is not set, then we will read address from stdin.
USAGE:
$ $THIS <flags> <address>
FLAGS:
-a | --active: Toggles floating of the active window.
-w | --width <n>: Set a width of the floating window, can be pixels or percent (ex. 80%).
-h | --height <n>: Set a height of the floating window, can be pixels or percent (ex. 80%).
--help: Show this help page.
EOF
}
log() {
logging log --source "$THIS_FILE" "$@"
}
# Suppress output of hyprctl
hypr_dispatch() {
hyprctl dispatch "$@" >/dev/null 2>&1 && return $?
}
toggle_floating() {
hypr_dispatch togglefloating "address:$address"
}
resize_window() {
if [[ -n $width ]] && [[ -n $height ]]; then
log "Resizing window: width: $width, height: $height"
hypr_dispatch resizewindowpixel exact "$width $height,address:$address"
fi
echo "$address"
}
center_window() {
local address=""
read -r address
local activeaddress=$(hyprctl activewindow -j | jq -r '.address')
if [[ $address == $activeaddress ]]; then
log "Centering window..."
hypr_dispatch centerwindow
fi
}
################################################################################
# MAIN
################################################################################
# Setup logging
source "$SCRIPTS/hypr/logging"
setup-logging "$LOG_FILE" "$LOG_LABEL"
while [[ $# -gt 0 ]]; do
if [[ $1 == "--help" ]]; then
usage && exit 0
elif [[ $1 == "-w" ]] || [[ $1 == "--width" ]]; then
shift
width=$1
elif [[ $1 == "-h" ]] || [[ $1 == "--height" ]]; then
shift
height=$1
elif [[ $1 == "-a" ]] || [[ $1 == "--active" ]]; then
address=$(hyprctl activewindow -j | jq -r '.address')
else
address=$1
fi
shift
done
if [[ -z $address ]]; then
read -p "Window address: " address
fi
if [[ -z $address ]]; then
log --error "No address was supplied" && exit 1
fi
log "Begin toggling floating for: '$address'"
floating=$(hyprctl clients -j | jq ".[] | select(.address == \"$address\") | .floating")
log "Is currently floating: $floating"
toggle_floating
if [ ! "$floating" == "true" ]; then
resize_window | center_window
fi

View File

@@ -0,0 +1,97 @@
#!/usr/bin/env bash
set -e
set -o nounset
set -o pipefail
SCRIPTS=${SCRIPTS:-$HOME/.local/scripts}
THIS_FILE=${BASH_SOURCE[0]}
LOG_LABEL=$(basename "$THIS_FILE")
THIS=${THIS:-$LOG_LABEL}
LOG_FILE=${LOG_FILE:-"/tmp/$LOG_LABEL.log"}
usage() {
cat <<EOF
Shows a window picker and window details, then prompts for an action that can be
performed on the selected window.
USAGE:
$ $THIS <flags>
FLAGS:
-h | --help: Show this page.
EOF
}
# Logging utility function, use in place of echo.
log() {
logging log --source "$THIS_FILE" "$@"
}
handle_selected_value() {
local selection=""
read -r selection
if [[ -z $selection ]]; then
log "No selected value."
return 1
fi
log "Prompting for action, window: '$selection'"
local res=$(echo "$selection" | "$SCRIPTS/hypr/utils/windows/window-action-picker")
log "Action callback result: $res"
echo "$res"
}
prompt_for_window_selection() {
local selected_value=$("$SCRIPTS/hypr/window-picker")
local status=$?
if [[ $status -ne 0 ]]; then
exit $status
fi
echo "$selected_value"
}
################################################################################
# MAIN
################################################################################
# Setup logging file and label.
source "$SCRIPTS/hypr/logging"
setup-logging $LOG_FILE $LOG_LABEL
should_quit="0"
log "Starting $THIS..."
while [[ $# -gt 0 ]]; do
if [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then
usage && exit 0
elif [[ -n $1 ]]; then
address=$1
fi
shift
done
# Load colors if they haven't been loaded already.
[[ -z ${FZF_DEFAULT_OPTS} ]] &&
[[ -f $SCRIPTS/catppuccin-colors ]] &&
source $SCRIPTS/catppuccin-colors
trap 'log "Stoping..."; should_quit="1"' SIGINT
while [[ $should_quit -eq 0 ]]; do
res=$(prompt_for_window_selection | handle_selected_value)
if [[ ! $res =~ ^back ]]; then
should_quit=1
elif [[ $res == "back:close" ]]; then
sleep 0.3 # allow time for windows close, to prevent showing closed windows.
fi
log "Should quit: $should_quit"
done

View File

@@ -1,319 +1,117 @@
#!/usr/bin/env bash
set -e
set -o nounset
set -o pipefail
THIS_FILE=${BASH_SOURCE[0]}
THIS=$(basename $THIS_FILE)
LOG_LABEL=$(basename $THIS_FILE)
SCRIPTS=${SCRIPTS:-$HOME/.local/scripts}
LOG_FILE=${LOG_FILE:-"/tmp/$LOG_LABEL.log"}
usage() {
cat <<EOF
Show a table with details about the currently active windows. You can choose a window and perform
an action. This script will prompt for what you would like to do depending on the options passed.
There are no required options for this script to work.
Utility for performing actions on windows.
USAGE:
$ $THIS [OPTIONS]
$ $THIS <command> <flags>
OPTIONS:
FLAGS:
-h | --help: Show this page.
--launch: Launch in a new terminal window, user will be prompted what to do with selected window.
-c | --clip: Copy selected window's address to the system clipboard.
-x | --close <address>: Close the selected window.
-f | --focus <address>: Focus the selected window, if optional address is supplied then we focus it.
-i | --ignore: Ignore the selected window.
-m | --move <address>: Move the selected window to another workspace and switch to that workspace.
-s | --silent-move <address>: Move the selected window to another workspace and remain on current workspace.
-t | --to-workspace <id>: Used with one of the move options to set which workspace to move to. If not supplied
then we will prompt for a workspace to move to.
-h | --help: Show this page.
COMMANDS:
close: Close window(s).
focus: Focuses a window, handling special workspaces properly.
launch: Launches an interactive picker in a new terminal.
picker: Window picker that prompts for an action to perform on the window.
toggle-floating: Toggles floating property of a window.
NOTES:
If using the 'launch' option then flags passed after the '--launch' flag will be passed into the
launched terminal, allowing you to launch with a specific mode turned on, any flags passed in prior to
'--launch' will be ignored.
Run "$THIS <command> --help" for more information on a command.
EOF
}
if [[ "$1" == "close" ]]; then
shift
THIS="$THIS close" "$SCRIPTS/hypr/utils/windows/close-windows" "$@"
exit $?
fi
window_class="com.ghostty.$THIS"
window_padding_x="10"
clipboard_flag="0"
close_flag="0"
focus_flag="0"
ignore_flag="0"
launch_flag="0"
move_flag="0"
move_silent_flag="0"
move_to_workspace_name=""
refresh_flag="0"
should_quit="0"
launch_args=()
selected_value=""
while [[ $# -gt 0 ]]; do
if [[ $launch_flag == "1" ]]; then
launch_args+=("$1")
else
if [[ $1 =~ ^-c ]] || [[ $1 =~ ^--clip ]]; then
clipboard_flag="1"
elif [[ $1 =~ ^-x ]] || [[ $1 =~ ^--close ]]; then
close_flag="1"
selected_value=$2
shift
elif [[ $1 =~ ^-f ]] || [[ $1 =~ ^--focus ]]; then
focus_flag="1"
selected_value=$2
shift
elif [[ $1 =~ ^-h ]] || [[ $1 =~ ^--help ]]; then
usage && exit 0
elif [[ $1 =~ ^-i ]] || [[ $1 =~ ^--ignore ]]; then
ignore_flag="1"
elif [[ $1 =~ ^-m ]] || [[ $1 =~ ^--move ]]; then
move_flag="1"
selected_value=$2
shift
elif [[ $1 =~ ^-s ]] || [[ $1 =~ ^--silent-move ]]; then
move_flag="1"
move_silent_flag="1"
selected_value=$2
shift
elif [[ $1 =~ ^-t ]] || [[ $1 =~ ^--to-workspace ]]; then
shift
move_to_workspace_name=$1
elif [[ $1 =~ ^--launch ]]; then
launch_flag="1"
fi
fi
shift
done
action_footer() {
cat <<'EOF'
___ __ _
/ _ |____/ /_(_)__ ___
/ __ / __/ __/ / _ \/ _ \
/_/ |_\__/\__/_/\___/_//_/
EOF
}
log() {
logging log --source "$THIS_FILE" "$@"
}
# Reset flags and selection.
reset_flags() {
selected_value=""
clipboard_flag="0"
close_flag="0"
focus_flag="0"
ignore_flag="0"
launch_flag="0"
move_flag="0"
move_silent_flag="0"
move_to_workspace_name=""
refresh_flag="0"
should_quit="0"
launch_usage() {
cat <<EOF
Launches an interactive picker in a new terminal window.
USAGE:
$ $THIS launch <flags>
FLAGS:
-h | --help: Show this page.
EOF
}
ask_what_to_do_with_selection() {
local choices=(
"Focus the selected window.:Focus window"
"Close the selected window.:Close window"
"Close the selected window and go back to the window list.:Close window and back"
"Move the selected window to another workspace, focusing the window.\n\nA workspace picker will be presented to choose which workspace to move to.:Move to workspace"
"Move the selected window to another workspace, without focusing the window.\n\nA workspace picker will be presented to choose which workspace to move to.:Move to workspace - silent"
"Copy the window address to the system clipboard:Copy to clipboard"
"Move back to window picker and reload windows.:Back"
"Quit:Quit"
)
choice=$(
printf "%s\n" "${choices[@]}" |
fzf --style=full --footer="$(action_footer)" \
--delimiter=':' --with-nth=2 \
--header="What should we do with the selected window?" \
--preview-label="[ Description ]" \
--preview="echo -e {1}; echo -e '\n\n\e[35mSelected Window:\e[0m'; $SCRIPTS/hypr/preview-stats window $selected_value \"{title, workspace, address}\";"
)
# Set choice to just the action portion.
choice="${choice#*:}"
log "Choice: $choice"
# Set appropriate flags based on the choice.
if [[ $choice == "Quit" ]]; then
exit 0
elif [[ $choice == "Close window" ]]; then
should_quit="1"
close_flag="1"
elif [[ $choice == "Close window and back" ]]; then
close_flag="1"
refresh_flag="1"
should_quit="0"
elif [[ $choice == "Copy to clipboard" ]]; then
should_quit="1"
clipboard_flag="1"
elif [[ $choice == "Focus window" ]]; then
should_quit="1"
focus_flag="1"
elif [[ $choice == "Move to workspace" ]]; then
should_quit="1"
move_flag="1"
elif [[ $choice == "Move to workspace - silent" ]]; then
should_quit="1"
move_silent_flag="1"
move_flag="1"
elif [[ $choice == "Refresh window list" ]]; then
refresh_flag="1"
should_quit="0"
# Launch in a new terminal window.
launch() {
if [[ $@ =~ ^-h ]] || [[ $@ =~ ^--help ]]; then
launch_usage && exit 0
fi
log "Launching terminal."
ghostty --class="$window_class" --window-padding-x="$window_padding_x" \
--keybind="ctrl+c=quit" \
-e "${BASH_SOURCE[0]}" "$@"
}
# Prevent hyprctl dispatch calls from printing to the console.
hypr_dispatch() {
hyprctl dispatch "$@" >/dev/null 2>&1
show_picker() {
log "Showing picker..."
THIS="$THIS picker" "$SCRIPTS/hypr/utils/windows/windowctl-picker" "$@"
return $?
}
move_to_workspace() {
local workspace_id=""
if [[ -z $move_to_workspace_name ]]; then
move_to_workspace_name=$(
$SCRIPTS/hypr/workspace-picker --return-name-if-special \
--header="Select a workspace to move window to:"
)
fi
if [[ -z $move_to_workspace_name ]]; then
log --error "No workspace set to move window to."
exit 1
fi
# Check if moving to a special workspace to pass the appropriate args in to hyprctl.
if [[ $move_to_workspace_name =~ ^special ]]; then
workspace_id=$move_to_workspace_name
else
workspace_id=$(hyprctl workspaces -j | jq -r ".[] | select(.name | contains(\"$move_to_workspace_name\")) | .id")
fi
if [[ -z $workspace_id ]]; then
log --error "No workspace id found for: '$move_to_workspace_name'"
exit 1
fi
action="movetoworkspace"
if [[ $move_silent_flag == "1" ]]; then
action="movetoworkspacesilent"
fi
log "Moving window: '$selected_value' to workspace: '$workspace_id'"
hypr_dispatch $action "$workspace_id,address:$selected_value"
}
focus_window() {
log "Focusing window, selection: $selected_value"
local address="$selected_value"
local name=$(hyprctl clients -j | jq -r ".[] | select(.address == \"$address\") | .workspace.name")
local active_workspace=$(hyprctl activewindow -j | jq -r ".workspace.name")
log "Window workspace: '$name', active workspace: '$active_workspace'"
if [[ $name =~ ^special ]] && [[ ! $active_workspace == $name ]]; then
log "Toggling special workspace prior to focusing window."
name="${name#special:*}"
hypr_dispatch togglespecialworkspace $name
fi
hypr_dispatch focuswindow "address:$address"
}
handle_selected_value() {
if [[ $ignore_flag == "1" ]]; then
log "Ignore flag set, selection: '$selected_value'"
exit 0
elif [[ $clipboard_flag == "1" ]]; then
log "Copying to clipboard, selection: $selected_value"
wl-copy $selected_value
elif [[ $focus_flag == "1" ]]; then
focus_window
elif [[ $close_flag == "1" ]]; then
log "Closing window, selection: $selected_value"
hypr_dispatch closewindow "address:$selected_value"
if [[ $refresh_flag == "1" ]]; then
log "Refreshing windows..."
# Need to sleep here breifly otherwise recently closed windows will still show
# in the window picker.
reset_flags && sleep 0.3
fi
elif [[ $move_flag == "1" ]] || [[ $move_silent_flag == "1" ]]; then
move_to_workspace
# && exit 0
else
log "No flag set, selection: '$selected_value'"
fi
}
##################################################
# MAIN
##################################################
# Setup logging file and label.
source "$SCRIPTS/hypr/logging"
setup-logging "/tmp/$THIS.log" "$THIS"
setup-logging "$LOG_LABEL"
log "Starting with selected value: '$selected_value'"
if [[ $launch_flag == "1" ]]; then
ghostty --class="$window_class" --window-padding-x="$window_padding_x" \
--keybind="ctrl+c=quit" \
-e "${BASH_SOURCE[0]}" "${launch_args[@]}"
else
# Load colors if they haven't been loaded already.
[[ -z ${FZF_DEFAULT_OPTS} ]] &&
[[ -f $SCRIPTS/catppuccin-colors ]] &&
source $SCRIPTS/catppuccin-colors
if [[ -n $selected_value ]]; then
# Handle value if it was passed in.
# TODO: This should probably ensure that flags were set.
handle_selected_value && exit 0
while [[ $# -gt 0 ]]; do
if [[ $1 == "close" ]]; then
shift
THIS="$THIS close" "$SCRIPTS/hypr/utils/windows/close-windows" "$@"
exit $?
elif [[ $1 == "focus" ]]; then
shift
THIS="$THIS focus" "$SCRIPTS/hypr/utils/windows/focus-window" "$@"
exit $?
elif [[ $1 == "launch" ]]; then
shift
launch picker "$@" && exit 0
elif [[ $1 == "picker" ]]; then
shift
show_picker "$@"
exit $?
elif [[ $1 == "toggle-floating" ]]; then
shift
THIS="$THIS toggle-floating" "$SCRIPTS/hypr/utils/windows/window-toggle-floating" "$@"
exit $?
elif [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then
usage && exit 0
else
trap 'log "Stoping..."; should_quit="1"' SIGINT
while [[ $should_quit == "0" ]]; do
# not sure if this should be here or somewhere else, as it will
# cause any passed in flags to be ignored, but they're generally empty
# when using this interactive mode anyway.
reset_flags
selected_value=$("$SCRIPTS/hypr/window-picker")
status=$?
if [[ $status -ne 0 ]]; then
should_quit="1"
else
if [[ -n $selected_value ]]; then
handle_selected_value
# If we got here then no flag was passed in initially on how to handle the
# selected window, so ask what they'd like to do. Then handle it.
log "Asking what to do with selction."
ask_what_to_do_with_selection
[[ -n $selected_value ]] && handle_selected_value
# If you make it here, We just give up... Don't start an endless loop.
# log "Giving up without a selection."
fi
fi
done
log --error "Unhandled arg: $1"
exit 1
fi
fi
shift
done
# If we've reached here then no commands were passed / handled.
usage && exit 1

7
gen
View File

@@ -74,10 +74,15 @@ generate_script() {
cat >"$dest" <<'EOF'
#!/usr/bin/env bash
set -e
set -o nounset
set -o pipefail
SCRIPTS=${SCRIPTS:-$HOME/.local/scripts}
THIS_FILE=${BASH_SOURCE[0]}
LOG_LABEL=$(basename "$THIS_FILE")
THIS=${THIS:-$LOG_LABEL}
LOG_FILE=${LOG_FILE:-"/tmp/$LOG_LABEL.log"}
# Logging utility function, use in place of echo.
log() {
@@ -90,7 +95,7 @@ log() {
# Setup logging file and label.
source "$SCRIPTS/hypr/logging"
setup-logging "$LOG_LABEL"
setup-logging "$LOG_FILE" "$LOG_LABEL"
log "Starting $THIS..."