Skip to content

Commit

Permalink
fix(hyprland): monitors
Browse files Browse the repository at this point in the history
  • Loading branch information
Diaoul committed Oct 20, 2024
1 parent beedd3f commit 01f9618
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 101 deletions.
2 changes: 1 addition & 1 deletion .config/hypr/hyprland.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exec-once = ~/.config/hypr/scripts/launch-waybar.sh
exec-once = wlsunset -l 49 -L 2
# monitors and workspaces
exec-once = ~/.config/hypr/scripts/monitors.sh listen
exec = sleep 3 && ~/.config/hypr/scripts/monitors.sh configure_monitors
exec = sleep 2 && ~/.config/hypr/scripts/monitors.sh initialize
# wallpaper
# see https://github.com/Horus645/swww/issues/144
exec-once = swww query || swww-daemon
Expand Down
202 changes: 102 additions & 100 deletions .config/hypr/scripts/monitors.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ declare -i throttle_by=4
@throttle() {
# shellcheck disable=SC2155
local -i now=$(date +%s)
if ((now - last_called > throttle_by))
then
if ((now - last_called > throttle_by)); then
# delay execution
sleep $throttle_by
# execute
Expand All @@ -18,97 +17,97 @@ declare -i throttle_by=4
}

function move_workspace() {
workspaces_json="$1"
id=$2
monitor=$3

# configure workspace
workspace_json=$(echo "$workspaces_json" | jq -r ".[] | select(.id == $id)")
current_monitor=$(echo "$workspaces_json" | jq -r ".[] | select(.id == $id).monitor")
if [ -z "$workspace_json" ] || [ "$current_monitor" != "$monitor" ]; then
echo "Setting workspace $id to monitor $monitor"
hyprctl keyword workspace "$id, monitor:$monitor,persistent:true" > /dev/null
hyprctl dispatch moveworkspacetomonitor $i "$monitor" > /dev/null

if [ -z "$workspace_json" ]; then
echo "Workspace $id does not exist, creating it"
hyprctl dispatch workspace "$id" > /dev/null
fi
fi
workspaces_json="$1"
id=$2
monitor=$3

# configure workspace
workspace_json=$(echo "$workspaces_json" | jq -r ".[] | select(.id == $id)")
current_monitor=$(echo "$workspaces_json" | jq -r ".[] | select(.id == $id).monitor")
if [ -z "$workspace_json" ]; then
echo "Workspace $id does not exist, creating it"
hyprctl dispatch workspace "$id" >/dev/null
fi
if [ -z "$workspace_json" ] || [ "$current_monitor" != "$monitor" ]; then
echo "Setting workspace $id to monitor $monitor"
hyprctl keyword workspace "$id, monitor:$monitor,persistent:true" >/dev/null
hyprctl dispatch moveworkspacetomonitor $i "$monitor" >/dev/null

fi
}

function arrange_workspaces() {
# Maintain 10 persistent workspaces across multiple monitors
# This script assumes that the monitors are in horizontal layout and already
# correctly setup
monitors_json=$(hyprctl monitors -j)
workspaces_json=$(hyprctl workspaces -j)

mapfile -t monitors < <(echo "$monitors_json" | jq -r '. | sort_by(.x) | .[].name')
workspace_count=$(echo "$workspaces_json" | jq -r '. | length')

echo "Detected ${#monitors[@]} monitors with $workspace_count workspaces"

# assign and move workspaces
if [[ "${#monitors[@]}" == 1 ]]; then
for ((i = 10; i >= 1; i--)); do
move_workspace "$workspaces_json" $i "${monitors[0]}"
done
elif [[ "${#monitors[@]}" == 2 ]]; then
for ((i = 10; i >= 6; i--)); do
move_workspace "$workspaces_json" $i "${monitors[1]}"
done
for ((i = 5; i >= 1; i--)); do
move_workspace "$workspaces_json" $i "${monitors[0]}"
done
elif [[ "${#monitors[@]}" == 3 ]]; then
for ((i = 10; i >= 8; i--)); do
move_workspace "$workspaces_json" $i "${monitors[2]}"
done
for ((i = 7; i >= 4; i--)); do
move_workspace "$workspaces_json" $i "${monitors[1]}"
done
for ((i = 3; i >= 1; i--)); do
move_workspace "$workspaces_json" $i "${monitors[0]}"
done
else # more than 3 monitors...
echo "Too many monitors"
fi
# Maintain 10 persistent workspaces across multiple monitors
# This script assumes that the monitors are in horizontal layout and already
# correctly setup
monitors_json=$(hyprctl monitors -j)
workspaces_json=$(hyprctl workspaces -j)

# activate first workspace of monitor if out of bounds
mapfile -t monitors < <(hyprctl monitors -j | jq -r '. | sort_by(.x) | .[].name')
for name in "${monitors[@]}"; do
active_workspace=$(echo "$monitors_json" | jq -r ".[] | select(.name == \"$name\") | .activeWorkspace.id")
if [[ $active_workspace -gt 10 ]]; then
first_workspace=$(echo "$workspaces_json" | jq -r "map(select(.monitor == \"$name\")) | min_by(.id) | .id")
echo "Activating workspace $first_workspace on monitor $name"
hyprctl dispatch workspace "$first_workspace" > /dev/null
fi
mapfile -t monitors < <(echo "$monitors_json" | jq -r '. | sort_by(.x) | .[].name')
workspace_count=$(echo "$workspaces_json" | jq -r '. | length')

echo "Detected ${#monitors[@]} monitors with $workspace_count workspaces"

# assign and move workspaces
if [[ "${#monitors[@]}" == 1 ]]; then
for ((i = 10; i >= 1; i--)); do
move_workspace "$workspaces_json" $i "${monitors[0]}"
done
elif [[ "${#monitors[@]}" == 2 ]]; then
for ((i = 10; i >= 6; i--)); do
move_workspace "$workspaces_json" $i "${monitors[1]}"
done
for ((i = 5; i >= 1; i--)); do
move_workspace "$workspaces_json" $i "${monitors[0]}"
done
elif [[ "${#monitors[@]}" == 3 ]]; then
for ((i = 10; i >= 8; i--)); do
move_workspace "$workspaces_json" $i "${monitors[2]}"
done
for ((i = 7; i >= 4; i--)); do
move_workspace "$workspaces_json" $i "${monitors[1]}"
done
for ((i = 3; i >= 1; i--)); do
move_workspace "$workspaces_json" $i "${monitors[0]}"
done
else # more than 3 monitors...
echo "Too many monitors"
fi

# activate first workspace of monitor if out of bounds
mapfile -t monitors < <(hyprctl monitors -j | jq -r '. | sort_by(.x) | .[].name')
for name in "${monitors[@]}"; do
active_workspace=$(echo "$monitors_json" | jq -r ".[] | select(.name == \"$name\") | .activeWorkspace.id")
if [[ $active_workspace -gt 10 ]]; then
first_workspace=$(echo "$workspaces_json" | jq -r "map(select(.monitor == \"$name\")) | min_by(.id) | .id")
echo "Activating workspace $first_workspace on monitor $name"
hyprctl dispatch workspace "$first_workspace" >/dev/null
fi
done

}

function configure_monitors() {
# rely an kanshi for profile detection and output configuration
# see https://todo.sr.ht/~emersion/kanshi/54#event-235509
echo "Configuring monitors..."
kanshi > /dev/null 2>&1 &
sleep 1
killall kanshi

# arrange workspaces to match the new configuration
echo "Configuring workspaces..."
arrange_workspaces
# rely an kanshi for profile detection and output configuration
# see https://todo.sr.ht/~emersion/kanshi/54#event-235509
echo "Configuring monitors..."
kanshi >/dev/null 2>&1 &
sleep 1
killall kanshi

# arrange workspaces to match the new configuration
echo "Configuring workspaces..."
# arrange_workspaces
}

function handle_event() {
if [[ ${1:0:12} == "monitoradded" ]]; then
echo "Event detected: monitor added"
@throttle configure_monitors
elif [[ ${1:0:14} == "monitorremoved" ]]; then
echo "Event detected: monitor removed"
@throttle configure_monitors
fi
if [[ ${1:0:12} == "monitoradded" ]]; then
echo "Event detected: monitor added"
@throttle configure_monitors
elif [[ ${1:0:14} == "monitorremoved" ]]; then
echo "Event detected: monitor removed"
@throttle configure_monitors
fi
}

cli_help() {
Expand All @@ -125,24 +124,27 @@ Commands:
"
}


case "$1" in
configure_monitors)
configure_monitors
;;
arrange_workspaces)
arrange_workspaces
;;
listen)
echo "Listening to monitor events..."
socat -U - "UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" | while read -r line; do handle_event "$line"; done
;;
help)
cli_help
;;
*)
echo "Invalid command $1"
cli_help
exit 1
;;
initialize)
configure_monitors
arrange_workspaces
;;
configure_monitors)
configure_monitors
;;
arrange_workspaces)
arrange_workspaces
;;
listen)
echo "Listening to monitor events..."
socat -U - "UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" | while read -r line; do handle_event "$line"; done
;;
help)
cli_help
;;
*)
echo "Invalid command $1"
cli_help
exit 1
;;
esac

0 comments on commit 01f9618

Please sign in to comment.