diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 8df52ab9..4df5d2e2 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2791,26 +2791,55 @@ void CCompositor::arrangeMonitors() { ++it; } - // auto left - int maxOffset = 0; + // Variables to store the max and min values of monitors on each axis. + int maxXOffsetRight = 0; + int maxXOffsetLeft = 0; + int maxYOffsetUp = 0; + int maxYOffsetDown = 0; + + // Finds the max and min values of explicitely placed monitors. for (auto& m : arranged) { - if (m->vecPosition.x + m->vecSize.x > maxOffset) - maxOffset = m->vecPosition.x + m->vecSize.x; + if (m->vecPosition.x + m->vecSize.x > maxXOffsetRight) + maxXOffsetRight = m->vecPosition.x + m->vecSize.x; + if (m->vecPosition.x < maxXOffsetLeft) + maxXOffsetLeft = m->vecPosition.x; + if (m->vecPosition.y + m->vecSize.y > maxYOffsetDown) + maxYOffsetDown = m->vecPosition.y + m->vecSize.y; + if (m->vecPosition.y < maxYOffsetUp) + maxYOffsetUp = m->vecPosition.y; } + // Iterates through all non-explicitly placed monitors. for (auto& m : toArrange) { - Debug::log(LOG, "arrangeMonitors: {} auto [{}, {:.2f}]", m->szName, maxOffset, 0.f); - m->moveTo({maxOffset, 0}); - maxOffset += m->vecSize.x; + Debug::log(LOG, "arrangeMonitors: {} auto [{}, {:.2f}]", m->szName, maxXOffsetRight, 0.f); + // Moves the monitor to their appropriate position on the x/y axis and + // increments/decrements the corresponding max offset. + if (m->activeMonitorRule.autoDir == eAutoDirs::DIR_AUTO_UP) { + m->moveTo({0, maxYOffsetUp - m->vecSize.y}); + maxYOffsetUp = m->vecPosition.y; + } else if (m->activeMonitorRule.autoDir == eAutoDirs::DIR_AUTO_DOWN) { + m->moveTo({0, maxYOffsetDown}); + maxYOffsetDown += m->vecSize.y; + } else if (m->activeMonitorRule.autoDir == eAutoDirs::DIR_AUTO_LEFT) { + m->moveTo({maxXOffsetLeft - m->vecSize.x, 0}); + maxXOffsetLeft = m->vecPosition.x; + } else if (m->activeMonitorRule.autoDir == eAutoDirs::DIR_AUTO_RIGHT) { + m->moveTo({maxXOffsetRight, 0}); + maxXOffsetRight += m->vecSize.x; + } else { + Debug::log(WARN, + "Invalid auto direction. Valid options are 'auto'," + "'auto-up', 'auto-down', 'auto-left', and 'auto-right'."); + } } - // reset maxOffset (reuse) + // reset maxXOffsetRight (reuse) // and set xwayland positions aka auto for all - maxOffset = 0; + maxXOffsetRight = 0; for (auto& m : m_vMonitors) { - Debug::log(LOG, "arrangeMonitors: {} xwayland [{}, {:.2f}]", m->szName, maxOffset, 0.f); - m->vecXWaylandPosition = {maxOffset, 0}; - maxOffset += (*PXWLFORCESCALEZERO ? m->vecTransformedSize.x : m->vecSize.x); + Debug::log(LOG, "arrangeMonitors: {} xwayland [{}, {:.2f}]", m->szName, maxXOffsetRight, 0.f); + m->vecXWaylandPosition = {maxXOffsetRight, 0}; + maxXOffsetRight += (*PXWLFORCESCALEZERO ? m->vecTransformedSize.x : m->vecSize.x); if (*PXWLFORCESCALEZERO) m->xwaylandScale = m->scale; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index eaaed1f7..dda56530 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1642,6 +1642,16 @@ std::optional CConfigManager::handleMonitor(const std::string& comm if (ARGS[2].starts_with("auto")) { newrule.offset = Vector2D(-INT32_MAX, -INT32_MAX); + // If this is the first monitor rule needs to be on the right. + if (ARGS[2] == "auto-right" || ARGS[2] == "auto" || m_dMonitorRules.empty()) + newrule.autoDir = eAutoDirs::DIR_AUTO_RIGHT; + else if (ARGS[2] == "auto-left") + newrule.autoDir = eAutoDirs::DIR_AUTO_LEFT; + else if (ARGS[2] == "auto-up") + newrule.autoDir = eAutoDirs::DIR_AUTO_UP; + else if (ARGS[2] == "auto-down") + newrule.autoDir = eAutoDirs::DIR_AUTO_DOWN; + } else { if (!ARGS[2].contains("x")) { error += "invalid offset "; diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 29a41976..8dcfc397 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1258,8 +1258,8 @@ std::unordered_map CWindow::getEnv() { std::unordered_map results; // - std::string environFile = "/proc/" + std::to_string(PID) + "/environ"; - std::ifstream ifs(environFile, std::ios::binary); + std::string environFile = "/proc/" + std::to_string(PID) + "/environ"; + std::ifstream ifs(environFile, std::ios::binary); if (!ifs.good()) return {}; diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 4dd58a4e..75178836 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -10,10 +10,18 @@ #include "Timer.hpp" #include "Region.hpp" #include - #include "signal/Signal.hpp" +// Enum for the different types of auto directions, e.g. auto-left, auto-up. +enum class eAutoDirs { + DIR_AUTO_UP, + DIR_AUTO_DOWN, + DIR_AUTO_LEFT, + DIR_AUTO_RIGHT +}; + struct SMonitorRule { + eAutoDirs autoDir; std::string name = ""; Vector2D resolution = Vector2D(1280, 720); Vector2D offset = Vector2D(0, 0); diff --git a/src/managers/TokenManager.cpp b/src/managers/TokenManager.cpp index e48addd0..8f7929ee 100644 --- a/src/managers/TokenManager.cpp +++ b/src/managers/TokenManager.cpp @@ -15,9 +15,9 @@ std::string CTokenManager::registerNewToken(std::any data, std::chrono::system_c do { uuid_t uuid_; uuid_generate_random(uuid_); - uuid = std::format("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", (uint16_t)uuid_[0], (uint16_t)uuid_[1], (uint16_t)uuid_[2], - (uint16_t)uuid_[3], (uint16_t)uuid_[4], (uint16_t)uuid_[5], (uint16_t)uuid_[6], (uint16_t)uuid_[7], (uint16_t)uuid_[8], (uint16_t)uuid_[9], - (uint16_t)uuid_[10], (uint16_t)uuid_[11], (uint16_t)uuid_[12], (uint16_t)uuid_[13], (uint16_t)uuid_[14], (uint16_t)uuid_[15]); + uuid = std::format("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", (uint16_t)uuid_[0], (uint16_t)uuid_[1], + (uint16_t)uuid_[2], (uint16_t)uuid_[3], (uint16_t)uuid_[4], (uint16_t)uuid_[5], (uint16_t)uuid_[6], (uint16_t)uuid_[7], (uint16_t)uuid_[8], + (uint16_t)uuid_[9], (uint16_t)uuid_[10], (uint16_t)uuid_[11], (uint16_t)uuid_[12], (uint16_t)uuid_[13], (uint16_t)uuid_[14], (uint16_t)uuid_[15]); } while (m_mTokens.contains(uuid)); m_mTokens[uuid] = std::make_shared(uuid, data, expires);