diff --git a/src/Window.hpp b/src/Window.hpp index 437b4a40..2cb6eb95 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -217,6 +217,7 @@ class CWindow { bool m_bIsModal = false; bool m_bX11DoesntWantBorders = false; bool m_bX11ShouldntFocus = false; + float m_fX11SurfaceScaledBy = 1.f; // // For nofocus diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index e19a94d4..eb641786 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -207,6 +207,7 @@ void CConfigManager::setDefaultVars() { configValues["gestures:workspace_swipe_numbered"].intValue = 0; configValues["xwayland:use_nearest_neighbor"].intValue = 1; + configValues["xwayland:force_zero_scaling"].intValue = 0; configValues["autogenerated"].intValue = 0; } diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index b8ecbd76..76827ba9 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -739,7 +739,8 @@ void Events::listener_commitWindow(void* owner, void* data) { PWINDOW->updateSurfaceOutputs(); - g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface.wlr(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y); + g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface.wlr(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, + PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0); if (PWINDOW->m_bIsX11 || !PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen) return; diff --git a/src/helpers/SubsurfaceTree.cpp b/src/helpers/SubsurfaceTree.cpp index 40cda642..7058d32e 100644 --- a/src/helpers/SubsurfaceTree.cpp +++ b/src/helpers/SubsurfaceTree.cpp @@ -229,6 +229,8 @@ void Events::listener_commitSubsurface(void* owner, void* data) { addSurfaceGlobalOffset(pNode, &lx, &ly); + const double SCALE = pNode->pWindowOwner && pNode->pWindowOwner->m_bIsX11 ? 1.0 / pNode->pWindowOwner->m_fX11SurfaceScaledBy : 1.0; + // I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox) // What this does is that basically, if the pNode is a child of some other node, on commit, // it will also damage (check & damage if needed) all its siblings. @@ -237,12 +239,12 @@ void Events::listener_commitSubsurface(void* owner, void* data) { const auto NODECOORDS = pNode->pSubsurface ? Vector2D(pNode->pSubsurface->pSubsurface->current.x, pNode->pSubsurface->pSubsurface->current.y) : Vector2D(); if (&cs != pNode->pSubsurface && cs.pSubsurface) { - g_pHyprRenderer->damageSurface(cs.pSubsurface->surface, lx - NODECOORDS.x + cs.pSubsurface->current.x, ly - NODECOORDS.y + cs.pSubsurface->current.y); + g_pHyprRenderer->damageSurface(cs.pSubsurface->surface, lx - NODECOORDS.x + cs.pSubsurface->current.x, ly - NODECOORDS.y + cs.pSubsurface->current.y, SCALE); } } if (pNode->pSurface && pNode->pSurface->exists()) - g_pHyprRenderer->damageSurface(pNode->pSurface->wlr(), lx, ly); + g_pHyprRenderer->damageSurface(pNode->pSurface->wlr(), lx, ly, SCALE); } void Events::listener_destroySubsurface(void* owner, void* data) { diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 7cd03b3a..1801247d 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -148,6 +148,17 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool f pWindow->m_vReportedPosition = pWindow->m_vRealPosition.vec(); pWindow->m_vReportedSize = size; + static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue; + + pWindow->m_fX11SurfaceScaledBy = 1.f; + + if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11) { + if (const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); PMONITOR) { + size = size * PMONITOR->scale; + pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale; + } + } + if (pWindow->m_bIsX11) wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y); else diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 9f72603f..9dd6e5da 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -330,6 +330,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { surfaceLocal = mouseCoords - surfacePos + Vector2D(geom.x, geom.y); } + if (pFoundWindow && pFoundWindow->m_bIsX11) // for x11 force scale zero + surfaceLocal = surfaceLocal * pFoundWindow->m_fX11SurfaceScaledBy; + bool allowKeyboardRefocus = true; if (*PHOGFOCUS && !refocus && g_pCompositor->m_pLastFocus) { diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 939b5783..ce8cb0ff 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1355,7 +1355,7 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) { PMONITOR->vecReservedBottomRight.x, PMONITOR->vecReservedBottomRight.y); } -void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) { +void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, double scale) { if (!pSurface) return; // wut? @@ -1365,6 +1365,8 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) { pixman_region32_t damageBox; pixman_region32_init(&damageBox); wlr_surface_get_effective_damage(pSurface, &damageBox); + if (scale != 1.0) + wlr_region_scale(&damageBox, &damageBox, scale); // schedule frame events if (!wl_list_empty(&pSurface->current.frame_callback_list)) { diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 3e73287c..9301d46b 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -11,16 +11,14 @@ struct SMonitorRule; // TODO: add fuller damage tracking for updating only parts of a window -enum DAMAGETRACKINGMODES -{ +enum DAMAGETRACKINGMODES { DAMAGE_TRACKING_INVALID = -1, DAMAGE_TRACKING_NONE = 0, DAMAGE_TRACKING_MONITOR, DAMAGE_TRACKING_FULL }; -enum eRenderPassMode -{ +enum eRenderPassMode { RENDER_PASS_ALL = 0, RENDER_PASS_MAIN, RENDER_PASS_POPUP @@ -35,7 +33,7 @@ class CHyprRenderer { void renderMonitor(CMonitor* pMonitor); void outputMgrApplyTest(wlr_output_configuration_v1*, bool); void arrangeLayersForMonitor(const int&); - void damageSurface(wlr_surface*, double, double); + void damageSurface(wlr_surface*, double, double, double scale = 1.0); void damageWindow(CWindow*); void damageBox(wlr_box*); void damageBox(const int& x, const int& y, const int& w, const int& h);