From 723870337f299d4c80aa0048144f3a1ca1c885bd Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:30:39 +0000 Subject: layout: rethonk layouts from the ground up (#12890) Rewrites layouts to be much smaller, and deal with much less annoying BS. Improves the overall architecture, unifies handling of pseudotiling, and various other improvements. --- src/layout/space/Space.cpp | 185 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/layout/space/Space.cpp (limited to 'src/layout/space/Space.cpp') diff --git a/src/layout/space/Space.cpp b/src/layout/space/Space.cpp new file mode 100644 index 00000000..742c398a --- /dev/null +++ b/src/layout/space/Space.cpp @@ -0,0 +1,185 @@ +#include "Space.hpp" + +#include "../target/Target.hpp" +#include "../algorithm/Algorithm.hpp" + +#include "../../debug/log/Logger.hpp" +#include "../../desktop/Workspace.hpp" +#include "../../config/ConfigManager.hpp" + +using namespace Layout; + +SP CSpace::create(PHLWORKSPACE w) { + auto space = SP(new CSpace(w)); + space->m_self = space; + return space; +} + +CSpace::CSpace(PHLWORKSPACE parent) : m_parent(parent) { + recheckWorkArea(); +} + +void CSpace::add(SP t) { + m_targets.emplace_back(t); + + recheckWorkArea(); + + if (m_algorithm) + m_algorithm->addTarget(t); + + m_parent->updateWindows(); +} + +void CSpace::move(SP t, std::optional focalPoint) { + m_targets.emplace_back(t); + + recheckWorkArea(); + + if (m_algorithm) + m_algorithm->moveTarget(t, focalPoint); + + m_parent->updateWindows(); +} + +void CSpace::remove(SP t) { + std::erase_if(m_targets, [&t](const auto& e) { return !e || e == t; }); + + recheckWorkArea(); + + if (m_algorithm) + m_algorithm->removeTarget(t); + + if (m_parent) // can be null if the workspace is gone + m_parent->updateWindows(); +} + +void CSpace::setAlgorithmProvider(SP algo) { + m_algorithm = algo; +} + +void CSpace::recheckWorkArea() { + if (!m_parent || !m_parent->m_monitor) { + Log::logger->log(Log::ERR, "CSpace: recheckWorkArea on no parent / mon?!"); + return; + } + + const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(m_parent.lock()); + + auto workArea = m_parent->m_monitor->logicalBoxMinusReserved(); + + static auto PGAPSOUTDATA = CConfigValue("general:gaps_out"); + static auto PFLOATGAPSDATA = CConfigValue("general:float_gaps"); + auto* const PGAPSOUT = sc((PGAPSOUTDATA.ptr())->getData()); + auto* PFLOATGAPS = sc(PFLOATGAPSDATA.ptr()->getData()); + if (PFLOATGAPS->m_bottom < 0 || PFLOATGAPS->m_left < 0 || PFLOATGAPS->m_right < 0 || PFLOATGAPS->m_top < 0) + PFLOATGAPS = PGAPSOUT; + + auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT); + auto gapsFloat = WORKSPACERULE.gapsOut.value_or(*PFLOATGAPS); + + Desktop::CReservedArea reservedGaps{gapsOut.m_top, gapsOut.m_right, gapsOut.m_bottom, gapsOut.m_left}; + Desktop::CReservedArea reservedFloatGaps{gapsFloat.m_top, gapsFloat.m_right, gapsFloat.m_bottom, gapsFloat.m_left}; + + auto floatWorkArea = workArea; + + reservedFloatGaps.applyip(floatWorkArea); + reservedGaps.applyip(workArea); + + m_workArea = workArea; + m_floatingWorkArea = floatWorkArea; +} + +const CBox& CSpace::workArea(bool floating) const { + return floating ? m_floatingWorkArea : m_workArea; +} + +PHLWORKSPACE CSpace::workspace() const { + return m_parent.lock(); +} + +void CSpace::toggleTargetFloating(SP t) { + t->setWasTiling(true); + m_algorithm->setFloating(t, !t->floating()); + t->setWasTiling(false); + + m_parent->updateWindows(); + + recalculate(); +} + +CBox CSpace::targetPositionLocal(SP t) const { + return t->position().translate(-m_workArea.pos()); +} + +void CSpace::resizeTarget(const Vector2D& Δ, SP target, eRectCorner corner) { + if (!m_algorithm) + return; + + m_algorithm->resizeTarget(Δ, target, corner); +} + +void CSpace::moveTarget(const Vector2D& Δ, SP target) { + if (!m_algorithm) + return; + + m_algorithm->moveTarget(Δ, target); +} + +SP CSpace::algorithm() const { + return m_algorithm; +} + +void CSpace::recalculate() { + recheckWorkArea(); + + if (m_algorithm) + m_algorithm->recalculate(); +} + +void CSpace::setFullscreen(SP t, eFullscreenMode mode) { + t->setFullscreenMode(mode); + + if (mode == FSMODE_NONE && m_algorithm && t->floating()) + m_algorithm->recenter(t); + + recalculate(); +} + +std::expected CSpace::layoutMsg(const std::string_view& sv) { + if (m_algorithm) + return m_algorithm->layoutMsg(sv); + + return {}; +} + +std::optional CSpace::predictSizeForNewTiledTarget() { + if (m_algorithm) + return m_algorithm->predictSizeForNewTiledTarget(); + + return std::nullopt; +} + +void CSpace::swap(SP a, SP b) { + for (auto& t : m_targets) { + if (t == a) + t = b; + else if (t == b) + t = a; + } + + if (m_algorithm) + m_algorithm->swapTargets(a, b); +} + +void CSpace::moveTargetInDirection(SP t, Math::eDirection dir, bool silent) { + if (m_algorithm) + m_algorithm->moveTargetInDirection(t, dir, silent); +} + +SP CSpace::getNextCandidate(SP old) { + return !m_algorithm ? nullptr : m_algorithm->getNextCandidate(old); +} + +const std::vector>& CSpace::targets() const { + return m_targets; +} -- cgit v1.2.3