diff --git a/src/Window.hpp b/src/Window.hpp index dbfa2e04..915cf018 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -185,6 +185,7 @@ class CWindow { DYNLISTENER(setOverrideRedirect); DYNLISTENER(associateX11); DYNLISTENER(dissociateX11); + DYNLISTENER(ackConfigure); // DYNLISTENER(newSubsurfaceWindow); CWLSurface m_pWLSurface; @@ -204,9 +205,11 @@ class CWindow { CAnimatedVariable m_vRealSize; // for not spamming the protocols - Vector2D m_vReportedPosition; - Vector2D m_vReportedSize; - Vector2D m_vPendingReportedSize; + Vector2D m_vReportedPosition; + Vector2D m_vReportedSize; + Vector2D m_vPendingReportedSize; + bool m_bPendingSizeAcked = false; + std::optional m_iPendingSizeAck; // for restoring floating statuses Vector2D m_vLastFloatingSize; diff --git a/src/events/Events.hpp b/src/events/Events.hpp index fc68880e..371586cc 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -62,6 +62,7 @@ namespace Events { DYNLISTENFUNC(setOverrideRedirect); DYNLISTENFUNC(associateX11); DYNLISTENFUNC(dissociateX11); + DYNLISTENFUNC(ackConfigure); // Window subsurfaces // LISTENER(newSubsurfaceWindow); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index f131efa4..1fbc9070 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -504,6 +504,7 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->hyprListener_requestResize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_resize, &Events::listener_requestResize, PWINDOW, "XDG Window Late"); PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW, "XDG Window Late"); + PWINDOW->hyprListener_ackConfigure.initCallback(&PWINDOW->m_uSurface.xdg->events.ack_configure, &Events::listener_ackConfigure, PWINDOW, "XDG Window Late"); } else { PWINDOW->hyprListener_fullscreenWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_fullscreen, &Events::listener_fullscreenWindow, PWINDOW, "XWayland Window Late"); @@ -682,6 +683,7 @@ void Events::listener_unmapWindow(void* owner, void* data) { PWINDOW->hyprListener_requestMove.removeCallback(); PWINDOW->hyprListener_requestResize.removeCallback(); PWINDOW->hyprListener_fullscreenWindow.removeCallback(); + PWINDOW->hyprListener_ackConfigure.removeCallback(); } else { Debug::log(LOG, "Unregistered late callbacks XWL"); PWINDOW->hyprListener_fullscreenWindow.removeCallback(); @@ -788,13 +790,26 @@ void Events::listener_unmapWindow(void* owner, void* data) { PWINDOW->onUnmap(); } +void Events::listener_ackConfigure(void* owner, void* data) { + CWindow* PWINDOW = (CWindow*)owner; + const auto E = (wlr_xdg_surface_configure*)data; + + if (!PWINDOW->m_iPendingSizeAck.has_value() || E->serial != PWINDOW->m_iPendingSizeAck) + return; + + PWINDOW->m_bPendingSizeAcked = true; + PWINDOW->m_iPendingSizeAck.reset(); +} + void Events::listener_commitWindow(void* owner, void* data) { CWindow* PWINDOW = (CWindow*)owner; if (!PWINDOW->m_bMappedX11 || PWINDOW->isHidden() || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11)) return; - PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged. + if (PWINDOW->m_bIsX11 || PWINDOW->m_bPendingSizeAcked) + PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged. + PWINDOW->m_bPendingSizeAcked = false; PWINDOW->updateSurfaceOutputs(); diff --git a/src/helpers/SubsurfaceTree.cpp b/src/helpers/SubsurfaceTree.cpp index 84ba5cbb..c10d45e1 100644 --- a/src/helpers/SubsurfaceTree.cpp +++ b/src/helpers/SubsurfaceTree.cpp @@ -248,14 +248,13 @@ void Events::listener_commitSubsurface(void* owner, void* data) { g_pHyprRenderer->damageSurface(pNode->pSurface->wlr(), lx, ly, SCALE); if (pNode->pWindowOwner) { - // update reported size. Some windows do not send a ::commit afterwards. Odd. - pNode->pWindowOwner->m_vReportedSize = pNode->pWindowOwner->m_vPendingReportedSize; + if (pNode->pWindowOwner->m_bIsX11) + pNode->pWindowOwner->m_vReportedSize = pNode->pWindowOwner->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged. // tearing: if solitary, redraw it. This still might be a single surface window const auto PMONITOR = g_pCompositor->getMonitorFromID(pNode->pWindowOwner->m_iMonitorID); if (PMONITOR->solitaryClient == pNode->pWindowOwner && pNode->pWindowOwner->canBeTorn() && PMONITOR->tearingState.canTear && pNode->pSurface->wlr()->current.committed & WLR_SURFACE_STATE_BUFFER) { - CRegion damageBox; wlr_surface_get_effective_damage(pNode->pSurface->wlr(), damageBox.pixman()); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index c5ed1199..abc1aeda 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -162,8 +162,10 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) { g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv()); g_pCompositor->changeWindowZOrder(pWindow, true); - } else + } else { pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goalv(); + pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize; + } } void IHyprLayout::onBeginDragWindow() { diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 04fbaf21..f9d57a3f 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -180,7 +180,7 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool f if (pWindow->m_bIsX11) wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, windowPos.x, windowPos.y, size.x, size.y); else - wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y); + pWindow->m_iPendingSizeAck = wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y); } void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {