Created
May 8, 2025 08:56
-
-
Save fabienjuif/a00753dfab0042af25cb7df56a543824 to your computer and use it in GitHub Desktop.
Sway / Switch refresh rate (MAX_REFRESH_RATE) without vrr with half this value + vrr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| function usage() { | |
| echo "Usage: $0 <mode>" | |
| echo "Modes:" | |
| echo -e "\t- switch: Switch between max refresh rate with VRR disabled to half the refresh rate and VRR enabled" | |
| echo -e "\t- read: Read the current refresh rate" | |
| } | |
| # check min args | |
| if [ "$#" -ne 1 ]; then | |
| usage | |
| exit 1 | |
| fi | |
| MODE=$1 | |
| # check mode values | |
| if [ "${MODE}" != "switch" ] && [ "${MODE}" != "read" ]; then | |
| echo "Invalid mode: ${MODE}" | |
| echo "" | |
| usage | |
| exit 1 | |
| fi | |
| OUT=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused == true) | "\(.name) \(.current_mode.width) \(.current_mode.height) \(.current_mode.refresh) \(.adaptive_sync_status)"') | |
| IFS=' ' read -r OUTPUT_NAME OUTPUT_WIDTH OUTPUT_HEIGHT OUTPUT_REFRESH VRR <<< "$OUT" | |
| # in read mode | |
| OUTPUT_REFRESH=$((OUTPUT_REFRESH / 1000)) | |
| if [ "${MODE}" == "read" ]; then | |
| # check if VRR is enabled | |
| if [ "${VRR}" == "enabled" ]; then | |
| echo "${OUTPUT_REFRESH}Hz vrr" | |
| else | |
| echo "${OUTPUT_REFRESH}Hz" | |
| fi | |
| exit 0 | |
| fi | |
| # in switch mode | |
| REFRESH_RATES=($(swaymsg -t get_outputs | jq -r \ | |
| --argjson w "${OUTPUT_WIDTH}" \ | |
| --argjson h "${OUTPUT_HEIGHT}" \ | |
| '.[] | select(.focused == true) | .modes[] | |
| | select(.width == $w and .height == $h) | |
| | .refresh')) | |
| MAX_REFRESH_RATE=$(echo ${REFRESH_RATES} | sort -nr | head -n1) | |
| closest() { | |
| TARGET=$((MAX_REFRESH_RATE / 2)) | |
| local closest_val diff min_diff val | |
| min_diff= | |
| for val in "${REFRESH_RATES[@]}"; do | |
| diff=$(( val > TARGET ? val - TARGET : TARGET - val )) | |
| if [ -z "$min_diff" ] || [ "$diff" -lt "$min_diff" ]; then | |
| min_diff=$diff | |
| closest_val=$val | |
| fi | |
| done | |
| echo "$closest_val" | |
| } | |
| MIN_REFRESH_RATE=$(closest) | |
| MAX_REFRESH_RATE=$((MAX_REFRESH_RATE / 1000)) | |
| MIN_REFRESH_RATE=$((MIN_REFRESH_RATE / 1000)) | |
| echo MAX_REFRESH_RATE: ${MAX_REFRESH_RATE}Hz | |
| echo MIN_REFRESH_RATE: ${MIN_REFRESH_RATE}Hz | |
| # based on refresh rate (wxh@<refresh>Hz) | |
| if [[ "${OUTPUT_REFRESH}" == "${MAX_REFRESH_RATE}" ]]; then | |
| # set to MIN_REFRESH_RATE (VRR enabled) | |
| swaymsg output "${OUTPUT_NAME}" mode ${OUTPUT_WIDTH}x${OUTPUT_HEIGHT}@${MIN_REFRESH_RATE}Hz adaptive_sync on | |
| else | |
| # set to MAX_REFRESH_RATE (VRR disabled) | |
| swaymsg output "${OUTPUT_NAME}" mode ${OUTPUT_WIDTH}x${OUTPUT_HEIGHT}@${MAX_REFRESH_RATE}Hz adaptive_sync off | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment