summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvaxerski <43317083+vaxerski@users.noreply.github.com>2022-04-12 16:44:18 +0200
committervaxerski <43317083+vaxerski@users.noreply.github.com>2022-04-12 16:44:18 +0200
commitb6a93b2f0383fc8f084c7757f0f67b8c0ebeccc7 (patch)
tree9da15dc91a16ddbbb9c32161eda96c2be4073131 /src
parent8197fded02f34e76527c0bc17cc69e4fea3cdda4 (diff)
Added window grouping for dwindle
furthermore, added LayoutRenderHints.
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp15
-rw-r--r--src/Window.hpp3
-rw-r--r--src/config/ConfigManager.cpp2
-rw-r--r--src/layout/DwindleLayout.cpp167
-rw-r--r--src/layout/DwindleLayout.hpp10
-rw-r--r--src/layout/IHyprLayout.hpp23
-rw-r--r--src/managers/AnimationManager.cpp4
-rw-r--r--src/managers/KeybindManager.cpp10
-rw-r--r--src/managers/KeybindManager.hpp2
-rw-r--r--src/render/Renderer.cpp3
10 files changed, 221 insertions, 18 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index dca964b6..88553570 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -253,13 +253,13 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) {
wlr_box box = {w->m_vRealPosition.x, w->m_vRealPosition.y, w->m_vRealSize.x, w->m_vRealSize.y};
- if (wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID))
+ if (wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden)
return &(*w);
}
for (auto& w : m_lWindows) {
wlr_box box = {w.m_vRealPosition.x, w.m_vRealPosition.y, w.m_vRealSize.x, w.m_vRealSize.y};
- if (wlr_box_contains_point(&box, pos.x, pos.y) && w.m_bIsMapped && !w.m_bIsFloating && PMONITOR->activeWorkspace == w.m_iWorkspaceID)
+ if (wlr_box_contains_point(&box, pos.x, pos.y) && w.m_bIsMapped && !w.m_bIsFloating && PMONITOR->activeWorkspace == w.m_iWorkspaceID && !w.m_bHidden)
return &w;
}
@@ -270,7 +270,7 @@ CWindow* CCompositor::vectorToWindowTiled(const Vector2D& pos) {
const auto PMONITOR = getMonitorFromVector(pos);
for (auto& w : m_lWindows) {
wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y};
- if (w.m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w.m_iWorkspaceID == PMONITOR->activeWorkspace && !w.m_bIsFloating)
+ if (w.m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w.m_iWorkspaceID == PMONITOR->activeWorkspace && !w.m_bIsFloating && !w.m_bHidden)
return &w;
}
@@ -282,13 +282,13 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) {
wlr_box box = {w->m_vRealPosition.x, w->m_vRealPosition.y, w->m_vRealSize.x, w->m_vRealSize.y};
- if (w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible(w->m_iWorkspaceID))
+ if (w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden)
return &(*w);
}
for (auto& w : m_lWindows) {
wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y};
- if (!w.m_bIsFloating && w.m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w.m_iWorkspaceID == PMONITOR->activeWorkspace)
+ if (!w.m_bIsFloating && w.m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w.m_iWorkspaceID == PMONITOR->activeWorkspace && !w.m_bHidden)
return &w;
}
@@ -317,7 +317,7 @@ CWindow* CCompositor::windowFromCursor() {
CWindow* CCompositor::windowFloatingFromCursor() {
for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) {
wlr_box box = {w->m_vRealPosition.x, w->m_vRealPosition.y, w->m_vRealSize.x, w->m_vRealSize.y};
- if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID))
+ if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden)
return &(*w);
}
@@ -424,6 +424,9 @@ bool CCompositor::windowValidMapped(CWindow* pWindow) {
if (!pWindow->m_bIsMapped)
return false;
+ if (pWindow->m_bHidden)
+ return false;
+
if (!g_pXWaylandManager->getWindowSurface(pWindow))
return false;
diff --git a/src/Window.hpp b/src/Window.hpp
index d34a5d06..216773fb 100644
--- a/src/Window.hpp
+++ b/src/Window.hpp
@@ -73,6 +73,9 @@ public:
bool m_bFadingOut = false;
bool m_bReadyToDelete = false;
+ // For hidden windows and stuff
+ bool m_bHidden = false;
+
// For the list lookup
bool operator==(const CWindow& rhs) {
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 59d9566a..97dae134 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -28,6 +28,8 @@ CConfigManager::CConfigManager() {
configValues["decoration:blur_passes"].intValue = 1;
configValues["dwindle:pseudotile"].intValue = 0;
+ configValues["dwindle:col.group_border"].intValue = 0x66777700;
+ configValues["dwindle:col.group_border_active"].intValue = 0x66ffff00;
configValues["animations:enabled"].intValue = 1;
configValues["animations:speed"].floatValue = 7.f;
diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp
index b497388a..b007ae8e 100644
--- a/src/layout/DwindleLayout.cpp
+++ b/src/layout/DwindleLayout.cpp
@@ -2,6 +2,23 @@
#include "../Compositor.hpp"
void SDwindleNodeData::recalcSizePosRecursive() {
+
+ // check the group, if we are in one and not active, ignore.
+ if (pGroupParent && pGroupParent->groupMembers[pGroupParent->groupMemberActive] != this) {
+ if (pWindow)
+ pWindow->m_bHidden = true;
+ return;
+ } else {
+ if (pWindow)
+ pWindow->m_bHidden = false;
+ }
+
+ if (pGroupParent) {
+ // means we are in a group and focused. let's just act like the full window in this
+ size = pGroupParent->size;
+ position = pGroupParent->position;
+ }
+
if (children[0]) {
const auto REVERSESPLITRATIO = 2.f - splitRatio;
@@ -20,19 +37,22 @@ void SDwindleNodeData::recalcSizePosRecursive() {
children[1]->size = Vector2D(size.x, size.y / 2.f * REVERSESPLITRATIO);
}
- if (children[0]->isNode)
- children[0]->recalcSizePosRecursive();
- else
- layout->applyNodeDataToWindow(children[0]);
- if (children[1]->isNode)
- children[1]->recalcSizePosRecursive();
- else
- layout->applyNodeDataToWindow(children[1]);
+ children[0]->recalcSizePosRecursive();
+ children[1]->recalcSizePosRecursive();
} else {
layout->applyNodeDataToWindow(this);
}
}
+void SDwindleNodeData::getAllChildrenRecursive(std::deque<SDwindleNodeData*>* pDeque) {
+ if (children[0]) {
+ children[0]->getAllChildrenRecursive(pDeque);
+ children[1]->getAllChildrenRecursive(pDeque);
+ } else {
+ pDeque->push_back(this);
+ }
+}
+
int CHyprDwindleLayout::getNodesOnWorkspace(const int& id) {
int no = 0;
for (auto& n : m_lDwindleNodesData) {
@@ -217,10 +237,19 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
OPENINGON->pParent = NEWPARENT;
PNODE->pParent = NEWPARENT;
- NEWPARENT->recalcSizePosRecursive();
+ if (OPENINGON->pGroupParent) {
+ // means we opened on a group
+ PNODE->pGroupParent = OPENINGON->pGroupParent;
+ PNODE->pGroupParent->groupMembers.push_back(PNODE);
+ PNODE->pGroupParent->groupMemberActive = PNODE->pGroupParent->groupMembers.size() - 1;
- applyNodeDataToWindow(PNODE);
- applyNodeDataToWindow(OPENINGON);
+ PNODE->pGroupParent->recalcSizePosRecursive();
+ } else {
+ NEWPARENT->recalcSizePosRecursive();
+
+ applyNodeDataToWindow(PNODE);
+ applyNodeDataToWindow(OPENINGON);
+ }
pWindow->m_vRealPosition = PNODE->position + PNODE->size / 2.f;
pWindow->m_vRealSize = Vector2D(5,5);
@@ -259,6 +288,30 @@ void CHyprDwindleLayout::onWindowRemoved(CWindow* pWindow) {
else
PSIBLING->recalcSizePosRecursive();
+ // check if it was grouped
+ if (PNODE->pGroupParent) {
+ const auto MEMBERSCOPY = PNODE->pGroupParent->groupMembers;
+ PNODE->pGroupParent->groupMembers.clear();
+ for (auto& c : MEMBERSCOPY) {
+ if (c != PNODE) {
+ PNODE->pGroupParent->groupMembers.push_back(c);
+ }
+ }
+
+ if ((long unsigned int)PNODE->pGroupParent->groupMemberActive >= PNODE->pGroupParent->groupMembers.size())
+ PNODE->pGroupParent->groupMemberActive = 0;
+
+ if (PNODE->pGroupParent->groupMembers.size() <= 1) {
+ PNODE->pGroupParent->isGroup = false;
+ PSIBLING->pGroupParent = nullptr;
+ PNODE->pGroupParent->groupMembers.clear();
+
+ PSIBLING->recalcSizePosRecursive();
+ } else {
+ PNODE->pGroupParent->recalcSizePosRecursive();
+ }
+ }
+
m_lDwindleNodesData.remove(*PPARENT);
m_lDwindleNodesData.remove(*PNODE);
@@ -557,4 +610,96 @@ void CHyprDwindleLayout::recalculateWindow(CWindow* pWindow) {
return;
PNODE->recalcSizePosRecursive();
+}
+
+void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
+ if (!g_pCompositor->windowValidMapped(pWindow))
+ return;
+
+ // get the node
+ const auto PNODE = getNodeFromWindow(pWindow);
+
+ if (!PNODE)
+ return; // reject
+
+ const auto PGROUPPARENT = PNODE->pGroupParent;
+
+ if (PGROUPPARENT) {
+ // if there is a parent, release it
+ for (auto& node : PGROUPPARENT->groupMembers)
+ node->pGroupParent = nullptr;
+
+ PGROUPPARENT->groupMembers.clear();
+
+ PGROUPPARENT->isGroup = false;
+
+ PGROUPPARENT->recalcSizePosRecursive();
+ } else {
+ // if there is no parent, let's make one
+
+ const auto PPARENT = PNODE->pParent;
+
+ if (!PPARENT)
+ return; // reject making group on single window
+
+
+ PPARENT->isGroup = true;
+
+ // recursively get all members
+ std::deque<SDwindleNodeData*> allChildren;
+ PPARENT->getAllChildrenRecursive(&allChildren);
+
+ PPARENT->groupMembers = allChildren;
+
+ for (auto& c : PPARENT->groupMembers)
+ c->pGroupParent = PPARENT;
+
+ PPARENT->groupMemberActive = 0;
+
+ PPARENT->recalcSizePosRecursive();
+ }
+}
+
+void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow) {
+ if (!g_pCompositor->windowValidMapped(pWindow))
+ return; // reject
+
+ const auto PNODE = getNodeFromWindow(pWindow);
+
+ if (!PNODE)
+ return; // reject
+
+ if (!PNODE->pGroupParent)
+ return; // reject
+
+ PNODE->pGroupParent->groupMemberActive++;
+
+ if ((long unsigned int)PNODE->pGroupParent->groupMemberActive >= PNODE->pGroupParent->groupMembers.size())
+ PNODE->pGroupParent->groupMemberActive = 0;
+
+ PNODE->pGroupParent->recalcSizePosRecursive();
+
+ // focus
+ g_pCompositor->focusWindow(PNODE->pGroupParent->groupMembers[PNODE->pGroupParent->groupMemberActive]->pWindow);
+}
+
+SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(CWindow* pWindow) {
+ // window should be valid, insallah
+
+ SWindowRenderLayoutHints hints;
+
+ const auto PNODE = getNodeFromWindow(pWindow);
+ if (!PNODE)
+ return hints; // left for the future, maybe floating funkiness
+
+ if (PNODE->pGroupParent) {
+ hints.isBorderColor = true;
+
+ if (pWindow == g_pCompositor->m_pLastWindow)
+ hints.borderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border_active"));
+ else
+ hints.borderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border"));
+ }
+
+ return hints;
} \ No newline at end of file
diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp
index 8d849bcf..47da6cd3 100644
--- a/src/layout/DwindleLayout.hpp
+++ b/src/layout/DwindleLayout.hpp
@@ -2,6 +2,7 @@
#include "IHyprLayout.hpp"
#include <list>
+#include <deque>
class CHyprDwindleLayout;
@@ -13,6 +14,11 @@ struct SDwindleNodeData {
std::array<SDwindleNodeData*, 2> children = { nullptr, nullptr };
+ bool isGroup = false;
+ int groupMemberActive = 0;
+ std::deque<SDwindleNodeData*> groupMembers;
+ SDwindleNodeData* pGroupParent = nullptr;
+
Vector2D position;
Vector2D size;
@@ -26,6 +32,7 @@ struct SDwindleNodeData {
}
void recalcSizePosRecursive();
+ void getAllChildrenRecursive(std::deque<SDwindleNodeData*>*);
CHyprDwindleLayout* layout = nullptr;
};
@@ -41,6 +48,9 @@ public:
virtual void onMouseMove(const Vector2D&);
virtual void onWindowCreatedFloating(CWindow*);
virtual void fullscreenRequestForWindow(CWindow*);
+ virtual void toggleWindowGroup(CWindow*);
+ virtual void switchGroupWindow(CWindow*);
+ virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
private:
diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp
index 3e85cc24..16414895 100644
--- a/src/layout/IHyprLayout.hpp
+++ b/src/layout/IHyprLayout.hpp
@@ -3,6 +3,11 @@
#include "../defines.hpp"
#include "../Window.hpp"
+struct SWindowRenderLayoutHints {
+ bool isBorderColor = false;
+ CColor borderColor;
+};
+
interface IHyprLayout {
public:
@@ -61,4 +66,22 @@ public:
*/
virtual void fullscreenRequestForWindow(CWindow*) = 0;
+ /*
+ Called when the user requests a window to be made into a group,
+ or when they want the group to be released.
+ Everything else is free to interpret by the layout.
+ */
+ virtual void toggleWindowGroup(CWindow*) = 0;
+
+ /*
+ Called when the user requests a group window switch
+ */
+ virtual void switchGroupWindow(CWindow*) = 0;
+
+ /*
+ Required to be handled, but may return just SWindowRenderLayoutHints()
+ Called when the renderer requests any special draw flags for
+ a specific window, e.g. border color for groups.
+ */
+ virtual SWindowRenderLayoutHints requestRenderHints(CWindow*) = 0;
}; \ No newline at end of file
diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp
index 4495214a..48d56148 100644
--- a/src/managers/AnimationManager.cpp
+++ b/src/managers/AnimationManager.cpp
@@ -52,7 +52,9 @@ void CAnimationManager::tick() {
continue;
// process the borders
- const auto& COLOR = g_pCompositor->isWindowActive(&w) ? BORDERACTIVECOL : BORDERINACTIVECOL;
+ const auto RENDERHINTS = g_pLayoutManager->getCurrentLayout()->requestRenderHints(&w);
+
+ const auto& COLOR = RENDERHINTS.isBorderColor ? RENDERHINTS.borderColor : g_pCompositor->isWindowActive(&w) ? BORDERACTIVECOL : BORDERINACTIVECOL;
if (BORDERSENABLED) {
if (!deltazero(COLOR, w.m_cRealBorderColor)) {
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index 331273c3..54d5b605 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -54,6 +54,8 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
else if (k.handler == "movetoworkspace") { moveActiveToWorkspace(k.arg); }
else if (k.handler == "pseudo") { toggleActivePseudo(k.arg); }
else if (k.handler == "movefocus") { moveFocusTo(k.arg); }
+ else if (k.handler == "togglegroup") { toggleGroup(k.arg); }
+ else if (k.handler == "changegroupactive") { changeGroupActive(k.arg); }
found = true;
}
@@ -289,4 +291,12 @@ void CKeybindManager::moveFocusTo(std::string args) {
Vector2D middle = PWINDOWTOCHANGETO->m_vPosition + PWINDOWTOCHANGETO->m_vSize / 2.f;
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, middle.x, middle.y);
}
+}
+
+void CKeybindManager::toggleGroup(std::string args) {
+ g_pLayoutManager->getCurrentLayout()->toggleWindowGroup(g_pCompositor->m_pLastWindow);
+}
+
+void CKeybindManager::changeGroupActive(std::string args) {
+ g_pLayoutManager->getCurrentLayout()->switchGroupWindow(g_pCompositor->m_pLastWindow);
} \ No newline at end of file
diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp
index de4e8fa3..edd43a26 100644
--- a/src/managers/KeybindManager.hpp
+++ b/src/managers/KeybindManager.hpp
@@ -32,6 +32,8 @@ private:
void fullscreenActive(std::string);
void moveActiveToWorkspace(std::string);
void moveFocusTo(std::string);
+ void toggleGroup(std::string);
+ void changeGroupActive(std::string);
};
inline std::unique_ptr<CKeybindManager> g_pKeybindManager; \ No newline at end of file
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index d4ee312a..922229ea 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -89,6 +89,9 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
}
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate) {
+ if (pWindow->m_bHidden)
+ return;
+
if (pWindow->m_bFadingOut) {
g_pHyprOpenGL->renderSnapshot(&pWindow);
return;