hyprwm / Hyprland

Hyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
https://hyprland.org
BSD 3-Clause "New" or "Revised" License
21.92k stars 914 forks source link

VRR is broken in Hyprland #5918

Closed Gwenodai closed 1 month ago

Gwenodai commented 6 months ago

Hyprland Version

System/Version info ```sh 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

vaxerski commented 6 months ago

4436 literally same title

Gwenodai commented 6 months ago

4436 literally same title

Same title but very different bug with a solution I've already tried.

vaxerski commented 6 months ago

sounds like the same to me? fps jumps to max?

Gwenodai commented 6 months ago

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.

vaxerski commented 6 months ago

okay, I get you now

vaxerski commented 6 months ago

is the game fullscreen? is it xwayland?

Gwenodai commented 6 months ago

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)

Gwenodai commented 6 months ago

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.

Atemu commented 5 months ago

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
Gwenodai commented 5 months ago

I am not running into that issue. I already have my power profile forced.

Gwenodai commented 5 months ago

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.

Atemu commented 5 months ago

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. ```
Gwenodai commented 5 months ago

@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.

Gwenodai commented 5 months ago

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.

Gwenodai commented 5 months ago

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.

Atemu commented 5 months ago

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.

Gwenodai commented 5 months ago

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 vrr and no_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 } ```

displays.conf

``` monitor=DP-1,1920x1080@143.85,0x0,1.0 monitor=DP-2,1920x1080@60.0,1920x0,1.0 ```

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)$ ```

RaduAvramescu commented 5 months ago

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.

Atemu commented 5 months ago

cc @UjinT34

UjinT34 commented 5 months ago

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.

Gwenodai commented 5 months ago

@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.

neon-grim commented 5 months ago

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.

UjinT34 commented 4 months ago

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.

RaduAvramescu commented 4 months ago

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:

  1. 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
  2. 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.

Atemu commented 4 months ago

Thanks a bunch for attempting to fix this @UjinT34. I used the PR

I experience different symptoms to @RaduAvramescu:

  1. 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).
  2. 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?

  1. Start game on desktop x
  2. Switch to desktop y
  3. Wait a little
  4. Switch back to desktop x
  5. Observe game going super-speed mode; seemingly playing back all the frames it couldn't while on another virtual desktop
myned commented 4 months ago

@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

Gwenodai commented 4 months ago

@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:

  1. Sometimes acting as if they're in focus when said workspace is hidden
  2. With vrr=1 games 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 with vrr=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 :)

myned commented 4 months ago

@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.

myned commented 4 months ago

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.

Gwenodai commented 4 months ago

@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.

UjinT34 commented 4 months ago

https://github.com/hyprwm/Hyprland/pull/6877 needs more testing. Fixed the slow mouse movement and incorrect activation. Special workspaces are treated differently and most of the vrr logic won't with them.

Atemu commented 1 month ago

The primary issue in this particular bug should be fixed by https://github.com/hyprwm/Hyprland/pull/6877, so this issue can be closed.

Gwenodai commented 1 month ago

The primary issue in this particular bug should be fixed by #6877, so this issue can be closed.

True. Thanks, I'd forgotten that this issue was still open.