mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-27 02:49:48 +01:00
Add split preselection (#2240)
This commit is contained in:
parent
4ad03af544
commit
a8541d5f64
3 changed files with 95 additions and 18 deletions
|
@ -130,14 +130,15 @@ void CConfigManager::setDefaultVars() {
|
|||
configValues["decoration:dim_around"].floatValue = 0.4f;
|
||||
configValues["decoration:screen_shader"].strValue = STRVAL_EMPTY;
|
||||
|
||||
configValues["dwindle:pseudotile"].intValue = 0;
|
||||
configValues["dwindle:force_split"].intValue = 0;
|
||||
configValues["dwindle:preserve_split"].intValue = 0;
|
||||
configValues["dwindle:special_scale_factor"].floatValue = 0.8f;
|
||||
configValues["dwindle:split_width_multiplier"].floatValue = 1.0f;
|
||||
configValues["dwindle:no_gaps_when_only"].intValue = 0;
|
||||
configValues["dwindle:use_active_for_splits"].intValue = 1;
|
||||
configValues["dwindle:default_split_ratio"].floatValue = 1.f;
|
||||
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;
|
||||
configValues["dwindle:no_gaps_when_only"].intValue = 0;
|
||||
configValues["dwindle:use_active_for_splits"].intValue = 1;
|
||||
configValues["dwindle:default_split_ratio"].floatValue = 1.f;
|
||||
|
||||
configValues["master:special_scale_factor"].floatValue = 0.8f;
|
||||
configValues["master:mfact"].floatValue = 0.55f;
|
||||
|
|
|
@ -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) {
|
||||
|
@ -334,11 +339,37 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|||
const auto SIDEBYSIDE = NEWPARENT->size.x > NEWPARENT->size.y * *PWIDTHMULTIPLIER;
|
||||
NEWPARENT->splitTop = !SIDEBYSIDE;
|
||||
|
||||
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
|
||||
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 "";
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue