Skip to content

Instantly share code, notes, and snippets.

@GrabbenD
Last active November 7, 2023 17:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GrabbenD/adc5a7a863cbd1553461376cf4c50467 to your computer and use it in GitHub Desktop.
Save GrabbenD/adc5a7a863cbd1553461376cf4c50467 to your computer and use it in GitHub Desktop.
[Sway] Use VRR in fullscreen only

VRR for fullscreen apps only

The idea behind this script is to only use VRR when a application is in fullscreen mode, here's the features:

  • Has multi monitor support through a output whitelist config (I'd like this to be automatic in the future but there doesn't seem to be any way in swaymsg to identify if a output is VRR capable, one thing which comes to mind is checking EDID for VRR range).
  • Determine if VRR needs to be toggled when a application is in fullscreen mode (which is how Windows does it usually and it's a option in Hyprland). This applies to:
    • Opening a app
    • Changing focus
    • Switching workplaces
    • Going into fullscreen mode (e.g. Youtube videos in Chromium)

As a result, you don't have to manually toggle VRR (which mitigates cursor stuttering in desktop mode when multi-tasking while gaming if VRR was to be enabled globally)


  1. Make sure to install jq before proceeding:

  2. $ less ~/.config/sway/config

    output DP-1 {
        mode 3840x1600@143.998Hz
        position 0 0
        adaptive_sync off # Recommended to avoid cursor stutter after starting Sway
    }
    
    output DP-2 {
        mode 1920x1080@119.982Hz
        position 3840 260
        adaptive_sync off
    }
    
    exec "~/.config/sway/scripts/vrr_fullscreen.sh"
  3. $ mkdir -p ~/.config/sway/scripts/ && chmod +x ~/.config/sway/scripts/vrr_fullscreen.sh

    $ touch ~/.config/sway/scripts/vrr_fullscreen.sh

    #!/bin/bash
    
    # List of supported outputs for VRR
    output_vrr_whitelist=(
        "DP-1"
        "DP-2"
    )
    
    # Toggle VRR for fullscreened apps in prespecified displays to avoid stutters while in desktop
    swaymsg -t subscribe -m '[ "window" ]' | while read window_json; do
        window_event=$(echo ${window_json} | jq -r '.change')
    
        # Process only focus change and fullscreen toggle
        if [[ $window_event = "focus" || $window_event = "fullscreen_mode" ]]; then
            output_json=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused == true)')
            output_name=$(echo ${output_json} | jq -r '.name')
    
            # Use only VRR in whitelisted outputs
            if [[ ${output_vrr_whitelist[*]} =~ ${output_name} ]]; then
                output_vrr_status=$(echo ${output_json} | jq -r '.adaptive_sync_status')
                window_fullscreen_status=$(echo ${window_json} | jq -r '.container.fullscreen_mode')
    
                # Only update output if nesseccary to avoid flickering
                [[ $output_vrr_status = "disabled" && $window_fullscreen_status = "1" ]] && swaymsg output "${output_name}" adaptive_sync 1
                [[ $output_vrr_status = "enabled" && $window_fullscreen_status = "0" ]] && swaymsg output "${output_name}" adaptive_sync 0
            fi
        fi
    done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment