Skip to content

Instantly share code, notes, and snippets.

@fabienjuif
Created May 8, 2025 08:56
Show Gist options
  • Select an option

  • Save fabienjuif/a00753dfab0042af25cb7df56a543824 to your computer and use it in GitHub Desktop.

Select an option

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