Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/desktop/WLSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ bool CWLSurface::small() const {
if (!m_resource->m_current.texture)
return false;

const auto O = m_windowOwner.lock();
const auto O = m_windowOwner.lock();
const auto REPORTED_SIZE = O->getReportedSize();

return O->m_reportedSize.x > m_resource->m_current.size.x + 1 || O->m_reportedSize.y > m_resource->m_current.size.y + 1;
return REPORTED_SIZE.x > m_resource->m_current.size.x + 1 || REPORTED_SIZE.y > m_resource->m_current.size.y + 1;
}

Vector2D CWLSurface::correctSmallVec() const {
Expand All @@ -73,8 +74,9 @@ Vector2D CWLSurface::correctSmallVec() const {

const auto SIZE = getViewporterCorrectedSize();
const auto O = m_windowOwner.lock();
const auto REP = O->getReportedSize();

return Vector2D{(O->m_reportedSize.x - SIZE.x) / 2, (O->m_reportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_realSize->value() / O->m_reportedSize);
return Vector2D{(REP.x - SIZE.x) / 2, (REP.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_realSize->value() / REP);
}

Vector2D CWLSurface::correctSmallVecBuf() const {
Expand Down
27 changes: 24 additions & 3 deletions src/desktop/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "../managers/TokenManager.hpp"
#include "../managers/animation/AnimationManager.hpp"
#include "../managers/ANRManager.hpp"
#include "../managers/eventLoop/EventLoopManager.hpp"
#include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../protocols/core/Subcompositor.hpp"
Expand Down Expand Up @@ -576,7 +577,12 @@ void CWindow::onMap() {
if (!m_isMapped || isX11OverrideRedirect())
return;

sendWindowSize();
g_pEventLoopManager->doLater([this, self = m_self] {
if (!self)
return;

sendWindowSize();
});
},
false);

Expand Down Expand Up @@ -1549,13 +1555,20 @@ std::string CWindow::fetchClass() {
}

void CWindow::onAck(uint32_t serial) {
const auto SERIAL = std::ranges::find_if(m_pendingSizeAcks | std::views::reverse, [serial](const auto& e) { return e.first == serial; });
const auto SERIAL = std::ranges::find_if(m_pendingSizeAcks | std::views::reverse, [serial](const auto& e) { return e.first <= serial; });

if (SERIAL == m_pendingSizeAcks.rend())
return;

m_pendingSizeAck = *SERIAL;
std::erase_if(m_pendingSizeAcks, [&](const auto& el) { return el.first <= SERIAL->first; });

if (m_isX11)
return;

m_wlSurface->resource()->m_pending.ackedSize = m_pendingSizeAck->second; // apply pending size. We pinged, the window ponged.
m_wlSurface->resource()->m_pending.updated.bits.acked = true;
m_pendingSizeAck.reset();
}

void CWindow::onResourceChangeX11() {
Expand Down Expand Up @@ -1805,7 +1818,7 @@ void CWindow::sendWindowSize(bool force) {
if (m_isX11 && m_xwaylandSurface)
m_xwaylandSurface->configure({REPORTPOS, REPORTSIZE});
else if (m_xdgSurface && m_xdgSurface->m_toplevel)
m_pendingSizeAcks.emplace_back(m_xdgSurface->m_toplevel->setSize(REPORTSIZE), REPORTPOS.floor());
m_pendingSizeAcks.emplace_back(m_xdgSurface->m_toplevel->setSize(REPORTSIZE), REPORTSIZE.floor());
}

NContentType::eContentType CWindow::getContentType() {
Expand Down Expand Up @@ -1910,3 +1923,11 @@ SP<CWLSurfaceResource> CWindow::getSolitaryResource() {

return nullptr;
}

Vector2D CWindow::getReportedSize() {
if (m_isX11)
return m_reportedSize;
if (m_wlSurface && m_wlSurface->resource())
return m_wlSurface->resource()->m_current.ackedSize;
return m_reportedSize;
}
1 change: 1 addition & 0 deletions src/desktop/Window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ class CWindow {
PHLWINDOW parent();
bool priorityFocus();
SP<CWLSurfaceResource> getSolitaryResource();
Vector2D getReportedSize();

CBox getWindowMainSurfaceBox() const {
return {m_realPosition->value().x, m_realPosition->value().y, m_realSize->value().x, m_realSize->value().y};
Expand Down
3 changes: 2 additions & 1 deletion src/events/Windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,8 @@ void Events::listener_commitWindow(void* owner, void* data) {
if (!PWINDOW->m_isMapped || PWINDOW->isHidden())
return;

PWINDOW->m_reportedSize = PWINDOW->m_pendingReportedSize; // apply pending size. We pinged, the window ponged.
if (PWINDOW->m_isX11)
PWINDOW->m_reportedSize = PWINDOW->m_pendingReportedSize;

if (!PWINDOW->m_isX11 && !PWINDOW->isFullscreen() && PWINDOW->m_isFloating) {
const auto MINSIZE = PWINDOW->m_xdgSurface->m_toplevel->layoutMinSize();
Expand Down
3 changes: 3 additions & 0 deletions src/protocols/types/SurfaceState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,7 @@ void SSurfaceState::updateFrom(SSurfaceState& ref) {

if (ref.updated.bits.acquire)
acquire = ref.acquire;

if (ref.updated.bits.acked)
ackedSize = ref.ackedSize;
}
4 changes: 4 additions & 0 deletions src/protocols/types/SurfaceState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct SSurfaceState {
bool offset : 1;
bool viewport : 1;
bool acquire : 1;
bool acked : 1;
} bits;
} updated;

Expand All @@ -37,6 +38,9 @@ struct SSurfaceState {
Vector2D size, bufferSize;
Vector2D offset;

// for xdg_shell resizing
Vector2D ackedSize;

// viewporter protocol surface state
struct {
bool hasDestination = false;
Expand Down
63 changes: 31 additions & 32 deletions src/render/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1123,15 +1123,25 @@ void CHyprRenderer::calculateUVForSurface(PHLWINDOW pWindow, SP<CWLSurfaceResour
if (*PEXPANDEDGES) {
const auto MONITOR_WL_SCALE = std::ceil(pMonitor->m_scale);
const bool SCALE_UNAWARE = MONITOR_WL_SCALE != pSurface->m_current.scale && !pSurface->m_current.viewport.hasDestination;
const auto EXPECTED_SIZE =
((pSurface->m_current.viewport.hasDestination ? pSurface->m_current.viewport.destination : pSurface->m_current.bufferSize / pSurface->m_current.scale) *
pMonitor->m_scale)
.round();
if (!SCALE_UNAWARE && (EXPECTED_SIZE.x < projSize.x || EXPECTED_SIZE.y < projSize.y)) {
// this will not work with shm AFAIK, idk why.
// NOTE: this math is wrong if we have a source... or geom updates later, but I don't think we can do much
const auto FIX = (projSize / EXPECTED_SIZE).clamp(Vector2D{1, 1}, Vector2D{1000000, 1000000});
uvBR = uvBR * FIX;
const auto EXPECTED_SIZE = ((pSurface->m_current.viewport.hasDestination ?
pSurface->m_current.viewport.destination :
(pSurface->m_current.viewport.hasSource ? pSurface->m_current.viewport.source.size() / pSurface->m_current.scale : projSize)) *
pMonitor->m_scale)
.round();

const auto RATIO = projSize / EXPECTED_SIZE;
if (!SCALE_UNAWARE) {
if (*PEXPANDEDGES && !SCALE_UNAWARE && (RATIO.x > 1 || RATIO.y > 1)) {
const auto FIX = RATIO.clamp(Vector2D{1, 1}, Vector2D{1000000, 1000000});
uvBR = uvBR * FIX;
}

// FIXME: probably do this for in anims on all views...
const auto SHOULD_SKIP = !pWindow || pWindow->m_animatingIn;
if (!SHOULD_SKIP && (RATIO.x < 1 || RATIO.y < 1)) {
const auto FIX = RATIO.clamp(Vector2D{0.0001, 0.0001}, Vector2D{1, 1});
uvBR = uvBR * FIX;
}
}
}

Expand All @@ -1147,32 +1157,21 @@ void CHyprRenderer::calculateUVForSurface(PHLWINDOW pWindow, SP<CWLSurfaceResour
if (!main || !pWindow)
return;

CBox geom = pWindow->m_xdgSurface->m_current.geometry;
// FIXME: this doesn't work. We always set MAXIMIZED anyways, so this doesn't need to work, but it's problematic.

// Adjust UV based on the xdg_surface geometry
if (geom.x != 0 || geom.y != 0 || geom.w != 0 || geom.h != 0) {
const auto XPERC = geom.x / pSurface->m_current.size.x;
const auto YPERC = geom.y / pSurface->m_current.size.y;
const auto WPERC = (geom.x + geom.w ? geom.w : pSurface->m_current.size.x) / pSurface->m_current.size.x;
const auto HPERC = (geom.y + geom.h ? geom.h : pSurface->m_current.size.y) / pSurface->m_current.size.y;
// CBox geom = pWindow->m_xdgSurface->m_current.geometry;

const auto TOADDTL = Vector2D(XPERC * (uvBR.x - uvTL.x), YPERC * (uvBR.y - uvTL.y));
uvBR = uvBR - Vector2D((1.0 - WPERC) * (uvBR.x - uvTL.x), (1.0 - HPERC) * (uvBR.y - uvTL.y));
uvTL = uvTL + TOADDTL;
}
// // Adjust UV based on the xdg_surface geometry
// if (geom.x != 0 || geom.y != 0 || geom.w != 0 || geom.h != 0) {
// const auto XPERC = geom.x / pSurface->m_current.size.x;
// const auto YPERC = geom.y / pSurface->m_current.size.y;
// const auto WPERC = (geom.x + geom.w ? geom.w : pSurface->m_current.size.x) / pSurface->m_current.size.x;
// const auto HPERC = (geom.y + geom.h ? geom.h : pSurface->m_current.size.y) / pSurface->m_current.size.y;

// Adjust UV based on our animation progress
if (pSurface->m_current.size.x > projSizeUnscaled.x || pSurface->m_current.size.y > projSizeUnscaled.y) {
auto maxSize = projSizeUnscaled;

if (pWindow->m_wlSurface->small() && !pWindow->m_wlSurface->m_fillIgnoreSmall)
maxSize = pWindow->m_wlSurface->getViewporterCorrectedSize();

if (pSurface->m_current.size.x > maxSize.x)
uvBR.x = uvBR.x * (maxSize.x / pSurface->m_current.size.x);
if (pSurface->m_current.size.y > maxSize.y)
uvBR.y = uvBR.y * (maxSize.y / pSurface->m_current.size.y);
}
// const auto TOADDTL = Vector2D(XPERC * (uvBR.x - uvTL.x), YPERC * (uvBR.y - uvTL.y));
// uvBR = uvBR - Vector2D((1.0 - WPERC) * (uvBR.x - uvTL.x), (1.0 - HPERC) * (uvBR.y - uvTL.y));
// uvTL = uvTL + TOADDTL;
// }

g_pHyprOpenGL->m_renderData.primarySurfaceUVTopLeft = uvTL;
g_pHyprOpenGL->m_renderData.primarySurfaceUVBottomRight = uvBR;
Expand Down
24 changes: 15 additions & 9 deletions src/render/pass/SurfacePassElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,27 +174,33 @@ CBox CSurfacePassElement::getTexBox() {

// center the surface if it's smaller than the viewport we assign it
if (PSURFACE && !PSURFACE->m_fillIgnoreSmall && PSURFACE->small() /* guarantees PWINDOW */) {
const auto CORRECT = PSURFACE->correctSmallVec();
const auto SIZE = PSURFACE->getViewporterCorrectedSize();
const auto CORRECT = PSURFACE->correctSmallVec();
const auto SIZE = PSURFACE->getViewporterCorrectedSize();
const auto REPORTED = PWINDOW->getReportedSize();

if (!INTERACTIVERESIZEINPROGRESS) {
windowBox.translate(CORRECT);

windowBox.width = SIZE.x * (PWINDOW->m_realSize->value().x / PWINDOW->m_reportedSize.x);
windowBox.height = SIZE.y * (PWINDOW->m_realSize->value().y / PWINDOW->m_reportedSize.y);
windowBox.width = SIZE.x * (PWINDOW->m_realSize->value().x / REPORTED.x);
windowBox.height = SIZE.y * (PWINDOW->m_realSize->value().y / REPORTED.y);
} else {
windowBox.width = SIZE.x;
windowBox.height = SIZE.y;
}
}

} else { // here we clamp to 2, these might be some tiny specks
windowBox = {sc<int>(outputX) + m_data.pos.x + m_data.localPos.x, sc<int>(outputY) + m_data.pos.y + m_data.localPos.y,
std::max(sc<float>(m_data.surface->m_current.size.x), 2.F), std::max(sc<float>(m_data.surface->m_current.size.y), 2.F)};

const auto SURFSIZE = m_data.surface->m_current.size;

windowBox = {sc<int>(outputX) + m_data.pos.x + m_data.localPos.x, sc<int>(outputY) + m_data.pos.y + m_data.localPos.y, std::max(sc<float>(SURFSIZE.x), 2.F),
std::max(sc<float>(SURFSIZE.y), 2.F)};
if (m_data.pWindow && m_data.pWindow->m_realSize->isBeingAnimated() && m_data.surface && !m_data.mainSurface && m_data.squishOversized /* subsurface */) {
// adjust subsurfaces to the window
windowBox.width = (windowBox.width / m_data.pWindow->m_reportedSize.x) * m_data.pWindow->m_realSize->value().x;
windowBox.height = (windowBox.height / m_data.pWindow->m_reportedSize.y) * m_data.pWindow->m_realSize->value().y;
const auto REPORTED = m_data.pWindow->getReportedSize();
if (REPORTED.x != 0 && REPORTED.y != 0) {
windowBox.width = (windowBox.width / REPORTED.x) * m_data.pWindow->m_realSize->value().x;
windowBox.height = (windowBox.height / REPORTED.y) * m_data.pWindow->m_realSize->value().y;
}
}
}

Expand Down
Loading