layout: rethonk layouts from the ground up (#12890)
Rewrites layouts to be much smaller, and deal with much less annoying BS. Improves the overall architecture, unifies handling of pseudotiling, and various other improvements.
This commit is contained in:
parent
51f8849e54
commit
723870337f
82 changed files with 8431 additions and 5527 deletions
|
|
@ -1867,6 +1867,22 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
|
||||
/*
|
||||
* layout:
|
||||
*/
|
||||
SConfigOptionDescription{
|
||||
.value = "layout:single_window_aspect_ratio",
|
||||
.description = "If specified, whenever only a single window is open, it will be coerced into the specified aspect ratio. Ignored if the y-value is zero.",
|
||||
.type = CONFIG_OPTION_VECTOR,
|
||||
.data = SConfigOptionDescription::SVectorData{{0, 0}, {0, 0}, {1000., 1000.}},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "layout:single_window_aspect_ratio_tolerance",
|
||||
.description = "Minimum distance for single_window_aspect_ratio to take effect, in fractions of the monitor's size.",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{0.1f, 0.f, 1.f},
|
||||
},
|
||||
|
||||
/*
|
||||
* dwindle:
|
||||
*/
|
||||
|
|
@ -1946,18 +1962,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:single_window_aspect_ratio",
|
||||
.description = "If specified, whenever only a single window is open, it will be coerced into the specified aspect ratio. Ignored if the y-value is zero.",
|
||||
.type = CONFIG_OPTION_VECTOR,
|
||||
.data = SConfigOptionDescription::SVectorData{{0, 0}, {0, 0}, {1000., 1000.}},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:single_window_aspect_ratio_tolerance",
|
||||
.description = "Minimum distance for single_window_aspect_ratio to take effect, in fractions of the monitor's size.",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{0.1f, 0.f, 1.f},
|
||||
},
|
||||
|
||||
/*
|
||||
* master:
|
||||
|
|
@ -2043,6 +2047,53 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
|
||||
/*
|
||||
* scrolling:
|
||||
*/
|
||||
|
||||
SConfigOptionDescription{
|
||||
.value = "scrolling:fullscreen_on_one_column",
|
||||
.description = "when enabled, a single column on a workspace will always span the entire screen.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "scrolling:column_width",
|
||||
.description = "the default width of a column, [0.1 - 1.0].",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{.value = 0.5, .min = 0.1, .max = 1.0},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "scrolling:focus_fit_method",
|
||||
.description = "When a column is focused, what method should be used to bring it into view",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{.firstIndex = 0, .choices = "center,fit"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "scrolling:follow_focus",
|
||||
.description = "when a window is focused, should the layout move to bring it into view automatically",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{.value = true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "scrolling:follow_min_visible",
|
||||
.description = "when a window is focused, require that at least a given fraction of it is visible for focus to follow",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{.value = 0.4, .min = 0.0, .max = 1.0},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "scrolling:explicit_column_widths",
|
||||
.description = "A comma-separated list of preconfigured widths for colresize +conf/-conf",
|
||||
.type = CONFIG_OPTION_STRING_SHORT,
|
||||
.data = SConfigOptionDescription::SStringData{"0.333, 0.5, 0.667, 1.0"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "scrolling:direction",
|
||||
.description = "Direction in which new windows appear and the layout scrolls",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{.firstIndex = 0, .choices = "right,left,down,up"},
|
||||
},
|
||||
|
||||
/*
|
||||
* Quirks
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,13 +18,14 @@
|
|||
#include "../desktop/rule/layerRule/LayerRule.hpp"
|
||||
#include "../debug/HyprCtl.hpp"
|
||||
#include "../desktop/state/FocusState.hpp"
|
||||
#include "../layout/space/Space.hpp"
|
||||
#include "../layout/supplementary/WorkspaceAlgoMatcher.hpp"
|
||||
#include "defaultConfig.hpp"
|
||||
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../hyprerror/HyprError.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/permissions/DynamicPermissionManager.hpp"
|
||||
#include "../debug/HyprNotificationOverlay.hpp"
|
||||
|
|
@ -616,6 +617,9 @@ CConfigManager::CConfigManager() {
|
|||
registerConfigVar("decoration:screen_shader", {STRVAL_EMPTY});
|
||||
registerConfigVar("decoration:border_part_of_window", Hyprlang::INT{1});
|
||||
|
||||
registerConfigVar("layout:single_window_aspect_ratio", Hyprlang::VEC2{0, 0});
|
||||
registerConfigVar("layout:single_window_aspect_ratio_tolerance", {0.1f});
|
||||
|
||||
registerConfigVar("dwindle:pseudotile", Hyprlang::INT{0});
|
||||
registerConfigVar("dwindle:force_split", Hyprlang::INT{0});
|
||||
registerConfigVar("dwindle:permanent_direction_override", Hyprlang::INT{0});
|
||||
|
|
@ -628,8 +632,6 @@ CConfigManager::CConfigManager() {
|
|||
registerConfigVar("dwindle:smart_split", Hyprlang::INT{0});
|
||||
registerConfigVar("dwindle:smart_resizing", Hyprlang::INT{1});
|
||||
registerConfigVar("dwindle:precise_mouse_move", Hyprlang::INT{0});
|
||||
registerConfigVar("dwindle:single_window_aspect_ratio", Hyprlang::VEC2{0, 0});
|
||||
registerConfigVar("dwindle:single_window_aspect_ratio_tolerance", {0.1f});
|
||||
|
||||
registerConfigVar("master:special_scale_factor", {1.f});
|
||||
registerConfigVar("master:mfact", {0.55f});
|
||||
|
|
@ -645,6 +647,14 @@ CConfigManager::CConfigManager() {
|
|||
registerConfigVar("master:drop_at_cursor", Hyprlang::INT{1});
|
||||
registerConfigVar("master:always_keep_position", Hyprlang::INT{0});
|
||||
|
||||
registerConfigVar("scrolling:fullscreen_on_one_column", Hyprlang::INT{1});
|
||||
registerConfigVar("scrolling:column_width", Hyprlang::FLOAT{0.5F});
|
||||
registerConfigVar("scrolling:focus_fit_method", Hyprlang::INT{1});
|
||||
registerConfigVar("scrolling:follow_focus", Hyprlang::INT{1});
|
||||
registerConfigVar("scrolling:follow_min_visible", Hyprlang::FLOAT{0.4});
|
||||
registerConfigVar("scrolling:explicit_column_widths", Hyprlang::STRING{"0.333, 0.5, 0.667, 1.0"});
|
||||
registerConfigVar("scrolling:direction", Hyprlang::STRING{"right"});
|
||||
|
||||
registerConfigVar("animations:enabled", Hyprlang::INT{1});
|
||||
registerConfigVar("animations:workspace_wraparound", Hyprlang::INT{0});
|
||||
|
||||
|
|
@ -715,9 +725,9 @@ CConfigManager::CConfigManager() {
|
|||
registerConfigVar("binds:movefocus_cycles_fullscreen", Hyprlang::INT{0});
|
||||
registerConfigVar("binds:movefocus_cycles_groupfirst", Hyprlang::INT{0});
|
||||
registerConfigVar("binds:disable_keybind_grabbing", Hyprlang::INT{0});
|
||||
registerConfigVar("binds:window_direction_monitor_fallback", Hyprlang::INT{1});
|
||||
registerConfigVar("binds:allow_pin_fullscreen", Hyprlang::INT{0});
|
||||
registerConfigVar("binds:drag_threshold", Hyprlang::INT{0});
|
||||
registerConfigVar("binds:window_direction_monitor_fallback", Hyprlang::INT{1});
|
||||
|
||||
registerConfigVar("gestures:workspace_swipe_distance", Hyprlang::INT{300});
|
||||
registerConfigVar("gestures:workspace_swipe_invert", Hyprlang::INT{1});
|
||||
|
|
@ -1338,7 +1348,8 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
|||
static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
|
||||
for (auto const& m : g_pCompositor->m_monitors) {
|
||||
*(m->m_cursorZoom) = *PZOOMFACTOR;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->m_id);
|
||||
if (m->m_activeWorkspace)
|
||||
m->m_activeWorkspace->m_space->recalculate();
|
||||
}
|
||||
|
||||
// Update the keyboard layout to the cfg'd one if this is not the first launch
|
||||
|
|
@ -1406,9 +1417,6 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
|||
// Update window border colors
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
// update layout
|
||||
g_pLayoutManager->switchToLayout(std::any_cast<Hyprlang::STRING>(m_config->getConfigValue("general:layout")));
|
||||
|
||||
// manual crash
|
||||
if (std::any_cast<Hyprlang::INT>(m_config->getConfigValue("debug:manual_crash")) && !m_manualCrashInitiated) {
|
||||
m_manualCrashInitiated = true;
|
||||
|
|
@ -1447,6 +1455,9 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
|||
if (!m_isFirstLaunch)
|
||||
ensurePersistentWorkspacesPresent();
|
||||
|
||||
// update layouts
|
||||
Layout::Supplementary::algoMatcher()->updateWorkspaceLayouts();
|
||||
|
||||
EMIT_HOOK_EVENT("configReloaded", nullptr);
|
||||
if (g_pEventManager)
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"configreloaded", ""});
|
||||
|
|
@ -1469,8 +1480,9 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
|||
|
||||
// invalidate layouts if they changed
|
||||
if (COMMAND == "monitor" || COMMAND.contains("gaps_") || COMMAND.starts_with("dwindle:") || COMMAND.starts_with("master:")) {
|
||||
for (auto const& m : g_pCompositor->m_monitors)
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->m_id);
|
||||
for (auto const& m : g_pCompositor->m_monitors) {
|
||||
g_layoutManager->recalculateMonitor(m);
|
||||
}
|
||||
}
|
||||
|
||||
// Update window border colors
|
||||
|
|
@ -1642,6 +1654,8 @@ SWorkspaceRule CConfigManager::mergeWorkspaceRules(const SWorkspaceRule& rule1,
|
|||
mergedRule.onCreatedEmptyRunCmd = rule2.onCreatedEmptyRunCmd;
|
||||
if (rule2.defaultName.has_value())
|
||||
mergedRule.defaultName = rule2.defaultName;
|
||||
if (rule2.layout.has_value())
|
||||
mergedRule.layout = rule2.layout;
|
||||
if (!rule2.layoutopts.empty()) {
|
||||
for (const auto& layoutopt : rule2.layoutopts) {
|
||||
mergedRule.layoutopts[layoutopt.first] = layoutopt.second;
|
||||
|
|
@ -2710,6 +2724,9 @@ std::optional<std::string> CConfigManager::handleWorkspaceRules(const std::strin
|
|||
opt = opt.substr(0, opt.find(':'));
|
||||
|
||||
wsRule.layoutopts[opt] = val;
|
||||
} else if ((delim = rule.find("layout:")) != std::string::npos) {
|
||||
std::string layout = rule.substr(delim + 7);
|
||||
wsRule.layout = std::move(layout);
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
@ -3072,20 +3089,20 @@ std::string SConfigOptionDescription::jsonify() const {
|
|||
else if (typeid(Hyprlang::FLOAT) == std::type_index(CONFIGVALUE.type()))
|
||||
currentValue = std::format("{:.2f}", std::any_cast<Hyprlang::FLOAT>(CONFIGVALUE));
|
||||
else if (typeid(Hyprlang::STRING) == std::type_index(CONFIGVALUE.type()))
|
||||
currentValue = std::any_cast<Hyprlang::STRING>(CONFIGVALUE);
|
||||
currentValue = std::format("\"{}\"", std::any_cast<Hyprlang::STRING>(CONFIGVALUE));
|
||||
else if (typeid(Hyprlang::VEC2) == std::type_index(CONFIGVALUE.type())) {
|
||||
const auto V = std::any_cast<Hyprlang::VEC2>(CONFIGVALUE);
|
||||
currentValue = std::format("{}, {}", V.x, V.y);
|
||||
currentValue = std::format("\"{}, {}\"", V.x, V.y);
|
||||
} else if (typeid(void*) == std::type_index(CONFIGVALUE.type())) {
|
||||
const auto DATA = sc<ICustomConfigValueData*>(std::any_cast<void*>(CONFIGVALUE));
|
||||
currentValue = DATA->toString();
|
||||
currentValue = std::format("\"{}\"", DATA->toString());
|
||||
}
|
||||
|
||||
try {
|
||||
using T = std::decay_t<decltype(val)>;
|
||||
if constexpr (std::is_same_v<T, SStringData>) {
|
||||
return std::format(R"#( "value": "{}",
|
||||
"current": "{}",
|
||||
"current": {},
|
||||
"explicit": {})#",
|
||||
val.value, currentValue, EXPLICIT);
|
||||
} else if constexpr (std::is_same_v<T, SRangeData>) {
|
||||
|
|
@ -3104,7 +3121,7 @@ std::string SConfigOptionDescription::jsonify() const {
|
|||
val.value, val.min, val.max, currentValue, EXPLICIT);
|
||||
} else if constexpr (std::is_same_v<T, SColorData>) {
|
||||
return std::format(R"#( "value": "{}",
|
||||
"current": "{}",
|
||||
"current": {},
|
||||
"explicit": {})#",
|
||||
val.color.getAsHex(), currentValue, EXPLICIT);
|
||||
} else if constexpr (std::is_same_v<T, SBoolData>) {
|
||||
|
|
@ -3125,12 +3142,12 @@ std::string SConfigOptionDescription::jsonify() const {
|
|||
"min_y": {},
|
||||
"max_x": {},
|
||||
"max_y": {},
|
||||
"current": "{}",
|
||||
"current": {},
|
||||
"explicit": {})#",
|
||||
val.vec.x, val.vec.y, val.min.x, val.min.y, val.max.x, val.max.y, currentValue, EXPLICIT);
|
||||
} else if constexpr (std::is_same_v<T, SGradientData>) {
|
||||
return std::format(R"#( "value": "{}",
|
||||
"current": "{}",
|
||||
"current": {},
|
||||
"explicit": {})#",
|
||||
val.gradient, currentValue, EXPLICIT);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ struct SWorkspaceRule {
|
|||
std::optional<bool> noShadow;
|
||||
std::optional<std::string> onCreatedEmptyRunCmd;
|
||||
std::optional<std::string> defaultName;
|
||||
std::optional<std::string> layout;
|
||||
std::map<std::string, std::string> layoutopts;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue