diff --git a/src/Window.cpp b/src/Window.cpp index ca9625ad..7825e7d3 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -516,6 +516,8 @@ void CWindow::applyDynamicRule(const SWindowRule& r) { m_sAdditionalConfigData.forceOpaque = true; } else if (r.szRule == "immediate") { m_sAdditionalConfigData.forceTearing = true; + } else if (r.szRule == "nearestneighbor") { + m_sAdditionalConfigData.nearestNeighbor = true; } else if (r.szRule.starts_with("rounding")) { try { m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1)); @@ -605,6 +607,7 @@ void CWindow::updateDynamicRules() { m_sAdditionalConfigData.keepAspectRatio = false; m_sAdditionalConfigData.xray = -1; m_sAdditionalConfigData.forceTearing = false; + m_sAdditionalConfigData.nearestNeighbor = false; const auto WINDOWRULES = g_pConfigManager->getMatchingRules(this); for (auto& r : WINDOWRULES) { diff --git a/src/Window.hpp b/src/Window.hpp index b54ecdbc..dfec0ab5 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -143,6 +143,7 @@ struct SWindowAdditionalConfigData { CWindowOverridableVar xray = -1; // -1 means unset, takes precedence over the renderdata one CWindowOverridableVar borderSize = -1; // -1 means unset, takes precedence over the renderdata one CWindowOverridableVar forceTearing = false; + CWindowOverridableVar nearestNeighbor = false; }; struct SWindowRule { diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 2ecac5c9..0d9cc288 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -935,7 +935,7 @@ bool windowRuleValid(const std::string& RULE) { RULE == "nomaximizerequest" || RULE == "fakefullscreen" || RULE == "nomaxsize" || RULE == "pin" || RULE == "noanim" || RULE == "dimaround" || RULE == "windowdance" || RULE == "maximize" || RULE == "keepaspectratio" || RULE.starts_with("animation") || RULE.starts_with("rounding") || RULE.starts_with("workspace") || RULE.starts_with("bordercolor") || RULE == "forcergbx" || RULE == "noinitialfocus" || RULE == "stayfocused" || RULE.starts_with("bordersize") || RULE.starts_with("xray") || - RULE.starts_with("center") || RULE.starts_with("group") || RULE == "immediate"; + RULE.starts_with("center") || RULE.starts_with("group") || RULE == "immediate" || RULE == "nearestneighbor"; } bool layerRuleValid(const std::string& RULE) { diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 914a02e0..378880b1 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1073,6 +1073,8 @@ std::string dispatchSetProp(std::string request) { PWINDOW->m_sAdditionalConfigData.keepAspectRatio.forceSetIgnoreLocked(configStringToInt(VAL), lock); } else if (PROP == "immediate") { PWINDOW->m_sAdditionalConfigData.forceTearing.forceSetIgnoreLocked(configStringToInt(VAL), lock); + } else if (PROP == "nearestneighbor") { + PWINDOW->m_sAdditionalConfigData.nearestNeighbor.forceSetIgnoreLocked(configStringToInt(VAL), lock); } else { return "prop not found"; } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index e0966302..4326b89f 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -427,7 +427,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS); static auto* const PXWLUSENN = &g_pConfigManager->getConfigValuePtr("xwayland:use_nearest_neighbor")->intValue; - if (pWindow->m_bIsX11 && *PXWLUSENN) + if ((pWindow->m_bIsX11 && *PXWLUSENN) || pWindow->m_sAdditionalConfigData.nearestNeighbor.toUnderlying()) g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; wlr_surface_for_each_surface(pWindow->m_pWLSurface.wlr(), renderSurface, &renderdata); @@ -483,7 +483,13 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* renderdata.dontRound = true; // don't round popups renderdata.pMonitor = pMonitor; renderdata.squishOversized = false; // don't squish popups + + if (pWindow->m_sAdditionalConfigData.nearestNeighbor.toUnderlying()) + g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; + wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata); + + g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; } }