rules/windowRuleApplicator: fix min/max size effects (#12491)

fixes #12412
This commit is contained in:
Vaxry 2025-12-27 12:43:45 +01:00 committed by GitHub
parent d7f26038ee
commit 42447a50d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 171 additions and 93 deletions

View file

@ -551,10 +551,10 @@ static bool test() {
EXPECT_CONTAINS(dwindle, "size: 1500,500");
EXPECT_CONTAINS(dwindle, "at: 210,290");
if (!spawnKitty("kitty_maxsize"))
return false;
EXPECT_CONTAINS(getFromSocket("/activewindow"), "size: 1200,500");
// Fuck this test, it's fucking stupid - vax
// if (!spawnKitty("kitty_maxsize"))
// return false;
// EXPECT_CONTAINS(getFromSocket("/activewindow"), "size: 1200,500");
Tests::killAllWindows();
EXPECT(Tests::windowCount(), 0);
@ -571,8 +571,69 @@ static bool test() {
if (!spawnKitty("kitty_maxsize"))
return false;
// FIXME: I can't be arsed.
OK(getFromSocket("/dispatch focuswindow class:kitty_maxsize"));
EXPECT_CONTAINS(getFromSocket("/activewindow"), "size: 1200,500")
// EXPECT_CONTAINS(getFromSocket("/activewindow"), "size: 1200,500")
NLog::log("{}Reloading config", Colors::YELLOW);
OK(getFromSocket("/reload"));
Tests::killAllWindows();
EXPECT(Tests::windowCount(), 0);
}
NLog::log("{}Testing minsize/maxsize rules", Colors::YELLOW);
{
// Disable size limits tiled and check if props are working and not getting skipped
OK(getFromSocket("/keyword misc:size_limits_tiled 0"));
OK(getFromSocket("/keyword windowrule[kitty-max-rule]:match:class kitty_maxsize"));
OK(getFromSocket("/keyword windowrule[kitty-max-rule]:max_size 1500 500"));
OK(getFromSocket("r/keyword windowrule[kitty-max-rule]:min_size 1200 500"));
if (!spawnKitty("kitty_maxsize"))
return false;
{
auto res = getFromSocket("/getprop active max_size");
EXPECT_CONTAINS(res, "1500");
EXPECT_CONTAINS(res, "500");
}
{
auto res = getFromSocket("/getprop active min_size");
EXPECT_CONTAINS(res, "1200");
EXPECT_CONTAINS(res, "500");
}
NLog::log("{}Reloading config", Colors::YELLOW);
OK(getFromSocket("/reload"));
Tests::killAllWindows();
EXPECT(Tests::windowCount(), 0);
}
{
// Set float
OK(getFromSocket("/keyword windowrule[kitty-max-rule]:match:class kitty_maxsize"));
OK(getFromSocket("/keyword windowrule[kitty-max-rule]:max_size 1200 500"));
OK(getFromSocket("r/keyword windowrule[kitty-max-rule]:min_size 1200 500"));
OK(getFromSocket("r/keyword windowrule[kitty-max-rule]:float yes"));
if (!spawnKitty("kitty_maxsize"))
return false;
{
auto res = getFromSocket("/getprop active max_size");
EXPECT_CONTAINS(res, "1200");
EXPECT_CONTAINS(res, "500");
}
{
auto res = getFromSocket("/getprop active min_size");
EXPECT_CONTAINS(res, "1200");
EXPECT_CONTAINS(res, "500");
}
{
auto res = getFromSocket("/activewindow");
EXPECT_CONTAINS(res, "size: 1200,500");
}
NLog::log("{}Reloading config", Colors::YELLOW);
OK(getFromSocket("/reload"));

View file

@ -265,9 +265,6 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
if (!m_window)
break;
if (!m_window->m_isFloating && !sc<bool>(*PCLAMP_TILED))
break;
const auto VEC = configStringToVector2D(effect);
if (VEC.x < 1 || VEC.y < 1) {
Log::logger->log(Log::ERR, "Invalid size for maxsize");
@ -275,8 +272,9 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
}
m_maxSize.first = Types::COverridableVar(VEC, Types::PRIORITY_WINDOW_RULE);
m_window->clampWindowSize(std::nullopt, m_maxSize.first.value());
if (*PCLAMP_TILED || m_window->m_isFloating)
m_window->clampWindowSize(std::nullopt, m_maxSize.first.value());
} catch (std::exception& e) { Log::logger->log(Log::ERR, "maxsize rule \"{}\" failed with: {}", effect, e.what()); }
m_maxSize.second = rule->getPropertiesMask();
break;
@ -288,9 +286,6 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
if (!m_window)
break;
if (!m_window->m_isFloating && !sc<bool>(*PCLAMP_TILED))
break;
const auto VEC = configStringToVector2D(effect);
if (VEC.x < 1 || VEC.y < 1) {
Log::logger->log(Log::ERR, "Invalid size for maxsize");
@ -298,7 +293,8 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
}
m_minSize.first = Types::COverridableVar(VEC, Types::PRIORITY_WINDOW_RULE);
m_window->clampWindowSize(std::nullopt, m_minSize.first.value());
if (*PCLAMP_TILED || m_window->m_isFloating)
m_window->clampWindowSize(m_minSize.first.value(), std::nullopt);
} catch (std::exception& e) { Log::logger->log(Log::ERR, "minsize rule \"{}\" failed with: {}", effect, e.what()); }
m_minSize.second = rule->getPropertiesMask();
break;

View file

@ -83,7 +83,7 @@ CRegion CWLSurface::computeDamage() const {
return {};
CRegion damage = m_resource->m_current.accumulateBufferDamage();
damage.transform(wlTransformToHyprutils(m_resource->m_current.transform), m_resource->m_current.bufferSize.x, m_resource->m_current.bufferSize.y);
damage.transform(Math::wlTransformToHyprutils(m_resource->m_current.transform), m_resource->m_current.bufferSize.x, m_resource->m_current.bufferSize.y);
const auto BUFSIZE = m_resource->m_current.bufferSize;
const auto CORRECTVEC = correctSmallVecBuf();

View file

@ -1574,41 +1574,13 @@ bool CWindow::isModal() {
return (m_xwaylandSurface && m_xwaylandSurface->m_modal);
}
Vector2D CWindow::requestedMinSize() {
bool hasSizeHints = m_xwaylandSurface ? m_xwaylandSurface->m_sizeHints : false;
bool hasTopLevel = m_xdgSurface ? m_xdgSurface->m_toplevel : false;
if ((m_isX11 && !hasSizeHints) || (!m_isX11 && !hasTopLevel))
return Vector2D(1, 1);
Vector2D minSize = m_isX11 ? Vector2D(m_xwaylandSurface->m_sizeHints->min_width, m_xwaylandSurface->m_sizeHints->min_height) : m_xdgSurface->m_toplevel->layoutMinSize();
minSize = minSize.clamp({1, 1});
return minSize;
}
Vector2D CWindow::requestedMaxSize() {
constexpr int NO_MAX_SIZE_LIMIT = 99999;
if (((m_isX11 && !m_xwaylandSurface->m_sizeHints) || (!m_isX11 && (!m_xdgSurface || !m_xdgSurface->m_toplevel)) || m_ruleApplicator->noMaxSize().valueOrDefault()))
return Vector2D(NO_MAX_SIZE_LIMIT, NO_MAX_SIZE_LIMIT);
Vector2D maxSize = m_isX11 ? Vector2D(m_xwaylandSurface->m_sizeHints->max_width, m_xwaylandSurface->m_sizeHints->max_height) : m_xdgSurface->m_toplevel->layoutMaxSize();
if (maxSize.x < 5)
maxSize.x = NO_MAX_SIZE_LIMIT;
if (maxSize.y < 5)
maxSize.y = NO_MAX_SIZE_LIMIT;
return maxSize;
}
Vector2D CWindow::realToReportSize() {
if (!m_isX11)
return m_realSize->goal().clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
return m_realSize->goal().clamp(Vector2D{0, 0}, Math::VECTOR2D_MAX);
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
const auto REPORTSIZE = m_realSize->goal().clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
const auto REPORTSIZE = m_realSize->goal().clamp(Vector2D{1, 1}, Math::VECTOR2D_MAX);
const auto PMONITOR = m_monitor.lock();
if (*PXWLFORCESCALEZERO && PMONITOR)
@ -1628,7 +1600,7 @@ Vector2D CWindow::xwaylandSizeToReal(Vector2D size) {
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
const auto PMONITOR = m_monitor.lock();
const auto SIZE = size.clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
const auto SIZE = size.clamp(Vector2D{1, 1}, Math::VECTOR2D_MAX);
const auto SCALE = *PXWLFORCESCALEZERO ? PMONITOR->m_scale : 1.0f;
return SIZE / SCALE;
@ -2718,3 +2690,42 @@ void CWindow::unmanagedSetGeometry() {
m_pendingReportedSize = m_realSize->goal();
}
}
std::optional<Vector2D> CWindow::minSize() {
// first check for overrides
if (m_ruleApplicator->minSize().hasValue())
return m_ruleApplicator->minSize().value();
// then check if we have any proto overrides
bool hasSizeHints = m_xwaylandSurface ? m_xwaylandSurface->m_sizeHints : false;
bool hasTopLevel = m_xdgSurface ? m_xdgSurface->m_toplevel : false;
if ((m_isX11 && !hasSizeHints) || (!m_isX11 && !hasTopLevel))
return std::nullopt;
Vector2D minSize = m_isX11 ? Vector2D(m_xwaylandSurface->m_sizeHints->min_width, m_xwaylandSurface->m_sizeHints->min_height) : m_xdgSurface->m_toplevel->layoutMinSize();
minSize = minSize.clamp({1, 1});
return minSize;
}
std::optional<Vector2D> CWindow::maxSize() {
// first check for overrides
if (m_ruleApplicator->maxSize().hasValue())
return m_ruleApplicator->maxSize().value();
// then check if we have any proto overrides
if (((m_isX11 && !m_xwaylandSurface->m_sizeHints) || (!m_isX11 && (!m_xdgSurface || !m_xdgSurface->m_toplevel)) || m_ruleApplicator->noMaxSize().valueOrDefault()))
return std::nullopt;
constexpr const double NO_MAX_SIZE_LIMIT = std::numeric_limits<double>::max();
Vector2D maxSize = m_isX11 ? Vector2D(m_xwaylandSurface->m_sizeHints->max_width, m_xwaylandSurface->m_sizeHints->max_height) : m_xdgSurface->m_toplevel->layoutMaxSize();
if (maxSize.x < 5)
maxSize.x = NO_MAX_SIZE_LIMIT;
if (maxSize.y < 5)
maxSize.y = NO_MAX_SIZE_LIMIT;
return maxSize;
}

View file

@ -347,6 +347,8 @@ namespace Desktop::View {
SP<CWLSurfaceResource> getSolitaryResource();
Vector2D getReportedSize();
std::optional<Vector2D> calculateExpression(const std::string& s);
std::optional<Vector2D> minSize();
std::optional<Vector2D> maxSize();
CBox getWindowMainSurfaceBox() const {
return {m_realPosition->value().x, m_realPosition->value().y, m_realSize->value().x, m_realSize->value().y};

View file

@ -967,7 +967,7 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
if (m_createdByUser) {
CBox transformedBox = {0, 0, m_transformedSize.x, m_transformedSize.y};
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_transform)), m_transformedSize.x, m_transformedSize.y);
transformedBox.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_transform)), m_transformedSize.x, m_transformedSize.y);
m_pixelSize = Vector2D(transformedBox.width, transformedBox.height);
}
@ -1487,7 +1487,7 @@ Vector2D CMonitor::middle() {
void CMonitor::updateMatrix() {
m_projMatrix = Mat3x3::identity();
if (m_transform != WL_OUTPUT_TRANSFORM_NORMAL)
m_projMatrix.translate(m_pixelSize / 2.0).transform(wlTransformToHyprutils(m_transform)).translate(-m_transformedSize / 2.0);
m_projMatrix.translate(m_pixelSize / 2.0).transform(Math::wlTransformToHyprutils(m_transform)).translate(-m_transformedSize / 2.0);
}
WORKSPACEID CMonitor::activeWorkspaceID() {

View file

@ -1,7 +1,7 @@
#include "Math.hpp"
#include "../memory/Memory.hpp"
Hyprutils::Math::eTransform wlTransformToHyprutils(wl_output_transform t) {
Hyprutils::Math::eTransform Math::wlTransformToHyprutils(wl_output_transform t) {
switch (t) {
case WL_OUTPUT_TRANSFORM_NORMAL: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_NORMAL;
case WL_OUTPUT_TRANSFORM_180: return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_180;
@ -16,7 +16,7 @@ Hyprutils::Math::eTransform wlTransformToHyprutils(wl_output_transform t) {
return Hyprutils::Math::eTransform::HYPRUTILS_TRANSFORM_NORMAL;
}
wl_output_transform invertTransform(wl_output_transform tr) {
wl_output_transform Math::invertTransform(wl_output_transform tr) {
if ((tr & WL_OUTPUT_TRANSFORM_90) && !(tr & WL_OUTPUT_TRANSFORM_FLIPPED))
tr = sc<wl_output_transform>(tr ^ sc<int>(WL_OUTPUT_TRANSFORM_180));

View file

@ -9,5 +9,9 @@
// NOLINTNEXTLINE
using namespace Hyprutils::Math;
eTransform wlTransformToHyprutils(wl_output_transform t);
wl_output_transform invertTransform(wl_output_transform tr);
namespace Math {
constexpr const Vector2D VECTOR2D_MAX = {std::numeric_limits<double>::max(), std::numeric_limits<double>::max()};
eTransform wlTransformToHyprutils(wl_output_transform t);
wl_output_transform invertTransform(wl_output_transform tr);
}

View file

@ -325,7 +325,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dir
// first, check if OPENINGON isn't too big.
const auto PREDSIZEMAX = OPENINGON ? Vector2D(OPENINGON->box.w, OPENINGON->box.h) : PMONITOR->m_size;
if (const auto MAXSIZE = pWindow->requestedMaxSize(); MAXSIZE.x < PREDSIZEMAX.x || MAXSIZE.y < PREDSIZEMAX.y) {
if (const auto MAXSIZE = pWindow->maxSize().value_or(Math::VECTOR2D_MAX); MAXSIZE.x < PREDSIZEMAX.x || MAXSIZE.y < PREDSIZEMAX.y) {
// we can't continue. make it floating.
pWindow->m_isFloating = true;
std::erase(m_dwindleNodesData, PNODE);

View file

@ -647,12 +647,8 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
} else if (g_pInputManager->m_dragMode == MBIND_RESIZE || g_pInputManager->m_dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->m_dragMode == MBIND_RESIZE_BLOCK_RATIO) {
if (DRAGGINGWINDOW->m_isFloating) {
Vector2D MINSIZE = DRAGGINGWINDOW->requestedMinSize().clamp(DRAGGINGWINDOW->m_ruleApplicator->minSize().valueOr(Vector2D(MIN_WINDOW_SIZE, MIN_WINDOW_SIZE)));
Vector2D MAXSIZE;
if (DRAGGINGWINDOW->m_ruleApplicator->maxSize().hasValue())
MAXSIZE = DRAGGINGWINDOW->requestedMaxSize().clamp({}, DRAGGINGWINDOW->m_ruleApplicator->maxSize().value());
else
MAXSIZE = DRAGGINGWINDOW->requestedMaxSize().clamp({}, Vector2D(std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
Vector2D MINSIZE = DRAGGINGWINDOW->minSize().value_or(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE});
Vector2D MAXSIZE = DRAGGINGWINDOW->maxSize().value_or(Math::VECTOR2D_MAX);
Vector2D newSize = m_beginDragSizeXY;
Vector2D newPos = m_beginDragPositionXY;
@ -1028,7 +1024,7 @@ bool IHyprLayout::updateDragWindow() {
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
*DRAGGINGWINDOW->m_realPosition = MOUSECOORDS - DRAGGINGWINDOW->m_realSize->goal() / 2.f;
} else if (!DRAGGINGWINDOW->m_isFloating && g_pInputManager->m_dragMode == MBIND_MOVE) {
Vector2D MINSIZE = DRAGGINGWINDOW->requestedMinSize().clamp(DRAGGINGWINDOW->m_ruleApplicator->minSize().valueOr(Vector2D(MIN_WINDOW_SIZE, MIN_WINDOW_SIZE)));
Vector2D MINSIZE = DRAGGINGWINDOW->minSize().value_or(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE});
DRAGGINGWINDOW->m_lastFloatingSize = (DRAGGINGWINDOW->m_realSize->goal() * 0.8489).clamp(MINSIZE, Vector2D{}).floor();
*DRAGGINGWINDOW->m_realPosition = g_pInputManager->getMouseCoordsInternal() - DRAGGINGWINDOW->m_realSize->goal() / 2.f;
if (g_pInputManager->m_dragThresholdReached) {

View file

@ -207,7 +207,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
PNODE->percMaster = lastSplitPercent;
// first, check if it isn't too big.
if (const auto MAXSIZE = pWindow->requestedMaxSize(); MAXSIZE.x < PMONITOR->m_size.x * lastSplitPercent || MAXSIZE.y < PMONITOR->m_size.y) {
if (const auto MAXSIZE = pWindow->maxSize().value_or(Math::VECTOR2D_MAX); MAXSIZE.x < PMONITOR->m_size.x * lastSplitPercent || MAXSIZE.y < PMONITOR->m_size.y) {
// we can't continue. make it floating.
pWindow->m_isFloating = true;
m_masterNodesData.remove(*PNODE);
@ -219,7 +219,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection dire
PNODE->percMaster = lastSplitPercent;
// first, check if it isn't too big.
if (const auto MAXSIZE = pWindow->requestedMaxSize();
if (const auto MAXSIZE = pWindow->maxSize().value_or(Math::VECTOR2D_MAX);
MAXSIZE.x < PMONITOR->m_size.x * (1 - lastSplitPercent) || MAXSIZE.y < PMONITOR->m_size.y * (1.f / (WINDOWSONWORKSPACE - 1))) {
// we can't continue. make it floating.
pWindow->m_isFloating = true;

View file

@ -637,7 +637,7 @@ void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::
Vector2D CPointerManager::getCursorPosForMonitor(PHLMONITOR pMonitor) {
return CBox{m_pointerPos - pMonitor->m_position, {0, 0}}
.transform(wlTransformToHyprutils(invertTransform(pMonitor->m_transform)), pMonitor->m_transformedSize.x / pMonitor->m_scale,
.transform(Math::wlTransformToHyprutils(Math::invertTransform(pMonitor->m_transform)), pMonitor->m_transformedSize.x / pMonitor->m_scale,
pMonitor->m_transformedSize.y / pMonitor->m_scale)
.pos() *
pMonitor->m_scale;
@ -648,7 +648,7 @@ Vector2D CPointerManager::transformedHotspot(PHLMONITOR pMonitor) {
return {}; // doesn't matter, we have no hw cursor, and this is only for hw cursors
return CBox{m_currentCursorImage.hotspot * pMonitor->m_scale, {0, 0}}
.transform(wlTransformToHyprutils(invertTransform(pMonitor->m_transform)), pMonitor->m_cursorSwapchain->currentOptions().size.x,
.transform(Math::wlTransformToHyprutils(Math::invertTransform(pMonitor->m_transform)), pMonitor->m_cursorSwapchain->currentOptions().size.x,
pMonitor->m_cursorSwapchain->currentOptions().size.y)
.pos();
}

View file

@ -88,6 +88,14 @@ CBox CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow) {
else if (pWindow->m_xdgSurface)
box = pWindow->m_xdgSurface->m_current.geometry;
Vector2D MINSIZE = pWindow->minSize().value_or(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE});
Vector2D MAXSIZE = pWindow->maxSize().value_or(Math::VECTOR2D_MAX);
Vector2D oldSize = box.size();
box.w = std::clamp(box.w, MINSIZE.x, MAXSIZE.x);
box.h = std::clamp(box.h, MINSIZE.y, MAXSIZE.y);
box.translate((oldSize - box.size()) / 2.F);
return box;
}

View file

@ -68,7 +68,7 @@ CScreencopyFrame::CScreencopyFrame(SP<CZwlrScreencopyFrameV1> resource_, int32_t
m_box = box_;
const auto POS = m_box.pos() * m_monitor->m_scale;
m_box.transform(wlTransformToHyprutils(m_monitor->m_transform), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y).scale(m_monitor->m_scale).round();
m_box.transform(Math::wlTransformToHyprutils(m_monitor->m_transform), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y).scale(m_monitor->m_scale).round();
m_box.x = POS.x;
m_box.y = POS.y;
@ -200,7 +200,7 @@ void CScreencopyFrame::renderMon() {
CBox monbox = CBox{0, 0, m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y}
.translate({-m_box.x, -m_box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh.
.transform(wlTransformToHyprutils(invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y);
.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y);
g_pHyprOpenGL->pushMonitorTransformEnabled(true);
g_pHyprOpenGL->setRenderModifEnabled(false);
g_pHyprOpenGL->renderTexture(TEXTURE, monbox,

View file

@ -118,7 +118,7 @@ CToplevelExportFrame::CToplevelExportFrame(SP<CHyprlandToplevelExportFrameV1> re
m_box = {0, 0, sc<int>(m_window->m_realSize->value().x * PMONITOR->m_scale), sc<int>(m_window->m_realSize->value().y * PMONITOR->m_scale)};
m_box.transform(wlTransformToHyprutils(PMONITOR->m_transform), PMONITOR->m_transformedSize.x, PMONITOR->m_transformedSize.y).round();
m_box.transform(Math::wlTransformToHyprutils(PMONITOR->m_transform), PMONITOR->m_transformedSize.x, PMONITOR->m_transformedSize.y).round();
m_shmStride = NFormatUtils::minStride(PSHMINFO, m_box.w);

View file

@ -528,7 +528,7 @@ void CWLSurfaceResource::commitState(SSurfaceState& state) {
}
if (m_current.texture)
m_current.texture->m_transform = wlTransformToHyprutils(m_current.transform);
m_current.texture->m_transform = Math::wlTransformToHyprutils(m_current.transform);
if (m_role->role() == SURFACE_ROLE_SUBSURFACE) {
auto subsurface = sc<CSubsurfaceRole*>(m_role.get())->m_subsurface.lock();

View file

@ -29,7 +29,7 @@ CRegion SSurfaceState::accumulateBufferDamage() {
Vector2D trc = transform % 2 == 1 ? Vector2D{bufferSize.y, bufferSize.x} : bufferSize;
bufferDamage = surfaceDamage.scale(scale).transform(wlTransformToHyprutils(invertTransform(transform)), trc.x, trc.y).add(bufferDamage);
bufferDamage = surfaceDamage.scale(scale).transform(Math::wlTransformToHyprutils(Math::invertTransform(transform)), trc.x, trc.y).add(bufferDamage);
damage.clear();
return bufferDamage;
}

View file

@ -754,7 +754,7 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP
m_renderData.monitorProjection = Mat3x3::identity();
if (pMonitor->m_transform != WL_OUTPUT_TRANSFORM_NORMAL) {
const Vector2D tfmd = pMonitor->m_transform % 2 == 1 ? Vector2D{FBO->m_size.y, FBO->m_size.x} : FBO->m_size;
m_renderData.monitorProjection.translate(FBO->m_size / 2.0).transform(wlTransformToHyprutils(pMonitor->m_transform)).translate(-tfmd / 2.0);
m_renderData.monitorProjection.translate(FBO->m_size / 2.0).transform(Math::wlTransformToHyprutils(pMonitor->m_transform)).translate(-tfmd / 2.0);
}
m_renderData.pCurrentMonData = &m_monitorRenderResources[pMonitor];
@ -1373,7 +1373,7 @@ void CHyprOpenGLImpl::scissor(const CBox& originalBox, bool transform) {
if (transform) {
CBox box = originalBox;
const auto TR = wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform));
const auto TR = Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform));
box.transform(TR, m_renderData.pMonitor->m_transformedSize.x, m_renderData.pMonitor->m_transformedSize.y);
if (box != m_lastScissorBox) {
@ -1479,7 +1479,7 @@ void CHyprOpenGLImpl::renderRectWithDamageInternal(const CBox& box, const CHyprC
m_renderData.renderModif.applyToBox(newBox);
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(
newBox, wlTransformToHyprutils(invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
newBox, Math::wlTransformToHyprutils(Math::invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
useProgram(m_shaders->m_shQUAD.program);
@ -1489,7 +1489,7 @@ void CHyprOpenGLImpl::renderRectWithDamageInternal(const CBox& box, const CHyprC
m_shaders->m_shQUAD.setUniformFloat4(SHADER_COLOR, col.r * col.a, col.g * col.a, col.b * col.a, col.a);
CBox transformedBox = box;
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
transformedBox.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
m_renderData.pMonitor->m_transformedSize.y);
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
@ -1640,10 +1640,10 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
static const auto PCURSORTIMEOUT = CConfigValue<Hyprlang::FLOAT>("cursor:inactive_timeout");
// get the needed transform for this texture
const bool TRANSFORMS_MATCH = wlTransformToHyprutils(m_renderData.pMonitor->m_transform) == tex->m_transform; // FIXME: combine them properly!!!
const bool TRANSFORMS_MATCH = Math::wlTransformToHyprutils(m_renderData.pMonitor->m_transform) == tex->m_transform; // FIXME: combine them properly!!!
eTransform TRANSFORM = HYPRUTILS_TRANSFORM_NORMAL;
if (m_monitorTransformEnabled || TRANSFORMS_MATCH)
TRANSFORM = wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform));
TRANSFORM = Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform));
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot);
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
@ -1747,12 +1747,12 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
if (usingFinalShader && *PDT == 0) {
PHLMONITORREF pMonitor = m_renderData.pMonitor;
Vector2D p = ((g_pInputManager->getMouseCoordsInternal() - pMonitor->m_position) * pMonitor->m_scale);
p = p.transform(wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_pixelSize);
p = p.transform(Math::wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_pixelSize);
shader->setUniformFloat2(SHADER_POINTER, p.x / pMonitor->m_pixelSize.x, p.y / pMonitor->m_pixelSize.y);
std::vector<float> pressedPos = m_pressedHistoryPositions | std::views::transform([&](const Vector2D& vec) {
Vector2D pPressed = ((vec - pMonitor->m_position) * pMonitor->m_scale);
pPressed = pPressed.transform(wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_pixelSize);
pPressed = pPressed.transform(Math::wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_pixelSize);
return std::array<float, 2>{pPressed.x / pMonitor->m_pixelSize.x, pPressed.y / pMonitor->m_pixelSize.y};
}) |
std::views::join | std::ranges::to<std::vector<float>>();
@ -1803,7 +1803,7 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
}
CBox transformedBox = newBox;
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
transformedBox.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
m_renderData.pMonitor->m_transformedSize.y);
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
@ -1887,7 +1887,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box)
m_renderData.renderModif.applyToBox(newBox);
// get transform
const auto TRANSFORM = wlTransformToHyprutils(invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform));
const auto TRANSFORM = Math::wlTransformToHyprutils(Math::invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform));
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot);
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
@ -1934,7 +1934,7 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra
m_renderData.renderModif.applyToBox(newBox);
// get transform
const auto TRANSFORM = wlTransformToHyprutils(invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform));
const auto TRANSFORM = Math::wlTransformToHyprutils(Math::invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform));
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot);
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
@ -1985,7 +1985,7 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
setCapStatus(GL_STENCIL_TEST, false);
// get transforms for the full monitor
const auto TRANSFORM = wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform));
const auto TRANSFORM = Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform));
CBox MONITORBOX = {0, 0, m_renderData.pMonitor->m_transformedSize.x, m_renderData.pMonitor->m_transformedSize.y};
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(MONITORBOX, TRANSFORM);
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
@ -2000,7 +2000,7 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi
// prep damage
CRegion damage{*originalDamage};
damage.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
damage.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
m_renderData.pMonitor->m_transformedSize.y);
damage.expand(std::clamp(*PBLURSIZE, sc<int64_t>(1), sc<int64_t>(40)) * pow(2, BLUR_PASSES));
@ -2415,7 +2415,7 @@ void CHyprOpenGLImpl::renderTextureWithBlurInternal(SP<CTexture> tex, const CBox
const auto LASTBR = m_renderData.primarySurfaceUVBottomRight;
CBox transformedBox = box;
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
transformedBox.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
m_renderData.pMonitor->m_transformedSize.y);
CBox monitorSpaceBox = {transformedBox.pos().x / m_renderData.pMonitor->m_pixelSize.x * m_renderData.pMonitor->m_transformedSize.x,
@ -2501,7 +2501,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
float round = data.round + (data.round == 0 ? 0 : scaledBorderSize);
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(
newBox, wlTransformToHyprutils(invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
newBox, Math::wlTransformToHyprutils(Math::invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
const auto BLEND = m_blend;
@ -2522,7 +2522,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT2_LENGTH, 0);
CBox transformedBox = newBox;
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
transformedBox.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
m_renderData.pMonitor->m_transformedSize.y);
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
@ -2585,7 +2585,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
float round = data.round + (data.round == 0 ? 0 : scaledBorderSize);
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(
newBox, wlTransformToHyprutils(invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
newBox, Math::wlTransformToHyprutils(Math::invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
const auto BLEND = m_blend;
@ -2610,7 +2610,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
m_shaders->m_shBORDER1.setUniformFloat(SHADER_GRADIENT_LERP, lerp);
CBox transformedBox = newBox;
transformedBox.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
transformedBox.transform(Math::wlTransformToHyprutils(Math::invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x,
m_renderData.pMonitor->m_transformedSize.y);
const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y);
@ -2664,7 +2664,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun
const auto col = color;
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(
newBox, wlTransformToHyprutils(invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
newBox, Math::wlTransformToHyprutils(Math::invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix);
blend(true);
@ -2745,7 +2745,7 @@ void CHyprOpenGLImpl::renderMirrored() {
CBox monbox = {0, 0, mirrored->m_transformedSize.x * scale, mirrored->m_transformedSize.y * scale};
// transform box as it will be drawn on a transformed projection
monbox.transform(wlTransformToHyprutils(mirrored->m_transform), mirrored->m_transformedSize.x * scale, mirrored->m_transformedSize.y * scale);
monbox.transform(Math::wlTransformToHyprutils(mirrored->m_transform), mirrored->m_transformedSize.x * scale, mirrored->m_transformedSize.y * scale);
monbox.x = (monitor->m_transformedSize.x - monbox.w) / 2;
monbox.y = (monitor->m_transformedSize.y - monbox.h) / 2;
@ -2761,8 +2761,8 @@ void CHyprOpenGLImpl::renderMirrored() {
data.box = monbox;
data.replaceProjection = Mat3x3::identity()
.translate(monitor->m_pixelSize / 2.0)
.transform(wlTransformToHyprutils(monitor->m_transform))
.transform(wlTransformToHyprutils(invertTransform(mirrored->m_transform)))
.transform(Math::wlTransformToHyprutils(monitor->m_transform))
.transform(Math::wlTransformToHyprutils(Math::invertTransform(mirrored->m_transform)))
.translate(-monitor->m_transformedSize / 2.0);
g_pHyprRenderer->m_renderPass.add(makeUnique<CTexPassElement>(std::move(data)));

View file

@ -1467,8 +1467,8 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
CRegion frameDamage{g_pHyprOpenGL->m_renderData.damage};
const auto TRANSFORM = invertTransform(pMonitor->m_transform);
frameDamage.transform(wlTransformToHyprutils(TRANSFORM), pMonitor->m_transformedSize.x, pMonitor->m_transformedSize.y);
const auto TRANSFORM = Math::invertTransform(pMonitor->m_transform);
frameDamage.transform(Math::wlTransformToHyprutils(TRANSFORM), pMonitor->m_transformedSize.x, pMonitor->m_transformedSize.y);
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR)
frameDamage.add(0, 0, sc<int>(pMonitor->m_transformedSize.x), sc<int>(pMonitor->m_transformedSize.y));
@ -2031,7 +2031,7 @@ void CHyprRenderer::damageMirrorsWith(PHLMONITOR pMonitor, const CRegion& pRegio
monbox.y = (monitor->m_transformedSize.y - monbox.h) / 2;
transformed.scale(scale);
transformed.transform(wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_pixelSize.x * scale, pMonitor->m_pixelSize.y * scale);
transformed.transform(Math::wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_pixelSize.x * scale, pMonitor->m_pixelSize.y * scale);
transformed.translate(Vector2D(monbox.x, monbox.y));
mirror->addDamage(transformed);