Hyprland
Hyprland copied to clipboard
VRR is broken in Hyprland
Hyprland Version
System/Version info
Hyprland, built from branch main at commit cba1ade848feac44b2eda677503900639581c3f4 (props: bump version to 0.40.0).
Date: Sat May 4 15:42:32 2024
Tag: , commits: 1
flags: (if any)
System Information:
System name: Linux
Node name: gwen-x570
Release: 6.8.9-300.fc40.x86_64
Version: #1 SMP PREEMPT_DYNAMIC Thu May 2 18:59:06 UTC 2024
GPU information:
05:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP106 [GeForce GTX 1060 6GB] [10de:1c03] (rev a1) (prog-if 00 [VGA controller])
0c:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 22 [Radeon RX 6700/6700 XT/6750 XT / 6800M/6850M XT] [1002:73df] (rev c1) (prog-if 00 [VGA controller])
os-release: NAME="Fedora Linux"
VERSION="40 (Sway)"
ID=fedora
VERSION_ID=40
VERSION_CODENAME=""
PLATFORM_ID="platform:f40"
PRETTY_NAME="Fedora Linux 40 (Sway)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:40"
DEFAULT_HOSTNAME="fedora"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f40/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://gitlab.com/fedora/sigs/sway/SIG/-/issues"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=40
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=40
SUPPORT_END=2025-05-13
VARIANT="Sway"
VARIANT_ID=sway
plugins:
Bug or Regression?
Bug
Description
The refresh rate of my monitor in games with VRR enabled constantly jumps up to it's maximum every 1-2 seconds. Using the mouse causes this to happen even more often (multiple times a second) even though the mouse isn't on screen at all in games where it controls the camera.
I've tried unplugging the mouse and changing every setting I can related to display, direct scanout, input. I've also tried launching hyprland with a blank config containing nothing except display configurations and a hotkey to launch a game or vkcube or glxgears.
I've tried all of the above on fresh installs of Fedora and Arch as well with different kernels as well as versions 0.40.0, 0.39.1, 0.39.0 of hyprland all with no luck as in all cases it's exhibited the exact same bug.
The thing that makes me believe that this is a Hyprland specific issue is that this doesn't occur under Sway at all. With Sway the monitor refresh rate never jumps from the in game framerate no matter what is occuring in game, what input is being recieved or what processes are running in the background or on other screens. And for my own sanitys sake I've tested and can confirm this doesn't happen under windows either. So it's not an issue with my hardware, linux or wayland, but with Hyprland.
I've attatched a clip below I have of the issue showing both my monitor's refresh rate and mangohud's frametime graph/fps counter in a 3rd person shooter where I'm standing still with the fps capped and barely stressing my hardware.
(Ignore the GTX 1060 in the system info, it's used only for vfio and not active)
How to reproduce
Launch a fullscreen game with vrr enabled and limit your framerate to something lower than your monitors maximum and check if it actually holds that refresh rate on your monitors OSD.
Crash reports, logs, images, videos
https://github.com/hyprwm/Hyprland/assets/14289733/ffcbc0ca-60f0-40e3-ab7f-301b0c527d09
#4436 literally same title
#4436 literally same title
Same title but very different bug with a solution I've already tried.
sounds like the same to me? fps jumps to max?
sounds like the same to me? fps jumps to max?
Their issue was the refresh rate being stuck at max and jumping if below thier vrr range which was caused by an animation in hyprland running in the background that forced the refresh rate up.
Mine is that my refresh rate matches my fps but spikes. Which I've now narrowed down to something to do with the way hyprland manages it's mouse input. https://github.com/hyprwm/Hyprland/pull/5895 seems to have fixed the random spikes but I still get a spike to max every time I press any mouse button (left mouse, right mouse, button 4, button 5, etc) but not on mouse movements or any keyboard input. Spamming mouse buttons causes the behaviour in the video even though you'd think it would cause many more spikes. So I have no clue what causes it but it's definitely mouse input related.
okay, I get you now
is the game fullscreen? is it xwayland?
Yes it's full screen. I'm not sure if the game I tested (Orcs must die 3) was xwayland or not, but the same issue occurs on glxgears or vkcube if I cap their fps and fullscreen them and then press mouse buttons while keeping the pointer stationary (so that mouse movements don't artificially raise the fps)
Yes it's full screen. I'm not sure if the game I tested (Orcs must die 3) was xwayland or not, but the same issue occurs on glxgears or vkcube if I cap their fps and fullscreen them and then press mouse buttons while keeping the pointer stationary (so that mouse movements don't artificially raise the fps)
Actually I just tested this again. It must be just an xwayland thing as it does doesn't appear in vkcube but does in glxgears.
Please ensure you're not running into https://gitlab.freedesktop.org/drm/amd/-/issues/1500.
echo 4 | sudo tee /sys/class/drm/card1/device/pp_power_profile_mode
I am not running into that issue. I already have my power profile forced.
#6483 claims to fix this and #6222. While it does prevent the refresh rate from jumping up to the max on mouse movement in applications where the mouse is visible. It however still doesn't solve the issue of mouse button inputs causing the refresh rate to spike up to max every now and then as shown in the video originally posted.
Honestly I have no clue why inputs from mouse buttons cause this but not inputs from keyboard or controller buttons do so.
Hm, in my case button inputs do not change refresh rate but moving the camera using my mouse (no cursor visible) apparently still does. Mangohud also flickers during this; it might not be visible in the additional frames being generated?
Moving the mouse cursor while it's visible does not trigger this anymore using https://github.com/hyprwm/Hyprland/pull/6483 as expected.
More critically though, when apps are in fullscreen, the frame presentation is messed up for a few frames whenever the mouse is moved with frame order sometimes being wrong but also randomly every second or so with no input. It's really weird and hard to describe but you'll know it when you see it. It manifests as a sort of stutter where it rubber-bands between some previous frame(s?) and the actual one.
When I set the app to windowed and then fullscreen 2 it, this does not happen.
Does that also happen for you @Gwenodai?
What I also noticed is that when I switch to a different workspace than the one the game is in, wait a little and then switch back again, the game is in super speed mode and "catches up" to the current time for a few frames. During this time, animations appear very quick. However, it does not just appear to be a presentation issue with frames being queued because the audio also does this; environmental sound effects that would play with <1Hz (and do in the background which is extra weird) then come out with a few dozen Hz for a second or so. This must be causing some sort of queuing inside the game?
I am not sure this is directly related to VRR though.
(I repro'd this in GW2 standing in Lion's Arch standing near the water features that trigger a distinct sound every so often.)
My config
# #######################################################################################
# AUTOGENERATED HYPR CONFIG.
# PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hypr.conf AND EDIT IT,
# OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
# #######################################################################################
# autogenerated = 1 # remove this line to remove the warning
# This is an example Hyprland config file.
# Refer to the wiki for more information.
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
# Please note not all available settings / options are set here.
# For a full list, see the wiki
# You can split this configuration into multiple files
# Create your files separately and then link them to this file like this:
# source = ~/.config/hypr/myColors.conf
################
### MONITORS ###
################
# See https://wiki.hyprland.org/Configuring/Monitors/
monitor=,preferred,auto,auto
###################
### MY PROGRAMS ###
###################
# See https://wiki.hyprland.org/Configuring/Keywords/
# Set programs that you use
$terminal = mlterm
$fileManager = dolphin
$menu = wofi --show drun
#################
### AUTOSTART ###
#################
# Autostart necessary processes (like notifications daemons, status bars, etc.)
# Or execute your favorite apps at launch like this:
# exec-once = $terminal
# exec-once = nm-applet &
# exec-once = waybar & hyprpaper & firefox
exec-once = hypridle
#############################
### ENVIRONMENT VARIABLES ###
#############################
# See https://wiki.hyprland.org/Configuring/Environment-variables/
env = XCURSOR_SIZE,24
env = HYPRCURSOR_SIZE,24
# Work around https://github.com/hyprwm/Hyprland/issues/6501
env = PATH,$HOME/.local/bin/:$PATH
#####################
### LOOK AND FEEL ###
#####################
# Refer to https://wiki.hyprland.org/Configuring/Variables/
# https://wiki.hyprland.org/Configuring/Variables/#general
general {
gaps_in = 2
gaps_out = 0
border_size = 1
# https://wiki.hyprland.org/Configuring/Variables/#variable-types for info about colors
col.active_border = rgba(33ccffee)# rgba(00ff99ee) 45deg
col.inactive_border = rgba(595959aa)
# Set to true enable resizing windows by clicking and dragging on borders and gaps
resize_on_border = true
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
allow_tearing = false
# layout = dwindle
}
# https://wiki.hyprland.org/Configuring/Variables/#decoration
decoration {
# rounding = 10
# Change transparency of focused and unfocused windows
active_opacity = 1.0
inactive_opacity = 1.0
drop_shadow = false
shadow_range = 4
shadow_render_power = 3
col.shadow = rgba(1a1a1aee)
# https://wiki.hyprland.org/Configuring/Variables/#blur
blur {
enabled = false
size = 3
passes = 1
vibrancy = 0.1696
}
}
# https://wiki.hyprland.org/Configuring/Variables/#animations
animations {
enabled = true
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
animation = global, 0, 7, myBezier
animation = workspaces, 1, 1.5, default
}
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
dwindle {
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true # You probably want this
force_split = 2
no_gaps_when_only = true
}
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
master {
new_is_master = true
}
group {
groupbar {
render_titles = false
height = 1
}
}
# https://wiki.hyprland.org/Configuring/Variables/#misc
misc {
force_default_wallpaper = 1 # Set to 0 or 1 to disable the anime mascot wallpapers
disable_hyprland_logo = true # If true disables the random hyprland logo / anime girl background. :(
# I'd like my screen to turn on when I press a button please
mouse_move_enables_dpms = true
key_press_enables_dpms = true
# Variable frame rate?
# TODO need to test whether this affects input delay
vfr = true
vrr = 1
no_direct_scanout = false
}
cursor {
no_hardware_cursors = true
hide_on_key_press = false
no_break_fs_vrr = true
}
# debug {
# overlay = true
# }
xwayland {
force_zero_scaling = true
}
#############
### INPUT ###
#############
# https://wiki.hyprland.org/Configuring/Variables/#input
input {
kb_layout = us
kb_variant = altgr-intl
kb_model =
kb_options = caps:escape
kb_rules =
repeat_rate = 30
repeat_delay = 200
accel_profile = flat
follow_mouse = 1
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
touchpad {
natural_scroll = false
scroll_factor = 0.5
}
}
# https://wiki.hyprland.org/Configuring/Variables/#gestures
gestures {
workspace_swipe = true
# workspace_swipe_distance = 200
workspace_swipe_min_speed_to_force = 10
workspace_swipe_invert = false
}
# Example per-device config
# See https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs for more
device {
name = pixa3854:00-093a:0274-touchpad
sensitivity = -0.25
}
####################
### KEYBINDINGSS ###
####################
# See https://wiki.hyprland.org/Configuring/Keywords/
$mainMod = SUPER # Sets "Windows" key as main modifier
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind = $mainMod, RETURN, exec, $terminal
bind = $mainMod, w, killactive,
unbind = $mainMod, e # Needs to be done for some reason? # TODO still necessary now that I do shift properly?
bind = $mainMod, e, exec, emacsclient -c
bind = $mainMod SHIFT, E, exit,
bind = $mainMod, ESCAPE, exec, loginctl lock-session
bind = $mainMod SHIFT, s, exec, systemctl suspend
bind = $mainMod, SPACE, togglefloating,
bind = $mainMod, x, exec, $menu
# bind = $mainMod, P, pseudo, # dwindle
bind = $mainMod, s, togglesplit, # dwindle
unbind = $mainMod, f
bind = $mainMod, f, fullscreen, 2
bind = $mainMod SHIFT, f, fullscreen, 1
bind = $mainMod, t, togglegroup,
# Move focus with mainMod + vi keys
bind = $mainMod, h, movefocus, l
bind = $mainMod, l, movefocus, r
bind = $mainMod, k, movefocus, u
bind = $mainMod, j, movefocus, d
# Move window with mainMod + vi keys
bind = $mainMod SHIFT, h, movewindoworgroup, l
bind = $mainMod SHIFT, l, movewindoworgroup, r
bind = $mainMod SHIFT, k, movewindoworgroup, u
bind = $mainMod SHIFT, j, movewindoworgroup, d
bind = $mainMod, u, lockactivegroup, lock
bind = $mainMod, d, lockactivegroup, unlock
bind = $mainMod, grave, changegroupactive, f
bind = $mainMod SHIFT, grave, changegroupactive, b
# Switch workspaces with mainMod + [0-9]
bind = $mainMod, 1, workspace, 1
bind = $mainMod, 2, workspace, 2
bind = $mainMod, 3, workspace, 3
bind = $mainMod, 4, workspace, 4
bind = $mainMod, 5, workspace, 5
bind = $mainMod, 6, workspace, 6
bind = $mainMod, 7, workspace, 7
bind = $mainMod, 8, workspace, 8
bind = $mainMod, 9, workspace, 9
bind = $mainMod, 0, workspace, 10
# Move active window to a workspace with mainMod + SHIFT + [0-9]
bind = $mainMod SHIFT, 1, movetoworkspacesilent, 1
bind = $mainMod SHIFT, 2, movetoworkspacesilent, 2
bind = $mainMod SHIFT, 3, movetoworkspacesilent, 3
bind = $mainMod SHIFT, 4, movetoworkspacesilent, 4
bind = $mainMod SHIFT, 5, movetoworkspacesilent, 5
bind = $mainMod SHIFT, 6, movetoworkspacesilent, 6
bind = $mainMod SHIFT, 7, movetoworkspacesilent, 7
bind = $mainMod SHIFT, 8, movetoworkspacesilent, 8
bind = $mainMod SHIFT, 9, movetoworkspacesilent, 9
bind = $mainMod SHIFT, 0, movetoworkspacesilent, 10
# Example special workspace (scratchpad)
bind = $mainMod, p, togglespecialworkspace, magic
bind = $mainMod SHIFT, p, movetoworkspacesilent, special:magic
# Scroll through existing workspaces with mainMod + scroll
bind = $mainMod, mouse_down, workspace, e+1
bind = $mainMod, mouse_up, workspace, e-1
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow
binde = , XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 2%+
binde = , XF86AudioLowerVolume, exec, wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 2%-
binde = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
binde = , XF86MonBrightnessUp, exec, brightnessctl set +3%
binde = , XF86MonBrightnessDown, exec, brightnessctl set 3%-
##############################
### WINDOWS AND WORKSPACES ###
##############################
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules
# Example windowrule v1
# windowrule = float, ^(kitty)$
# Example windowrule v2
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
@Atemu Upon further testing it would appear my initial findings were indeed incorrect. The issue is now even worse than it used to be. I still have the jumping refresh rate during mouse button inputs but I also now have the refresh rate locked to the max when the mouse is in motion even with the cursor invisible in fps and third person games.
As for the other bug you described with frame presentation. I can't manage to reproduce it myself, so I'm of no help there sadly.
As far as I can tell 0.40.0 is the last proper build with proper functional vrr support when the mouse is in motion. I've tested the latest git as well as 0.41.1, and 0.41.0 and they all break from the actual refresh rate when moving the mouse.
'no_break_fs_vrr' in the current git also does not seem to do anything at all for the issue. However it does allow you to create a laggy cursor in full screen apps with visible cursors, so there's that.
So for now I'm gonna go back to 0.40.0 until later releases. I can live with the mini spikes on mouse button inputs but vrr may as well be disabled entirely with every version above 0.40.0.
Oh my god I've finally narrowed down my particular issue with the spikes!
When you have a window fullscreened it gets given the properties "fullscreen": true and "fullscreenMode": 0. This is what games request upon being launched and what happens when you use a bind to call fullscreen, 0 for the active application. (I assume the same most likely applies to fullscreen, 1 windows too)
However the issue comes into play when a window has those properties along with "floating": true. This causes it to spike the refresh rate sometimes when you interact with it using mouse buttons for some reason. I'd never considered that the floating parameter would even have any effect on a fullscreened window before. And it seems that every game I've tested starts with those exact parameters, which explains why I've been experiencing the issue.
Hopefully this can help narrow down the cause of the issue. However I have no idea if the issue exists above 0.40.0 as it seems vrr is completely broken on any later version, so I can't test that.
As for the other bug you described with frame presentation. I can't manage to reproduce it myself, so I'm of no help there sadly.
Interesting.
Is V-sync (FIFO) enabled/forced? I force it in Mangohud for all games as it's required for VRR to work properly.
'no_break_fs_vrr' in the current git also does not seem to do anything at all for the issue. However it does allow you to create a laggy cursor in full screen apps with visible cursors, so there's that.
This might be intended behaviour. If the game is running at 60fps, your refresh rate should be 60Hz and the cursor therefore as laggy as 60Hz. Or do you mean it's laggier than the low refresh rate would suggest?
However I have no idea if the issue exists above 0.40.0 as it seems vrr is completely broken on any later version, so I can't test that.
VRR is working for me on 0.41.1, though with the issues I mentioned.
Could you post your config? Particularly vrr and no_direct_scanout.
Is V-sync (FIFO) enabled/forced? I force it in Mangohud for all games as it's required for VRR to work properly.
I don't have V-sync forced or even set in mangohud at all. I just have it set to limit my fps via:
fps_limit_method=late
fps_limit=140,120,60,30
V-sync doesn't seem to have any effect whatsoever on vrr for me so I just default to turning it off in games. And after setting rules so that steam games and other specified games run in tiled fullscreen instead of floating fullscreen I've had zero vrr issues on 0.40.0 with my current set up. (I really have no idea why that even works)
This might be intended behaviour. If the game is running at 60fps, your refresh rate should be 60Hz and the cursor therefore as laggy as 60Hz. Or do you mean it's laggier than the low refresh rate would suggest?
Oh yea I believe it is the intended behaviour. I was joking about how it affects non game apps when set to fullscreen, though that may be due to VFR and VRR being on. I'd assume it might fix games where your cursor is meant to be visible but all I know is that it has zero effect on any games where the cursor controls that camera (invisible cursor). In those games the refresh rate sits at 144 when the mouse is moving regardless of that setting, so it's not really something you can test atm.
VRR is working for me on 0.41.1, though with the issues I mentioned.
Oh yes I didn't mean it was 100% non-functional. Moreso that due to the fact that you can't even move the mouse at all anymore without breaking vrr above 0.40.0, it's practically completely broken unless you happen to be using a controller or playing only with a keyboard I guess. Considering half the games I play use my mouse I'd consider it a completely broken feature that should just be disabled if you're running anything above 0.40.0. That or just stick with 0.40.0 until it eventually gets fixed later down the line if vrr is as important to you as it is to me.
Could you post your config? Particularly
vrrandno_direct_scanout.
My config is split up a bit so I'll post them in idividual parts below. Though do note I've tried multiple different vrr and no_direct_scanout settings and they mostly don't seem to matter outside of weird interactions. Like no_direct_scanout = false seems to disable vrr sometimes on older hyprland versions but only on regular workspaces for some reason. Either way I've tested many different combinations across every version of hyprland I've tested but settled on vrr = 1 and no_direct_scanout = false for my daily use as vrr = 2 only inherits the fullscreen status of the regular workspace on the monitor and not the special workspace above it. This results in vrr only being enabled if a game is on a regular workspace or if the workspace below the special one has a fullscreen application open.
hyprland.conf
monitor=,preferred,auto,auto
source=~/.config/hypr/config/variables.conf
source=~/.config/hypr/config/startup.conf
source=~/.config/hypr/config/settings.conf
source=~/.config/hypr/config/animations.conf
source=~/.config/hypr/config/displays.conf
source=~/.config/hypr/config/displaysExternal.conf
source=~/.config/hypr/config/keybinds.conf
source=~/.config/hypr/config/rules.conf
variables.conf
env = XCURSOR_THEME,Vimix-cursors
env = XCURSOR_SIZE,24
env = QT_QPA_PLATFORM, wayland
env = QT_QPA_PLATFORMTHEME, qt5ct
env = WLR_NO_HARDWARE_CURSORS,1 # Moving into 'cursor' after 0.41.0
env = XDG_CURRENT_DESKTOP,Hyprland
env = XDG_SESSION_TYPE,wayland
env = XDG_SESSION_DESKTOP,Hyprland
startup.conf
$scripts = $HOME/.config/hypr/scripts
# wallpaper
exec-once = swww query || swww init
# Core components (authentication, lock screen, notification daemon)
exec-once = $HOME/.local/bin/polkit-daemon
exec-once = dbus-update-activation-environment --all
exec-once = sleep 1 && dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # Some fix idk
exec-once = sleep 1 && systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
# Clipboard: history
exec-once = wl-paste --type text --watch cliphist store
exec-once = wl-paste --type image --watch cliphist store
# UI applications
exec-once = waybar
exec-once = ags -c ~/.config/ags/overview.js
exec-once = swaync
exec-once = swayosd-server
# Daemons
exec-once = $scripts/hyprDaemon.sh
exec-once = hypridle
# Startup applications
exec-once = corectrl --minimize-systray
exec-once = LD_PRELOAD=/home/gwen/Storage/repos/extest/target/i686-unknown-linux-gnu/release/libextest.so mangohud steam -silent #Steam with patches
exec-once = flatpak run com.spotify.Client
exec-once = heroic
exec-once = vesktop --start-minimized
exec-once = flatpak run com.sindresorhus.Caprine
exec-once = flatpak run ca.andyholmes.Valent --gapplication-service
exec-once = sunshine
# Set Display and Audio back to default
exec-once = $scripts/resetMonitors.sh
# Special startup script (Manually hidden/Scripted startups)
exec-once = $scripts/specialStartup.sh
settings.conf
input {
kb_layout = us
numlock_by_default = true
repeat_delay = 250
repeat_rate = 35
sensitivity = 0.7
accel_profile = flat
mouse_refocus = true
float_switch_override_focus = 1
special_fallthrough = false
follow_mouse = 1
}
# # Only used in 0.41.0
# cursor {
# no_hardware_cursors = true
# inactive_timeout = 3
# default_monitor = DP-1
# # # Only used in git (probably 0.42.0)
# # no_break_fs_vrr = true
# # min_refresh_rate = 48
# }
binds {
workspace_back_and_forth=1
scroll_event_delay = 0
}
general {
# Gaps and border
no_border_on_floating = false
gaps_in = 3
gaps_out = 3
gaps_workspaces = 50
border_size = 1
#Colours
col.active_border = rgba(ff00ad85)
col.inactive_border = rgba(59595900)
resize_on_border = false
extend_border_grab_area = false
hover_icon_on_border = false
# no_focus_fallback = true
layout = dwindle
allow_tearing = false
# Moving into 'cursor' after 0.41.0
default_cursor_monitor = DP-1
cursor_inactive_timeout = 3
}
dwindle {
preserve_split = true
pseudotile = true
smart_split = false
smart_resizing = true
no_gaps_when_only = false
}
decoration {
rounding = 20
active_opacity = 1.0
inactive_opacity = 0.9
fullscreen_opacity = 1.0
blur {
enabled = true
xray = false
special = true
new_optimizations = true
size = 5
passes = 3
brightness = 0.8
noise = 0.01
contrast = 1
ignore_opacity = false
popups = true
popups_ignorealpha = 0.6
}
# Shadow
drop_shadow = true
shadow_ignore_window = true
shadow_range = 16
shadow_offset = 2 2
shadow_render_power = 2
col.shadow = rgba(00000076)
# Dim
dim_inactive = false
dim_strength = 0.1
dim_special = 0
}
misc {
vfr = 1
vrr = 1
no_direct_scanout = false
focus_on_activate = false
animate_manual_resizes = false
animate_mouse_windowdragging = false
enable_swallow = false
# swallow_regex = (kitty|YACReaderLibrary)
mouse_move_enables_dpms = true
key_press_enables_dpms = true
disable_hyprland_logo = true
force_default_wallpaper = 0
new_window_takes_over_fullscreen = 0
initial_workspace_tracking = 0
}
animations.conf
animations {
enabled = true
# Animation curves
bezier = linear, 0, 0, 1, 1
bezier = md3_standard, 0.2, 0, 0, 1
bezier = md3_decel, 0.05, 0.7, 0.1, 1
bezier = md3_accel, 0.3, 0, 0.8, 0.15
bezier = overshot, 0.05, 0.9, 0.1, 1.1
bezier = crazyshot, 0.1, 1.5, 0.76, 0.92
bezier = hyprnostretch, 0.05, 0.9, 0.1, 1.0
bezier = menu_decel, 0.1, 1, 0, 1
bezier = menu_accel, 0.38, 0.04, 1, 0.07
bezier = easeInOutCirc, 0.85, 0, 0.15, 1
bezier = easeOutCirc, 0, 0.55, 0.45, 1
bezier = easeOutExpo, 0.16, 1, 0.3, 1
bezier = softAcDecel, 0.26, 0.26, 0.15, 1
bezier = md2, 0.4, 0, 0.2, 1 # use with .2s duration
# Animation configs
animation = windows, 1, 3, md3_decel, popin 60%
animation = windowsIn, 1, 3, md3_decel, popin 60%
animation = windowsOut, 1, 3, md3_accel, popin 60%
animation = border, 1, 10, default
animation = fade, 1, 3, md3_decel
animation = layersIn, 1, 3, menu_decel, slide
animation = layersOut, 1, 1.6, menu_accel
animation = fadeLayersIn, 1, 3, menu_decel
animation = fadeLayersOut, 1, 1.6, menu_accel
animation = workspaces, 1, 7, menu_decel, slide
animation = specialWorkspace, 1, 3, md3_decel, slidevert
}
displaysExternal.conf
monitor=HDMI-A-1,disabled
keybinds.conf
#################### Variables ###################
$terminal = kitty --single-instance
$fileManager = nemo
$webBroswer = google-chrome
$menu = pkill rofi || rofi -show drun -display-drun "" -icon-theme "Papirus Dark" -show-icons
$menu2 = pkill rofi || rofi -show run -display-run "" -icon-theme "Papirus Dark" -show-icons
################### keybinds ###################
# Volume
bindle = , XF86AudioRaiseVolume, exec, swayosd-client --output-volume raise
bindle = , XF86AudioLowerVolume, exec, swayosd-client --output-volume lower
bindl = , XF86AudioMute, exec, swayosd-client --output-volume mute-toggle
################################### Applications ###################################
# Apps: just normal apps
bind = Super, Q, exec, $terminal
bind = Super, E, exec, $fileManager
bind = Super, W, exec, $webBroswer
bind = Super, G, exec, swaync-client -t -sw
# Apps: Settings and config
bind = Control+Shift, Escape, exec, flatpak run net.nokyan.Resources
# Actions
bind = Super+Shift, P, pseudo, # dwindle
bind = Super, Z, togglesplit, # dwindle
bind = Super, C, killactive,
bind = Super, V, togglefloating,
bind = Super+Shift, V, exec, $scripts/pin.sh
bind = Super, Tab, exec, ags -t overview # open overview
# Screenshot, Color picker, Clipboard history
bind = Super+Control, S, exec, $HOME/.local/bin/hyprshot -m window -m active -o $HOME/Documents/Pictures/Screenshots | wl-copy
bindl = , Print, exec, $HOME/.local/bin/hyprshot -m output -m active -o $HOME/Documents/Pictures/Screenshots | wl-copy
bind = Super+Control, C, exec, hyprpicker -a
bind = Super+Control, V, exec, pkill rofi || cliphist list | rofi -dmenu | cliphist decode | wl-copy
# Media
bindl= ,XF86AudioPlay, exec, playerctl play-pause
bindl= ,XF86AudioStop, exec, playerctl stop
bindl= ,XF86AudioNext, exec, playerctl next
bindl= ,XF86AudioPrev, exec, playerctl previous
# App launchers
bind = Super, R, exec, $menu
bind = Super+Shift, R, exec, $menu2
##################################### Special keybinds #####################################
# Refresh waybar, swaync, rofi
bindr = Control+Super, R, exec, $scripts/refresh.sh
# Wallpapers
bind = Super+Shift, W, exec, $scripts/wallpaperSelect.sh # Select wallpaper to apply
# Waybar / Bar related
bind = Super, B, exec, killall -SIGUSR1 waybar # Toggle hide/show waybar
########################### Keybinds for Hyprland ############################
# Swap windows
bind = Super+Shift, left, movewindow, l
bind = Super+Shift, right, movewindow, r
bind = Super+Shift, up, movewindow, u
bind = Super+Shift, down, movewindow, d
# Move focus
bind = Super, left, movefocus, l
bind = Super, right, movefocus, r
bind = Super, up, movefocus, u
bind = Super, down, movefocus, d
bind = Super, Space, exec, $scripts/swapWorkspaces.sh "DP-1" "DP-2"
# Workspace switch with arrows
bind = Control+Super, right, workspace, +1
bind = Control+Super, left, workspace, -1
# Window split ratio
binde = Super, Minus, splitratio, -0.1
binde = Super, Equal, splitratio, 0.1
binde = Super, Semicolon, splitratio, -0.1
binde = Super, Apostrophe, splitratio, 0.1
# Fullscreen
bind = Super, F, fullscreen, 0
bind = Super, D, fullscreen, 1
bind = Super_Alt, F, fakefullscreen
# Switching
bind = Super, 1, focusworkspaceoncurrentmonitor, 1
bind = Super, 2, focusworkspaceoncurrentmonitor, 2
bind = Super, 3, focusworkspaceoncurrentmonitor, 3
bind = Super, 4, focusworkspaceoncurrentmonitor, 4
bind = Super, 5, focusworkspaceoncurrentmonitor, 5
bind = Super, 6, focusworkspaceoncurrentmonitor, 6
bind = Super, 7, focusworkspaceoncurrentmonitor, 7
bind = Super, 8, focusworkspaceoncurrentmonitor, 8
bind = Super, 9, focusworkspaceoncurrentmonitor, 9
bind = Super, 0, focusworkspaceoncurrentmonitor, 10
bind = Super, S, togglespecialworkspace,
bind = Super, X, togglespecialworkspace, game # Game workspace
bind = Super, A, togglespecialworkspace, alt
bind = Alt, Tab, cyclenext
bind = Alt, Tab, bringactivetotop, # bring it to the top
# Move window to workspace Super + Alt + [0-9]
bind = Super+Shift, 1, movetoworkspacesilent, 1
bind = Super+Shift, 2, movetoworkspacesilent, 2
bind = Super+Shift, 3, movetoworkspacesilent, 3
bind = Super+Shift, 4, movetoworkspacesilent, 4
bind = Super+Shift, 5, movetoworkspacesilent, 5
bind = Super+Shift, 6, movetoworkspacesilent, 6
bind = Super+Shift, 7, movetoworkspacesilent, 7
bind = Super+Shift, 8, movetoworkspacesilent, 8
bind = Super+Shift, 9, movetoworkspacesilent, 9
bind = Super+Shift, 0, movetoworkspacesilent, 10
bind = Super+Shift, S, movetoworkspacesilent, special
bind = Super+Shift, X, movetoworkspacesilent, special:game # Game workspace
bind = Super+Shift, A, movetoworkspacesilent, special:alt
# Scroll through existing workspaces with (Control) + Super + scroll
bind = Super, mouse_up, workspace, e+1
bind = Super, mouse_down, workspace, e-1
bind = Control+Super, mouse_up, workspace, +1
bind = Control+Super, mouse_down, workspace, -1
# Move/resize windows with Super + LMB/RMB and dragging
bindm = Super, mouse:272, movewindow
bindm = Super, mouse:273, resizewindow
rules.conf
######## Window rules ########
# Fullscreen/Pinned windows
windowrulev2 = bordercolor rgba(FFB2BCAA),pinned:1
windowrulev2 = bordercolor rgba(00fbff85),fullscreen:1
# Supress maximize events
windowrulev2 = suppressevent maximize, class:.* # (!)
# file-roller
windowrulev2 = center,class:^(file-roller)$
windowrulev2 = center,class:^(org.gnome.FileRoller)$
windowrulev2 = float,class:^(file-roller)$
windowrulev2 = float,class:^(org.gnome.FileRoller)$
windowrulev2 = size 900 600,class:^(org.gnome.FileRoller)$
# Nemo File Manager
windowrulev2 = float,class:^(nemo)$,title:(Properties)$
# Steam
windowrule = float,title:^(Create or select new Steam library folder)$
windowrule = float,title:^(Steam Settings)$
windowrule = workspace special:game,title:^(Steam Big Picture Mode)$
windowrule = tile,title:^(Steam Big Picture Mode)$
# ProtonUp-Qt
windowrulev2 = float,class:^(net.davidotek.pupgui2)$
# Calculator
windowrulev2 = float,class:^(org.gnome.Calculator)$
windowrulev2 = size 420 640,class:^(org.gnome.Calculator)$
# Google-Chrome
windowrulev2 = float,class:^(google-chrome)$,title:^(Open File)$
windowrulev2 = float,class:^(google-chrome)$,title:^(Open Files)$
# Spotify
windowrulev2 = workspace special:alt silent,class:(Spotify)$
# Start games tiled to prevent vrr spike bug
windowrulev2 = tile,class:^(steam_app_)(.*)$
windowrulev2 = tile,class:^(.*)(exe)$
######## Misc Dialogs/Pop-up windows ########
windowrule = float,title:^(Choose Files)$
windowrule = float,title:^(Choose wallpaper)(.*)$
windowrule = float,title:^(Confirm to replace files)$
windowrule = float,title:^(File Operation Progress)$
windowrule = float,title:^(Library)(.*)$
windowrule = float,title:^(Open File)(.*)$
windowrule = float,title:^(Open Folder)(.*)$
windowrule = float,title:^(Select Folder)(.*)$
windowrule = float,title:^(Open)$
windowrule = float,title:^(Save As)(.*)$
windowrule = float,title:^(Select a File)(.*)$
######## Workspace rules ########
workspace = 1, monitor:DP-1, default:true, persistent:true
######## Layer rules ########
# Rofi (App launcher)
layerrule = ignorealpha 0.0, rofi
layerrule = blur, rofi
layerrule = animation slide bottom, rofi
# Waybar
layerrule = ignorealpha 0.0, waybar
layerrule = blur, waybar
# SwayNotificationCenter
layerrule = ignorealpha 0.0, swaync-control-center
layerrule = ignorealpha 0.0, swaync-notification-window
layerrule = blur, swaync-control-center
layerrule = blur, swaync-notification-window
layerrule = animation slide right, swaync-control-center
# SwayOSD (Volume OSD)
layerrule = ignorealpha 0.01, swayosd
layerrule = blur, swayosd
# hyprswitch (Win+Tab popup)
layerrule = ignorealpha 0.0, hyprswitch
layerrule = blur, hyprswitch
# Colour picker/Screenshots
layerrule = noanim, hyprpicker
layerrule = noanim, selection
# Overview
layerrule = ignorealpha 0.0, overview
layerrule = blur, overview
layerrule = animation slide top, overview
# Misc
layerrule = ignorealpha 0.6, shell:*
layerrule = ignorealpha 0.0 gtk-layer-shell
layerrule = blur, shell:*
layerrule = blur, gtk-layer-shell
######## Transparent Windows ########
windowrulev2 = opacity 0.85,floating:1 # Make all floating windows transparent
# Force full opacity on fullscreen windows above this
windowrulev2 = opacity 1.0 override, fullscreen:1
# Windows that want opacity while fullscreen below this
windowrule = opacity 0.9, ^(sublime_text)$
windowrule = opacity 0.8, ^(nemo)$
windowrule = opacity 0.85, ^(vesktop)$
windowrulev2 = opacity 0.85,class:(Spotify)$
######## PIP rules ########
windowrulev2 = opacity 1.0 0.75,title:^(Picture-in-Picture)$
windowrulev2 = float, title:^(Picture-in-Picture)$
windowrulev2 = move 72% 7%,title:^(Picture-in-Picture)$
windowrulev2 = pin,title:^(Picture-in-Picture)$
windowrulev2 = size 25% 25%,title:^(Picture-in-Picture)$
Oh yea I believe it is the intended behaviour. I was joking about how it affects non game apps when set to fullscreen, though that may be due to VFR and VRR being on. I'd assume it might fix games where your cursor is meant to be visible but all I know is that it has zero effect on any games where the cursor controls that camera (invisible cursor). In those games the refresh rate sits at 144 when the mouse is moving regardless of that setting, so it's not really something you can test atm.
@Gwenodai I can confirm the above: no_break_fs_vrr works for me in games with a visible cursor: the refresh rate follows the game FPS when moving the mouse (as an example, Divinity: Original Sin 2).
However, in games with an invisible one (The Witcher 3: Wild Hunt for example), whenever I move the mouse, the refresh rate of the monitor maxes out immediately.
cc @UjinT34
no_break_fs_vrr is very limited. It only works with no_hardware_cursors = true and fullscreen apps when VRR is active. And this option alone will cause mouse to freeze if the app doesn't have a steady framerate. Most of the non-game app won't. So there is cursor:min_refresh_rate which fixes the freezing but might cause flickering and stuttering.
These options might not be suitable for every situation and for now should be tweaked manually depending on the current app. Try setting min_refresh_rate = 0 for games.
Framerate spikes are caused by compositor scheduling a new frame based on certain events and conditions. There are plenty of those. Some are easily tracked, others are deep inside wlroots. no_break_fs_vrr prevents some extra schedules related to mouse movement which are meant to redraw the cursor in the new position. It is very strange that there are issues with invisible cursors. But I also don't understand why no_break_fs_vrr doesn't work with hardware cursors... Something is causing extra frame scheduling.
@Atemu I've just encountered the other issue you mentioned here the other day:
More critically though, when apps are in fullscreen, the frame presentation is messed up for a few frames whenever the mouse is moved with frame order sometimes being wrong but also randomly every second or so with no input. It's really weird and hard to describe but you'll know it when you see it. It manifests as a sort of stutter where it rubber-bands between some previous frame(s?) and the actual one. When I set the app to windowed and then fullscreen 2 it, this does not happen.
I ran into it after having updated my packages the night before and it really perplexed me for a bit as I hadn't changed anything Hyprland wise and suddenly was experiencing it to varying degrees in different games. But I remembered you mentioning it, so I messed with hyprland stuff for a short while before I realised that it wasn't actually a Hyprland bug that you were experiencing.
But the short answer here is that it seems to be a bug introduced in Mesa 24.1 probably due to the explicit sync developments.
The long answer is, while using the affected Mesa drivers the bug seems to be barely present on Hyprland with vfr = 0. As in if you pay perfect attention you might see a single out of place frame/stutter a few times a minute at most. But the second you enable vfr in Hyprland you will begin seeing misplaced frames and stuttering more and more the further your games framerate strays from your monitor's refresh rate. This behaviour has nothing to do with vrr as far as I can tell, seeing as it also manifests on my non vrr monitors unless vfr is disabled.
The really odd thing is that I managed to heavily mitigate it by spamming my fullscreen, 0 and togglefloating keybinds for a bit out of frustration. Spamming those for a bit somehow reliably reduces the 'stutters' to only a few times a minute at most while still retaining full vrr functionality with both vrr and vfr enabled. And this is in a game where if I limit the fps to 60 I'd see multiple stutters per second, basically rendering it unplayable with vfr on otherwise.
But TL;DR: Either wait for a fix from Mesa or downgrade your mesa version in the meantime.
I've encountered a very similar problem described in this issue. My monitors refresh rate would max out, whenever I move the cursor, regardless if its visible. I tried disabling hardware cursor through the hyprland option and env variable, but nothing worked. The weird issue is that this issue seems to come and go and only presents itself after I've used the system for a while. Reinstalling nixos and rebuilding my system fixes my issue and I cant say why, since I havent really changed anything in my config.
Please test https://github.com/hyprwm/Hyprland/pull/6877 It should fix VRR for games with invisible cursor and those which lock and hide compositor cursor and handle its rendering themselves. Note that the cursor will become extra slow the lower your fps gets. Just verify that the game doesn't have rendering issues and VRR works as expected.
Please test #6877 It should fix VRR for games with invisible cursor and those which lock and hide compositor cursor and handle its rendering themselves. Note that the cursor will become extra slow the lower your fps gets. Just verify that the game doesn't have rendering issues and VRR works as expected.
Thanks for working on the fix! I have some good news and some bad news related to that fix:
- The good news: in The Witcher 3: Wild Hunt (the game I mentioned previously, and the only game I tested with the new build), if I move the mouse the refresh rate no longer maxes out, it follows the FPS as expected
- When moving the cursor in The Witcher 3: Wild Hunt menus, it's very difficult to move it - it's as if the DPI is 1/4 of what it's actually set to.
What seems to fix the second point from above is setting vrr from 2 to 0 or commenting out no_break_fs_vrr = true (but of course, VRR is lost in that case, or moving the cursor forces max refresh rate on the monitor). I also have no_direct_scanout = false and no_hardware_cursors = true set. Commenting these out doesn't seem to have an impact on the cursor speed.
But, it does look like this issue is listed in the PR and you've mentioned it in your comment, if it's the same thing. Not sure if we should continue this conversation here or in that PR.
Thanks a bunch for attempting to fix this @UjinT34. I used the PR
I experience different symptoms to @RaduAvramescu:
- When I move my visible mouse cursor in GW2, the frame rate jumps between 5ms and 50ms (keeping it still, I'm at a fairly consistent 16ms).
- When I move my camera (no mouse cursor), it's smooth but suuuper slow; feels like <1/4 DPI but likely the same effect as @RaduAvramescu experiences.
A little later, I played around a little and toggled vfr off. This causes VRR to not function anymore which is a bit unexpected?
After toggling it back on, VRR worked again but the behaviour in 1. was now also present when moving the camera and the speed still being extremely slow (worst of both worlds!).
After restarting the game, it's back to the initial behaviour.
Another weird thing is that you seemingly cannot disable VRR. If I set vrr = 0 in a running config, both my desktop and the game still cause the monitor's refresh rate to react.
Relevant settings are:
# https://wiki.hyprland.org/Configuring/Variables/#misc
misc {
force_default_wallpaper = 1 # Set to 0 or 1 to disable the anime mascot wallpapers
disable_hyprland_logo = true # If true disables the random hyprland logo / anime girl background. :(
# I'd like my screen to turn on when I press a button please
mouse_move_enables_dpms = true
key_press_enables_dpms = true
# Variable frame rate?
# TODO need to test whether this affects input delay
vfr = true
vrr = 1
no_direct_scanout = false
}
cursor {
no_hardware_cursors = true
hide_on_key_press = false
no_break_fs_vrr = true
}
The weird rubber-band symptoms were indeed caused by explicit sync handling still being buggy as @Gwenodai figured out.
Downgrading xwayland to 23.2.7 is the easiest workaround for that issue though by no means ideal.
The weird issue with the game playing catch-up after switching back to it is also still present. Could someone reproduce this for me?
- Start game on desktop x
- Switch to desktop y
- Wait a little
- Switch back to desktop x
- Observe game going super-speed mode; seemingly playing back all the frames it couldn't while on another virtual desktop
@Atemu
I've had that same issue with GW2 since I started using Hyprland. The frames accumulate in the background while the window is not being rendered and are pushed out all at once when visible again. I'm not sure how it's handled by the ArenaNet servers, but actions were also sped up so it might be exploitative and could trigger anticheat measures with some games.
It also differs in effect depending on the game, and some just act as if they were minimized. I believe the current workaround is to use gamescope in another TTY, which also solves some other issues apparently.
Ideally the window would be rendered while not visible, which is tracked by https://github.com/hyprwm/Hyprland/issues/3776
@Myned
It also differs in effect depending on the game, and some just act as if they were minimized. I believe the current workaround is to use gamescope in another TTY, which also solves some other issues apparently.
Out of curiosity, would another workaround be moving the game into a special workspace? I've noticed things in special workspaces sometimes act weirdly. Here's two examples I have of odd behaviour:
- Sometimes acting as if they're in focus when said workspace is hidden
- With
vrr=1games fullscreened on regular workspaces result in a locked 144hz whereas the same applications on a special workspace results in a refresh rate that matches the framerate. All works fine in either case withvrr=2(I'm on 0.40.0 so this may be different now)
Sadly I've not tried the PR yet as I've not had the time but I'm excited to see this being worked on :)
@Gwenodai
There is no difference in rendering for fullscreen GW2 on a special workspace with Hyprland built at commit bc6b0880dda2607a80f000c134f573c970452a0f. The game still dumps out the frames after being hidden by toggling the special workspace.
For 1, that may be related to https://github.com/hyprwm/Hyprland/issues/6237 depending on how focus is changed. on-created-empty, for example, requires initial_workspace_tracking = 0 currently in order to focus the launched window. Otherwise, I haven't experienced exactly the case of focus sticking when toggling a special workspace.
For 2, I'm not able to replicate - vrrtest with vrr = 1/2 both have variable refresh on my system.
Also, with regard to vrr = 1/0, when reloading config it does not apply until a restart of the session for me, which may explain:
Another weird thing is that you seemingly cannot disable VRR. If I set vrr = 0 in a running config, both my desktop and the game still cause the monitor's refresh rate to react.
@Myned
I used the wrong wording for 1 sorry. I meant that certain programs don't send notifications when on special workspaces as they believe they are viewable to the user. But being hidden away on another workspace makes them react as if they are closed and send notifications as you'd expect when they're not visible. That's what I meant by focused sorry. I've never experienced https://github.com/hyprwm/Hyprland/issues/6237 before.
Yea I'd assume 2 functions correctly now, as it did back on 0.39.3 or the last official version before 0.40.0. I was just using it as an example of special workspaces treating applications differently than regular workspaces.