#pragma once #include "../helpers/memory/Memory.hpp" #include "../helpers/math/Math.hpp" #include "../managers/input/InputManager.hpp" #include "../config/shared/ConfigErrors.hpp" #include "supplementary/DragController.hpp" #include #include enum eFullscreenMode : int8_t; namespace Layout { class ITarget; class CSpace; enum eRectCorner : uint8_t { CORNER_NONE = 0, CORNER_TOPLEFT = (1 << 0), CORNER_TOPRIGHT = (1 << 1), CORNER_BOTTOMRIGHT = (1 << 2), CORNER_BOTTOMLEFT = (1 << 3), }; inline eRectCorner cornerFromBox(const CBox& box, const Vector2D& pos) { const auto CENTER = box.middle(); if (pos.x < CENTER.x) return pos.y < CENTER.y ? CORNER_TOPLEFT : CORNER_BOTTOMLEFT; return pos.y < CENTER.y ? CORNER_TOPRIGHT : CORNER_BOTTOMRIGHT; } enum eSnapEdge : uint8_t { SNAP_INVALID = 0, SNAP_UP = (1 << 0), SNAP_DOWN = (1 << 1), SNAP_LEFT = (1 << 2), SNAP_RIGHT = (1 << 3), }; enum eFullscreenRequestResult : uint8_t { FULLSCREEN_REQUEST_DEFAULT = 0, FULLSCREEN_REQUEST_HANDLED_BY_LAYOUT, }; class CLayoutManager { public: CLayoutManager(); ~CLayoutManager() = default; enum eRecalculateMonitorReason : uint8_t { RECALCULATE_MONITOR_REASON_UNKNOWN, // when the recalculate monitor reason is unknown or not important to preserve RECALCULATE_MONITOR_REASON_WORKSPACE_CHANGE, RECALCULATE_MONITOR_REASON_TOGGLE_SPECIAL_WORKSPACE, RECALCULATE_MONITOR_REASON_TOGGLE_FULLSCREEN, }; void newTarget(SP target, SP space); void removeTarget(SP target); void changeFloatingMode(SP target); void beginDragTarget(SP target, eMouseBindMode mode); void moveMouse(const Vector2D& mousePos); void resizeTarget(const Vector2D& Δ, SP target, eRectCorner corner = CORNER_NONE); void moveTarget(const Vector2D& Δ, SP target); void setTargetGeom(const CBox& box, SP target); // floats only void endDragTarget(); Config::ErrorResult layoutMsg(const std::string_view& sv); eFullscreenRequestResult fullscreenRequestForTarget(SP target, eFullscreenMode currentEffectiveMode, eFullscreenMode effectiveMode); void switchTargets(SP a, SP b, bool preserveFocus = true); void moveInDirection(SP target, const std::string& direction, bool silent = false); SP getNextCandidate(SP space, SP from); bool isReachable(SP target); void bringTargetToTop(SP target); std::optional predictSizeForNewTiledTarget(); void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, SP target, eMouseBindMode mode, int corner, const Vector2D& beginSize); void invalidateMonitorGeometries(PHLMONITOR); void recalculateMonitor(PHLMONITOR, eRecalculateMonitorReason reason = RECALCULATE_MONITOR_REASON_UNKNOWN); const UP& dragController(); private: UP m_dragStateController = makeUnique(); }; } inline UP g_layoutManager;