Open modestbadger1773 opened 7 months ago
I've made some bash scripts that combined with innate functionality of this plugin and hyprland's keybinds allow for a functional overview mode.
#!/bin/sh
# Files to store mappings and fullscreen state
mapping_file="/tmp/client_workspace_mapping.txt"
fullscreen_file="/tmp/client_fullscreen_state.txt"
# Clear the mapping file and fullscreen state file or create if doesn't exist
: > $mapping_file
: > $fullscreen_file
# Workspace to move clients to
target_workspace=1
# Result string for hyptctl --batch
# Also switch to target workspace and first workspace for other monitor
result="dispatch workspace 1; dispatch workspace $target_workspace;"
# For every Hyprland client address
for client in $(hyprctl clients -j | jq -r ".[] | select(.workspace.id != $target_workspace and .workspace.id != -1) | @base64"); do
workspace_id=$(echo $client | base64 --decode | jq -r ".workspace.id")
address=$(echo $client | base64 --decode | jq -r ".address")
fullscreen=$(echo $client | base64 --decode | jq "if .fullscreen == true then 1 elif .fullscreen == false then 0 else .fullscreen end")
# Save mapping to file
echo "$address $workspace_id" >> $mapping_file
# If client is fullscreen, record this state and prepare to exit fullscreen
if [ "$fullscreen" -eq 1 ]; then
echo "$address" >> $fullscreen_file
# Append command to exit fullscreen for this client
result="$result dispatch fullscreen,address:$address;"
fi
# Append hyprctl command to execute with address
result="$result dispatch movetoworkspacesilent $target_workspace,address:$address;"
done
# Execute commands
hyprctl --batch "$result"
#!/bin/sh
# Files where the client to workspace mappings and fullscreen states are stored
mapping_file="/tmp/client_workspace_mapping.txt"
fullscreen_file="/tmp/client_fullscreen_state.txt"
# Use hyprctl activewindow and extract the window ID
focused_window_id=$(hyprctl activewindow | grep 'Window' | awk '{print $2}')
echo "Focused Window ID: $focused_window_id"
# Initialize variable for the focused client's original workspace
focused_client_workspace=""
# Check if focused_window_id is not empty
if [ -n "$focused_window_id" ]; then
# Look up the focused window's original workspace
focused_client_workspace=$(grep "$focused_window_id" "$mapping_file" | awk '{print $2}')
fi
echo "Focused Client's Original Workspace: $focused_client_workspace"
# Initialize result string for hyprctl --batch
result=""
# Read each mapping from the file and prepare hyprctl --batch commands
while IFS= read -r line; do
address=$(echo "$line" | awk '{print $1}')
original_workspace=$(echo "$line" | awk '{print $2}')
# Move client to its original workspace
result="$result dispatch movetoworkspacesilent $original_workspace,address:$address;"
# Check if client was fullscreen and append command if necessary
if grep -q "$address" "$fullscreen_file"; then
result="$result dispatch fullscreen,address:$address;"
fi
done < "$mapping_file"
# If the focused client's workspace was found, use it; otherwise, default to workspace 1
if [ -z "$focused_client_workspace" ]; then
echo "No focused client workspace found, defaulting to workspace 1."
focused_client_workspace=1
else
echo "Moving to focused client's original workspace: $focused_client_workspace"
fi
# Append the command to switch to the workspace of the originally focused client
result="$result dispatch workspace $focused_client_workspace;"
# Execute commands
echo "Executing command: $result"
hyprctl --batch "$result"
I call these commands with:
bind = ALT, grave, exec, $UserScripts/showall.sh
bindr = ALT, grave, easymotion, bgcolor:rgba(000000af), bordercolor:rgba(00ff00ff), textcolor:rgba(00ff00ff), action:hyprctl dispatch focuswindow address:{};bash $UserScripts/returnall.sh
Which brings all clients to Workspace 1. Then, once I choose the client I want, all the clients return to their original Workspaces and I am moved to the chosen client's workspace with it active.
If I want to work with all the clients on one Workspace, I can escape out of the previous keybind. If I later want to return all clients to their respective workspaces (and follow my chosen client) I can use:
bindr = $mainMod, grave, easymotion, bgcolor:rgba(000000af), bordercolor:rgba(00ff00ff), textcolor:rgba(00ff00ff), action:hyprctl dispatch focuswindow address:{};bash $UserScripts/returnall.sh
Hopefully these scripts can be helpful for someone other than just me. If anyone has any questions, I'm happy to give as much (of my admittedly meager) support as I can.
Bind this script:
bind = ALT,tab, exec, ~/.config/hypr/scripts/hycov-easymotion
#!/bin/bash
workspace_name=$(hyprctl -j activeworkspace | jq -r '.name')
if [ "$workspace_name" = "OVERVIEW" ]; then
hyprctl dispatch hycov:toggleoverview
else
hyprctl dispatch hycov:toggleoverview
hyprctl dispatch 'easymotion action:hyprctl --batch "dispatch focuswindow address:{} ; dispatch hycov:toggleoverview"'
fi
I added a socket event to the script so that the labels also hide when selecting a window with the mouse:
#!/bin/bash
handle() {
case $1 in
workspace*)
workspace_name=$(hyprctl -j activeworkspace | jq -r '.name')
if [ "$workspace_name" != "OVERVIEW" ]; then
hyprctl dispatch easymotionexit
exit 0
fi
;;
esac
}
workspace_name=$(hyprctl -j activeworkspace | jq -r '.name')
if [ "$workspace_name" = "OVERVIEW" ]; then
hyprctl dispatch hycov:toggleoverview
else
hyprctl dispatch hycov:toggleoverview
hyprctl dispatch "easymotion action:hyprctl --batch 'dispatch focuswindow address:{} ; dispatch hycov:toggleoverview'"
fi
socat -U - UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read -r line; do handle "$line"; done
It would also be possible to show and hide the overview with labels using a single hotkey if it were possible to define submaps that work in easymode to execute the script with the same hotkey
if [ "$workspace_name" = "OVERVIEW" ]; then
hyprctl dispatch easymotionexit
hyprctl dispatch hycov:toggleoverview
else
hyprctl dispatch hycov:toggleoverview
hyprctl dispatch "easymotion action:hyprctl --batch 'dispatch focuswindow address:{} ; dispatch hycov:toggleoverview'"
fi
@luravoid
hycov support leaveoverview and enteroverview dispatch. you should ues this replace toggleoverview.
workspace_name=$(hyprctl -j activeworkspace | jq -r '.name')
if [ "$workspace_name" = "OVERVIEW" ]; then
hyprctl dispatch hycov:leaveoverview
else
hyprctl dispatch hycov:enteroverview
hyprctl dispatch 'easymotion action:hyprctl --batch "dispatch focuswindow address:{} ; dispatch hycov:leaveoverview"'
fi
Ok, now it's perfect. Single keybinding opens and closes hycov with labels
bind = ALT, Tab, exec, ~/.config/hypr/scripts/hycov-easymotion
submap=__easymotionsubmap__
bind = ALT, Tab, exec, ~/.config/hypr/scripts/hycov-easymotion
submap=reset
#!/bin/bash
handle() {
case $1 in
renameworkspace*)
workspace_name=$(hyprctl -j activeworkspace | jq -r '.name')
if [ "$workspace_name" != "OVERVIEW" ]; then
hyprctl dispatch easymotionexit
exit 0
fi
;;
esac
}
workspace_name=$(hyprctl -j activeworkspace | jq -r '.name')
if [ "$workspace_name" = "OVERVIEW" ]; then
hyprctl dispatch hycov:leaveoverview
else
hyprctl dispatch hycov:enteroverview
hyprctl dispatch "easymotion action:hyprctl --batch 'dispatch focuswindow address:{} ; dispatch hycov:leaveoverview'"
fi
socat -U - UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read -r line; do handle "$line"; done
This makes the whole plugin hundred times more awesome. Hopefully it can somehow get merged with the master. But then using separate custom scripts is also fine enough.
This is the script I'm currently using. It allows not only to focus the selected window but also to move the window to the active workspace.
#!/bin/bash
# Plugins: hycov, hyprland-easymotion
oneshot=false
color=6e3a3a
mode="focus" # Default mode
store_file="/tmp/.win_store"
if [ ! -f "$store_file" ]; then
touch "$store_file"
fi
handle() {
case $1 in
custom*)
event_data=$(echo $1 | cut -d'>' -f3)
if [[ "$event_data" == "changemode" ]]; then
if [[ "$mode" == "focus" ]]; then
mode="move"
hyprctl dispatch easymotion "bgcolor:rgb($color)"
else
mode="focus"
hyprctl dispatch easymotion
fi
echo "Changed mode to: $mode"
fi
;;
renameworkspace*)
workspace_name=$(hyprctl -j monitors | jq -r '.[] | select(.activeWorkspace.name == "OVERVIEW") | .activeWorkspace.name')
if [ "$workspace_name" = "OVERVIEW" ]; then
if [ "$mode" = "focus" ]; then
hyprctl dispatch easymotion
elif [ "$mode" = "move" ]; then
hyprctl dispatch easymotion "bgcolor:rgb($color)"
fi
else
hyprctl dispatch easymotionexit
mode="focus"
if [[ "$oneshot" == true ]]; then
exit
fi
fi
;;
easymotionselect*)
address=$(echo $1 | cut -d',' -f1 | cut -d'>' -f3)
workspace_name=$(hyprctl -j monitors | jq -r '.[] | select(.activeWorkspace.name == "OVERVIEW") | .activeWorkspace.name')
active_workspace=$(hyprctl -j activeworkspace | jq -r '.id')
if [ "$workspace_name" = "OVERVIEW" ]; then
if [ "$mode" = "focus" ]; then
hyprctl dispatch focuswindow address:$address
hyprctl dispatch hycov:leaveoverview
elif [ "$mode" = "move" ]; then
hyprctl dispatch hycov:leaveoverview
original_workspace=$(hyprctl -j clients | jq -r --arg ADDRESS "$address" '.[] | select(.address == $ADDRESS) | .workspace.name')
if grep -q "^$address" "$store_file"; then
sed -i "/^$address/d" "$store_file"
fi
hyprctl dispatch movetoworkspace $active_workspace,address:$address
echo "$address $original_workspace" >>"$store_file"
mode="focus"
fi
if [[ "$oneshot" == true ]]; then
exit
fi
fi
;;
easymotionexit*)
workspace_name=$(hyprctl -j monitors | jq -r '.[] | select(.activeWorkspace.name == "OVERVIEW") | .activeWorkspace.name')
if [ "$workspace_name" = "OVERVIEW" ]; then
hyprctl dispatch hycov:leaveoverview
mode="focus"
fi
if [[ "$oneshot" == true ]]; then
exit
fi
;;
esac
}
case $1 in
-o|--oneshot)
oneshot=true
hyprctl dispatch hycov:enteroverview
case $2 in
move)
mode="move"
hyprctl dispatch easymotion "bgcolor:rgb($color)"
;;
focus)
hyprctl dispatch easymotion
;;
*)
hyprctl dispatch easymotion
;;
esac
;;
-h|--help)
echo "Usage: $(basename $0) [OPTIONS]"
echo " -o, --oneshot [move|focus] Run once with 'move' or 'focus' mode"
echo " -h, --help Show this help message"
exit
;;
*)
echo "$(basename $0) started"
;;
esac
socat -U - UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read -r line; do handle "$line"; done
Bindings:
bind = ALT, Tab, hycov:toggleoverview
submap = __easymotionsubmap__
bind = ,Tab, event, changemode
bind = ALT, Tab, hycov:leaveoverview
submap = reset
Being able to press a key and have all clients in a grid view that could selected through easymotion would also be an awesome implementation for later on.
As I said in other request - fantastic work, does exactly what I wanted it to.
https://github.com/DreamMaoMao/hycov