diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2026-04-28 15:56:07 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-28 15:56:07 +0100 |
| commit | 98fbbafef78057c818fb02b15c27e38ad2f5b5bc (patch) | |
| tree | c62aa1eae704e7595d58f7edeb3804e8bfd0099d /src/layout/algorithm/tiled | |
| parent | d4c6ff434c5c7aa66bc7c28e5ce336d2a694bfcc (diff) | |
config/errors: Report and categorize errors properly for actions (#14192)
Makes all errors categorized, some not displayed, some displayed.
All errors can be obtained after hl.dispatch()
Diffstat (limited to 'src/layout/algorithm/tiled')
8 files changed, 117 insertions, 108 deletions
diff --git a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp index 32035de0..eabb7767 100644 --- a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp +++ b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.cpp @@ -637,7 +637,7 @@ SP<SDwindleNodeData> CDwindleAlgorithm::getMasterNode() { return nullptr; } -std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_view& sv) { +Config::ErrorResult CDwindleAlgorithm::layoutMsg(const std::string_view& sv) { const auto ARGS = CVarList2(std::string{sv}, 0, ' '); const auto CURRENT_NODE = getNodeFromWindow(Desktop::focusState()->window()); @@ -645,12 +645,12 @@ std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_ if (ARGS[0] == "togglesplit") { if (CURRENT_NODE) { if (!toggleSplit(CURRENT_NODE)) - return std::unexpected("can't togglesplit in the current workspace"); + return Config::configError("can't togglesplit in the current workspace", Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::INVALID_STATE); } } else if (ARGS[0] == "swapsplit") { if (CURRENT_NODE) { if (!swapSplit(CURRENT_NODE)) - return std::unexpected("can't swapsplit in the current workspace"); + return Config::configError("can't swapsplit in the current workspace", Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::INVALID_STATE); } } else if (ARGS[0] == "rotatesplit") { if (CURRENT_NODE) { @@ -660,7 +660,7 @@ std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_ angle = std::stoi(std::string{ARGS[1]}); } catch (const std::exception& e) { Log::logger->log(Log::WARN, "Invalid angle argument for rotatesplit: {}", ARGS[1]); - return std::unexpected("Invalid angle argument"); + return Config::configError("Invalid angle argument", Config::eConfigErrorLevel::ERROR, Config::eConfigErrorCode::INVALID_ARGUMENT); } } rotateSplit(CURRENT_NODE, angle); @@ -675,13 +675,13 @@ std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_ const auto STABLE = ARGS[2].empty() || ARGS[2] != "unstable"; if (!moveToRoot(node, STABLE)) - return std::unexpected("can't movetoroot in the current workspace"); + return Config::configError("can't movetoroot in the current workspace", Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::INVALID_STATE); } else if (ARGS[0] == "preselect") { auto direction = ARGS[1]; if (direction.empty()) { Log::logger->log(Log::ERR, "Expected direction for preselect"); - return std::unexpected("No direction for preselect"); + return Config::configError("No direction for preselect", Config::eConfigErrorLevel::ERROR, Config::eConfigErrorCode::INVALID_ARGUMENT); } switch (direction.front()) { @@ -715,15 +715,15 @@ std::expected<void, std::string> CDwindleAlgorithm::layoutMsg(const std::string_ bool exact = ARGS[2].starts_with("exact"); if (ratio.empty()) - return std::unexpected("splitratio requires an arg"); + return Config::configError("splitratio requires an arg", Config::eConfigErrorLevel::ERROR, Config::eConfigErrorCode::INVALID_ARGUMENT); auto delta = getPlusMinusKeywordResult(std::string{ratio}, 0.F); if (!CURRENT_NODE || !CURRENT_NODE->pParent) - return std::unexpected("cannot alter split ratio on no / single node"); + return Config::configError("cannot alter split ratio on no / single node", Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::INVALID_STATE); if (!delta) - return std::unexpected(std::format("failed to parse \"{}\" as a delta", ratio)); + return Config::configError(std::format("failed to parse \"{}\" as a delta", ratio), Config::eConfigErrorLevel::ERROR, Config::eConfigErrorCode::INVALID_ARGUMENT); const float newRatio = exact ? *delta : CURRENT_NODE->pParent->splitRatio + *delta; CURRENT_NODE->pParent->splitRatio = std::clamp(newRatio, 0.1F, 1.9F); diff --git a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp index 9216e843..300daa63 100644 --- a/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp +++ b/src/layout/algorithm/tiled/dwindle/DwindleAlgorithm.hpp @@ -30,22 +30,22 @@ namespace Layout::Tiled { CDwindleAlgorithm() = default; virtual ~CDwindleAlgorithm() = default; - virtual void newTarget(SP<ITarget> target); - virtual void movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt); - virtual void removeTarget(SP<ITarget> target); + virtual void newTarget(SP<ITarget> target); + virtual void movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt); + virtual void removeTarget(SP<ITarget> target); - virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE); - virtual void recalculate(); + virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE); + virtual void recalculate(); - virtual SP<ITarget> getNextCandidate(SP<ITarget> old); + virtual SP<ITarget> getNextCandidate(SP<ITarget> old); - virtual std::expected<void, std::string> layoutMsg(const std::string_view& sv); - virtual std::optional<Vector2D> predictSizeForNewTarget(); + virtual Config::ErrorResult layoutMsg(const std::string_view& sv); + virtual std::optional<Vector2D> predictSizeForNewTarget(); - virtual void swapTargets(SP<ITarget> a, SP<ITarget> b); - virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent); + virtual void swapTargets(SP<ITarget> a, SP<ITarget> b); + virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent); - SP<SDwindleNodeData> getNodeFromWindow(PHLWINDOW w); + SP<SDwindleNodeData> getNodeFromWindow(PHLWINDOW w); private: std::vector<SP<SDwindleNodeData>> m_dwindleNodesData; diff --git a/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp b/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp index 11a59a5f..46506391 100644 --- a/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp +++ b/src/layout/algorithm/tiled/master/MasterAlgorithm.cpp @@ -428,7 +428,7 @@ void CMasterAlgorithm::recalculate() { calculateWorkspace(); } -std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_view& sv) { +Config::ErrorResult CMasterAlgorithm::layoutMsg(const std::string_view& sv) { auto switchToWindow = [&](SP<ITarget> target) { if (!target || !validMapped(target->window())) return; @@ -441,11 +441,15 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v g_pInputManager->m_forcedFocus.reset(); }; - CVarList2 vars(std::string{sv}, 0, 's'); + CVarList2 vars(std::string{sv}, 0, 's'); + + const auto invalidArg = [](std::string msg) { return Config::configError(std::move(msg), Config::eConfigErrorLevel::ERROR, Config::eConfigErrorCode::INVALID_ARGUMENT); }; + const auto noTarget = [](std::string msg) { return Config::configError(std::move(msg), Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::NO_TARGET); }; + const auto stateErr = [](std::string msg) { return Config::configError(std::move(msg), Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::INVALID_STATE); }; if (vars.size() < 1 || vars[0].empty()) { Log::logger->log(Log::ERR, "layoutmsg called without params"); - return std::unexpected("layoutmsg without params"); + return invalidArg("layoutmsg without params"); } auto command = vars[0]; @@ -461,15 +465,15 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v if (command == "swapwithmaster") { if (!PWINDOW) - return std::unexpected("No focused window"); + return noTarget("No focused window"); if (!isWindowTiled(PWINDOW)) - return std::unexpected("focused window isn't tiled"); + return stateErr("focused window isn't tiled"); const auto PMASTER = getMasterNode(); if (!PMASTER) - return std::unexpected("no master node"); + return stateErr("no master node"); const auto NEWCHILD = PMASTER->pTarget.lock(); @@ -503,12 +507,12 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v // * auto (default) - swap the focus with the first child, if the current focus was master, otherwise focus master else if (command == "focusmaster") { if (!PWINDOW) - return std::unexpected("no focused window"); + return noTarget("no focused window"); const auto PMASTER = getMasterNode(); if (!PMASTER) - return std::unexpected("no master"); + return stateErr("no master"); const auto& ARG = vars[1]; // returns empty string if out of bounds @@ -541,21 +545,21 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v focusAuto(); } else if (command == "cyclenext") { if (!PWINDOW) - return std::unexpected("no window"); + return noTarget("no window"); const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop"; const auto PNEXTWINDOW = getNextTarget(PWINDOW->layoutTarget(), true, !NOLOOP); switchToWindow(PNEXTWINDOW); } else if (command == "cycleprev") { if (!PWINDOW) - return std::unexpected("no window"); + return noTarget("no window"); const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop"; const auto PPREVWINDOW = getNextTarget(PWINDOW->layoutTarget(), false, !NOLOOP); switchToWindow(PPREVWINDOW); } else if (command == "swapnext") { if (!validMapped(PWINDOW)) - return std::unexpected("no window"); + return noTarget("no window"); if (PWINDOW->layoutTarget()->floating()) { Config::Actions::swapNext(true); @@ -572,7 +576,7 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v } } else if (command == "swapprev") { if (!validMapped(PWINDOW)) - return std::unexpected("no window"); + return noTarget("no window"); if (PWINDOW->layoutTarget()->floating()) { Config::Actions::swapNext(false); @@ -589,10 +593,10 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v } } else if (command == "addmaster") { if (!validMapped(PWINDOW)) - return std::unexpected("no window"); + return noTarget("no window"); if (PWINDOW->layoutTarget()->floating()) - return std::unexpected("window is floating"); + return stateErr("window is floating"); const auto PNODE = getNodeFromTarget(PWINDOW->layoutTarget()); @@ -601,7 +605,7 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v static auto SMALLSPLIT = CConfigValue<Config::INTEGER>("master:allow_small_split"); if (MASTERS + 2 > WINDOWS && *SMALLSPLIT == 0) - return std::unexpected("nothing to do"); + return stateErr("nothing to do"); g_pCompositor->setWindowFullscreenInternal(PWINDOW, FSMODE_NONE); @@ -622,10 +626,10 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v } else if (command == "removemaster") { if (!validMapped(PWINDOW)) - return std::unexpected("no window"); + return noTarget("no window"); if (PWINDOW->layoutTarget()->floating()) - return std::unexpected("window isnt tiled"); + return stateErr("window isnt tiled"); const auto PNODE = getNodeFromTarget(PWINDOW->layoutTarget()); @@ -633,7 +637,7 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v const auto MASTERS = getMastersNo(); if (WINDOWS < 2 || MASTERS < 2) - return std::unexpected("nothing to do"); + return stateErr("nothing to do"); g_pCompositor->setWindowFullscreenInternal(PWINDOW, FSMODE_NONE); @@ -652,7 +656,7 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v calculateWorkspace(); } else if (command == "orientationleft" || command == "orientationright" || command == "orientationtop" || command == "orientationbottom" || command == "orientationcenter") { if (!PWINDOW) - return std::unexpected("no window"); + return noTarget("no window"); g_pCompositor->setWindowFullscreenInternal(PWINDOW, FSMODE_NONE); @@ -677,7 +681,7 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v } else if (command == "mfact") { if (!PWINDOW) - return std::unexpected("no window"); + return noTarget("no window"); const bool exact = vars[1] == "exact"; @@ -685,7 +689,7 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v try { ratio = std::stof(std::string{exact ? vars[2] : vars[1]}); - } catch (...) { return std::unexpected("bad ratio"); } + } catch (...) { return invalidArg("bad ratio"); } const auto PNODE = getNodeFromWindow(PWINDOW); @@ -699,11 +703,11 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v const auto PNODE = getNodeFromWindow(PWINDOW); if (!PNODE) - return std::unexpected("window couldnt be found"); + return noTarget("window couldnt be found"); const auto OLDMASTER = PNODE->isMaster ? PNODE : getMasterNode(); if (!OLDMASTER) - return std::unexpected("no old master"); + return stateErr("no old master"); auto oldMasterIt = std::ranges::find(m_masterNodesData, OLDMASTER); @@ -735,11 +739,11 @@ std::expected<void, std::string> CMasterAlgorithm::layoutMsg(const std::string_v const auto PNODE = getNodeFromWindow(PWINDOW); if (!PNODE) - return std::unexpected("window couldnt be found"); + return noTarget("window couldnt be found"); const auto OLDMASTER = PNODE->isMaster ? PNODE : getMasterNode(); if (!OLDMASTER) - return std::unexpected("no old master"); + return stateErr("no old master"); auto oldMasterIt = std::ranges::find(m_masterNodesData, OLDMASTER); diff --git a/src/layout/algorithm/tiled/master/MasterAlgorithm.hpp b/src/layout/algorithm/tiled/master/MasterAlgorithm.hpp index 44c61369..00e82784 100644 --- a/src/layout/algorithm/tiled/master/MasterAlgorithm.hpp +++ b/src/layout/algorithm/tiled/master/MasterAlgorithm.hpp @@ -48,22 +48,22 @@ namespace Layout::Tiled { CMasterAlgorithm() = default; virtual ~CMasterAlgorithm() = default; - virtual void newTarget(SP<ITarget> target); - virtual void movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt); - virtual void removeTarget(SP<ITarget> target); + virtual void newTarget(SP<ITarget> target); + virtual void movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt); + virtual void removeTarget(SP<ITarget> target); - virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE); - virtual void recalculate(); + virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE); + virtual void recalculate(); - virtual SP<ITarget> getNextCandidate(SP<ITarget> old); + virtual SP<ITarget> getNextCandidate(SP<ITarget> old); - virtual std::expected<void, std::string> layoutMsg(const std::string_view& sv); - virtual std::optional<Vector2D> predictSizeForNewTarget(); + virtual Config::ErrorResult layoutMsg(const std::string_view& sv); + virtual std::optional<Vector2D> predictSizeForNewTarget(); - virtual void swapTargets(SP<ITarget> a, SP<ITarget> b); - virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent); + virtual void swapTargets(SP<ITarget> a, SP<ITarget> b); + virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent); - SP<SMasterNodeData> getNodeFromTarget(SP<ITarget>) const; + SP<SMasterNodeData> getNodeFromTarget(SP<ITarget>) const; private: std::vector<SP<SMasterNodeData>> m_masterNodesData; @@ -87,4 +87,4 @@ namespace Layout::Tiled { bool isWindowTiled(PHLWINDOW); eOrientation defaultOrientation(); }; -};
\ No newline at end of file +}; diff --git a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp index 29810fb2..36c59a4e 100644 --- a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp +++ b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.cpp @@ -165,11 +165,11 @@ SP<ITarget> CMonocleAlgorithm::getNextCandidate(SP<ITarget> old) { return next->get()->target.lock(); } -std::expected<void, std::string> CMonocleAlgorithm::layoutMsg(const std::string_view& sv) { +Config::ErrorResult CMonocleAlgorithm::layoutMsg(const std::string_view& sv) { CVarList2 vars(std::string{sv}, 0, 's'); if (vars.size() < 1) - return std::unexpected("layoutmsg requires at least 1 argument"); + return Config::configError("layoutmsg requires at least 1 argument", Config::eConfigErrorLevel::ERROR, Config::eConfigErrorCode::INVALID_ARGUMENT); const auto COMMAND = vars[0]; @@ -181,7 +181,7 @@ std::expected<void, std::string> CMonocleAlgorithm::layoutMsg(const std::string_ return {}; } - return std::unexpected(std::format("Unknown monocle layoutmsg: {}", COMMAND)); + return Config::configError(std::format("Unknown monocle layoutmsg: {}", COMMAND), Config::eConfigErrorLevel::ERROR, Config::eConfigErrorCode::INVALID_ARGUMENT); } std::optional<Vector2D> CMonocleAlgorithm::predictSizeForNewTarget() { diff --git a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp index b23f85be..3f07748b 100644 --- a/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp +++ b/src/layout/algorithm/tiled/monocle/MonocleAlgorithm.hpp @@ -21,20 +21,20 @@ namespace Layout::Tiled { CMonocleAlgorithm(); virtual ~CMonocleAlgorithm(); - virtual void newTarget(SP<ITarget> target); - virtual void movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt); - virtual void removeTarget(SP<ITarget> target); + virtual void newTarget(SP<ITarget> target); + virtual void movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt); + virtual void removeTarget(SP<ITarget> target); - virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE); - virtual void recalculate(); + virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE); + virtual void recalculate(); - virtual SP<ITarget> getNextCandidate(SP<ITarget> old); + virtual SP<ITarget> getNextCandidate(SP<ITarget> old); - virtual std::expected<void, std::string> layoutMsg(const std::string_view& sv); - virtual std::optional<Vector2D> predictSizeForNewTarget(); + virtual Config::ErrorResult layoutMsg(const std::string_view& sv); + virtual std::optional<Vector2D> predictSizeForNewTarget(); - virtual void swapTargets(SP<ITarget> a, SP<ITarget> b); - virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent); + virtual void swapTargets(SP<ITarget> a, SP<ITarget> b); + virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent); private: std::vector<SP<SMonocleTargetData>> m_targetDatas; diff --git a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp index 3322d466..28941109 100644 --- a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp +++ b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp @@ -984,8 +984,13 @@ void CScrollingAlgorithm::moveTargetTo(SP<ITarget> t, Math::eDirection dir, bool focusTargetUpdate(t); } -std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::string_view& sv) { - auto centerOrFit = [this](const SP<SColumnData> COL) -> void { +Config::ErrorResult CScrollingAlgorithm::layoutMsg(const std::string_view& sv) { + const auto invalidArg = [](std::string msg) { return Config::configError(std::move(msg), Config::eConfigErrorLevel::ERROR, Config::eConfigErrorCode::INVALID_ARGUMENT); }; + const auto noTarget = [](std::string msg) { return Config::configError(std::move(msg), Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::NO_TARGET); }; + const auto notFound = [](std::string msg) { return Config::configError(std::move(msg), Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::NOT_FOUND); }; + const auto stateErr = [](std::string msg) { return Config::configError(std::move(msg), Config::eConfigErrorLevel::WARNING, Config::eConfigErrorCode::INVALID_STATE); }; + + auto centerOrFit = [this](const SP<SColumnData> COL) -> void { static const auto PFITMETHOD = CConfigValue<Config::INTEGER>("scrolling:focus_fit_method"); if (*PFITMETHOD == 1) m_scrollingData->fitCol(COL); @@ -998,7 +1003,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin if (ARGS[1] == "+col" || ARGS[1] == "col") { const auto TDATA = dataFor(Desktop::focusState()->window() ? Desktop::focusState()->window()->layoutTarget() : nullptr); if (!TDATA) - return std::unexpected("no window"); + return noTarget("no window"); const auto COL = m_scrollingData->next(TDATA->column.lock()); if (!COL) { @@ -1049,7 +1054,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin const auto PLUSMINUS = getPlusMinusKeywordResult(ARGS[1], 0); if (!PLUSMINUS.has_value()) - return std::unexpected("failed to parse offset"); + return invalidArg("failed to parse offset"); m_scrollingData->controller->adjustOffset(-(*PLUSMINUS)); m_scrollingData->recalculate(); @@ -1143,12 +1148,12 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin const auto PWINDOW = Desktop::focusState()->window(); if (!PWINDOW) - return std::unexpected("no focused window"); + return noTarget("no focused window"); const auto WDATA = dataFor(PWINDOW->layoutTarget()); if (!WDATA || m_scrollingData->columns.size() == 0) - return std::unexpected("can't fit: no window or columns"); + return stateErr("can't fit: no window or columns"); if (ARGS[1] == "active") { // fit the current column to 1.F @@ -1192,7 +1197,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin } if (!begun) - return std::unexpected("couldn't find beginning"); + return notFound("couldn't find beginning"); const auto USABLE = usableArea(); @@ -1271,7 +1276,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin static const auto PCONFWRAPFOCUS = CConfigValue<Config::INTEGER>("scrolling:wrap_focus"); if (!TDATA || ARGS[1].empty()) - return std::unexpected("no window to focus"); + return noTarget("no window to focus"); // Determine if we're in vertical scroll mode (strips are horizontal) const bool isVerticalScroll = (getDynamicDirection() == SCROLL_DIR_DOWN || getDynamicDirection() == SCROLL_DIR_UP); @@ -1294,7 +1299,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin if (!*PNOFALLBACK) PREV = TDATA->column->targetDatas.back(); else - return std::unexpected("fallback disabled (no target)"); + return notFound("fallback disabled (no target)"); } focusTargetUpdate(PREV->target.lock()); @@ -1307,7 +1312,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin if (!*PNOFALLBACK) NEXT = TDATA->column->targetDatas.front(); else - return std::unexpected("fallback disabled (no target)"); + return notFound("fallback disabled (no target)"); } focusTargetUpdate(NEXT->target.lock()); @@ -1361,11 +1366,11 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin } else if (ARGS[0] == "promote" || ARGS[0] == "consume" || ARGS[0] == "expel" || ARGS[0] == "consume_or_expel") { const auto TDATA = dataFor(Desktop::focusState()->window() ? Desktop::focusState()->window()->layoutTarget() : nullptr); if (!TDATA) - return std::unexpected("no window focused"); + return noTarget("no window focused"); const auto CURRENT_COL = TDATA->column.lock(); if (!CURRENT_COL) - return std::unexpected("no current col"); + return stateErr("no current col"); // expel a target from srcCol into its own new column at insertIdx auto expelTarget = [&](SP<SScrollingTargetData> tdata, SP<SColumnData> srcCol, std::optional<int64_t> insertIdx) { @@ -1388,7 +1393,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin expelTarget(TDATA, CURRENT_COL, idx == -1 ? std::nullopt : std::optional<int64_t>{idx}); } else if (ARGS[0] == "expel") { if (CURRENT_COL->targetDatas.size() < 2) - return std::unexpected("column has only one window"); + return stateErr("column has only one window"); const auto lastTarget = CURRENT_COL->targetDatas.back(); const auto currentIdx = m_scrollingData->idx(CURRENT_COL); @@ -1399,19 +1404,19 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin } else if (ARGS[0] == "consume") { const auto NEXT_COL = m_scrollingData->next(CURRENT_COL); if (!NEXT_COL) - return std::unexpected("no next column"); + return notFound("no next column"); consumeTarget(CURRENT_COL, NEXT_COL); } else if (ARGS[0] == "consume_or_expel") { if (ARGS.size() < 2) - return std::unexpected("not enough args"); + return invalidArg("not enough args"); const std::string& direction = ARGS[1]; const bool prev = direction == "prev"; const bool next = direction == "next"; if (!prev && !next) - return std::unexpected("invalid direction, expected prev or next"); + return invalidArg("invalid direction, expected prev or next"); if (CURRENT_COL->targetDatas.size() > 1) { const auto currentIdx = m_scrollingData->idx(CURRENT_COL); @@ -1419,7 +1424,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin } else { const auto ADJ_COL = prev ? m_scrollingData->prev(CURRENT_COL) : m_scrollingData->next(CURRENT_COL); if (!ADJ_COL) - return std::unexpected("no adjacent column"); + return notFound("no adjacent column"); CURRENT_COL->remove(TDATA->target.lock()); ADJ_COL->add(TDATA); @@ -1432,24 +1437,24 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin static const auto PCONFWRAPSWAPCOL = CConfigValue<Config::INTEGER>("scrolling:wrap_swapcol"); if (ARGS.size() < 2) - return std::unexpected("not enough args"); + return invalidArg("not enough args"); const auto TDATA = dataFor(Desktop::focusState()->window() ? Desktop::focusState()->window()->layoutTarget() : nullptr); if (!TDATA) - return std::unexpected("no window"); + return noTarget("no window"); const auto CURRENT_COL = TDATA->column.lock(); if (!CURRENT_COL) - return std::unexpected("no current col"); + return stateErr("no current col"); if (m_scrollingData->columns.size() < 2) - return std::unexpected("not enough columns to swap"); + return stateErr("not enough columns to swap"); const int64_t currentIdx = m_scrollingData->idx(CURRENT_COL); const size_t colCount = m_scrollingData->columns.size(); if (currentIdx == -1) - return std::unexpected("no current column"); + return stateErr("no current column"); const std::string& direction = ARGS[1]; int64_t targetIdx = -1; @@ -1466,7 +1471,7 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin else targetIdx = (currentIdx == (int64_t)colCount - 1) ? (colCount - 1) : (currentIdx + 1); else - return std::unexpected("no target (invalid direction?)"); + return invalidArg("no target (invalid direction?)"); ; std::swap(m_scrollingData->columns.at(currentIdx), m_scrollingData->columns.at(targetIdx)); @@ -1478,16 +1483,16 @@ std::expected<void, std::string> CScrollingAlgorithm::layoutMsg(const std::strin } else if (ARGS[0] == "center") { const auto TDATA = dataFor(Desktop::focusState()->window() ? Desktop::focusState()->window()->layoutTarget() : nullptr); if (!TDATA) - return std::unexpected("no window"); + return noTarget("no window"); const auto CURRENT_COL = TDATA->column.lock(); if (!CURRENT_COL) - return std::unexpected("no current col"); + return stateErr("no current col"); m_scrollingData->centerCol(CURRENT_COL); m_scrollingData->recalculate(); } else - return std::unexpected("no such layoutmsg for scrolling"); + return invalidArg("no such layoutmsg for scrolling"); return {}; } diff --git a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp index 2f6a5ce6..288d15a6 100644 --- a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp +++ b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp @@ -94,23 +94,23 @@ namespace Layout::Tiled { CScrollingAlgorithm(); virtual ~CScrollingAlgorithm(); - virtual void newTarget(SP<ITarget> target); - virtual void movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt); - virtual void removeTarget(SP<ITarget> target); + virtual void newTarget(SP<ITarget> target); + virtual void movedTarget(SP<ITarget> target, std::optional<Vector2D> focalPoint = std::nullopt); + virtual void removeTarget(SP<ITarget> target); - virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE); - virtual void recalculate(); + virtual void resizeTarget(const Vector2D& Δ, SP<ITarget> target, eRectCorner corner = CORNER_NONE); + virtual void recalculate(); - virtual SP<ITarget> getNextCandidate(SP<ITarget> old); + virtual SP<ITarget> getNextCandidate(SP<ITarget> old); - virtual std::expected<void, std::string> layoutMsg(const std::string_view& sv); - virtual std::optional<Vector2D> predictSizeForNewTarget(); + virtual Config::ErrorResult layoutMsg(const std::string_view& sv); + virtual std::optional<Vector2D> predictSizeForNewTarget(); - virtual void swapTargets(SP<ITarget> a, SP<ITarget> b); - virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent); + virtual void swapTargets(SP<ITarget> a, SP<ITarget> b); + virtual void moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent); - CBox usableArea(); - SP<SScrollingTargetData> dataFor(SP<ITarget> t); + CBox usableArea(); + SP<SScrollingTargetData> dataFor(SP<ITarget> t); enum eInputMode : uint8_t { INPUT_MODE_SOFT = 0, |
