summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
authorvaxerski <vaxry@vaxry.net>2024-02-28 11:45:43 +0000
committervaxerski <vaxry@vaxry.net>2024-02-28 11:45:43 +0000
commitf4f3aa2e505ca1b22688fb4a32f31c4bfb851dd0 (patch)
tree98c8547e45a04445b24b2aa90b0a3e0d302a0cd6 /src/layout
parentc198d744b77f272c2fc187eb6d431580a99ab6c3 (diff)
layout: add size prediction for initial xdg commits
fixes #4022
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/DwindleLayout.cpp66
-rw-r--r--src/layout/DwindleLayout.hpp1
-rw-r--r--src/layout/IHyprLayout.cpp4
-rw-r--r--src/layout/IHyprLayout.hpp6
-rw-r--r--src/layout/MasterLayout.cpp27
-rw-r--r--src/layout/MasterLayout.hpp1
6 files changed, 97 insertions, 8 deletions
diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp
index 0f4a5f87..2bb6e4c3 100644
--- a/src/layout/DwindleLayout.cpp
+++ b/src/layout/DwindleLayout.cpp
@@ -127,7 +127,13 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
const auto PWINDOW = pNode->pWindow;
// get specific gaps and rules for this workspace,
// if user specified them in config
- const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID));
+ const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(pNode->workspaceID));
+
+ if (!g_pCompositor->windowExists(PWINDOW)) {
+ Debug::log(ERR, "Node {} holding invalid {}!!", pNode, PWINDOW);
+ onWindowRemovedTiling(PWINDOW);
+ return;
+ }
if (PWINDOW->m_bIsFullscreen && !pNode->ignoreFullscreenChecks)
return;
@@ -143,13 +149,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
- if (!g_pCompositor->windowExists(PWINDOW) || !PWINDOW->m_bIsMapped) {
- Debug::log(ERR, "Node {} holding invalid {}!!", pNode, PWINDOW);
- onWindowRemovedTiling(PWINDOW);
- return;
- }
-
- CBox nodeBox = pNode->box;
+ CBox nodeBox = pNode->box;
nodeBox.round();
PWINDOW->m_vSize = nodeBox.size();
@@ -1093,3 +1093,53 @@ void CHyprDwindleLayout::onEnable() {
void CHyprDwindleLayout::onDisable() {
m_lDwindleNodesData.clear();
}
+
+Vector2D CHyprDwindleLayout::predictSizeForNewWindow() {
+ if (!g_pCompositor->m_pLastMonitor)
+ return {};
+
+ // get window candidate
+ CWindow* candidate = g_pCompositor->m_pLastWindow;
+
+ if (!candidate)
+ candidate = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
+
+ // create a fake node
+ SDwindleNodeData node;
+
+ if (!candidate)
+ return g_pCompositor->m_pLastMonitor->vecSize;
+ else {
+ const auto PNODE = getNodeFromWindow(candidate);
+
+ if (!PNODE)
+ return {};
+
+ node = *PNODE;
+ node.pWindow = nullptr;
+
+ CBox box = PNODE->box;
+
+ static auto* const PSMARTSPLIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:smart_split");
+ static auto* const PPRESERVESPLIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:preserve_split");
+ static auto* const PFLMULT = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("dwindle:split_width_multiplier");
+
+ bool splitTop = false;
+
+ if (**PPRESERVESPLIT == 0 && **PSMARTSPLIT == 0)
+ splitTop = box.h * **PFLMULT > box.w;
+
+ const auto SPLITSIDE = !splitTop;
+
+ if (SPLITSIDE)
+ node.box = {{}, {box.w / 2.0, box.h}};
+ else
+ node.box = {{}, {box.w, box.h / 2.0}};
+
+ // TODO: make this better and more accurate
+
+ return node.box.size();
+ }
+
+ return {};
+}
diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp
index f5501b28..fc73540a 100644
--- a/src/layout/DwindleLayout.hpp
+++ b/src/layout/DwindleLayout.hpp
@@ -59,6 +59,7 @@ class CHyprDwindleLayout : public IHyprLayout {
virtual void alterSplitRatio(CWindow*, float, bool);
virtual std::string getLayoutName();
virtual void replaceWindowDataWith(CWindow* from, CWindow* to);
+ virtual Vector2D predictSizeForNewWindow();
virtual void onEnable();
virtual void onDisable();
diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp
index 49e20435..16474056 100644
--- a/src/layout/IHyprLayout.cpp
+++ b/src/layout/IHyprLayout.cpp
@@ -593,4 +593,8 @@ void IHyprLayout::requestFocusForWindow(CWindow* pWindow) {
g_pCompositor->focusWindow(pWindow);
}
+Vector2D IHyprLayout::predictSizeForNewWindow() {
+ return Vector2D{};
+}
+
IHyprLayout::~IHyprLayout() {}
diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp
index 5c74078e..ffe004bc 100644
--- a/src/layout/IHyprLayout.hpp
+++ b/src/layout/IHyprLayout.hpp
@@ -181,6 +181,12 @@ class IHyprLayout {
*/
virtual void requestFocusForWindow(CWindow*);
+ /*
+ Called to predict the size of a newly opened window to send it a configure.
+ Return 0,0 if unpredictable
+ */
+ virtual Vector2D predictSizeForNewWindow();
+
private:
Vector2D m_vBeginDragXY;
Vector2D m_vLastDragXY;
diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp
index 6a3cd492..1a488b0d 100644
--- a/src/layout/MasterLayout.cpp
+++ b/src/layout/MasterLayout.cpp
@@ -1459,6 +1459,33 @@ void CHyprMasterLayout::replaceWindowDataWith(CWindow* from, CWindow* to) {
applyNodeDataToWindow(PNODE);
}
+Vector2D CHyprMasterLayout::predictSizeForNewWindow() {
+ static auto* const PNEWISMASTER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:new_is_master");
+
+ if (!g_pCompositor->m_pLastMonitor)
+ return {};
+
+ const int NODES = getNodesOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
+
+ if (NODES <= 0)
+ return g_pCompositor->m_pLastMonitor->vecSize;
+
+ const auto MASTER = getMasterNodeOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
+ if (!MASTER) // wtf
+ return {};
+
+ if (*PNEWISMASTER) {
+ return MASTER->size;
+ } else {
+ const auto SLAVES = NODES - getMastersOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
+
+ // TODO: make this better
+ return {g_pCompositor->m_pLastMonitor->vecSize.x - MASTER->size.x, g_pCompositor->m_pLastMonitor->vecSize.y / (SLAVES + 1)};
+ }
+
+ return {};
+}
+
void CHyprMasterLayout::onEnable() {
for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_bIsFloating || !w->m_bIsMapped || w->isHidden())
diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp
index e316556a..d48aefdc 100644
--- a/src/layout/MasterLayout.hpp
+++ b/src/layout/MasterLayout.hpp
@@ -65,6 +65,7 @@ class CHyprMasterLayout : public IHyprLayout {
virtual void alterSplitRatio(CWindow*, float, bool);
virtual std::string getLayoutName();
virtual void replaceWindowDataWith(CWindow* from, CWindow* to);
+ virtual Vector2D predictSizeForNewWindow();
virtual void onEnable();
virtual void onDisable();