aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorvaxerski <[email protected]>2022-05-28 20:46:20 +0200
committervaxerski <[email protected]>2022-05-28 20:46:20 +0200
commitbdf1c1619529792e95cd6cf2aa1d68e51db76252 (patch)
treec1fc311647342d21ba49707651ce70e654aa7b81
parentb1b24cb21a36713aa7c8c0d39464504c97423139 (diff)
downloadHyprland-bdf1c1619529792e95cd6cf2aa1d68e51db76252.tar.gz
Hyprland-bdf1c1619529792e95cd6cf2aa1d68e51db76252.zip
Added IHyprWindowDecoration and Group Bars
-rw-r--r--src/Window.cpp3
-rw-r--r--src/Window.hpp5
-rw-r--r--src/layout/DwindleLayout.cpp53
-rw-r--r--src/layout/DwindleLayout.hpp5
-rw-r--r--src/layout/IHyprLayout.hpp10
-rw-r--r--src/managers/AnimationManager.cpp6
-rw-r--r--src/render/Renderer.cpp4
-rw-r--r--src/render/decorations/CHyprGroupBarDecoration.cpp99
-rw-r--r--src/render/decorations/CHyprGroupBarDecoration.hpp30
-rw-r--r--src/render/decorations/IHyprWindowDecoration.cpp7
-rw-r--r--src/render/decorations/IHyprWindowDecoration.hpp31
11 files changed, 248 insertions, 5 deletions
diff --git a/src/Window.cpp b/src/Window.cpp
index 5bb1738e..cc76aed2 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -13,4 +13,7 @@ CWindow::~CWindow() {
g_pCompositor->m_pLastFocus = nullptr;
g_pCompositor->m_pLastWindow = nullptr;
}
+
+ for (auto& wd : m_dWindowDecorations)
+ delete wd;
} \ No newline at end of file
diff --git a/src/Window.hpp b/src/Window.hpp
index 253600b2..0dd105bb 100644
--- a/src/Window.hpp
+++ b/src/Window.hpp
@@ -4,6 +4,8 @@
#include "events/Events.hpp"
#include "helpers/SubsurfaceTree.hpp"
#include "helpers/AnimatedVariable.hpp"
+#include "render/decorations/IHyprWindowDecoration.hpp"
+#include <deque>
struct SWindowSpecialRenderData {
float alpha = 1.f;
@@ -88,6 +90,9 @@ public:
// For hidden windows and stuff
bool m_bHidden = false;
+ // Window decorations
+ std::deque<IHyprWindowDecoration*> m_dWindowDecorations;
+
// Special render data, rules, etc
SWindowSpecialRenderData m_sSpecialRenderData;
SWindowAdditionalConfigData m_sAdditionalConfigData;
diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp
index ef312abd..0f41265b 100644
--- a/src/layout/DwindleLayout.cpp
+++ b/src/layout/DwindleLayout.cpp
@@ -275,6 +275,10 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
if (OPENINGON->pGroupParent) {
// means we opened on a group
+
+ // add the group deco
+ pWindow->m_dWindowDecorations.emplace_back(new CHyprGroupBarDecoration(pWindow));
+
PNODE->pGroupParent = OPENINGON->pGroupParent;
PNODE->pGroupParent->groupMembers.push_back(PNODE);
PNODE->pGroupParent->groupMemberActive = PNODE->pGroupParent->groupMembers.size() - 1;
@@ -693,6 +697,10 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
for (auto& node : PGROUPPARENT->groupMembers) {
node->pGroupParent = nullptr;
node->pWindow->m_cRealBorderColor.setValueAndWarp(INACTIVEBORDERCOL); // no anim here because they pop in
+
+ for (auto& wd : node->pWindow->m_dWindowDecorations) {
+ wd->updateWindow(node->pWindow);
+ }
}
PGROUPPARENT->groupMembers.clear();
@@ -725,6 +733,8 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
c->pGroupParent = PPARENT;
c->pWindow->m_cRealBorderColor = GROUPINACTIVEBORDERCOL;
+ c->pWindow->m_dWindowDecorations.push_back(new CHyprGroupBarDecoration(c->pWindow));
+
if (c->pWindow == g_pCompositor->m_pLastWindow)
c->pWindow->m_cRealBorderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border_active"));
}
@@ -735,6 +745,31 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
}
}
+std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
+
+ std::deque<CWindow*> result;
+
+ if (!g_pCompositor->windowExists(pWindow))
+ return result; // reject with empty
+
+ // get the node
+ const auto PNODE = getNodeFromWindow(pWindow);
+
+ if (!PNODE)
+ return result; // reject with empty
+
+ const auto PGROUPPARENT = PNODE->pGroupParent;
+
+ if (!PGROUPPARENT)
+ return result; // reject with empty
+
+ for (auto& node : PGROUPPARENT->groupMembers) {
+ result.push_back(node->pWindow);
+ }
+
+ return result;
+}
+
void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
if (!g_pCompositor->windowValidMapped(pWindow))
return; // reject
@@ -760,6 +795,12 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
PNODE->pGroupParent->recalcSizePosRecursive();
+ for (auto& gm : PNODE->pGroupParent->groupMembers) {
+ for (auto& deco : gm->pWindow->m_dWindowDecorations) {
+ deco->updateWindow(gm->pWindow);
+ }
+ }
+
// focus
g_pCompositor->focusWindow(PNODE->pGroupParent->groupMembers[PNODE->pGroupParent->groupMemberActive]->pWindow);
}
@@ -850,7 +891,7 @@ void CHyprDwindleLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
PNODE->pParent->recalcSizePosRecursive();
}
-void CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
+std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
if (message == "togglegroup")
toggleWindowGroup(header.pWindow);
else if (message == "changegroupactivef")
@@ -859,6 +900,12 @@ void CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::string
switchGroupWindow(header.pWindow, false);
else if (message == "togglesplit")
toggleSplit(header.pWindow);
+ else if (message == "groupinfo") {
+ auto res = getGroupMembers(g_pCompositor->m_pLastWindow);
+ return res;
+ }
+
+ return "";
}
void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) {
@@ -870,4 +917,8 @@ void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) {
PNODE->pParent->splitTop = !PNODE->pParent->splitTop;
PNODE->pParent->recalcSizePosRecursive();
+}
+
+std::string CHyprDwindleLayout::getLayoutName() {
+ return "dwindle";
} \ No newline at end of file
diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp
index 91d3a820..4abd04ef 100644
--- a/src/layout/DwindleLayout.hpp
+++ b/src/layout/DwindleLayout.hpp
@@ -3,6 +3,7 @@
#include "IHyprLayout.hpp"
#include <list>
#include <deque>
+#include "../render/decorations/CHyprGroupBarDecoration.hpp"
class CHyprDwindleLayout;
@@ -50,10 +51,11 @@ public:
virtual void onMouseMove(const Vector2D&);
virtual void onWindowCreatedFloating(CWindow*);
virtual void fullscreenRequestForWindow(CWindow*);
- virtual void layoutMessage(SLayoutMessageHeader, std::string);
+ virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
virtual void switchWindows(CWindow*, CWindow*);
virtual void alterSplitRatioBy(CWindow*, float);
+ virtual std::string getLayoutName();
private:
@@ -73,6 +75,7 @@ public:
void toggleWindowGroup(CWindow*);
void switchGroupWindow(CWindow*, bool forward);
void toggleSplit(CWindow*);
+ std::deque<CWindow*> getGroupMembers(CWindow*);
friend struct SDwindleNodeData;
}; \ No newline at end of file
diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp
index 71f30e3d..01e3e04a 100644
--- a/src/layout/IHyprLayout.hpp
+++ b/src/layout/IHyprLayout.hpp
@@ -74,9 +74,10 @@ public:
/*
Called when a dispatcher requests a custom message
- The layout is free to ignore.
+ The layout is free to ignore.
+ std::any is the reply. Can be empty.
*/
- virtual void layoutMessage(SLayoutMessageHeader, std::string) = 0;
+ virtual std::any layoutMessage(SLayoutMessageHeader, std::string) = 0;
/*
Required to be handled, but may return just SWindowRenderLayoutHints()
@@ -96,4 +97,9 @@ public:
on a window
*/
virtual void alterSplitRatioBy(CWindow*, float) = 0;
+
+ /*
+ Called when something wants the current layout's name
+ */
+ virtual std::string getLayoutName() = 0;
}; \ No newline at end of file
diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp
index 5c417cb2..0df6a3bf 100644
--- a/src/managers/AnimationManager.cpp
+++ b/src/managers/AnimationManager.cpp
@@ -140,8 +140,12 @@ void CAnimationManager::tick() {
case AVARDAMAGE_ENTIRE: {
g_pHyprRenderer->damageBox(&WLRBOXPREV);
- if (PWINDOW)
+ if (PWINDOW) {
g_pHyprRenderer->damageWindow(PWINDOW);
+ for (auto& wd : PWINDOW->m_dWindowDecorations) {
+ wd->updateWindow(PWINDOW);
+ }
+ }
break;
}
case AVARDAMAGE_BORDER: {
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index fc3f5702..86ab125d 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -109,6 +109,10 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
+ // render window decorations first
+ for (auto& wd : pWindow->m_dWindowDecorations)
+ wd->draw(pMonitor);
+
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
if (pWindow->m_bIsX11) {
diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp
new file mode 100644
index 00000000..eca14973
--- /dev/null
+++ b/src/render/decorations/CHyprGroupBarDecoration.cpp
@@ -0,0 +1,99 @@
+#include "CHyprGroupBarDecoration.hpp"
+#include "../../Compositor.hpp"
+
+CHyprGroupBarDecoration::CHyprGroupBarDecoration(CWindow* pWindow) {
+ m_pWindow = pWindow;
+ updateWindow(pWindow);
+}
+
+CHyprGroupBarDecoration::~CHyprGroupBarDecoration() {
+
+}
+
+SWindowDecorationExtents CHyprGroupBarDecoration::getWindowDecorationExtents() {
+ return m_seExtents;
+}
+
+eDecorationType CHyprGroupBarDecoration::getDecorationType() {
+ return DECORATION_GROUPBAR;
+}
+
+void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
+ damageEntire();
+
+ const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
+
+ if (pWindow->m_vRealPosition.vec() != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
+ // we draw 3px above the window's border with 3px
+ const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
+
+ m_seExtents.topLeft = Vector2D(0, BORDERSIZE + 3 + 3);
+ m_seExtents.bottomRight = Vector2D();
+
+ m_vLastWindowPos = pWindow->m_vRealPosition.vec();
+ m_vLastWindowSize = pWindow->m_vRealSize.vec();
+ }
+
+ // let's check if the window group is different.
+
+ if (g_pLayoutManager->getCurrentLayout()->getLayoutName() != "dwindle") {
+ // ????
+ for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) {
+ if ((*it) == this) {
+ pWindow->m_dWindowDecorations.erase(it);
+ delete this;
+ return;
+ }
+ }
+ }
+
+ // get the group info
+ SLayoutMessageHeader header;
+ header.pWindow = g_pCompositor->m_pLastWindow;
+
+ m_dwGroupMembers = std::any_cast<std::deque<CWindow*>>(g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "groupinfo"));
+
+ damageEntire();
+
+ if (m_dwGroupMembers.size() == 0) {
+ // remove
+ for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) {
+ if ((*it) == this) {
+ pWindow->m_dWindowDecorations.erase(it);
+ delete this;
+ return;
+ }
+ }
+ }
+}
+
+void CHyprGroupBarDecoration::damageEntire() {
+ wlr_box dm = {m_vLastWindowPos.x - m_seExtents.topLeft.x, m_vLastWindowPos.y - m_seExtents.topLeft.y, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x, m_seExtents.topLeft.y};
+ g_pHyprRenderer->damageBox(&dm);
+}
+
+void CHyprGroupBarDecoration::draw(SMonitor* pMonitor) {
+ // get how many bars we will draw
+ int barsToDraw = m_dwGroupMembers.size();
+
+ if (barsToDraw < 1 || m_pWindow->m_bHidden || !g_pCompositor->windowValidMapped(m_pWindow))
+ return;
+
+ const int PAD = 2; //2px
+
+ const int BARW = (m_vLastWindowSize.x - PAD * (barsToDraw - 1)) / barsToDraw;
+
+ int xoff = 0;
+
+ for (int i = 0; i < barsToDraw; ++i) {
+ wlr_box rect = {m_vLastWindowPos.x + xoff - pMonitor->vecPosition.x, m_vLastWindowPos.y - m_seExtents.topLeft.y - pMonitor->vecPosition.y, BARW, 3};
+
+ if (rect.width <= 0 || rect.height <= 0)
+ break;
+
+ CColor color = m_dwGroupMembers[i] == g_pCompositor->m_pLastWindow ? CColor(g_pConfigManager->getInt("dwindle:col.group_border_active")) : CColor(g_pConfigManager->getInt("dwindle:col.group_border"));
+ g_pHyprOpenGL->renderRect(&rect, color);
+
+ xoff += PAD + BARW;
+ }
+} \ No newline at end of file
diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp
new file mode 100644
index 00000000..74a597a6
--- /dev/null
+++ b/src/render/decorations/CHyprGroupBarDecoration.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "IHyprWindowDecoration.hpp"
+#include <deque>
+
+class CHyprGroupBarDecoration : public IHyprWindowDecoration {
+public:
+ CHyprGroupBarDecoration(CWindow*);
+ virtual ~CHyprGroupBarDecoration();
+
+ virtual SWindowDecorationExtents getWindowDecorationExtents();
+
+ virtual void draw(SMonitor*);
+
+ virtual eDecorationType getDecorationType();
+
+ virtual void updateWindow(CWindow*);
+
+ virtual void damageEntire();
+
+private:
+ SWindowDecorationExtents m_seExtents;
+
+ CWindow* m_pWindow = nullptr;
+
+ Vector2D m_vLastWindowPos;
+ Vector2D m_vLastWindowSize;
+
+ std::deque<CWindow*> m_dwGroupMembers;
+}; \ No newline at end of file
diff --git a/src/render/decorations/IHyprWindowDecoration.cpp b/src/render/decorations/IHyprWindowDecoration.cpp
new file mode 100644
index 00000000..ada71985
--- /dev/null
+++ b/src/render/decorations/IHyprWindowDecoration.cpp
@@ -0,0 +1,7 @@
+#include "IHyprWindowDecoration.hpp"
+
+#include "../../Window.hpp"
+
+IHyprWindowDecoration::~IHyprWindowDecoration() {
+
+} \ No newline at end of file
diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp
new file mode 100644
index 00000000..0815273d
--- /dev/null
+++ b/src/render/decorations/IHyprWindowDecoration.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "../../defines.hpp"
+
+enum eDecorationType {
+ DECORATION_NONE = -1,
+ DECORATION_GROUPBAR
+};
+
+struct SWindowDecorationExtents {
+ Vector2D topLeft;
+ Vector2D bottomRight;
+};
+
+class CWindow;
+struct SMonitor;
+
+class IHyprWindowDecoration {
+public:
+ virtual ~IHyprWindowDecoration() = 0;
+
+ virtual SWindowDecorationExtents getWindowDecorationExtents() = 0;
+
+ virtual void draw(SMonitor*) = 0;
+
+ virtual eDecorationType getDecorationType() = 0;
+
+ virtual void updateWindow(CWindow*) = 0;
+
+ virtual void damageEntire() = 0;
+}; \ No newline at end of file