diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index e9dad8922..10a771c98 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -1957,6 +1957,8 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
 
     // DMAbuf stuff for direct scanout
     g_pHyprRenderer->setWindowScanoutMode(pWindow);
+
+    g_pConfigManager->ensureVRR(PMONITOR);
 }
 
 void CCompositor::moveUnmanagedX11ToWindows(CWindow* pWindow) {
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 77c91d290..573a51c06 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -51,7 +51,8 @@ void CConfigManager::setDefaultVars() {
 
     configValues["misc:disable_hyprland_logo"].intValue      = 0;
     configValues["misc:disable_splash_rendering"].intValue   = 0;
-    configValues["misc:no_vfr"].intValue                     = 1;
+    configValues["misc:vfr"].intValue                        = 1;
+    configValues["misc:vrr"].intValue                        = 0;
     configValues["misc:mouse_move_enables_dpms"].intValue    = 0;
     configValues["misc:always_follow_on_dnd"].intValue       = 1;
     configValues["misc:layers_hog_keyboard_focus"].intValue  = 1;
@@ -1692,35 +1693,61 @@ void CConfigManager::ensureDPMS() {
 }
 
 void CConfigManager::ensureVRR(CMonitor* pMonitor) {
-    static auto* const PNOVRR = &getConfigValuePtr("misc:no_vfr")->intValue;
+    static auto* const PVRR = &getConfigValuePtr("misc:vrr")->intValue;
 
-    auto               ensureVRRForDisplay = [&](CMonitor* m) -> void {
-        if (!*PNOVRR && !m->vrrActive) {
-            // Adaptive sync (VRR)
-            wlr_output_enable_adaptive_sync(m->output, 1);
-
-            if (!wlr_output_test(m->output)) {
-                Debug::log(LOG, "Pending output %s does not accept VRR.", m->output->name);
+    static auto        ensureVRRForDisplay = [&](CMonitor* m) -> void {
+        if (*PVRR == 0) {
+            if (m->vrrActive) {
                 wlr_output_enable_adaptive_sync(m->output, 0);
-            }
 
-            if (!wlr_output_commit(m->output)) {
-                Debug::log(ERR, "Couldn't commit output %s in ensureVRR -> true", m->output->name);
+                if (!wlr_output_commit(m->output)) {
+                    Debug::log(ERR, "Couldn't commit output %s in ensureVRR -> false", m->output->name);
+                }
             }
+            m->vrrActive = false;
+            return;
+        } else if (*PVRR == 1) {
+            if (!m->vrrActive) {
+                wlr_output_enable_adaptive_sync(m->output, 1);
 
+                if (!wlr_output_test(m->output)) {
+                    Debug::log(LOG, "Pending output %s does not accept VRR.", m->output->name);
+                    wlr_output_enable_adaptive_sync(m->output, 0);
+                }
+
+                if (!wlr_output_commit(m->output)) {
+                    Debug::log(ERR, "Couldn't commit output %s in ensureVRR -> true", m->output->name);
+                }
+            }
+            m->vrrActive = true;
+            return;
+        } else if (*PVRR == 2) {
+            /* fullscreen */
             m->vrrActive = true;
 
-            Debug::log(LOG, "VRR ensured on %s -> true", m->output->name);
-        } else if (*PNOVRR && m->vrrActive) {
-            wlr_output_enable_adaptive_sync(m->output, 0);
+            const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m->activeWorkspace);
 
-            if (!wlr_output_commit(m->output)) {
-                Debug::log(ERR, "Couldn't commit output %s in ensureVRR -> false", m->output->name);
+            if (!PWORKSPACE)
+                return; // ???
+
+            if (PWORKSPACE->m_bHasFullscreenWindow && m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_DISABLED) {
+                wlr_output_enable_adaptive_sync(m->output, 1);
+
+                if (!wlr_output_test(m->output)) {
+                    Debug::log(LOG, "Pending output %s does not accept VRR.", m->output->name);
+                    wlr_output_enable_adaptive_sync(m->output, 0);
+                }
+
+                if (!wlr_output_commit(m->output)) {
+                    Debug::log(ERR, "Couldn't commit output %s in ensureVRR -> true", m->output->name);
+                }
+            } else if (!PWORKSPACE->m_bHasFullscreenWindow && m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED) {
+                wlr_output_enable_adaptive_sync(m->output, 0);
+
+                if (!wlr_output_commit(m->output)) {
+                    Debug::log(ERR, "Couldn't commit output %s in ensureVRR -> false", m->output->name);
+                }
             }
-
-            m->vrrActive = false;
-
-            Debug::log(LOG, "VRR ensured on %s -> false", m->output->name);
         }
     };
 
diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp
index ee7734dff..11a830738 100644
--- a/src/events/Monitors.cpp
+++ b/src/events/Monitors.cpp
@@ -120,6 +120,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
     static auto* const                                    PDAMAGETRACKINGMODE = &g_pConfigManager->getConfigValuePtr("debug:damage_tracking")->intValue;
     static auto* const                                    PDAMAGEBLINK        = &g_pConfigManager->getConfigValuePtr("debug:damage_blink")->intValue;
     static auto* const                                    PNODIRECTSCANOUT    = &g_pConfigManager->getConfigValuePtr("misc:no_direct_scanout")->intValue;
+    static auto* const                                    PVFR                = &g_pConfigManager->getConfigValuePtr("misc:vfr")->intValue;
 
     static int                                            damageBlinkCleanup = 0; // because double-buffered
 
@@ -148,8 +149,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
 
     // checks //
     if (PMONITOR->ID == g_pHyprRenderer->m_pMostHzMonitor->ID ||
-        g_pHyprRenderer->m_pMostHzMonitor->output->adaptive_sync_status ==
-            WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
+        *PVFR == 1) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
         g_pCompositor->sanityCheckWorkspaces();
         g_pAnimationManager->tick();
 
@@ -204,7 +204,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
         pixman_region32_fini(&damage);
         wlr_output_rollback(PMONITOR->output);
 
-        if (*PDAMAGEBLINK || PMONITOR->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_DISABLED)
+        if (*PDAMAGEBLINK || *PVFR == 0)
             g_pCompositor->scheduleFrameForMonitor(PMONITOR);
 
         return;
@@ -311,7 +311,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
     if (!wlr_output_commit(PMONITOR->output))
         return;
 
-    if (*PDAMAGEBLINK || PMONITOR->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_DISABLED)
+    if (*PDAMAGEBLINK || *PVFR == 0)
         g_pCompositor->scheduleFrameForMonitor(PMONITOR);
 
     if (*PDEBUGOVERLAY == 1) {