vrr: add option to fix mouse breaking vrr (#6483)

* option to fix mouse breaking vrr

* skip damage on mouse move

* remove this-> & cleanup

* add cursor:min_refresh_rate to avoid cursor freezing

* run clang-format

---------

Co-authored-by: UjinT34 <ujin@uvpn.ru>
This commit is contained in:
UjinT34 2024-06-14 14:45:32 +03:00 committed by GitHub
parent b2590b58c5
commit a9d53a2252
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 30 additions and 6 deletions

View file

@ -522,6 +522,8 @@ CConfigManager::CConfigManager() {
m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{2}); m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{2});
m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0}); m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24});
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{1}); m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{1});
m_pConfig->addConfigValue("cursor:inactive_timeout", Hyprlang::INT{0}); m_pConfig->addConfigValue("cursor:inactive_timeout", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:no_warps", Hyprlang::INT{0}); m_pConfig->addConfigValue("cursor:no_warps", Hyprlang::INT{0});

View file

@ -362,6 +362,24 @@ void CMonitor::addDamage(const CBox* box) {
g_pCompositor->scheduleFrameForMonitor(this); g_pCompositor->scheduleFrameForMonitor(this);
} }
bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
static auto PNOBREAK = CConfigValue<Hyprlang::INT>("cursor:no_break_fs_vrr");
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
// skip scheduling extra frames for fullsreen apps with vrr
bool shouldSkip = *PNOBREAK && output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED && activeWorkspace && activeWorkspace->m_bHasFullscreenWindow &&
activeWorkspace->m_efFullscreenMode == FULLSCREEN_FULL;
// keep requested minimum refresh rate
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000 / *PMINRR) {
// damage whole screen because some previous cursor box damages were skipped
wlr_damage_ring_add_whole(&damage);
return false;
}
return shouldSkip;
}
bool CMonitor::isMirror() { bool CMonitor::isMirror() {
return pMirrorOf != nullptr; return pMirrorOf != nullptr;
} }

View file

@ -158,6 +158,7 @@ class CMonitor {
void addDamage(const pixman_region32_t* rg); void addDamage(const pixman_region32_t* rg);
void addDamage(const CRegion* rg); void addDamage(const CRegion* rg);
void addDamage(const CBox* box); void addDamage(const CBox* box);
bool shouldSkipScheduleFrameOnMouseEvent();
void setMirror(const std::string&); void setMirror(const std::string&);
bool isMirror(); bool isMirror();
bool matchesStaticSelector(const std::string& selector) const; bool matchesStaticSelector(const std::string& selector) const;

View file

@ -675,7 +675,7 @@ void CPointerManager::damageIfSoftware() {
continue; continue;
if ((mw->softwareLocks > 0 || mw->hardwareFailed || *PNOHW) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) { if ((mw->softwareLocks > 0 || mw->hardwareFailed || *PNOHW) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) {
g_pHyprRenderer->damageBox(&b); g_pHyprRenderer->damageBox(&b, mw->monitor->shouldSkipScheduleFrameOnMouseEvent());
break; break;
} }
} }

View file

@ -187,7 +187,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (*PZOOMFACTOR != 1.f) if (*PZOOMFACTOR != 1.f)
g_pHyprRenderer->damageMonitor(PMONITOR); g_pHyprRenderer->damageMonitor(PMONITOR);
if (!PMONITOR->solitaryClient.lock() && g_pHyprRenderer->shouldRenderCursor() && PMONITOR->output->software_cursor_locks > 0) bool skipFrameSchedule = PMONITOR->shouldSkipScheduleFrameOnMouseEvent();
if (!PMONITOR->solitaryClient.lock() && g_pHyprRenderer->shouldRenderCursor() && PMONITOR->output->software_cursor_locks > 0 && !skipFrameSchedule)
g_pCompositor->scheduleFrameForMonitor(PMONITOR); g_pCompositor->scheduleFrameForMonitor(PMONITOR);
PHLWINDOW forcedFocus = m_pForcedFocus.lock(); PHLWINDOW forcedFocus = m_pForcedFocus.lock();
@ -370,7 +372,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
foundSurface = foundSurface =
g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords, &pFoundLayerSurface); g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords, &pFoundLayerSurface);
if (g_pCompositor->m_pLastMonitor->output->software_cursor_locks > 0) if (g_pCompositor->m_pLastMonitor->output->software_cursor_locks > 0 && !skipFrameSchedule)
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor.get()); g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor.get());
// grabs // grabs

View file

@ -1763,7 +1763,7 @@ void CHyprRenderer::damageMonitor(CMonitor* pMonitor) {
Debug::log(LOG, "Damage: Monitor {}", pMonitor->szName); Debug::log(LOG, "Damage: Monitor {}", pMonitor->szName);
} }
void CHyprRenderer::damageBox(CBox* pBox) { void CHyprRenderer::damageBox(CBox* pBox, bool skipFrameSchedule) {
if (g_pCompositor->m_bUnsafeState) if (g_pCompositor->m_bUnsafeState)
return; return;
@ -1773,7 +1773,8 @@ void CHyprRenderer::damageBox(CBox* pBox) {
CBox damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height}; CBox damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height};
damageBox.scale(m->scale); damageBox.scale(m->scale);
m->addDamage(&damageBox); if (!skipFrameSchedule)
m->addDamage(&damageBox);
} }
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage"); static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");

View file

@ -48,7 +48,7 @@ class CHyprRenderer {
void arrangeLayersForMonitor(const int&); void arrangeLayersForMonitor(const int&);
void damageSurface(SP<CWLSurfaceResource>, double, double, double scale = 1.0); void damageSurface(SP<CWLSurfaceResource>, double, double, double scale = 1.0);
void damageWindow(PHLWINDOW, bool forceFull = false); void damageWindow(PHLWINDOW, bool forceFull = false);
void damageBox(CBox*); void damageBox(CBox*, bool skipFrameSchedule = false);
void damageBox(const int& x, const int& y, const int& w, const int& h); void damageBox(const int& x, const int& y, const int& w, const int& h);
void damageRegion(const CRegion&); void damageRegion(const CRegion&);
void damageMonitor(CMonitor*); void damageMonitor(CMonitor*);