Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select Clients From An Overview Mode #3

Open
modestbadger1773 opened this issue Apr 6, 2024 · 7 comments
Open

Select Clients From An Overview Mode #3

modestbadger1773 opened this issue Apr 6, 2024 · 7 comments

Comments

@modestbadger1773
Copy link
Contributor

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

@modestbadger1773
Copy link
Contributor Author

I've made some bash scripts that combined with innate functionality of this plugin and hyprland's keybinds allow for a functional overview mode.

Show All

#!/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"

Return All

#!/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"

Workflow

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.

@modestbadger1773 modestbadger1773 changed the title Integration (Perhaps Adoption) of Hycov Select Clients From An Overview Mode Apr 11, 2024
@luravoid
Copy link

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

@DreamMaoMao
Copy link

@luravoid

SO COOL!

2024-04-15_05-57-01.mp4

@luravoid
Copy link

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

@DreamMaoMao
Copy link

@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

@luravoid
Copy link

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

@thepenguinthatwants
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants