Add split preselection (#2240)

This commit is contained in:
Dashie 2023-05-06 02:02:18 +02:00 committed by GitHub
parent 4ad03af544
commit a8541d5f64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 18 deletions

View file

@ -132,6 +132,7 @@ void CConfigManager::setDefaultVars() {
configValues["dwindle:pseudotile"].intValue = 0;
configValues["dwindle:force_split"].intValue = 0;
configValues["dwindle:permanent_direction_override"].intValue = 0;
configValues["dwindle:preserve_split"].intValue = 0;
configValues["dwindle:special_scale_factor"].floatValue = 0.8f;
configValues["dwindle:split_width_multiplier"].floatValue = 1.0f;

View file

@ -1,7 +1,7 @@
#include "DwindleLayout.hpp"
#include "../Compositor.hpp"
void SDwindleNodeData::recalcSizePosRecursive(bool force) {
void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) {
if (children[0]) {
const auto REVERSESPLITRATIO = 2.f - splitRatio;
@ -13,6 +13,11 @@ void SDwindleNodeData::recalcSizePosRecursive(bool force) {
splitTop = size.y * *PFLMULT > size.x;
}
if (verticalOverride == true)
splitTop = true;
else if (horizontalOverride == true)
splitTop = false;
const auto SPLITSIDE = !splitTop;
if (SPLITSIDE) {
@ -336,9 +341,35 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
const auto PFORCESPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:force_split")->intValue;
static auto* const PFORCESPLIT = &g_pConfigManager->getConfigValuePtr("dwindle:force_split")->intValue;
static auto* const PERMANENTDIRECTIONOVERRIDE = &g_pConfigManager->getConfigValuePtr("dwindle:permanent_direction_override")->intValue;
if (*PFORCESPLIT == 0) {
bool horizontalOverride = false;
bool verticalOverride = false;
// let user select position -> top, right, bottom, left
if (overrideDirection != OneTimeFocus::NOFOCUS) {
// this is horizontal
if (overrideDirection % 2 == 0)
verticalOverride = true;
else
horizontalOverride = true;
// 0 -> top and left | 1,2 -> right and bottom
if (overrideDirection % 3 == 0) {
NEWPARENT->children[1] = OPENINGON;
NEWPARENT->children[0] = PNODE;
} else {
NEWPARENT->children[0] = OPENINGON;
NEWPARENT->children[1] = PNODE;
}
// whether or not the override persists after opening one window
if (*PERMANENTDIRECTIONOVERRIDE == 0)
overrideDirection = OneTimeFocus::NOFOCUS;
} else if (*PFORCESPLIT == 0) {
if ((SIDEBYSIDE &&
VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y / *PWIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x / 2.f,
NEWPARENT->position.y + NEWPARENT->size.y)) ||
@ -373,9 +404,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
}
// Update the children
if (NEWPARENT->size.x * *PWIDTHMULTIPLIER > NEWPARENT->size.y) {
// split left/right
if (!verticalOverride && (NEWPARENT->size.x * *PWIDTHMULTIPLIER > NEWPARENT->size.y || horizontalOverride)) {
// split left/right -> forced
OPENINGON->position = NEWPARENT->position;
OPENINGON->size = Vector2D(NEWPARENT->size.x / 2.f, NEWPARENT->size.y);
PNODE->position = Vector2D(NEWPARENT->position.x + NEWPARENT->size.x / 2.f, NEWPARENT->position.y);
@ -391,7 +421,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
OPENINGON->pParent = NEWPARENT;
PNODE->pParent = NEWPARENT;
NEWPARENT->recalcSizePosRecursive();
NEWPARENT->recalcSizePosRecursive(false, horizontalOverride, verticalOverride);
applyNodeDataToWindow(PNODE);
applyNodeDataToWindow(OPENINGON);
@ -811,8 +841,44 @@ void CHyprDwindleLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exa
}
std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
if (message == "togglesplit")
const auto ARGS = CVarList(message, 0, ' ');
if (ARGS[0] == "togglesplit") {
toggleSplit(header.pWindow);
} else if (ARGS[0] == "preselect") {
std::string direction = ARGS[1];
if (direction.empty()) {
Debug::log(ERR, "Expected direction for preselect");
return "";
}
switch (direction.front()) {
case 'u':
case 't': {
overrideDirection = OneTimeFocus::UP;
break;
}
case 'd':
case 'b': {
overrideDirection = OneTimeFocus::DOWN;
break;
}
case 'r': {
overrideDirection = OneTimeFocus::RIGHT;
break;
}
case 'l': {
overrideDirection = OneTimeFocus::LEFT;
break;
}
default: {
// any other character resets the focus direction
// needed for the persistent mode
overrideDirection = OneTimeFocus::NOFOCUS;
break;
}
}
}
return "";
}

View file

@ -9,6 +9,14 @@
class CHyprDwindleLayout;
enum eFullscreenMode : uint8_t;
enum OneTimeFocus {
UP = 0,
RIGHT,
DOWN,
LEFT,
NOFOCUS,
};
struct SDwindleNodeData {
SDwindleNodeData* pParent = nullptr;
bool isNode = false;
@ -34,7 +42,7 @@ struct SDwindleNodeData {
children[0] == rhs.children[0] && children[1] == rhs.children[1];
}
void recalcSizePosRecursive(bool force = false);
void recalcSizePosRecursive(bool force = false, bool horizontalOverride = false, bool verticalOverride = false);
void getAllChildrenRecursive(std::deque<SDwindleNodeData*>*);
CHyprDwindleLayout* layout = nullptr;
};
@ -77,5 +85,7 @@ class CHyprDwindleLayout : public IHyprLayout {
void toggleSplit(CWindow*);
OneTimeFocus overrideDirection = OneTimeFocus::NOFOCUS;
friend struct SDwindleNodeData;
};