7¤0ì?p[y?¨2ê0333333333Aœð;)…m)r¼ô&¢Mn®ƒÙHØÞß÷™$áùîˆcVCU+÷ý¶Î­™¨ó 0 	y@ “¬ôÀ@’Œ “�Šäá`0–1¤ 
B!cBÍˆ   „W5I2…Œ!                   able VarType>
        void createAnimation(const VarType& v, PHLANIMVAR<VarType>& pav, SP<SAnimationPropertyConfig> pConfig, PHLLS pLayer, eAVarDamagePolicy policy) {
            createAnimation(v, pav, pConfig, policy);
            pav->m_Context.pLayer = pLayer;
        }

        std::string         styleValidInConfigVar(const std::string&, const std::string&);

        SP<CEventLoopTimer> m_animationTimer;

        float               m_lastTickTimeMs;

      private:
        bool   m_tickScheduled = false;
        bool   m_lastTickValid = false;
        CTimer m_lastTickTimer;
    };

    UP<CHyprAnimationManager>& mgr();
}
#pragma once

#include "../desktop/DesktopTypes.hpp"

#include <optional>
#include <string>

namespace Animation::Workspace {
    enum eAnimationType : uint8_t {
        ANIMATION_TYPE_IN =   bool isGestureInProgress();

  private:
    PHLWORKSPACE  m_workspaceBegin = nullptr;
    PHLMONITORREF m_monitor;

    double        m_delta            = 0;
    int           m_initialDirection = 0;
    float         m_avgSpeed         = 0;
    int           m_speedPoints      = 0;
    int           m_touchID          = 0;

    friend class CWorkspaceSwipeGesture;
    friend class CInputManager;
};

inline UP<CUnifiedWorkspaceSwipeGesture> g_pUnifiedWorkspaceSwipe = makeUnique<CUnifiedWorkspaceSwipeGesture>();
#pragma once

#include <libeis.h>
#include <string>
#include <wayland-server-core.h>

/*
 * Responsible to creating a socket for input communication
 */
class CEis {
  public:
    CEis(std::string socketPath);
    ~CEis();

    void startEmulating(int activationId);
    void stopEmulating();

    void resetKeyboard();
    void resetPointer();

    void sendMotion(double x, double y);
    void sendKey(uint32_t key, bool pressed);
    void sendModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
    void sendButton(uint32_t button, bool pressed);
    void sendScrollDelta(double x, double y);
    void sendScrollDiscrete(int32_t x, int32_t y);
    void sendScrollStop(bool stopX, bool stopY);
    void sendPointerFrame();

    int  getFileDescriptor();

    //

    std::string m_socketPath;

  private:
    struct SKeymap {
        int32_t  m_fd   = 0;
        uint32_t m_size = 0;
    };

    struct SClient {
        eis_client* m_handle = nulProximity(CTablet::SProximityEvent);
    void               onTabletTip(CTablet::STipEvent);
    void               onTabletButton(CTablet::SButtonEvent);

    STouchData         m_touchData;

    // for refocus to be forced
    PHLWINDOWREF                 m_forcedFocus;

    std::vector<SP<IKeyboard>>   m_keyboards;
    std::vector<SP<IPointer>>    m_pointers;
    std::vector<SP<ITouch>>      m_touches;
    std::vector<SP<CTablet>>     m_tablets;
    std::vector<SP<CTabletTool>> m_tabletTools;
    std::vector<SP<CTabletPad>>  m_tabletPads;
    std::vector<WP<IHID>>        m_hids; // general container for all HID devices connected to the input manager.

    // Switches
    std::list<SSwitchDevice> m_switches;

    // Exclusive layer surfaces
    std::vector<PHLLSREF> m_exclusiveLSes;

    // constraints
    std::vector<WP<CPointerConstraint>> m_constraints;

    //
    void              newIdleInhibitor(std::any);
    void              recheckIdleInhibitorStatus();
    bool              isWindowInhibiting(const PHLWINDOW& pWindow, bool onlyHl = true);

    CTimer            m_lastCursorMovement;

    CInputMethodRelay m_relay;

    // for shared mods
    const std::vector<uint32_t>& getKeysFromAllKBs();
    uint32_t                     getModsFromAllKBs();

    // for virtual keyboards: whether we should respect them as normal ones
    bool        shouldIgnoreVirtualKeyboard(SP<IKeyboard>);

    std::string getNameForNewDevice(std::string);

    void        releaseAllMouseButtons();

 D;
};

struct SEventLoopDoLaterLock {
    SEventLoopDoLaterLock(uint64_t seq);
    ~SEventLoopDoLaterLock();

    uint64_t seq = 0;
};

class CEventLoopManager {
  public:
    CEventLoopManager(wl_display* display, wl_event_loop* wlEventLoop);
    ~CEventLoopManager();

    void enterLoop();

    // Note: will remove the timer if the ptr is lost.
    void addTimer(SP<CEventLoopTimer> timer);
    void removeTimer(SP<CEventLoopTimer> timer);

    void onTimerFire();

    // schedules a recalc of the timers
    void scheduleRecalc();

    // schedules a function to run later, aka in a wayland idle event. Returns a sequence which can be used to remove it.
    uint64_t doLater(const std::function<void()>& fn);
    void     removeDoLater(uint64_t seq);

    // automatically cleaned up doLater instance
    [[nodiscard]] UP<SEventLoopDoLaterLock> doLaterLock(const std::function<void()>& fn);

    struct SIdleData {
        wl_event_source*                                        eventSource = nullptr;
        std::vector<std::pair<uint64_t, std::function<void()>>> fns;
    };

    struct SReadableWaiter {
        wl_event_source*               source;
        Hyprutils::OS::CFileDescriptor fd;
        std::function<void()>          fn;

        SReadableWaiter(wl_event_source* src, Hyprutils::OS::CFileDescriptor f, std::function<void()> func) : source(src), fd(std::move(f)), fn(std::move(func)) {}

        ~SReadableWaiter() {
            if (source) {
                wl_event_source_remove(sour /// @warning Returns the topmost covering FS window is there are several.
        PHLWINDOW getFullscreenWindow(const PHLMONITOR monitor, const std::optional<bool> covering = true);

        /// @warning Will return the modes of the TOPMOST Covering FS Window if there are several
        SFullscreenMode getFullscreenModes(const PHLMONITOR monitor, const std::optional<bool> covering = true);

        // Handler

        eFullscreenHandler getFullscreenHandlerName(const PHLWINDOW window);

        std::string        getFullscreenHandlerNameAsString(const PHLWINDOW window);

        // FS Mode Setter

        void setFullscreenMode(const PHLWINDOW window, std::optional<eFullscreenMode> internal = std::nullopt, std::optional<eFullscreenMode> client = std::nullopt,
                               std::optional<bool> layoutAware = std::nullopt);

        // Misc. Operations

        // In order to avoid re-setting an FS window's size over and over again if it's FS and already set to the correct value.
        bool m_windowPosSettingQueued = false;

      private:
        struct SFsHandlersForWorkspace {
            const WP<IFullscreenHandler> TILED_FS_HANDLER;
            const WP<IFullscreenHandler> TILED_DEFAULT_FS_HANDLER;
            const WP<IFullscreenHandler> FLOATING_FS_HANDLER;
        };

        // FS Mode Setter Helpers
        void setWindowFullscreenModeInternal(const PHLWINDOW window, const eFullscreenMode mode, bool layoutAware);
        void setWindowFullscreenModeClient(con  void add(SP<CWLSurfaceResource> surf);
    void remove(SP<CWLSurfaceResource> surf);
    void setCallback(std::function<void()> onEnd_);
    void clear();

    bool m_keyboard = false;
    bool m_pointer  = false;

  private:
    std::vector<WP<CWLSurfaceResource>> m_surfs;
    std::function<void()>               m_onEnd;
    friend class CSeatManager;
};

class CSeatManager {
  public:
    CSeatManager();

    void     updateCapabilities(uint32_t capabilities); // in IHID caps

    void     setMouse(SP<IPointer> mouse);
    void     setKeyboard(SP<IKeyboard> keeb);
    void     updateActiveKeyboardData(); // updates the clients with the keymap and repeat info

    void     setKeyboardFocus(SP<CWLSurfaceResource> surf);
    void     sendKeyboardKey(uint32_t timeMs, uint32_t key, wl_keyboard_key_state state);
    void     sendKeyboardMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);

    void     setPointerFocus(SP<CWLSurfaceResource> surf, const Vector2D& local);
    void     sendPointerMotion(uint32_t timeMs, const Vector2D& local);
    void     sendPointerButton(uint32_t timeMs, uint32_t key, wl_pointer_button_state state);
    void     sendPointerFrame();
    void     sendPointerFrame(WP<CWLSeatResource> pResource);
    void     sendPointerAxis(uint32_t timeMs, wl_pointer_axis axis, double value, int32_t discrete, int32_t value120, wl_pointer_axis_source source,
                             wl_pointer_axis_relative_direction relative);

    void     sendTOW,
        TXT_KEY_PERMISSION_ALLOW_AND_REMEMBER,
        TXT_KEY_PERMISSION_ALLOW_ONCE,
        TXT_KEY_PERMISSION_DENY,
        TXT_KEY_PERMISSION_UNKNOWN_WAYLAND_APP,

        TXT_KEY_NOTIF_EXTERNAL_XDG_DESKTOP,
        TXT_KEY_NOTIF_NO_GUIUTILS,
        TXT_KEY_NOTIF_FAILED_ASSETS,
        TXT_KEY_NOTIF_INVALID_MONITOR_LAYOUT,
        TXT_KEY_NOTIF_MONITOR_MODE_FAIL,
        TXT_KEY_NOTIF_MONITOR_AUTO_SCALE,
        TXT_KEY_NOTIF_FAILED_TO_LOAD_PLUGIN,
        TXT_KEY_NOTIF_CM_RELOAD_FAILED,
        TXT_KEY_NOTIF_WIDE_COLOR_NOT_10B,
        TXT_KEY_NOTIF_NO_WATCHDOG,
        TXT_KEY_NOTIF_OUTDATED_CONFIG,

        TXT_KEY_SAFE_MODE_TITLE,
        TXT_KEY_SAFE_MODE_DESCRIPTION,
        TXT_KEY_SAFE_MODE_BUTTON_OPEN_CRASH_REPORT_DIR,
        TXT_KEY_SAFE_MODE_BUTTON_LOAD_CONFIG,
        TXT_KEY_SAFE_MODE_BUTTON_UNDERSTOOD,
    };

    class CI18nEngine {
      public:
        CI18nEngine();
        ~CI18nEngine() = default;

        std::string localize(eI18nKeys key, const std::unordered_map<std::string, std::string>& vars = {});
    };

    SP<CI18nEngine> i18nEngine();
};#pragma once

#include "../helpers/memory/Memory.hpp"

class CDonationNagManager {
  public:
    CDonationNagManager();

    // whether the donation nag was shown this boot.
    bool fired();

  private:
    struct SStateData {
        uint64_t epoch = 0;
        uint64_t major = 0;
    };

    SStateData getState();
    void       writeState(const SStateData& s);
    void       fire();

    bool       m_fired = f      m_colorsOkLabA.emplace_back(c.a);
            }
        }

        /* Vector containing the colors */
        std::vector<CHyprColor> m_colors;

        /* Vector containing pure colors for shoving into opengl */
        std::vector<float> m_colorsOkLabA;

        /* Float corresponding to the angle (rad) */
        float m_angle = 0;

        //
        bool operator==(const CGradientValueData& other) const {
            if (other.m_colors.size() != m_colors.size() || m_angle != other.m_angle)
                return false;

            for (size_t i = 0; i < m_colors.size(); ++i)
                if (m_colors[i] != other.m_colors[i])
                    return false;

            return true;
        }

        virtual std::string toString() const {
            std::string result;
            for (auto& c : m_colors) {
                result += std::format("{:x} ", c.getAsHex());
            }

            result += std::format("{}deg", sc<int>(m_angle * 180.0 / M_PI));
            return result;
        }
    };

    class CCssGapData : public IComplexConfigValue {
      public:
        CCssGapData() : m_top(0), m_right(0), m_bottom(0), m_left(0) {};
        CCssGapData(int64_t global) : m_top(global), m_right(global), m_bottom(global), m_left(global) {};
        CCssGapData(int64_t vertical, int64_t horizontal) : m_top(vertical), m_right(horizontal), m_bottom(vertical), m_left(horizontal) {};
        CCssGapData(int64_t top, int64_t horizontal, int64_t bottom) : m_top(top), m_rirovider {
        CConfigManager* manager = nullptr;
        lua_State*      state   = nullptr;
        std::string     name;
        int             tableRef = LUA_NOREF;
        bool            active   = true;
        bool            didError = false;
    };

    class CLuaTiledAlgorithm : public Layout::ITiledAlgorithm {
      public:
        explicit CLuaTiledAlgorithm(SP<SLuaLayoutProvider> provider);
        virtual ~CLuaTiledAlgorithm() = default;

        virtual void                       newTarget(SP<Layout::ITarget> target);
        virtual void                       movedTarget(SP<Layout::ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt);
        virtual void                       removeTarget(SP<Layout::ITarget> target);
        virtual void                       resizeTarget(const Vector2D& Î”, SP<Layout::ITarget> target, Layout::eRectCorner corner = Layout::CORNER_NONE);
        virtual void                       recalculate(Layout::eRecalculateReason reason = Layout::RECALCULATE_REASON_UNKNOWN);
        virtual void                       swapTargets(SP<Layout::ITarget> a, SP<Layout::ITarget> b);
        virtual void                       moveTargetInDirection(SP<Layout::ITarget> t, Math::eDirection dir, bool silent);
        virtual Config::ErrorResult        layoutMsg(const std::string_view& sv);
        virtual std::optional<Vector2D>    predictSizeForNewTarget();
        virtual SP<Layout::ITarget>        getNextCandidate(SP<Layout::ITarget> old);
 ... Args>
    int configError(lua_State* L, int stackLevel, std::format_string<Args...> fmt, Args&&... args) {
        return configError(L, std::format(fmt, std::forward<Args>(args)...), Config::Actions::eActionErrorLevel::ERROR, Config::Actions::eActionErrorCode::UNKNOWN, stackLevel);
    }

    template <typename T, size_t N>
    const T* findDescByName(const T (&descs)[N], std::string_view key) {
        for (const auto& desc : descs) {
            if (key == desc.name)
                return &desc;
        }

        return nullptr;
    }

    void setFn(lua_State* L, const char* name, lua_CFunction fn);
    void setMgrFn(lua_State* L, CConfigManager* mgr, const char* name, lua_CFunction fn);
    void markDispatcherTable(lua_State* L);
    int  wrapDispatcher(lua_State* L);
    bool pushDispatcherFunction(lua_State* L, int idx);

    template <typename T>
    SParseError parseTableField(lua_State* L, int tableIdx, const char* field, T& parser) {
        lua_getfield(L, tableIdx, field);
        if (lua_isnil(L, -1)) {
            lua_pop(L, 1);
            return {.errorCode = PARSE_ERROR_BAD_VALUE, .message = std::format("missing required field \"{}\"", field)};
        }

        auto err = parser.parse(L);
        lua_pop(L, 1);
        if (err.errorCode != PARSE_ERROR_OK)
            err.message = std::format("field \"{}\": {}", field, err.message);
        return err;
    }

    bool hasTableField(lua_State* L, int tableIdx, const char* field);
    void registerToplevelBindingaConfigInt(0); }, WE::WINDOW_RULE_EFFECT_BORDER_SIZE},
        {"rounding_power", []() -> ILuaConfigValue* { return new CLuaConfigFloat(2.F, 1.F, 10.F); }, WE::WINDOW_RULE_EFFECT_ROUNDING_POWER},
        {"scroll_mouse", []() -> ILuaConfigValue* { return new CLuaConfigFloat(1.F, 0.01F, 10.F); }, WE::WINDOW_RULE_EFFECT_SCROLL_MOUSE},
        {"scroll_touchpad", []() -> ILuaConfigValue* { return new CLuaConfigFloat(1.F, 0.01F, 10.F); }, WE::WINDOW_RULE_EFFECT_SCROLL_TOUCHPAD},
        {"animation", []() -> ILuaConfigValue* { return new CLuaConfigString(STRVAL_EMPTY); }, WE::WINDOW_RULE_EFFECT_ANIMATION},
        {"idle_inhibit", []() -> ILuaConfigValue* { return new CLuaConfigString(STRVAL_EMPTY); }, WE::WINDOW_RULE_EFFECT_IDLE_INHIBIT},
        {"opacity", []() -> ILuaConfigValue* { return new CLuaConfigString(STRVAL_EMPTY); }, WE::WINDOW_RULE_EFFECT_OPACITY},
        {"tag", []() -> ILuaConfigValue* { return new CLuaConfigString(STRVAL_EMPTY); }, WE::WINDOW_RULE_EFFECT_TAG},
        {"max_size", []() -> ILuaConfigValue* { return new CLuaConfigExpressionVec2(); }, WE::WINDOW_RULE_EFFECT_MAX_SIZE},
        {"min_size", []() -> ILuaConfigValue* { return new CLuaConfigExpressionVec2(); }, WE::WINDOW_RULE_EFFECT_MIN_SIZE},
        {"border_color", []() -> ILuaConfigValue* { return new CLuaConfigGradient(CHyprColor(0xFF000000)); }, WE::WINDOW_RULE_EFFECT_BORDER_COLOR},
        {"persistent_size", []() -> ILuaConfigValue* { return new CLuaConfigBool(false); }, WE::WINDOW_RULE_EFFECT_PERSISTENT                     --
-- EDIT THIS CONFIG ACCORDING TO THE WIKI INSTRUCTIONS.  --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

hl.config({ autogenerated = true }) -- remove this line to remove the warning

)#";
inline constexpr char             EXAMPLE_CONFIG_BYTES_LUA[] = {
#embed "../../../example/hyprland.lua"
};

inline constexpr std::string_view EXAMPLE_CONFIG_LUA = {EXAMPLE_CONFIG_BYTES_LUA, sizeof(EXAMPLE_CONFIG_BYTES_LUA)};
#pragma once

#include <hyprutils/animation/AnimationConfig.hpp>

#include <vector>
#include <string>
#include <optional>
#include <chrono>
#include <functional>
#include <string_view>
#include <unordered_map>
#include <expected>

#include "../../helpers/memory/Memory.hpp"
#include "../ConfigManager.hpp"
#include "../../managers/eventLoop/EventLoopTimer.hpp"

#include "./types/LuaConfigValue.hpp"
#include "./LuaEventHandler.hpp"

#include "../../desktop/rule/windowRule/WindowRule.hpp"
#include "../../desktop/rule/layerRule/LayerRule.hpp"

#include "../../SharedDefs.hpp"
#include "../../managers/KeybindManager.hpp"
#include "../shared/ConfigErrors.hpp"

extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}

namespace Config::Supplementary {
    struct SConfigOptionDescription;
};

namespace Config::Lua {
    class CConfigManager;
    class CConfigManagerPluginLuaTestAccessor;
}

namespace Config::Lua::Layouts {
    struct SLuaLayoutProvider;
}

namespace Config::Lua::Bindings {
    void registerBindings(lua_State* L, CConfi"
#include "./types/Vec2Value.hpp"

namespace Config::Values {

    inline auto vec2Range(float minX, float minY, float maxX, float maxY) {
        return [=](const Config::VEC2& v) -> std::expected<void, std::string> {
            if (v.x < minX || v.x > maxX || v.y < minY || v.y > maxY)
                return std::unexpected(std::format("value out of range [{}, {}] - [{}, {}]", minX, minY, maxX, maxY));
            return {};
        };
    }

    inline auto strChoice(std::vector<std::string> rawVec) {
        return [vec = std::move(rawVec)](const Config::STRING& v) -> std::expected<void, std::string> {
            if (!std::ranges::contains(vec, v)) {
                std::string allowed = "";
                for (const auto& e : vec) {
                    allowed += std::format("\"{}\", ", e);
                }

                allowed.resize(allowed.size() - 2);

                return std::unexpected(std::format("bad value \"{}\", allowed values are: {}", v, allowed));
            }
            return {};
        };
    }

    using Bool       = CBoolValue;
    using Color      = CColorValue;
    using CssGap     = CCssGapValue;
    using Float      = CFloatValue;
    using FontWeight = CFontWeightValue;
    using Gradient   = CGradientValue;
    using Int        = CIntValue;
    using String     = CStringValue;
    using Vec2       = CVec2Value;

    template <typename T>
    struct SValueOptions;

    template <>
    struct SValueOptions<CBoolValue> {
        using type = SBool      spawnWithRules(std::string, PHLWORKSPACE, SP<Desktop::Rule::CWindowRule> rule);
        std::vector<std::pair<std::string, std::string>> getHyprlandLaunchEnv(PHLWORKSPACE pInitialWorkspace);

        struct {
            CHyprSignalListener init;
            CHyprSignalListener shutdown;
        } m_listeners;

        bool m_firstExecDispatched = false;
        bool m_isLaunchingExecOnce = false;
    };

    UP<CExecutor>& executor();
};
#pragma once

#include "../../SharedDefs.hpp"
#include "../../helpers/memory/Memory.hpp"

#include <functional>
#include <unordered_map>
#include <string>

namespace Config::Legacy {
    class CDispatcherTranslator {
      public:
        CDispatcherTranslator();
        ~CDispatcherTranslator() = default;

        SDispatchResult run(const std::string& dispatcher, const std::string& data);

      private:
        std::unordered_map<std::string, std::function<SDispatchResult(const std::string&)>> m_dispMap;
    };

    UP<CDispatcherTranslator>& translator();
}#pragma once

#include <string_view>

inline constexpr std::string_view EXAMPLE_CONFIG = R"#(

# This config is a STUB! This should never be generated.
# Use the default lua config from https://github.com/hyprwm/Hyprland/blob/main/example/hyprland.lua

autogenerated = 1

$mainMod = SUPER
$terminal = kitty
$fileManager = dolphin
$menu = hyprlauncher

bind = $mainMod, Q, exec, $terminal
bind = $mainMod, C, killactive,
bind = $mainMod, M, exec, command -v hyprshutdown >/dev/null 2>&1 && hyprshte:
        CImageDescription(const SImageDescription& imageDescription, const uint64_t imageDescriptionId);
        uint64_t          m_id          = 0;
        uint              m_primariesId = 0;
        SImageDescription m_imageDescription;
    };

    union RGBAColor {
        struct {
            double r = 0, g = 0, b = 0, a = 0;
        } c;
        double     v[4];

        RGBAColor& operator*=(double value) {
            c.r *= value;
            c.g *= value;
            c.b *= value;
            return *this;
        }

        RGBAColor& operator/=(double value) {
            c.r /= value;
            c.g /= value;
            c.b /= value;
            return *this;
        }
    };

    using PImageDescription = WP<const CImageDescription>;

    RGBAColor         convertColor(RGBAColor color, PImageDescription srcDesc, PImageDescription dstDesc);
    CHyprColor        convertColor(const CHyprColor& color, PImageDescription srcDesc, PImageDescription dstDesc);

    PImageDescription getDefaultImageDescription();

    inline const auto DEFAULT_GAMMA22_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{
        .transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22,
        .primariesNameSet = true,
        .primariesNamed   = NColorManagement::CM_PRIMARIES_SRGB,
        .primaries        = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_SRGB),
        .luminances       = {.min = SDR_MIN_LUMINANCE, .max = 80, .reference = 80},
    });

  eturn sc<eTransferFunction>(tf);
        }
    }
    inline std::string tfToString(eTransferFunction tf) {
        switch (tf) {
            case CM_TRANSFER_FUNCTION_LINEAR: return "TF:INTERNAL LINEAR NOT NORMALISED";
            case CM_TRANSFER_FUNCTION_BT1886: return "TF:BT1886";
            case CM_TRANSFER_FUNCTION_GAMMA22: return "TF:GAMMA22";
            case CM_TRANSFER_FUNCTION_GAMMA28: return "TF:GAMMA28";
            case CM_TRANSFER_FUNCTION_ST240: return "TF:ST240";
            case CM_TRANSFER_FUNCTION_EXT_LINEAR: return "TF:EXT_LINEAR";
            case CM_TRANSFER_FUNCTION_LOG_100: return "TF:LOG_100";
            case CM_TRANSFER_FUNCTION_LOG_316: return "TF:LOG_316";
            case CM_TRANSFER_FUNCTION_XVYCC: return "TF:XVYCC";
            case CM_TRANSFER_FUNCTION_SRGB: return "TF:SRGB";
            case CM_TRANSFER_FUNCTION_EXT_SRGB: return "TF:EXT_SRGB";
            case CM_TRANSFER_FUNCTION_ST2084_PQ: return "TF:ST2084_PQ";
            case CM_TRANSFER_FUNCTION_ST428: return "TF:ST428";
            case CM_TRANSFER_FUNCTION_HLG: return "TF:HLG";
            default: return "TF:ERROR";
        }
    }

    using SPCPRimaries = Hyprgraphics::SPCPRimaries;

    namespace NColorPrimaries {

        inline const auto BT709 = SPCPRimaries{
            .red   = {.x = 0.64, .y = 0.33},
            .green = {.x = 0.30, .y = 0.60},
            .blue  = {.x = 0.15, .y = 0.06},
            .white = {.x = 0.3127, .y = 0.3290},
        };

        inline const auto DEFAULT_PRarType value = AVARTYPE_COLOR;
};

template <class T>
inline constexpr eAnimatedVarType typeToeAnimatedVarType = STypeToAnimatedVarType_t<T>::value;

// Utility to define a concept as a list of possible type
template <class T, class... U>
concept OneOf = (... or std::same_as<T, U>);

// Concept to describe which type can be placed into CAnimatedVariable
// This is mainly to get better errors if we put a type that's not supported
// Otherwise template errors are ugly
template <class T>
concept Animable = OneOf<T, Vector2D, float, CHyprColor>;

struct SAnimationContext {
    PHLWINDOWREF      pWindow;
    PHLWORKSPACEREF   pWorkspace;
    PHLLSREF          pLayer;

    eAVarDamagePolicy eDamagePolicy = AVARDAMAGE_NONE;
};

template <Animable VarType>
using CAnimatedVariable = Hyprutils::Animation::CGenericAnimatedVariable<VarType, SAnimationContext>;

template <Animable VarType>
using PHLANIMVAR = UP<CAnimatedVariable<VarType>>;

template <Animable VarType>
using PHLANIMVARREF = WP<CAnimatedVariable<VarType>>;
#pragma once

#include "Time.hpp"

class CTimer {
  public:
    void                   reset();
    float                  getSeconds() const;
    float                  getMillis() const;
    const Time::steady_tp& chrono() const;

  private:
    Time::steady_tp  m_lastReset;

    Time::steady_dur getDuration() const;
};
#pragma once

#include <chrono>
#include <cstdint>
#include <utility>
#include <ctime>

//NOLINTNEXTLINE
namespace Time {
    using steady_tp  = std::chrono::stead if (len < 0) {
                    *this += "<interrupted, read() resulted in errno ";
                    writeNum(errno);
                    *this += ">\n";
                }
                close(pipefd[0]);
            }
        }

        void flush() {
            size_t i = 0;
            while (i < m_writeBufPos) {
                auto written = ::write(m_fd, m_writeBuf + i, m_writeBufPos - i);
                if (written <= 0) {
                    return;
                }
                i += written;
            }
            m_writeBufPos = 0;
        }

      private:
        char   m_writeBuf[BUFSIZE] = {0};
        size_t m_writeBufPos       = 0;
        int    m_fd                = 0;
    };

    char const* getenv(const char* name);
    char const* strsignal(int sig);
}
#pragma once

#include <shared_mutex>
#include <unordered_map>
#include <format>
#include <vector>

namespace Log {
    struct SRollingLogFollow {
        std::unordered_map<int, std::string> m_socketToRollingLogFollowQueue;
        std::shared_mutex                    m_mutex;
        bool                                 m_running                  = false;
        static constexpr size_t              ROLLING_LOG_FOLLOW_TOO_BIG = 8192;

        // Returns true if the queue is empty for the given socket
        bool isEmpty(int socket) {
            std::shared_lock<std::shared_mutex> r(m_mutex);
            return m_socketToRollingLogFollowQueue[socket].empty();
        }

        std::string debugInfprRenderer;
    };

    class COverlay {
      public:
        COverlay();
        void draw();
        void renderData(PHLMONITOR, float durationUs);
        void renderDataNoOverlay(PHLMONITOR, float durationUs);
        void frameData(PHLMONITOR);

      private:
        std::map<PHLMONITORREF, CMonitorOverlay> m_monitorOverlays;
        CBox                                     m_lastDrawnBox;
        CTimer                                   m_frameTimer;

        void                                     createWarningTexture(float maxW);
        SP<Render::ITexture>                     m_warningTexture;
        float                                    m_warningTextureMaxW = 0;

        friend class CHyprMonitorDebugOverlay;
        friend class Render::IHyprRenderer;
    };

    UP<COverlay>& overlay();
}
#pragma once

namespace CrashReporter {
    void createAndSaveCrash(int sig);
};#pragma once

#include "defines.hpp"
#include <cstring>

namespace SignalSafe {
    template <uint16_t N>
    class CMaxLengthCString {
      public:
        CMaxLengthCString() {
            m_str[0] = '\0';
        }

        void operator+=(char const* rhs) {
            write(rhs, strlen(rhs));
        }

        void write(char const* data, size_t len) {
            if (m_boundsExceeded || m_strPos + len >= N) {
                m_boundsExceeded = true;
                return;
            }
            memcpy(m_str + m_strPos, data, len);
            m_strPos += len;
            m_str[m_strPos] = '\04.0"
// clang-format off
#define AQUAMARINE_VERSION_MAJOR 0
#define AQUAMARINE_VERSION_MINOR 14
#define AQUAMARINE_VERSION_PATCH 0
// clang-format on
#define HYPRLANG_VERSION     "0.6.8"
#define HYPRUTILS_VERSION    "0.14.0"
#define HYPRCURSOR_VERSION   "0.1.13"
#define HYPRGRAPHICS_VERSION "0.5.1"
#pragma once

#include <cmath>
#include <csignal>
#include <print>
#include <string_view>
#include <utility>

#include "helpers/memory/Memory.hpp"
#include "debug/log/Logger.hpp"

#ifndef NDEBUG
#ifdef HYPRLAND_DEBUG
#define ISDEBUG true
#else
#define ISDEBUG false
#endif
#else
#define ISDEBUG false
#endif

#define SPECIAL_WORKSPACE_START (-99)

#define STRVAL_EMPTY "[[EMPTY]]"

#define WORKSPACE_INVALID     -1L
#define WORKSPACE_NOT_CHANGED -101

#define MONITOR_INVALID  -1L
#define MONITOR_FALLBACK -2L

#define MIN_WINDOW_SIZE 20.0

// max value 32 because killed is a int uniform
#define POINTER_PRESSED_HISTORY_LENGTH 32

#define VECINRECT(vec, x1, y1, x2, y2)    ((vec).x >= (x1) && (vec).x < (x2) && (vec).y >= (y1) && (vec).y < (y2))
#define VECNOTINRECT(vec, x1, y1, x2, y2) ((vec).x < (x1) || (vec).x >= (x2) || (vec).y < (y1) || (vec).y >= (y2))

#define DELTALESSTHAN(a, b, delta) (abs((a) - (b)) < (delta))

#define STICKS(a, b) abs((a) - (b)) < 2

#define HYPRATOM(name) {name, 0}

template <typename... Args>
[[gnu::noinline]] [[gnu::cold]] void assertImpl(int line, std::string_view filename, std::format_string<Args...> reason, Args&&... args) {
    Log::logger->log(Log::CRIT, "\n========);
}

vec3 tfLinPow(vec3 color, float gamma, float thres, float scale, float alpha) {
    bvec3 isLow = lessThanEqual(color.rgb, vec3(thres));
    vec3  lo    = color.rgb * scale;
    vec3  hi    = pow(color.rgb, vec3(1.0 / gamma)) * alpha - (alpha - 1.0);
    return mix(hi, lo, isLow);
}

vec3 tfSRGB(vec3 color) {
    return tfLinPow(color, SRGB_POW, SRGB_CUT, SRGB_SCALE, SRGB_ALPHA);
}

vec3 tfExtSRGB(vec3 color) {
    // EXT sRGB is the sRGB transfer function mirrored around 0.
    return sign(color) * tfSRGB(abs(color));
}

vec3 tfBT1886(vec3 color) {
    return tfLinPow(color, BT1886_POW, BT1886_CUT, BT1886_SCALE, BT1886_ALPHA);
}

vec3 tfXVYCC(vec3 color) {
    // The transfer function for XVYCC is the BT1886 transfer function mirrored around 0,
    // same as what EXT sRGB is to sRGB.
    return sign(color) * tfBT1886(abs(color));
}

vec3 tfST240(vec3 color) {
    return tfLinPow(color, ST240_POW, ST240_CUT, ST240_SCALE, ST240_ALPHA);
}

vec3 toLinearRGB(vec3 color, int tf) {
    switch (tf) {
        case CM_TRANSFER_FUNCTION_LINEAR: return color;
        case CM_TRANSFER_FUNCTION_EXT_LINEAR: return color;
        case CM_TRANSFER_FUNCTION_ST2084_PQ: return tfInvPQ(color);
        case CM_TRANSFER_FUNCTION_GAMMA22: return pow(max(color, vec3(0.0)), vec3(2.2));
        case CM_TRANSFER_FUNCTION_GAMMA28: return pow(max(color, vec3(0.0)), vec3(2.8));
        case CM_TRANSFER_FUNCTION_HLG: return tfInvHLG(color);
        case CM_TRANSFER_FUNCTION_EXT_SRGB: return tfInvExtSRGB(color)es.h"

#if USE_CM
#include "cm_helpers.glsl"
#endif

#include "gain.glsl"

vec4 blurPrepare(vec4 pixColor, float contrast, float brightness
#if USE_CM
                 ,
                 int sourceTF, int targetTF, mat3 convertMatrix, vec2 srcTFRange, vec2 dstTFRange, float srcRefLuminance, float sdrBrightnessMultiplier
#endif
) {
#if USE_CM
    if (sourceTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
        pixColor.rgb /= sdrBrightnessMultiplier;
    }
    pixColor.rgb = convertMatrix * toLinearRGB(pixColor.rgb, sourceTF);
    pixColor     = toNit(pixColor, srcTFRange);
    pixColor     = fromLinearNit(pixColor, targetTF, dstTFRange);
#endif

    // contrast
    if (contrast != 1.0)
        pixColor.rgb = gain(pixColor.rgb, contrast);

    // brightness
    pixColor.rgb *= max(1.0, brightness);

    return pixColor;
}
)#"
R"#(#version 300 es

precision highp float;
in vec2 v_texcoord; // is in 0-1
uniform sampler2D tex;

layout(location = 0) out vec4 fragColor;
void main() {
    fragColor = texture(tex, v_texcoord);
}
)#"
R"#(#ifndef ALLOW_INCLUDES
#define ALLOW_INCLUDES
#extension GL_ARB_shading_language_include : enable
#endif
#include "constants.h"

const mat3 BT2020toLMS = mat3( //
    0.3592, -0.1922, 0.0070,   //
    0.6976, 1.1004, 0.0749,    //
    -0.0358, 0.0755, 0.8434    //
);
//const mat3 LMStoBT2020 = inverse(BT2020toLMS);
const mat3 LMStoBT2020 = mat3(                                                //
    2.0701800566956135096, 0.36498825003265747974, -0.049595542238932107896"inner_glow.glsl"

layout(location = 0) out vec4 fragColor;
#if USE_MIRROR
layout(location = 1) out vec4 mirrorColor;
#endif
void main() {
    vec4 pixColor = v_color;
#if USE_MIRROR
    vec4[2] pixColors =
#else
    fragColor =
#endif
    getInnerGlow(pixColor, colorSRGB, v_texcoord, radius, roundingPower, topLeft, fullSize, range, shadowPower, bottomRight,
                 gradientLength, gradient, angle, gradient2Length, gradient2, angle2, gradientLerp, alpha);
#if USE_MIRROR
    fragColor   = pixColors[0];
    mirrorColor = pixColors[1];
#endif
}
)#"
R"#(#version 300 es
#define ALLOW_INCLUDES
#extension GL_ARB_shading_language_include : enable

#include "defines.h"

precision         highp float;
in vec2           v_texcoord;
uniform sampler2D tex;
#if USE_BLUR
uniform vec2      uvSize;
uniform vec2      uvOffset;
uniform sampler2D blurredBG;
uniform float     blurAlpha;
#endif
#if USE_BLUR_MATTE
uniform sampler2D blurAlphaMatte;
#endif

uniform float alpha;

#if USE_DISCARD
uniform bool  discardOpaque;
uniform bool  discardAlpha;
uniform float discardAlphaValue;
#endif

#if USE_TINT
uniform vec3 tint;
#endif

#if USE_ROUNDING
uniform float radius;
uniform float roundingPower;
uniform vec2  topLeft;
uniform vec2  fullSize;
#include "rounding.glsl"
#else
const float radius        = 0.0;
const float roundingPower = 2.0;
#endif

#if USE_MOTION_BLUR
uniform vec4  motionPrevBox;
uniform vec4  motionCurrBox;
uniform vec4  motionSourceBox;
uniform vec2  motionSourceTexSize;
uniform int   mtional>
#include "OpenGL.hpp"
#include "./SyncFDManager.hpp"
#include "./pass/Pass.hpp"
#include "./pass/BorderPassElement.hpp"
#include "./pass/ClearPassElement.hpp"
#include "./pass/FramebufferElement.hpp"
#include "./pass/RectPassElement.hpp"
#include "./pass/RendererHintsPassElement.hpp"
#include "./pass/ShadowPassElement.hpp"
#include "./pass/SurfacePassElement.hpp"
#include "./pass/TexPassElement.hpp"
#include "./pass/TextureMatteElement.hpp"
#include "./pass/TransformedWindowPassElement.hpp"
#include "types.hpp"
#include "../output/Monitor.hpp"
#include "../desktop/state/Fadeout.hpp"
#include "../desktop/view/LayerSurface.hpp"
#include "Renderbuffer.hpp"
#include "../helpers/time/Timer.hpp"
#include "../helpers/math/Math.hpp"
#include "../helpers/time/Time.hpp"
#include "../../protocols/cursor-shape-v1.hpp"
#include "desktop/view/Popup.hpp"
#include "Framebuffer.hpp"
#include "Texture.hpp"

#include <hyprgraphics/resource/resources/TextResource.hpp>

struct SMonitorRule;
class CWorkspace;
class CInputPopup;
class IHLBuffer;
class CEventLoopTimer;
class CToplevelExportProtocolManager;
class CInputManager;
struct SSessionLockSurface;
namespace Screenshare {
    class CScreenshareFrame;
};
namespace Pointer {
    class CPointerManager;
}

namespace Render {
    using CScopeGuard = Hyprutils::Utils::CScopeGuard;

    class IElementRenderer;
    class CRenderPass;

    class IHyprRenderer {
      public:
        IHyprRenderer();
        virtual ~IHyprRenderer();

        enum eType : AT_DISCARD         = (1 << 1),  // RGBA/RGBX texture sampling
        SH_FEAT_TINT            = (1 << 2),  // uniforms: tint; condition: applyTint
        SH_FEAT_ROUNDING        = (1 << 3),  // uniforms: radius, roundingPower, topLeft, fullSize; condition: radius > 0
        SH_FEAT_CM              = (1 << 4),  // uniforms: srcTFRange, dstTFRange, srcRefLuminance, convertMatrix; condition: !skipCM
        SH_FEAT_TONEMAP         = (1 << 5),  // uniforms: maxLuminance, dstMaxLuminance, dstRefLuminance; condition: maxLuminance < dstMaxLuminance * 1.01
        SH_FEAT_SDR_MOD         = (1 << 6),  // uniforms: sdrSaturation, sdrBrightnessMultiplier; condition: SDR <-> HDR && (sdrSaturation != 1 || sdrBrightnessMultiplier != 1)
        SH_FEAT_BLUR            = (1 << 7),  // condition: render:use_shader_blur_blend
        SH_FEAT_ICC             = (1 << 8),  //
        SH_FEAT_MIRROR          = (1 << 9),  // condition: mirror or screenshare
        SH_FEAT_MOTION_BLUR     = (1 << 10), // condition: decoration:motion_blur:enabled
        SH_FEAT_BLUR_ALPHA_MASK = (1 << 11), // condition: transformed-window shader blur blend
        SH_FEAT_BLUR_MATTE      = (1 << 12), // condition: transformed-window blur matte
        SH_FEAT_ALT_TONEMAP     = (1 << 13), // condition: tonemapMode == 3

        // uniforms: targetPrimariesXYZ; condition: SH_FEAT_TONEMAP || SH_FEAT_SDR_MOD
    };

    using ShaderFeatureFlags = uint16_t;

    enum ePreparedFragmentShader : uint8_t {
        SH_FRAG_QUAD = 0,
 m_size      = {};
        eTransform                  m_transform = HYPRUTILS_TRANSFORM_NORMAL;
        bool                        m_opaque    = false;

        uint32_t                    m_drmFormat     = 0; // for shm
        bool                        m_isSynchronous = false;

        // CM
        NColorManagement::PImageDescription m_imageDescription;

        // TODO move to GLTexture
        GLuint m_texID   = 0;
        GLenum magFilter = GL_LINEAR; // useNearestNeighbor overwrites these
        GLenum minFilter = GL_LINEAR;

      protected:
        ITexture() = default;
        ITexture(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size, bool keepDataCopy = false, bool opaque = false);
        ITexture(std::span<const float> lut3D, size_t N);

        bool                 m_keepDataCopy = false;
        std::vector<uint8_t> m_dataCopy;
    };
}
#pragma once

#include "../defines.hpp"
#include <array>
#include <variant>

enum eShaderUniform : uint8_t {
    SHADER_PROJ = 0,
    SHADER_COLOR,
    SHADER_COLOR_SRGB,
    SHADER_ALPHA_MATTE,
    SHADER_TEX_TYPE,
    SHADER_SOURCE_TF,
    SHADER_TARGET_TF,
    SHADER_SRC_TF_RANGE,
    SHADER_DST_TF_RANGE,
    SHADER_TARGET_PRIMARIES_XYZ,
    SHADER_MAX_LUMINANCE,
    SHADER_SRC_REF_LUMINANCE,
    SHADER_DST_MAX_LUMINANCE,
    SHADER_DST_REF_LUMINANCE,
    SHADER_SDR_SATURATION,
    SHADER_SDR_BRIGHTNESS,
    SHADER_CONVERT_MATRIX,
    SHADER_TEX,
    SHADER_ALPHA,
    SHADER_POS_ATTRIB,
    SHADER_TEX_ATTR_t                discardMode    = DISCARD_OPAQUE;
            float                  discardOpacity = 0.f;

            CRegion                clipRegion;
            PHLLSREF               currentLS;

            Vector2D               primarySurfaceUVTopLeft     = Vector2D(-1, -1);
            Vector2D               primarySurfaceUVBottomRight = Vector2D(-1, -1);

            SMotionBlurData        motionBlur;
        };

        struct SBorderRenderData {
            int   round         = 0;
            float roundingPower = 2.F;
            int   borderSize    = 1;
            float a             = 1.0;
            int   outerRound    = -1; /* use round */
        };

        void makeEGLCurrent();
        void begin(PHLMONITOR, const CRegion& damage, SP<IFramebuffer> fb = nullptr, std::optional<CRegion> finalDamage = {});
        void beginSimple(PHLMONITOR, const CRegion& damage, SP<IRenderbuffer> rb = nullptr, SP<IFramebuffer> fb = nullptr);
        void end();

        void renderRect(const CBox&, const CHyprColor&, SRectRenderData data);
        void renderTexture(SP<ITexture>, const CBox&, STextureRenderData data);
        void renderRoundedShadow(const CBox&, int round, float roundingPower, int range, const Config::CGradientValueData& color, float a = 1.0);
        void renderRoundedShadow(const CBox&, int round, float roundingPower, int range, const Config::CGradientValueData& grad1, const Config::CGradientValueData& grad2,
                                 float lerp, float \
    void name##Override(const Types::COverridableVar<type>& other) {                                                                                                               \
        m_##name.first = other;                                                                                                                                                    \
    }

        // dynamic props
        DEFINE_PROP(bool, noanim, false)
        DEFINE_PROP(bool, blur, false)
        DEFINE_PROP(bool, blurPopups, false)
        DEFINE_PROP(bool, dimAround, false)
        DEFINE_PROP(bool, xray, false)
        DEFINE_PROP(bool, noScreenShare, false)

        DEFINE_PROP(Config::INTEGER, order, 0)
        DEFINE_PROP(Config::INTEGER, aboveLock, 0)

        DEFINE_PROP(Config::FLOAT, ignoreAlpha, 0.F)

        DEFINE_PROP(std::string, animationStyle, std::string(""))

#undef COMMA
#undef DEFINE_PROP

      private:
        PHLLSREF m_ls;

        void     applyDynamicRule(const SP<CLayerRule>& rule);
    };
};
#pragma once

#include "../RuleWithEffects.hpp"
#include "../../DesktopTypes.hpp"
#include "LayerRuleEffectContainer.hpp"

#include <expected>
#include <variant>

namespace Desktop::Rule {
    using LayerRuleEffectValue = std::variant<std::monostate, bool, int64_t, float, std::string>;

    struct SLayerRuleEffect {
        using storageType = CLayerRuleEffectContainer::storageType;
        using valueType   = LayerRuleEffectValue;

        CLayerRuleEffectContainer::storageType key = LA"../../DesktopTypes.hpp"
#include "../Rule.hpp"
#include "../../types/OverridableVar.hpp"
#include "../../../helpers/math/Math.hpp"
#include "../../../config/shared/complex/ComplexDataTypes.hpp"

namespace Desktop::Rule {
    class CLayerRule;

    class CLayerRuleApplicator {
      public:
        CLayerRuleApplicator(PHLLS ls);
        ~CLayerRuleApplicator() = default;

        CLayerRuleApplicator(const CLayerRuleApplicator&) = delete;
        CLayerRuleApplicator(CLayerRuleApplicator&)       = delete;
        CLayerRuleApplicator(CLayerRuleApplicator&&)      = delete;

        void propertiesChanged(std::underlying_type_t<eRuleProperty> props);
        void resetProps(std::underlying_type_t<eRuleProperty> props, Types::eOverridePriority prio = Types::PRIORITY_WINDOW_RULE);

        struct SCustomPropContainer {
            CLayerRuleEffectContainer::storageType idx      = LAYER_RULE_EFFECT_NONE;
            std::underlying_type_t<eRuleProperty>  propMask = RULE_PROP_NONE;
            std::string                            effect;
        };

        // This struct holds props that were dynamically registered. Plugins may read this.
        struct {
            std::unordered_map<CLayerRuleEffectContainer::storageType, UP<SCustomPropContainer>> props;
        } m_otherProps;

#define COMMA ,
#define DEFINE_PROP(type, name, def)                                                                                                                                               \
  private:   elper(std::span<const SP<CPopup>> nodes, std::function<void(SP<CPopup>, void*)> fn, void* data);
    };
}
#pragma once

#include "../../defines.hpp"
#include <vector>
#include "WLSurface.hpp"
#include "View.hpp"
#include "types/Geometric.hpp"

class CWLSubsurfaceResource;

namespace Desktop::View {
    class CPopup;
    class CSubsurface : public virtual IView, public virtual IGeometric {
      public:
        // root dummy nodes
        static SP<CSubsurface> create(PHLWINDOW pOwner);
        static SP<CSubsurface> create(WP<Desktop::View::CPopup> pOwner);

        // real nodes
        static SP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
        static SP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, WP<Desktop::View::CPopup> pOwner);

        static SP<CSubsurface> fromView(SP<IView>);

        virtual ~CSubsurface() = default;

        virtual eViewType              type() const;
        virtual bool                   visible() const;
        virtual std::optional<CBox>    logicalBox() const;
        virtual bool                   desktopComponent() const;
        virtual std::optional<CBox>    surfaceLogicalBox() const;
        virtual Vector2D               position(eGeometricValueType) const override;
        virtual Vector2D               size(eGeometricValueType) const override;
        virtual CBox                   geometricBox(eGeometricValueType) const override;

        Vector2D                       coordsRelativeToParent()         m_inputBlockReasons = INPUT_BLOCK_NONE;
        Desktop::Types::CMultiAVarContainer<float, std::underlying_type_t<eWindowAlpha>> m_alpha;
    };

    inline bool valid(const PHLWINDOW& w) {
        return w.get();
    }

    inline bool valid(const PHLWINDOWREF& w) {
        return !w.expired();
    }

    inline bool validMapped(const PHLWINDOW& w) {
        if (!valid(w))
            return false;
        return w->m_isMapped;
    }

    inline bool validMapped(const PHLWINDOWREF& w) {
        if (!valid(w))
            return false;
        return w->m_isMapped;
    }
}

/**
    format specification
    - 'x', only address, equivalent of (uintpr_t)CWindow*
    - 'm', with monitor id
    - 'w', with workspace id
    - 'c', with application class
*/

template <typename CharT>
struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> {
    bool formatAddressOnly = false;
    bool formatWorkspace   = false;
    bool formatMonitor     = false;
    bool formatClass       = false;
    FORMAT_PARSE(                           //
        FORMAT_FLAG('x', formatAddressOnly) //
        FORMAT_FLAG('m', formatMonitor)     //
        FORMAT_FLAG('w', formatWorkspace)   //
        FORMAT_FLAG('c', formatClass),
        PHLWINDOW)

    template <typename FormatContext>
    auto format(PHLWINDOW const& w, FormatContext& ctx) const {
        auto&& out = ctx.out();
        if (formatAddressOnly)
            return std::format_to(out, "{:x}", rc<uintptr_t>(w.get()));
        if (!w)
     ts echoing it back would enter FSMODE_MAXIMIZED.
        bool m_suppressNextMaximize = false;

        // desktop components
        SP<Desktop::View::CSubsurface> m_subsurfaceHead;
        SP<Desktop::View::CPopup>      m_popupHead;

        // Animated border
        Config::CGradientValueData m_realBorderColor         = {0};
        Config::CGradientValueData m_realBorderColorPrevious = {0};
        PHLANIMVAR<float>          m_borderFadeAnimationProgress;
        PHLANIMVAR<float>          m_borderAngleAnimationProgress;

        // Cached border size (invalidated by updateWindowData)
        mutable int  m_cachedBorderSize     = -1;
        mutable bool m_borderSizeCacheDirty = true;

        // Fade in-out
        bool m_animatingIn = false;

        // For pinned (sticky) windows
        bool m_pinned = false;

        // For preserving pinned state when fullscreening a pinned window
        bool m_pinFullscreened = false;

        // urgency hint
        bool m_isUrgent = false;

        // for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
        PHLWINDOWREF m_lastCycledWindow;

        // Window decorations
        // TODO: make this a SP.
        std::vector<UP<IHyprWindowDecoration>> m_windowDecorations;
        std::vector<IHyprWindowDecoration*>    m_decosToRemove;

        // Special render data, rules, etc
        UP<Desktop::Rule::CWindowRuleApplicator> m_ruleApplicator;

        // Transformers
     ./rule/windowRule/WindowRuleApplicator.hpp"
#include "../../protocols/types/ContentType.hpp"
#include "../../render/Framebuffer.hpp"
#include "types/GeometricMovableAnimated.hpp"
#include "types/AlphaModifiable.hpp"
#include "animationControllers/WindowAnimationController.hpp"

class CXDGSurfaceResource;
class CXWaylandSurface;
struct SXDGToplevelMoveRequest;
struct SXDGToplevelResizeRequest;
namespace Config {
    class CWorkspaceRule;
}

namespace Layout {
    class ITarget;
    class CWindowTarget;
}

namespace Desktop {
    enum eFocusReason : uint8_t;
}

namespace Desktop::View {

    class CGroup;

    enum eGroupRules : uint8_t {
        // effective only during first map, except for _ALWAYS variant
        GROUP_NONE        = 0,
        GROUP_SET         = 1 << 0, // Open as new group or add to focused group
        GROUP_SET_ALWAYS  = 1 << 1,
        GROUP_BARRED      = 1 << 2, // Don't insert to focused group.
        GROUP_LOCK        = 1 << 3, // Lock m_sGroupData.lock
        GROUP_LOCK_ALWAYS = 1 << 4,
        GROUP_INVADE      = 1 << 5, // Force enter a group, event if lock is engaged
        GROUP_OVERRIDE    = 1 << 6, // Override other rules
        GROUP_DENY        = 1 << 7, // deny
    };

    enum eGetWindowProperties : uint16_t {
        WINDOW_ONLY              = 0,
        RESERVED_EXTENTS         = 1 << 0,
        INPUT_EXTENTS            = 1 << 1,
        FULL_EXTENTS             = 1 << 2,
        FLOATING_ONLY            = 1 << 3,
        ALLOW_FLOATING       e, should be removed ASAP
        // once we remove the god-awful fadeout logic
        void removeSafe(PHLWINDOW w);

      private:
        std::vector<PHLWINDOW> m_windows;

        void                   moveToTop(PHLWINDOW w);
        void                   moveToBottom(PHLWINDOW w);
        void                   moveToZ(PHLWINDOW w, bool top);

        struct {
            CHyprSignalListener viewCreate;
        } m_listeners;
    };

    UP<CWindowState>& windowState();
};
#pragma once

#include "../DesktopTypes.hpp"
#include "../view/types/GeometricAnimated.hpp"
#include "../../helpers/AnimatedVariable.hpp"
#include "../../helpers/time/Time.hpp"

#include <optional>

namespace Render {
    class IFramebuffer;
}

namespace Desktop {
    enum eFadeoutPlane : uint8_t {
        FADEOUT_PLANE_LAYER_BACKGROUND = 0,
        FADEOUT_PLANE_LAYER_BOTTOM,
        FADEOUT_PLANE_WINDOW_TILED,
        FADEOUT_PLANE_WINDOW_FLOATING,
        FADEOUT_PLANE_WINDOW_OVER_FULLSCREEN,
        FADEOUT_PLANE_LAYER_TOP,
        FADEOUT_PLANE_LAYER_OVERLAY,
        FADEOUT_PLANE_POPUP,
    };

    struct SFadeoutPreBlur {
        CBox  box;
        int   round         = 0;
        float roundingPower = 2.F;
        bool  xray          = false;
        float alpha         = 1.F;
    };

    struct SFadeoutTextureBlur {
        bool                 enabled    = false;
        float                alpha      = 1.F;
        bool                 forceBlend = false;
        std::optional<float> ignoreAlpha;
 tor2D topLeft, bottomRight;
        };

        std::array<SDynamicData, RESERVED_DYNAMIC_TYPE_END> m_dynamicReserved;
    };
};
#pragma once

#include "Fadeout.hpp"

namespace Desktop {
    class CLayerFadeout final : public IFadeout {
      public:
        static SP<CLayerFadeout>      create(PHLLS layer, SP<Render::IFramebuffer> snapshot, float sourceAlpha);

        virtual PHLMONITORREF         monitor() const override;
        virtual eFadeoutPlane         plane() const override;
        virtual int                   zIndex() const override;
        virtual CBox                  renderBox() const override;
        virtual float                 alpha() const override;
        virtual bool                  done() const override;
        virtual SFadeoutRenderEffects effects() const override;

      private:
        CLayerFadeout() = default;

        PHLMONITORREF     m_monitor;
        eFadeoutPlane     m_plane  = FADEOUT_PLANE_LAYER_TOP;
        int               m_zIndex = 0;
        CBox              m_geometry;
        PHLANIMVAR<float> m_alpha;
        bool              m_marksBlurDirty = false;
    };
}
#pragma once

#include "../../helpers/memory/Memory.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../DesktopTypes.hpp"
#include "WindowQuery.hpp"

#include <vector>

namespace Desktop {
    class CWindowState {
      public:
        CWindowState();
        ~CWindowState() = default;

        const std::vector<PHLWINDOW>& windows() const;

        CWindowQuery       noRule);
        void         onDisconnect(bool destroy = false);
        void         applyCMType(NCMType::eCMType cmType, NTransferFunction::eTF cmSdrEotf);
        void         addDamage(const pixman_region32_t* rg);
        void         addDamage(const CRegion& rg);
        void         addDamage(const CBox& box);
        void         scheduleFrame(Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
        bool         shouldSkipScheduleFrameOnMouseEvent();
        void         setMirror(const std::string&);
        bool         isMirror();
        float        getDefaultScale();
        void         changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false);
        void         changeWorkspace(const WORKSPACEID& id, bool internal = false, bool noMouseMove = false, bool noFocus = false);
        void         setSpecialWorkspace(const PHLWORKSPACE& pWorkspace);
        void         setSpecialWorkspace(const WORKSPACEID& id);
        PHLWORKSPACE getCurrentWorkspace();
        WORKSPACEID  activeWorkspaceID();
        WORKSPACEID  activeSpecialWorkspaceID();
        void         scheduleDone();
        uint32_t     isSolitaryBlocked(bool full = false);
        void         recheckSolitary();
        uint8_t      isTearingBlocked(bool full = false);
        void         updateSurfaceScaleTransformDetails();
        bool         updateTearing();
        uint16_t     isDSBlocked                                  m_size;
        CRegion                                       m_current;
        std::array<CRegion, DAMAGE_RING_PREVIOUS_LEN> m_previous;
        size_t                                        m_previousIdx = 0;
    };
}
#pragma once

#include "../SharedDefs.hpp"

#include <string_view>

namespace Monitor {
    class IMonitorIdentifiable {
      public:
        virtual ~IMonitorIdentifiable() = default;

        virtual MONITORID        id() const                                             = 0;
        virtual std::string_view name() const                                           = 0;
        virtual std::string_view description() const                                    = 0;
        virtual std::string_view shortDescription() const                               = 0;
        virtual bool             matchesStaticSelector(std::string_view selector) const = 0;
    };
}
#pragma once

#include "IMonitorGeometry.hpp"

namespace Monitor {
    class IMonitorMutableGeometry : public virtual IMonitorGeometry {
      public:
        virtual void moveTo(const Vector2D& pos) = 0;
    };
}
#pragma once

#include "../defines.hpp"
#include <stack>
#include <vector>
#include "../SharedDefs.hpp"
#include "../helpers/MiscFunctions.hpp"
#include "../helpers/WLClasses.hpp"
#include <array>
#include <span>
#include "../helpers/AnimatedVariable.hpp"
#include "../helpers/CMType.hpp"
#include "IMonitorArrangeable.hpp"
#include "IMonitorQueryable.hpp"
#include "MonitorTypes.hyboard>              create(SP<Aquamarine::IKeyboard> keeb);

    virtual bool                      isVirtual();
    virtual SP<Aquamarine::IKeyboard> aq();

  private:
    CKeyboard(SP<Aquamarine::IKeyboard> keeb);

    WP<Aquamarine::IKeyboard> m_keyboard;

    struct {
        CHyprSignalListener destroy;
        CHyprSignalListener key;
        CHyprSignalListener modifiers;
    } m_listeners;
};#pragma once

#include "IHID.hpp"
#include "../macros.hpp"
#include "../helpers/math/Math.hpp"

AQUAMARINE_FORWARD(ITablet);
AQUAMARINE_FORWARD(ITabletTool);
AQUAMARINE_FORWARD(ITabletPad);

class CTabletTool;
class CTabletPad;
class CWLSurfaceResource;

/*
    A tablet device
    Tablets don't have an interface for now,
    if there will be a need it's trivial to do.
*/
class CTablet : public IHID {
  public:
    static SP<CTablet> create(SP<Aquamarine::ITablet> tablet);
    ~CTablet();

    virtual uint32_t        getCapabilities();
    virtual eHIDType        getType();
    SP<Aquamarine::ITablet> aq();

    enum eTabletToolAxes : uint16_t {
        HID_TABLET_TOOL_AXIS_X        = (1 << 0),
        HID_TABLET_TOOL_AXIS_Y        = (1 << 1),
        HID_TABLET_TOOL_AXIS_TILT_X   = (1 << 2),
        HID_TABLET_TOOL_AXIS_TILT_Y   = (1 << 3),
        HID_TABLET_TOOL_AXIS_DISTANCE = (1 << 4),
        HID_TABLET_TOOL_AXIS_PRESSURE = (1 << 5),
        HID_TABLET_TOOL_AXIS_ROTATION = (1 << 6),
        HID_TABLET_TOOL_AXIS_SLIDER   = (1 << 7),
        HID_TABLET_TOOL_AXIS_WHEEL    = (1 << 8),
    }   // Tracks the input region's infinite protocol state
    wl_output_transform transform       = WL_OUTPUT_TRANSFORM_NORMAL; // A newly created surface has its buffer transformation set to normal
    int                 scale           = 1;                          // A newly created surface has its buffer scale set to 1

    // these don't have well defined initial values in the protocol, but these work
    Vector2D size, bufferSize;
    Vector2D offset;

    // for xdg_shell resizing
    Vector2D ackedSize;

    // for wl_surface::frame callbacks.
    std::vector<SP<CWLCallbackResource>> callbacks;

    // for wp_presentation feedbacks, tied to this commit.
    std::vector<WP<CPresentationFeedback>> presentationFeedbacks;

    // viewporter protocol surface state
    struct {
        bool     hasDestination = false;
        bool     hasSource      = false;
        Vector2D destination;
        CBox     source;
    } viewport;
    Vector2D sourceSize();

    // drm syncobj protocol surface state
    CDRMSyncPointState acquire;
    eLockReason        lockMask = LOCK_REASON_NONE;

    // texture of surface content, used for rendering
    SP<Render::ITexture> texture;
    void                 updateSynchronousTexture(SP<Render::ITexture> lastTexture);

    // fifo
    bool barrierSet    = false;
    bool surfaceLocked = false;
    bool fifoScheduled = false;

    // commit timing
    std::optional<Time::steady_dur> pendingTimeout;
    std::optional<Time::steady_tp>  commitTimingTarget;
 sources server-side would fatally error the clients ("invalid object"
    // on their in-flight wl_output.release); they are kept here until every client has
    // released, then drop out via destroyResource.
    inline std::vector<SP<CWLOutputProtocol>> defunctOutputs;
};
#pragma once

/*
    Implementations for:
     - wl_compositor
     - wl_surface
     - wl_region
     - wl_callback
*/

#include <span>
#include <vector>
#include <queue>
#include <cstdint>
#include "../WaylandProtocol.hpp"
#include "../../render/Texture.hpp"
#include "../types/SurfaceStateQueue.hpp"
#include "wayland.hpp"
#include "../../desktop/view/WLSurface.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../../helpers/math/Math.hpp"
#include "../../helpers/time/Time.hpp"
#include "../types/Buffer.hpp"
#include "../../helpers/cm/ColorManagement.hpp"
#include "../types/SurfaceRole.hpp"
#include "../types/SurfaceState.hpp"

class CWLOutputResource;
class CWLSurfaceResource;
class CWLSubsurfaceResource;
class CViewportResource;
class CDRMSyncobjSurfaceResource;
class CFifoResource;
class CCommitTimerResource;
class CColorManagementSurface;
class CContentType;

class CWLCallbackResource {
  public:
    CWLCallbackResource(SP<CWlCallback>&& resource_);
    ~CWLCallbackResource() noexcept = default;
    // disable copy
    CWLCallbackResource(const CWLCallbackResource&)            = delete;
    CWLCallbackResource& operator=(const CWLCallbackResource&) = delete;

    // allow move
    CWLCallbackResource(CWLC   m_surfaces;

    friend class CWLSubcompositorResource;
    friend class CWLSubsurfaceResource;
};

namespace PROTO {
    inline UP<CWLSubcompositorProtocol> subcompositor;
};
#pragma once

/*
    Implementations for:
     - wl_seat
     - wl_keyboard
     - wl_pointer
     - wl_touch
*/

#include <vector>
#include <cstdint>
#include "../WaylandProtocol.hpp"
#include <wayland-server-protocol.h>
#include <wayland-util.h>
#include "wayland.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../../helpers/math/Math.hpp"
#include "../types/SurfaceRole.hpp"

constexpr const char* HL_SEAT_NAME = "Hyprland";

class IKeyboard;
class CWLSurfaceResource;

class CWLPointerResource;
class CWLKeyboardResource;
class CWLTouchResource;
class CWLSeatResource;

class CCursorSurfaceRole : public ISurfaceRole {
  public:
    virtual eSurfaceRole role() {
        return SURFACE_ROLE_CURSOR;
    }

    // gets the current pixel data from a shm surface
    // will assert if the surface is not a cursor
    static std::vector<uint8_t>& cursorPixelData(SP<CWLSurfaceResource> surface);

  private:
    std::vector<uint8_t> m_cursorShmPixelData;
};

class CWLTouchResource {
  public:
    CWLTouchResource(SP<CWlTouch> resource_, SP<CWLSeatResource> owner_);

    bool                good();
    void                sendDown(SP<CWLSurfaceResource> surface, uint32_t timeMs, int32_t id, const Vector2D& local);
    void                sendUp(uint32_t timeMs, int32_t id);
    void                sendMotion(uint32     std::string string;
            int32_t     begin = 0, end = 0;
            bool        committed = false;
        } preeditString;

        struct {
            uint32_t before = 0, after = 0;
            bool     committed = false;
        } deleteSurrounding;
    };

    SState     m_pending;
    SState     m_current;

    bool       good();
    void       activate();
    void       deactivate();
    void       surroundingText(const std::string& text, uint32_t cursor, uint32_t anchor);
    void       textChangeCause(zwpTextInputV3ChangeCause changeCause);
    void       textContentType(zwpTextInputV3ContentHint hint, zwpTextInputV3ContentPurpose purpose);
    void       done();
    void       unavailable();

    void       sendInputRectangle(const CBox& box);
    bool       hasGrab();
    void       sendKey(uint32_t time, uint32_t key, wl_keyboard_key_state state);
    void       sendMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
    void       setKeyboard(SP<IKeyboard> keyboard);

    wl_client* client();
    wl_client* grabClient();

  private:
    SP<CZwpInputMethodV2>                       m_resource;
    std::vector<WP<CInputMethodKeyboardGrabV2>> m_grabs;
    std::vector<WP<CInputMethodPopupV2>>        m_popups;

    WP<CInputMethodV2>                          m_self;

    bool                                        m_active = false;

    CBox                                        m_inputRectangle;

    friend class CInputMethodPopupV2;
    fP<CWLPointerResource> pointer);
    ~CImageCopyCaptureCursorSession();

    bool good();

  private:
    SP<CExtImageCopyCaptureCursorSessionV1> m_resource;
    SP<CImageCaptureSource>                 m_source;
    SP<CWLPointerResource>                  m_pointer;

    // cursor session stuff
    bool     m_entered = false;
    Vector2D m_pos     = Vector2D(0, 0);
    Vector2D m_hotspot = Vector2D(0, 0);

    // capture session stuff
    SP<CExtImageCopyCaptureSessionV1>    m_sessionResource;
    UP<Screenshare::CCursorshareSession> m_session;
    Vector2D                             m_bufferSize = Vector2D(0, 0);

    // frame stuff
    SP<CExtImageCopyCaptureFrameV1> m_frameResource;
    bool                            m_captured = false;
    SP<IHLBuffer>                   m_buffer;

    struct {
        CHyprSignalListener constraintsChanged;
        CHyprSignalListener stopped;
        CHyprSignalListener commit;
    } m_listeners;

    void sendCursorEvents();

    void createFrame(SP<CExtImageCopyCaptureFrameV1> resource);
    void destroyCaptureSession();
    void sendConstraints();
};

class CImageCopyCaptureProtocol : public IWaylandProtocol {
  public:
    CImageCopyCaptureProtocol(const wl_interface* iface, const int& ver, const std::string& name);

    virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);

    void         destroyResource(CExtImageCopyCaptureManagerV1* resource);
    void         destroyResource(CImageCopyCaptureSession* resouletTool> tool, double value);
    void tilt(SP<CTabletTool> tool, const Vector2D& value);
    void up(SP<CTabletTool> tool);
    void down(SP<CTabletTool> tool);
    void proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, SP<CWLSurfaceResource> surf);
    void proximityOut(SP<CTabletTool> tool);
    void buttonTool(SP<CTabletTool> tool, uint32_t button, uint32_t state);
    void motion(SP<CTabletTool> tool, const Vector2D& value);

    // Tablet pad events
    void mode(SP<CTabletPad> pad, uint32_t group, uint32_t mode, uint32_t timeMs);
    void buttonPad(SP<CTabletPad> pad, uint32_t button, uint32_t timeMs, uint32_t state);
    void strip(SP<CTabletPad> pad, uint32_t strip, double position, bool finger, uint32_t timeMs);
    void ring(SP<CTabletPad> pad, uint32_t ring, double position, bool finger, uint32_t timeMs);

  private:
    void onManagerResourceDestroy(wl_resource* res);
    void destroyResource(CTabletSeat* resource);
    void destroyResource(CTabletToolV2Resource* resource);
    void destroyResource(CTabletV2Resource* resource);
    void destroyResource(CTabletPadV2Resource* resource);
    void destroyResource(CTabletPadGroupV2Resource* resource);
    void destroyResource(CTabletPadRingV2Resource* resource);
    void destroyResource(CTabletPadStripV2Resource* resource);
    void onGetSeat(CZwpTabletManagerV2* pMgr, uint32_t id, wl_resource* seat);

    //
    std::vector<UP<CZwpTabletManagerV2>>       m_managers;
    std::vector<SP<CTabletSeat>>               m_seats;
            m_manager;

    //
    struct SCTMData {
        SCTMData();
        Mat3x3            ctmFrom = Mat3x3::identity(), ctmTo = Mat3x3::identity();
        PHLANIMVAR<float> progress;
    };
    std::map<PHLMONITORREF, UP<SCTMData>> m_ctmDatas;

    friend class CHyprlandCTMControlResource;
};

namespace PROTO {
    inline UP<CHyprlandCTMControlProtocol> ctm;
};
#pragma once

#include <vector>
#include <cstdint>
#include <string>
#include "WaylandProtocol.hpp"
#include "text-input-unstable-v3.hpp"
#include "../helpers/signal/Signal.hpp"
#include "../helpers/math/Math.hpp"

class CWLSurfaceResource;

class CTextInputV3 {
  public:
    CTextInputV3(SP<CZwpTextInputV3> resource_);
    ~CTextInputV3();

    void       enter(SP<CWLSurfaceResource> surf);
    void       leave(SP<CWLSurfaceResource> surf);
    void       preeditString(const std::string& text, int32_t cursorBegin, int32_t cursorEnd);
    void       commitString(const std::string& text);
    void       deleteSurroundingText(uint32_t beforeLength, uint32_t afterLength);
    void       sendDone();

    bool       good();

    wl_client* client();

    struct {
        CSignalT<> onCommit;
        CSignalT<> enable;
        CSignalT<> disable;
        CSignalT<> reset;
        CSignalT<> destroy;
    } m_events;

    struct SState {
        struct {
            bool        updated = false;
            std::string text    = "";
            uint32_t    cursor  = 0;
            uint32_t    anchor  = 0;
        } surrounding;

   void onNewFocus(PHLWINDOW pWindow);
    void onUnmap(PHLWINDOW pWindow);

    bool good();

  private:
    SP<CZwlrForeignToplevelManagerV1>          m_resource;
    bool                                       m_finished = false;
    PHLWINDOWREF                               m_lastFocus; // READ-ONLY

    SP<CForeignToplevelHandleWlr>              handleForWindow(PHLWINDOW pWindow);

    std::vector<WP<CForeignToplevelHandleWlr>> m_handles;
};

class CForeignToplevelWlrProtocol : public IWaylandProtocol {
  public:
    CForeignToplevelWlrProtocol(const wl_interface* iface, const int& ver, const std::string& name);

    virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);

    PHLWINDOW    windowFromHandleResource(wl_resource* res);

  private:
    void onManagerResourceDestroy(CForeignToplevelWlrManager* mgr);
    void destroyHandle(CForeignToplevelHandleWlr* handle);
    bool windowValidForForeign(PHLWINDOW pWindow);

    //
    std::vector<UP<CForeignToplevelWlrManager>> m_managers;
    std::vector<SP<CForeignToplevelHandleWlr>>  m_handles;

    friend class CForeignToplevelWlrManager;
    friend class CForeignToplevelHandleWlr;
};

namespace PROTO {
    inline UP<CForeignToplevelWlrProtocol> foreignToplevelWlr;
};
#pragma once

#include <vector>
#include <cstdint>
#include "WaylandProtocol.hpp"
#include "wlr-output-power-management-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp"

class COutputPower {
  public:
    COutputPower(SP<CZwlrOutputPFifoManagerResource(UP<CWpFifoManagerV1>&& resource_);
    ~CFifoManagerResource();

    bool good();

  private:
    UP<CWpFifoManagerV1> m_resource;
};

class CFifoProtocol : public IWaylandProtocol {
  public:
    CFifoProtocol(const wl_interface* iface, const int& ver, const std::string& name);

    virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);

  private:
    void destroyResource(CFifoManagerResource* resource);
    void destroyResource(CFifoResource* resource);

    void onMonitorPresent(PHLMONITOR m);

    //
    std::vector<UP<CFifoManagerResource>> m_managers;
    std::vector<UP<CFifoResource>>        m_fifos;

    friend class CFifoManagerResource;
    friend class CFifoResource;
};

namespace PROTO {
    inline UP<CFifoProtocol> fifo;
};
#pragma once

#include <hyprutils/math/Region.hpp>
#include <vector>
#include <unordered_map>
#include "WaylandProtocol.hpp"
#include "hyprland-surface-v1.hpp"
#include "../helpers/signal/Signal.hpp"

class CWLSurfaceResource;
class CHyprlandSurfaceProtocol;

class CHyprlandSurface {
  public:
    CHyprlandSurface(SP<CHyprlandSurfaceV1> resource, SP<CWLSurfaceResource> surface);

    bool good() const;
    void setResource(SP<CHyprlandSurfaceV1> resource);

  private:
    SP<CHyprlandSurfaceV1> m_resource;
    WP<CWLSurfaceResource> m_surface;
    float                  m_opacity              = 1.0;
    bool                   m_visibleRegionChanged = false;
    CRegion                m_visibleRegion;

   CXDGActivationProtocol> activation;
};
#pragma once

#include "WaylandProtocol.hpp"
#include "wlr-screencopy-unstable-v1.hpp"

#include "../helpers/time/Time.hpp"
#include "./types/Buffer.hpp"
#include <aquamarine/buffer/Buffer.hpp>

#include <vector>

class IHLBuffer;
namespace Screenshare {
    class CScreenshareSession;
    class CScreenshareFrame;
};

class CScreencopyClient {
  public:
    CScreencopyClient(SP<CZwlrScreencopyManagerV1> resource_);

    bool good();

  private:
    SP<CZwlrScreencopyManagerV1> m_resource;
    WP<CScreencopyClient>        m_self;

    wl_client*                   m_savedClient = nullptr;

    void                         captureOutput(uint32_t frame, int32_t overlayCursor, wl_resource* output, CBox box);

    friend class CScreencopyProtocol;
};

class CScreencopyFrame {
  public:
    CScreencopyFrame(SP<CZwlrScreencopyFrameV1> resource, WP<Screenshare::CScreenshareSession> session, bool overlayCursor);

    bool good();

  private:
    SP<CZwlrScreencopyFrameV1>           m_resource;
    WP<CScreencopyFrame>                 m_self;
    WP<CScreencopyClient>                m_client;

    WP<Screenshare::CScreenshareSession> m_session;
    UP<Screenshare::CScreenshareFrame>   m_frame;

    CHLBufferReference                   m_buffer;
    Time::steady_tp                      m_timestamp;
    bool                                 m_overlayCursor = true;

    //
    void shareFrame(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer, bool withDamage);

orationManagerV1* pMgr, uint32_t id, wl_resource* xdgToplevel);

    //
    std::vector<UP<CZxdgDecorationManagerV1>>            m_managers;
    std::unordered_map<wl_resource*, UP<CXDGDecoration>> m_decorations; // xdg_toplevel -> deco

    friend class CXDGDecoration;
};

namespace PROTO {
    inline UP<CXDGDecorationProtocol> xdgDecoration;
};
#pragma once

#include <vector>
#include <cstdint>
#include <tuple>
#include "WaylandProtocol.hpp"
#include "wlr-layer-shell-unstable-v1.hpp"
#include "../helpers/math/Math.hpp"
#include "../helpers/signal/Signal.hpp"
#include "types/SurfaceRole.hpp"

class CXDGPopupResource;
class CWLSurfaceResource;
class CLayerShellResource;

class CLayerShellRole : public ISurfaceRole {
  public:
    CLayerShellRole(SP<CLayerShellResource> ls);

    virtual eSurfaceRole role() {
        return SURFACE_ROLE_LAYER_SHELL;
    }

    WP<CLayerShellResource> m_layerSurface;
};

class CLayerShellResource {
  public:
    CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<CWLSurfaceResource> surf_, std::string namespace_, PHLMONITOR pMonitor, zwlrLayerShellV1Layer layer);
    ~CLayerShellResource();

    bool good();
    void configure(const Vector2D& size);
    void sendClosed();

    enum eCommittedState : uint8_t {
        STATE_SIZE          = (1 << 0),
        STATE_ANCHOR        = (1 << 1),
        STATE_EXCLUSIVE     = (1 << 2),
        STATE_MARGIN        = (1 << 3),
        STATE_INTERACTIVITY = (1 << 4),
        STATE_LAYER         = (1 << 5),
          applyPositioning(const CBox& availableBox, const Vector2D& t1coord /* relative to box */);

    WP<CXDGSurfaceResource>      m_surface;
    WP<CXDGSurfaceResource>      m_parent;
    WP<CXDGPopupResource>        m_self;

    bool                         m_taken = false;

    CBox                         m_geometry;

    struct {
        CSignalT<> reposition;
        CSignalT<> dismissed;
        CSignalT<> destroy; // only the role
    } m_events;

    // schedules a configure event
    void configure(const CBox& box);

    void done();
    void repositioned();

  private:
    SP<CXdgPopup>       m_resource;

    uint32_t            m_lastRepositionToken = 0;

    Vector2D            accumulateParentOffset();

    CXDGPositionerRules m_positionerRules;
};

class CXDGToplevelResource {
  public:
    CXDGToplevelResource(SP<CXdgToplevel> resource_, SP<CXDGSurfaceResource> owner_);
    ~CXDGToplevelResource();

    static SP<CXDGToplevelResource> fromResource(wl_resource*);

    WP<CXDGSurfaceResource>         m_owner;
    WP<CXDGToplevelResource>        m_self;

    PHLWINDOWREF                    m_window;

    bool                            good();
    Vector2D                        layoutMinSize();
    Vector2D                        layoutMaxSize();

    // schedule a configure event
    uint32_t setSize(const Vector2D& size);
    uint32_t setMaximized(bool maximized);
    uint32_t setFullscreen(bool fullscreen);
    uint32_t setActive(bool active);
    uint32_t setResizing(btor<UP<CExtWorkspaceResource>>        m_workspaces;

    friend class CExtWorkspaceManagerResource;
};

namespace PROTO {
    inline UP<CExtWorkspaceProtocol> extWorkspace;
}
#pragma once

#include <vector>
#include <cstdint>
#include <array>
#include "WaylandProtocol.hpp"
#include "wlr-virtual-pointer-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp"
#include "../devices/IPointer.hpp"
#include "../output/Monitor.hpp"

class CVirtualPointerV1Resource {
  public:
    CVirtualPointerV1Resource(SP<CZwlrVirtualPointerV1> resource_, PHLMONITORREF boundOutput_);
    ~CVirtualPointerV1Resource();

    struct {
        CSignalT<>                               destroy;
        CSignalT<IPointer::SMotionEvent>         move;
        CSignalT<IPointer::SMotionAbsoluteEvent> warp;
        CSignalT<IPointer::SButtonEvent>         button;
        CSignalT<IPointer::SAxisEvent>           axis;
        CSignalT<>                               frame;

        CSignalT<IPointer::SSwipeBeginEvent>     swipeBegin;
        CSignalT<IPointer::SSwipeUpdateEvent>    swipeUpdate;
        CSignalT<IPointer::SSwipeEndEvent>       swipeEnd;

        CSignalT<IPointer::SPinchBeginEvent>     pinchBegin;
        CSignalT<IPointer::SPinchUpdateEvent>    pinchUpdate;
        CSignalT<IPointer::SPinchEndEvent>       pinchEnd;

        CSignalT<IPointer::SHoldBeginEvent>      holdBegin;
        CSignalT<IPointer::SHoldEndEvent>        holdEnd;
    } m_events;

    bool          good();
    wl_client*    client();

urce> surf);

    bool good();

    void sendQueued(WP<CQueuedPresentationData> data, const timespec& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags);
    void sendDiscarded();

  private:
    UP<CWpPresentationFeedback> m_resource;
    WP<CWLSurfaceResource>      m_surface;
    bool                        m_done = false;

    friend class CPresentationProtocol;
};

class CPresentationProtocol : public IWaylandProtocol {
  public:
    CPresentationProtocol(const wl_interface* iface, const int& ver, const std::string& name);

    virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);

    void         onPresented(PHLMONITOR pMonitor, const timespec& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags);
    void         queueData(UP<CQueuedPresentationData>&& data);
    void         discardFeedbacks(std::vector<WP<CPresentationFeedback>>& feedbacks);
    void         discardFeedbacksForSurface(WP<CWLSurfaceResource> surface);
    bool         hasPendingFeedbacks() const;

  private:
    void onManagerResourceDestroy(wl_resource* res);
    void destroyResource(CPresentationFeedback* feedback);
    void onGetFeedback(CWpPresentation* pMgr, wl_resource* surf, uint32_t id);

    //
    std::vector<UP<CWpPresentation>>         m_managers;
    std::vector<UP<CPresentationFeedback>>   m_feedbacks;
    std::vector<UP<CQueuedPresentationData>> m_queue;

    friend class CPresentationFeedback;
};

namespace PROTO {
    inline UP<CPreouch(SP<ITouch> touch);
        void detachTablet(SP<CTablet> tablet);

        // only clamps to the layout.
        void warpTo(const Vector2D& logical);
        void move(const Vector2D& deltaLogical);
        void warpAbsolute(Vector2D abs, SP<IHID> dev);

        void setCursorBuffer(SP<Aquamarine::IBuffer> buf, const Vector2D& hotspot, const float& scale);
        void setCursorSurface(SP<Desktop::View::CWLSurface> buf, const Vector2D& hotspot);
        void resetCursorImage(bool apply = true);

        void lockSoftwareForMonitor(PHLMONITOR pMonitor);
        void unlockSoftwareForMonitor(PHLMONITOR pMonitor);
        void lockSoftwareAll();
        void unlockSoftwareAll();
        bool softwareLockedFor(PHLMONITOR pMonitor);
        bool hasVisibleHWCursor(PHLMONITOR pMonitor);

        void renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */,
                                      bool forceRender = false);

        // this is needed e.g. during screensharing where
        // the software cursors aren't locked during the cursor move, but they
        // are rendered later.
        void damageCursor(PHLMONITOR pMonitor, bool skipFrameSchedule = false);

        //
        Vector2D position();
        Vector2D hotspot();
        Vector2D cursorSizeLogical();

        void     recheckEnteredOutputs();

        // returns the thing in global coords
        CBox getCursoy, bool OR);

    void ensureListeners();
    void map();
    void unmap();
    void considerMap();
    void setWithdrawn(bool withdrawn);
    void recheckSupportedProps();

    struct {
        CHyprSignalListener destroyResource;
        CHyprSignalListener destroySurface;
        CHyprSignalListener commitSurface;
    } m_listeners;

    std::unordered_map<xcb_atom_t, bool> m_supportedProps;
    std::optional<std::string>           m_wmName;
    std::optional<std::string>           m_netWmName;

    friend class CXWM;
};
#pragma once

#include "../output/Monitor.hpp"
#include "../helpers/math/Direction.hpp"

#include <string_view>
#include <optional>

namespace Aquamarine {
    class IOutput;
}

namespace State {
    class IMonitorStateTracker;

    class CMonitorQuery {
      public:
        CMonitorQuery(const IMonitorStateTracker&);
        ~CMonitorQuery() = default;

        CMonitorQuery(const CMonitorQuery&) = delete;
        CMonitorQuery(CMonitorQuery&)       = delete;
        CMonitorQuery(CMonitorQuery&&)      = delete;

        CMonitorQuery&& id(MONITORID id) &&;
        CMonitorQuery&& name(std::string_view name) &&;
        CMonitorQuery&& description(std::string_view desc) &&;
        CMonitorQuery&& selector(std::string_view str) &&;
        CMonitorQuery&& configString(std::string_view str) &&;
        CMonitorQuery&& vec(Vector2D vec) &&;
        CMonitorQuery&& output(SP<Aquamarine::IOutput> output) &&;
        CMonitorQuery&& inDirection(Math::eDirection dir) &&;  m_dndSelection;
    SP<CX11DataDevice>                        m_dndDataDevice = makeShared<CX11DataDevice>();
    std::vector<SP<CX11DataOffer>>            m_dndDataOffers;

    inline xcb_connection_t*                  getConnection() {
        return m_connection ? *m_connection : nullptr;
    }
    struct {
        CHyprSignalListener newWLSurface;
        CHyprSignalListener newXShellSurface;
    } m_listeners;

    friend class CXWaylandSurface;
    friend class CXWayland;
    friend class CXDataSource;
    friend class CX11DataDevice;
    friend class CX11DataSource;
    friend class CX11DataOffer;
    friend class CWLDataDeviceProtocol;
    friend struct SXSelection;
    friend struct SXTransfer;
};
#pragma once

#include "../helpers/signal/Signal.hpp"
#include "../helpers/memory/Memory.hpp"
#include "../macros.hpp"

#include "XSurface.hpp"

#ifndef NO_XWAYLAND
#include "Server.hpp"
#include "XWM.hpp"
#else
class CXWaylandServer;
class CXWM;
#endif

class CXWayland {
  public:
    CXWayland(const bool wantsEnabled);

#ifndef NO_XWAYLAND
    UP<CXWaylandServer> m_server;
    UP<CXWM>            m_wm;
#endif
    bool enabled();

    void setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& size, const Vector2D& hotspot);

  private:
    bool m_enabled = false;
};

inline UP<CXWayland>                             g_pXWayland;

inline std::unordered_map<std::string, uint32_t> HYPRATOMS = {
#ifndef NO_XWAYLAND
    HYPRATOM("_NET_SUPPORTED"),
    HYPRATOM("_NET_SUPPORTI"../protocols/types/DataDevice.hpp"
#include "../managers/SeatManager.hpp"
#include "../managers/input/InputManager.hpp"
#include <wayland-server-protocol.h>
#include <hyprutils/os/FileDescriptor.hpp>
#ifndef NO_XWAYLAND
#include <xcb/xcb.h>
#endif

#define XDND_VERSION 5

class CXWaylandSurface;

class CX11DataOffer : public IDataOffer {
  public:
    CX11DataOffer()  = default;
    ~CX11DataOffer() = default;

    virtual eDataSourceType          type();
    virtual SP<CWLDataOfferResource> getWayland();
    virtual SP<CX11DataOffer>        getX11();
    virtual SP<IDataSource>          getSource();
    virtual void                     markDead();

    WP<IDataSource>                  m_source;
    WP<CX11DataOffer>                m_self;
    WP<CXWaylandSurface>             m_xwaylandSurface;
};

class CX11DataSource : public IDataSource {
  public:
    CX11DataSource()  = default;
    ~CX11DataSource() = default;

    virtual std::vector<std::string> mimes();
    virtual void                     send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
    virtual void                     accepted(const std::string& mime);
    virtual void                     cancelled();
    virtual bool                     hasDnd();
    virtual bool                     dndDone();
    virtual void                     error(uint32_t code, const std::string& msg);
    virtual void                     sendDndFinished();
    virtual uint32_t                 actions(); // wl_data_device_manager.GestureUpdate {
        const IPointer::SSwipeUpdateEvent* swipe     = nullptr;
        const IPointer::SPinchUpdateEvent* pinch     = nullptr;
        eTrackpadGestureDirection          direction = TRACKPAD_GESTURE_DIR_NONE;
        float                              scale     = 1.F;
    };

    struct STrackpadGestureEnd {
        const IPointer::SSwipeEndEvent* swipe     = nullptr;
        const IPointer::SPinchEndEvent* pinch     = nullptr;
        eTrackpadGestureDirection       direction = TRACKPAD_GESTURE_DIR_NONE;
        float                           scale     = 1.F;
    };

    virtual void  begin(const STrackpadGestureBegin& e);
    virtual void  update(const STrackpadGestureUpdate& e) = 0;
    virtual void  end(const STrackpadGestureEnd& e)       = 0;

    virtual float distance(const STrackpadGestureBegin& e);
    virtual float distance(const STrackpadGestureUpdate& e);

    virtual bool  isDirectionSensitive();

  protected:
    float m_lastPinchScale = 1.F, m_scale = 1.F;
};#pragma once

#include "ITrackpadGesture.hpp"
#include "../../../../desktop/DesktopTypes.hpp"

class CWorkspaceSwipeGesture : public ITrackpadGesture {
  public:
    CWorkspaceSwipeGesture()          = default;
    virtual ~CWorkspaceSwipeGesture() = default;

    virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
    virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
    virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);

    virtual bool isDire           isVecInPopup(const Vector2D& point);

    CBox                   globalBox();
    SP<CWLSurfaceResource> getSurface();

    void                   onCommit();

  private:
    SP<Desktop::View::CWLSurface> queryOwner();
    void                          updateBox();

    void                          onDestroy();
    void                          onMap();
    void                          onUnmap();

    WP<CInputMethodPopupV2>       m_popup;
    SP<Desktop::View::CWLSurface> m_surface;
    CBox                          m_lastBoxLocal;
    MONITORID                     m_lastMonitor = MONITOR_INVALID;

    struct {
        CHyprSignalListener map;
        CHyprSignalListener unmap;
        CHyprSignalListener destroy;
        CHyprSignalListener commit;
    } m_listeners;
};
#pragma once

#include "../../defines.hpp"
#include <list>
#include <any>
#include "../../helpers/WLClasses.hpp"
#include "../../helpers/time/Timer.hpp"
#include "InputMethodRelay.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../../desktop/view/WLSurface.hpp"
#include "../../devices/IPointer.hpp"
#include "../../devices/ITouch.hpp"
#include "../../devices/IKeyboard.hpp"
#include "../../devices/Tablet.hpp"
#include "../SessionLockManager.hpp"
#include "../SeatManager.hpp"

class CPointerConstraint;
class CIdleInhibitor;
class CVirtualKeyboardV1Resource;
class CVirtualPointerV1Resource;
class IKeyboard;

AQUAMARINE_FORWARD(IPointer);
AQUAMARINE_FORWARD(IKeyboard);
AQUAMARINE_FORWARD(ITouch);
AQUA client);

        WP<CScreenshareSession>  m_self;
        bool                     m_stopped = false;

        eScreenshareType         m_type = SHARE_NONE;
        PHLMONITORREF            m_monitor;
        PHLWINDOWREF             m_window;
        CBox                     m_captureBox = {}; // given capture area in logical coordinates (see xdg_output)

        wl_client*               m_client = nullptr;
        std::string              m_name   = "";

        std::vector<DRMFormat>   m_formats;
        Vector2D                 m_bufferSize = Vector2D(0, 0);

        SP<Render::IFramebuffer> m_tempFB;

        SP<CEventLoopTimer>      m_shareStopTimer;
        bool                     m_sharing = false;

        struct {
            CHyprSignalListener monitorDestroyed;
            CHyprSignalListener monitorModeChanged;
            CHyprSignalListener windowDestroyed;
            CHyprSignalListener windowSizeChanged;
            CHyprSignalListener windowMonitorChanged;
        } m_listeners;

        void screenshareEvents(bool started);
        void calculateConstraints();
        void init();

        friend class CScreenshareFrame;
        friend class CScreenshareManager;
    };

    class CCursorshareSession {
      public:
        CCursorshareSession(const CCursorshareSession&) = delete;
        CCursorshareSession(CCursorshareSession&&)      = delete;
        ~CCursorshareSession();

        eScreenshareError share(PHLMONITOR monitor, SP<IHLBuffer> buffer, FSourceBoxCall:CConfigManager;
    friend class CWorkspace;
    friend class Pointer::CPointerManager;
};

inline UP<CKeybindManager> g_pKeybindManager;
#pragma once

#include "../../macros.hpp"
#include "../../helpers/memory/Memory.hpp"
#include "../../helpers/AsyncDialogBox.hpp"
#include <vector>
#include <wayland-server-core.h>
#include <sys/types.h>
#include "../../helpers/defer/Promise.hpp"

// NOLINTNEXTLINE
namespace re2 {
    class RE2;
};

enum eDynamicPermissionType : uint8_t {
    PERMISSION_TYPE_UNKNOWN = 0,
    PERMISSION_TYPE_SCREENCOPY,
    PERMISSION_TYPE_PLUGIN,
    PERMISSION_TYPE_KEYBOARD,
    PERMISSION_TYPE_CURSOR_POS,
    PERMISSION_TYPE_INPUT_CAPTURE,
};

enum eDynamicPermissionRuleSource : uint8_t {
    PERMISSION_RULE_SOURCE_UNKNOWN = 0,
    PERMISSION_RULE_SOURCE_CONFIG,
    PERMISSION_RULE_SOURCE_RUNTIME_USER,
};

enum eDynamicPermissionAllowMode : uint8_t {
    PERMISSION_RULE_ALLOW_MODE_UNKNOWN = 0,
    PERMISSION_RULE_ALLOW_MODE_DENY,
    PERMISSION_RULE_ALLOW_MODE_ASK,
    PERMISSION_RULE_ALLOW_MODE_ALLOW,
    PERMISSION_RULE_ALLOW_MODE_PENDING, // popup is open
};

// NOLINTNEXTLINE
enum eSpecialPidTypes : int {
    SPECIAL_PID_TYPE_CONFIG = -3,
    SPECIAL_PID_TYPE_NONE   = -2,
};

class CDynamicPermissionRule;

struct SDynamicPermissionRuleDestroyWrapper {
    wl_listener             listener;
    CDynamicPermissionRule* parent = nullptr;
};

class CDynamicPermissionRule {
  public:
    ~CDynamicPermissionRule();

    wl_client* client() const;

  private:
    // con setCurrentPrimarySelection(SP<IDataSource> source);

    // do not write to directly, use set...
    WP<IPointer>  m_mouse;
    WP<IKeyboard> m_keyboard;

    void          setGrab(SP<CSeatGrab> grab); // nullptr removes
    SP<CSeatGrab> m_seatGrab;

  private:
    struct SPointerButtonSerial {
        uint32_t               serial = 0;
        uint32_t               button = 0;
        WP<CWLSurfaceResource> surface;
    };

    struct SSeatResourceContainer {
        SSeatResourceContainer(SP<CWLSeatResource>);

        WP<CWLSeatResource>               resource;
        uint32_t                          enterSerial = 0; // remember this forever
        std::vector<uint32_t>             serials;         // old -> new
        std::vector<SPointerButtonSerial> pointerButtonSerials;

        struct {
            CHyprSignalListener destroy;
        } listeners;
    };

    std::vector<SP<SSeatResourceContainer>> m_seatResources;
    void                                    onNewSeatResource(SP<CWLSeatResource> resource);
    SP<SSeatResourceContainer>              containerForResource(SP<CWLSeatResource> seatResource);

    void                                    refocusGrab();

    struct {
        CHyprSignalListener newSeatResource;
        CHyprSignalListener keyboardSurfaceDestroy;
        CHyprSignalListener pointerSurfaceDestroy;
        CHyprSignalListener touchSurfaceDestroy;
    } m_listeners;

    Vector2D m_lastLocalCoords;
    int      m_touchLocks = 0; // we assume there a      scheduleReload();

        void                             ensureMonitorStatus();
        void                             ensureVRR(PHLMONITOR pMonitor = nullptr);

        CMonitorRule                     get(const PHLMONITOR);
        const std::vector<CMonitorRule>& all();
        std::vector<CMonitorRule>&       allMut();

        struct {
            CSignalT<> stateReloaded;
        } m_events;

      private:
        std::vector<CMonitorRule> m_rules;
        bool                      m_reloadScheduled = false;

        struct {
            CHyprSignalListener preChecksRender;
        } m_listeners;
    };

    UP<CMonitorRuleManager>& monitorRuleMgr();
};#pragma once

#include <string>
#include <optional>
#include <cstdint>
#include <xf86drmMode.h>

#include "../../../helpers/math/Math.hpp"
#include "../../../helpers/cm/ColorManagement.hpp"
#include "../../../helpers/CMType.hpp"
#include "../../../helpers/TransferFunction.hpp"
#include "../../../desktop/reserved/ReservedArea.hpp"

namespace Config {
    // Enum for the different types of auto directions, e.g. auto-left, auto-up.
    enum eAutoDirs : uint8_t {
        DIR_AUTO_NONE = 0, /* None will be treated as right. */
        DIR_AUTO_UP,
        DIR_AUTO_DOWN,
        DIR_AUTO_LEFT,
        DIR_AUTO_RIGHT,
        DIR_AUTO_CENTER_UP,
        DIR_AUTO_CENTER_DOWN,
        DIR_AUTO_CENTER_LEFT,
        DIR_AUTO_CENTER_RIGHT
    };

    enum eMonitorRuleComparisonResult : uint8_t {
        COMPARISON_FULL_MATCH = 0, //CActionState {
      public:
        CActionState()  = default;
        ~CActionState() = default;

        int         m_passPressed   = -1; // -1 = dynamic (press+release), 0 = released, 1 = pressed
        uint32_t    m_lastCode      = 0;  // last keycode (keyboard event), 0 if last was mouse
        uint32_t    m_lastMouseCode = 0;  // last mouse button code, 0 if last was keyboard
        uint32_t    m_timeLastMs    = 0;  // timestamp of last key/mouse event
        std::string m_currentSubmap = ""; // current keybind submap name
    };

    UP<CActionState>& state();
};
#pragma once

#include <cstdint>
#include <string>

namespace Config {
    enum eConfigValueDataTypes : int8_t {
        CVD_TYPE_INVALID     = -1,
        CVD_TYPE_GRADIENT    = 0,
        CVD_TYPE_CSS_VALUE   = 1,
        CVD_TYPE_FONT_WEIGHT = 2,
    };

    class IComplexConfigValue {
      public:
        virtual ~IComplexConfigValue() = default;

        virtual eConfigValueDataTypes getDataType() = 0;

        virtual std::string           toString() const = 0;
    };
}#pragma once
#include "ComplexDataType.hpp"
#include "../../../helpers/Color.hpp"

#include <hyprutils/string/VarList2.hpp>

#include <vector>
#include <format>
#include <map>
#include <algorithm>

namespace Config {

    class CGradientValueData : public IComplexConfigValue {
      public:
        CGradientValueData() = default;
        CGradientValueData(CHyprColor col) {
            m_colors.push_back(col);
            updateColorsOk();
   d reset();

        //
        void setConfigForNode(const std::string& name, bool enabled, float speed, const std::string& bezier, const std::string& style = "");
        bool nodeExists(const std::string& name);

      private:
        Hyprutils::Animation::CAnimationConfigTree m_animationTree;
    };

    UP<CAnimationTreeController>& animationTree();
};#pragma once

#include <expected>
#include <string>
#include <optional>

#include "../../../desktop/DesktopTypes.hpp"
#include "../../../desktop/Workspace.hpp"
#include "../../../helpers/math/Direction.hpp"
#include "../ConfigErrors.hpp"

namespace Fullscreen {
    enum eFullscreenMode : int8_t;
}

namespace Config::Actions {
    struct SActionResult {
        bool passEvent = false;
    };

    using eActionErrorLevel = Config::eConfigErrorLevel;
    using eActionErrorCode  = Config::eConfigErrorCode;
    using SActionError      = Config::SConfigError;
    using Config::toString;

    inline std::unexpected<SActionError> actionError(std::string message, eActionErrorLevel level = eActionErrorLevel::ERROR, eActionErrorCode code = eActionErrorCode::UNKNOWN) {
        return Config::configError(std::move(message), level, code);
    }

    enum eTogglableAction : uint8_t {
        TOGGLE_ACTION_TOGGLE = 0,
        TOGGLE_ACTION_ENABLE,
        TOGGLE_ACTION_DISABLE,
    };

    using ActionResult = std::expected<SActionResult, SActionError>;

    ActionResult closeWindow(std::optional<PHLWINDOW> window = std::nullopt /* Active */);
    Acnst SP<Desktop::Rule::CLayerRule>& rule);
    };
}
#pragma once

#include "LuaObjectHelpers.hpp"
#include "../../../desktop/DesktopTypes.hpp"

namespace Config::Lua::Objects {
    class CLuaLayerSurface : public ILuaObjectWrapper {
      public:
        void        setup(lua_State* L) override;
        static void push(lua_State* L, PHLLSREF ls);
    };
}
#pragma once

#include "LuaObjectHelpers.hpp"
#include "../../../notification/NotificationOverlay.hpp"

namespace Config::Lua::Objects {
    class CLuaNotification : public ILuaObjectWrapper {
      public:
        void        setup(lua_State* L) override;
        static void push(lua_State* L, const SP<Notification::CNotification>& notification);
    };
}
#pragma once

#include "LuaConfigValue.hpp"

namespace Config::Lua {
    class CLuaConfigBool : public ILuaConfigValue {
      public:
        CLuaConfigBool(Config::BOOL def);
        virtual ~CLuaConfigBool() = default;

        virtual SParseError           parse(lua_State* s);
        virtual const std::type_info* underlying();
        virtual void const*           data();
        virtual std::string           toString();
        virtual void                  push(lua_State* s);
        virtual void                  reset();
        virtual Config::INTEGER       asInt();

        const Config::BOOL&           parsed();

      private:
        Config::BOOL m_default = false;
        Config::BOOL m_data    = false;
    };
};
#pragma once

#include <cstdint>
#include <typeinfo>

#inR},
        {"stay_focused", []() -> ILuaConfigValue* { return new CLuaConfigBool(false); }, WE::WINDOW_RULE_EFFECT_STAY_FOCUSED},
        {"confine_pointer", []() -> ILuaConfigValue* { return new CLuaConfigBool(false); }, WE::WINDOW_RULE_EFFECT_CONFINE_POINTER},
        {"tonemap", []() -> ILuaConfigValue* { return new CLuaConfigString(STRVAL_EMPTY); }, WE::WINDOW_RULE_EFFECT_TONEMAP},
    };

    std::string                                        argStr(lua_State* L, int idx);
    std::optional<std::string>                         tableOptStr(lua_State* L, int idx, const char* field);
    std::optional<double>                              tableOptNum(lua_State* L, int idx, const char* field);
    std::optional<bool>                                tableOptBool(lua_State* L, int idx, const char* field);

    PHLMONITOR                                         monitorFromLuaSelectorOrObject(lua_State* L, int idx, const char* fnName);
    PHLWORKSPACE                                       workspaceFromLuaSelectorOrObject(lua_State* L, int idx, const char* fnName);
    PHLWINDOW                                          windowFromLuaSelectorOrObject(lua_State* L, int idx, const char* fnName);
    std::optional<PHLMONITOR>                          tableOptMonitor(lua_State* L, int idx, const char* field, const char* fnName);
    std::optional<PHLWORKSPACE>                        tableOptWorkspace(lua_State* L, int idx, const char* field, const char* fnName);
    std::optional<PHLWINDOW>      unordered_map>
#include <unordered_set>
#include <vector>
#include <optional>
#include <cstdint>

#include "../../helpers/memory/Memory.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../../desktop/DesktopTypes.hpp"
#include "event/EventBus.hpp"

extern "C" {
#include <lua.h>
}

namespace Config::Lua {

    // Manages hl.on() event subscriptions for a single Lua state lifetime.
    // Destroyed (and recreated) on every config reload so callbacks never double-up.
    //
    // Hyprland objects (window, workspace, monitor, layer surface) are exposed to Lua
    // as typed userdata holding a weak pointer.  Field accesses read live C++ state via
    // __index; accessing a field on a destroyed object raises a Lua error.
    class CLuaEventHandler {
      public:
        explicit CLuaEventHandler(lua_State* L);
        ~CLuaEventHandler();

        // Store a Lua function (as a registry ref) to be called when `name` fires.
        // Returns a subscription handle, or std::nullopt if the event name is unknown.
        std::optional<uint64_t>                registerEvent(const std::string& name, int luaRef);
        bool                                   unregisterEvent(uint64_t handle);

        void                                   clearEvents();

        std::expected<void, std::string>       addCustomEvent(SP<Event::CEventBus::CCustomEvent> event);
        std::expected<void, std::string>       removeCustomEvent(const std::string& name);

        static std::unordered_set<std::sut:tablettool:pressure_range_max",
        "input:touchpad:flip_x",
        "input:touchpad:flip_y",
        "input:touchpad:drag_3fg",
        "input:virtualkeyboard:share_states",
        "input:virtualkeyboard:release_pressed_on_close",
    };

    std::vector<SP<IValue>>              getConfigValues();
    inline const std::vector<SP<IValue>> CONFIG_VALUES = getConfigValues();

    std::string                          getAsJson();
};
#pragma once

#include "IValue.hpp"

#include "../../ConfigValue.hpp"

namespace Config::Values {
    struct SBoolValueOptions {
        Supplementary::PropRefreshBits refresh = 0;
    };

    class CBoolValue : public IValue {
      public:
        CBoolValue(const char* name, const char* description, Config::BOOL def, SBoolValueOptions&& options = {});

        virtual ~CBoolValue() = default;

        virtual const std::type_info* underlying() const override;
        virtual void                  commence() override;

        Config::BOOL                  value() const;
        Config::BOOL                  defaultVal() const;

      private:
        CConfigValue<Config::BOOL> m_val;
        bool                       m_default = false;
    };
}
#pragma once

#include "IValue.hpp"

#include "../../ConfigValue.hpp"

#include <functional>
#include <expected>

namespace Config::Values {
    struct SVec2ValueOptions {
        std::function<std::expected<void, std::string>(const Config::VEC2&)> validator = {};
        Supplementary::PropRefreshBits       late <>
inline Config::IComplexConfigValue* CConfigValue<Config::IComplexConfigValue>::ptr() const {
    if (m_hlangp)
        return rc<Config::IComplexConfigValue*>((*rc<Hyprlang::CUSTOMTYPE* const*>(m_hlangp))->getData());
    else
        return *rc<Config::IComplexConfigValue* const*>(m_p);
}
#pragma once

#include <string>
#include <filesystem>
#include <expected>

#include "./shared/Types.hpp"
#include "../helpers/memory/Memory.hpp"

#include "values/types/IValue.hpp"

extern "C" {
struct lua_State;
}

namespace Config {

    using PLUGIN_LUA_FN = int (*)(lua_State*);

    struct SConfigOptionReply {
        // <type>* const*
        void* const*          dataptr   = nullptr;
        const std::type_info* type      = nullptr;
        bool                  setByUser = false;
    };

    enum eConfigManagerType : uint8_t {
        CONFIG_LEGACY = 0,
        CONFIG_LUA
    };

    const char* typeToString(eConfigManagerType t);

    class IConfigManager {
      protected:
        IConfigManager() = default;

      public:
        virtual ~IConfigManager() = default;

        virtual eConfigManagerType               type() = 0;

        virtual void                             init()   = 0;
        virtual void                             reload() = 0;
        virtual std::string                      verify() = 0;

        virtual int                              getDeviceInt(const std::string&, const std::string&, const std::string& fallback = "")    = 0;
        virtual float      l2.max;
            }
        } masteringLuminances;

        // Matrix data from ICC
        struct SICCData {
            bool                        present = false;
            size_t                      lutSize = 33;
            std::vector<float>          lutDataPacked;
            SP<Render::ITexture>        lutTexture;
            std::optional<SVCGTTable16> vcgt;
        } icc;

        uint32_t maxCLL  = 0;
        uint32_t maxFALL = 0;

        bool     operator==(const SImageDescription& d2) const {
            if (icc.present || d2.icc.present)
                return false;

            return isWindows == d2.isWindows && transferFunction == d2.transferFunction && transferFunctionPower == d2.transferFunctionPower &&
                (primariesNameSet == d2.primariesNameSet && (primariesNameSet ? primariesNamed == d2.primariesNamed : primaries == d2.primaries)) &&
                masteringPrimaries == d2.masteringPrimaries && luminances == d2.luminances && masteringLuminances == d2.masteringLuminances && maxCLL == d2.maxCLL &&
                maxFALL == d2.maxFALL;
        }

        const SPCPRimaries& getPrimaries() const {
            if (primariesNameSet || primaries == SPCPRimaries{})
                return NColorManagement::getPrimaries(primariesNamed);
            return primaries;
        }

        float getTFMinLuminance(float sdrMinLuminance = -1.0f) const {
            switch (transferFunction) {
                case CM_TRANSFER_FUNCTION_EXT_LINEAR: return 0;
   t;

    friend class CPromiseResult<T>;
    friend class CPromiseResolver<T>;
};#pragma once

namespace Env {
    bool envEnabled(const char* env);
    bool isTrace();
}
#pragma once
#include <optional>
#include <string>

namespace NFsUtils {
    // Returns the path to the hyprland directory in data home.
    std::optional<std::string> getDataHome();

    std::optional<std::string> readFileAsString(const std::string& path);

    // overwrites the file if exists
    bool writeToFile(const std::string& path, const std::string& content);

    bool executableExistsInPath(const std::string& exe);
};
#pragma once

#include <cstdint>
#include <optional>
#include <vector>
#include <functional>
#include <hyprutils/os/FileDescriptor.hpp>
#include "../memory/Memory.hpp"

/*
    Hyprland synchronization timelines are based on the wlroots' ones, which
    are based on Vk timeline semaphores: https://www.khronos.org/blog/vulkan-timeline-semaphores
*/

struct wl_event_source;

class CSyncTimeline {
  public:
    static SP<CSyncTimeline> create(int drmFD_);
    static SP<CSyncTimeline> create(int drmFD_, Hyprutils::OS::CFileDescriptor&& drmSyncobjFD);
    ~CSyncTimeline();

    // check if the timeline point has been signaled
    // flags: DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT or DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE
    // std::nullopt on fail
    std::optional<bool>            check(uint64_t point, uint32_t flags);

    bool                           addWaiter(std::function<void()>&& waiter, uint64_ox&) = delete;
    CAsyncDialogBox&          operator=(CAsyncDialogBox&&)      = delete;

    SP<CPromise<std::string>> open();
    void                      kill();
    bool                      isRunning() const;
    pid_t                     getPID() const;
    void                      setExecRule(std::string&& s);

    SP<CAsyncDialogBox>       lockSelf();

    // focus priority, only permission popups
    bool m_priority = false;

    void onWrite(int fd, uint32_t mask);

  private:
    CAsyncDialogBox(const std::string& title, const std::string& description, std::vector<std::string> buttons);

    pid_t                             m_dialogPid       = 0;
    wl_event_source*                  m_readEventSource = nullptr;
    Hyprutils::OS::CFileDescriptor    m_pipeReadFd;
    std::string                       m_stdout        = "";
    std::string                       m_execRuleToken = "";

    const std::string                 m_title;
    const std::string                 m_description;
    const std::vector<std::string>    m_buttons;

    SP<CPromiseResolver<std::string>> m_promiseResolver;

    // WARNING: cyclic reference. This will be removed once the event source is removed to avoid dangling pointers
    SP<CAsyncDialogBox> m_selfReference;
    WP<CAsyncDialogBox> m_selfWeakReference;
};
#pragma once

#include <vector>
#include <string>

namespace NSplashes {
    inline const std::vector<std::string> SPLASHES = {
        // clang-format off
        "Woo, animations!",
      ket: {} started\n", socket);
            m_running                               = true;
        }

        static SRollingLogFollow& get() {
            static SRollingLogFollow instance;
            return instance;
        };
    };
}
#pragma once

#include <hyprutils/cli/Logger.hpp>
#include <utility>

#include "../../helpers/memory/Memory.hpp"
#include "../../helpers/env/Env.hpp"

namespace Log {
    class CLogger {
      public:
        CLogger();
        ~CLogger() = default;

        void initIS(const std::string_view& IS);
        void initCallbacks();

        void log(Hyprutils::CLI::eLogLevel level, const std::string_view& str);

        template <typename... Args>
        //NOLINTNEXTLINE
        void log(Hyprutils::CLI::eLogLevel level, std::format_string<Args...> fmt, Args&&... args) {
            if (!m_logsEnabled)
                return;

            if (level == Hyprutils::CLI::LOG_TRACE && !m_isTrace)
                return;

            std::string logMsg = "";
            logMsg += std::format(fmt, std::forward<Args>(args)...);

            log(level, logMsg);
        }

        const std::string&       rolling();
        Hyprutils::CLI::CLogger& hu();

      private:
        void                    recheckCfg();

        Hyprutils::CLI::CLogger m_logger;
        bool                    m_logsEnabled = true;
        bool                    m_isTrace     = false;
    };

    inline UP<CLogger> logger = makeUnique<CLogger>();

    //
    inline constexpr const Hyprut   = 0;
    wl_event_source*               m_critSigSource  = nullptr;
    rlimit                         m_originalNofile = {};
    Hyprutils::OS::CFileDescriptor m_watchdogWriteFd;

    struct {
        CHyprSignalListener lock;
        CHyprSignalListener unlock;
    } m_listeners;
};

inline UP<CCompositor> g_pCompositor;
#pragma once

#include "../defines.hpp"

namespace NInit {
    bool isSudo();
    void gainRealTime();
};#pragma once

#include "SharedDefines.hpp"
#include "../desktop/DesktopTypes.hpp"
#include "../render/Texture.hpp"
#include "../helpers/time/Time.hpp"

namespace Notification {
    class CNotification {
      public:
        CNotification(std::string&& text, float timeout, CHyprColor color, eIcons icon, float fontSize);

        struct SRenderCache {
            SP<Render::ITexture> textTex;
            SP<Render::ITexture> iconTex;

            Vector2D             textSize = {};
            Vector2D             iconSize = {};

            PHLMONITORREF        monitor;
            std::string          fontFamily;
            int                  fontSizePx  = -1;
            eIconBackend         iconBackend = ICONS_BACKEND_NONE;
        } m_cache;

        void               setText(std::string&& text);
        void               setColor(CHyprColor color);
        void               setIcon(eIcons icon);
        void               setFontSize(float fontSize);
        void               resetTimeout(float timeMs);

        const std::string& text() const;
            exact = true;
    std::function<std::string(eHyprCtlOutputFormat, std::string)> fn;
};

struct SDispatchResult {
    bool        passEvent = false;
    bool        success   = true;
    std::string error;
};

using WINDOWID    = int64_t;
using MONITORID   = int64_t;
using WORKSPACEID = int64_t;
#pragma once

#include "includes.hpp"
#include "debug/log/Logger.hpp"
#include "helpers/Color.hpp"
#include "macros.hpp"
#include "desktop/DesktopTypes.hpp"

#if !defined(__GXX_RTTI)
#error "Hyprland requires C++ RTTI. Shit will hit the fan otherwise. Do not even try."
#endif
#pragma once

#include <sys/resource.h>

#include <ranges>

#include "helpers/math/Direction.hpp"
#include "managers/XWaylandManager.hpp"
#include "managers/KeybindManager.hpp"
#include "managers/SessionLockManager.hpp"
#include "desktop/view/Window.hpp"
#include "desktop/state/FadingOutState.hpp"
#include "desktop/state/LayerState.hpp"
#include "desktop/state/OtherViewState.hpp"
#include "desktop/state/ViewState.hpp"
#include "desktop/state/WindowState.hpp"
#include "helpers/cm/ColorManagement.hpp"

#include <aquamarine/backend/Backend.hpp>
#include <aquamarine/output/Output.hpp>

class CWLSurfaceResource;

enum eManagersInitStage : uint8_t {
    STAGE_PRIORITY = 0,
    STAGE_BASICINIT,
    STAGE_LATE
};

class CCompositor {
  public:
    CCompositor(bool onlyConf