mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 18:53:40 +01:00
fixup: fix breakage after hyprland#5762 + improve Hy3NodeData repr
Hy3NodeData now uses std::variant instead of a union, and all accesses are checked.
This commit is contained in:
parent
e6cabcfa3d
commit
dc5a0224ce
9 changed files with 431 additions and 403 deletions
19
flake.lock
generated
19
flake.lock
generated
|
@ -41,16 +41,15 @@
|
||||||
"xdph": "xdph"
|
"xdph": "xdph"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1713819507,
|
"lastModified": 1714409407,
|
||||||
"narHash": "sha256-mG0kD8HmkCsHRkTBmqGb/QvM1vAvkAmB5p2H5XQ0zLo=",
|
"narHash": "sha256-gc10Ag5O/s+EE24JZUXTpH4ogRsSyAfdgr7OvSNhQ8s=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "Hyprland",
|
"repo": "Hyprland",
|
||||||
"rev": "da839f20f1b1a57ec78d6b041f8d1369150d253e",
|
"rev": "f2b03e9679bc1a091fecffd98b50a4179b5c7d43",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"ref": "da839f20f1b1a57ec78d6b041f8d1369150d253e",
|
|
||||||
"repo": "Hyprland",
|
"repo": "Hyprland",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
@ -117,11 +116,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1713730424,
|
"lastModified": 1714171579,
|
||||||
"narHash": "sha256-MqYjTvQCxwuDIuAaqIEuyqserm5PYr0auiHHPuYFN/k=",
|
"narHash": "sha256-eaWDIvt8ufUKKz3Lc2a3PyemLJG1m9RYlF+HP3hWbaw=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprwayland-scanner",
|
"repo": "hyprwayland-scanner",
|
||||||
"rev": "7c9c8adfe7e424faa0c5ce6e8be90157fda53c06",
|
"rev": "126dad854f22fe30e6b82cd21808e76903d90ac5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -132,11 +131,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1713537308,
|
"lastModified": 1713714899,
|
||||||
"narHash": "sha256-XtTSSIB2DA6tOv+l0FhvfDMiyCmhoRbNB+0SeInZkbk=",
|
"narHash": "sha256-+z/XjO3QJs5rLE5UOf015gdVauVRQd2vZtsFkaXBq2Y=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "5c24cf2f0a12ad855f444c30b2421d044120c66f",
|
"rev": "6143fc5eeb9c4f00163267708e26191d1e918932",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
hyprland.url = "github:hyprwm/Hyprland?ref=da839f20f1b1a57ec78d6b041f8d1369150d253e";
|
hyprland.url = "github:hyprwm/Hyprland";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, hyprland, ... }: let
|
outputs = { self, hyprland, ... }: let
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <hyprland/src/Compositor.hpp>
|
#include <hyprland/src/Compositor.hpp>
|
||||||
#include <hyprland/src/desktop/DesktopTypes.hpp>
|
#include <hyprland/src/desktop/DesktopTypes.hpp>
|
||||||
|
#include <hyprland/src/desktop/Workspace.hpp>
|
||||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
#include <hyprland/src/plugins/PluginAPI.hpp>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
|
@ -15,18 +16,18 @@ std::shared_ptr<HOOK_CALLBACK_FN> windowTitleHookPtr;
|
||||||
std::shared_ptr<HOOK_CALLBACK_FN> urgentHookPtr;
|
std::shared_ptr<HOOK_CALLBACK_FN> urgentHookPtr;
|
||||||
std::shared_ptr<HOOK_CALLBACK_FN> tickHookPtr;
|
std::shared_ptr<HOOK_CALLBACK_FN> tickHookPtr;
|
||||||
|
|
||||||
bool performContainment(Hy3Node& node, bool contained, CWindow* window) {
|
bool performContainment(Hy3Node& node, bool contained, PHLWINDOW& window) {
|
||||||
if (node.data.type == Hy3NodeType::Group) {
|
if (node.data.is_group()) {
|
||||||
auto& group = node.data.as_group;
|
auto& group = node.data.as_group();
|
||||||
contained |= group.containment;
|
contained |= group.containment;
|
||||||
|
|
||||||
auto iter = node.data.as_group.children.begin();
|
auto iter = group.children.begin();
|
||||||
while (iter != node.data.as_group.children.end()) {
|
while (iter != group.children.end()) {
|
||||||
switch ((*iter)->data.type) {
|
switch ((*iter)->data.type()) {
|
||||||
case Hy3NodeType::Group: return performContainment(**iter, contained, window);
|
case Hy3NodeType::Group: return performContainment(**iter, contained, window);
|
||||||
case Hy3NodeType::Window:
|
case Hy3NodeType::Window:
|
||||||
if (contained) {
|
if (contained) {
|
||||||
auto wpid = (*iter)->data.as_window->getPID();
|
auto wpid = (*iter)->data.as_window()->getPID();
|
||||||
auto ppid = getPPIDof(window->getPID());
|
auto ppid = getPPIDof(window->getPID());
|
||||||
while (ppid > 10) { // `> 10` yoinked from HL swallow
|
while (ppid > 10) { // `> 10` yoinked from HL swallow
|
||||||
if (ppid == wpid) {
|
if (ppid == wpid) {
|
||||||
|
@ -58,7 +59,7 @@ bool performContainment(Hy3Node& node, bool contained, CWindow* window) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::onWindowCreated(CWindow* window, eDirection direction) {
|
void Hy3Layout::onWindowCreated(PHLWINDOW window, eDirection direction) {
|
||||||
for (auto& node: this->nodes) {
|
for (auto& node: this->nodes) {
|
||||||
if (node.parent == nullptr && performContainment(node, false, window)) {
|
if (node.parent == nullptr && performContainment(node, false, window)) {
|
||||||
return;
|
return;
|
||||||
|
@ -68,11 +69,11 @@ void Hy3Layout::onWindowCreated(CWindow* window, eDirection direction) {
|
||||||
IHyprLayout::onWindowCreated(window, direction);
|
IHyprLayout::onWindowCreated(window, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) {
|
void Hy3Layout::onWindowCreatedTiling(PHLWINDOW window, eDirection) {
|
||||||
hy3_log(
|
hy3_log(
|
||||||
LOG,
|
LOG,
|
||||||
"onWindowCreatedTiling called with window {:x} (floating: {}, monitor: {}, workspace: {})",
|
"onWindowCreatedTiling called with window {:x} (floating: {}, monitor: {}, workspace: {})",
|
||||||
(uintptr_t) window,
|
(uintptr_t) window.get(),
|
||||||
window->m_bIsFloating,
|
window->m_bIsFloating,
|
||||||
window->m_iMonitorID,
|
window->m_iMonitorID,
|
||||||
window->m_pWorkspace->m_iID
|
window->m_pWorkspace->m_iID
|
||||||
|
@ -85,7 +86,7 @@ void Hy3Layout::onWindowCreatedTiling(CWindow* window, eDirection) {
|
||||||
hy3_log(
|
hy3_log(
|
||||||
ERR,
|
ERR,
|
||||||
"onWindowCreatedTiling called with a window ({:x}) that is already tiled (node: {:x})",
|
"onWindowCreatedTiling called with a window ({:x}) that is already tiled (node: {:x})",
|
||||||
(uintptr_t) window,
|
(uintptr_t) window.get(),
|
||||||
(uintptr_t) existing
|
(uintptr_t) existing
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -142,16 +143,15 @@ void Hy3Layout::insertNode(Hy3Node& node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opening_after == nullptr) {
|
if (opening_after == nullptr) {
|
||||||
if (g_pCompositor->m_pLastWindow != nullptr
|
auto last_window = g_pCompositor->m_pLastWindow.lock();
|
||||||
&& g_pCompositor->m_pLastWindow->m_pWorkspace == node.workspace
|
if (last_window != nullptr && last_window->m_pWorkspace == node.workspace
|
||||||
&& !g_pCompositor->m_pLastWindow->m_bIsFloating
|
&& !last_window->m_bIsFloating
|
||||||
&& (node.data.type == Hy3NodeType::Window
|
&& (node.data.is_window() || last_window != node.data.as_window())
|
||||||
|| g_pCompositor->m_pLastWindow != node.data.as_window)
|
&& last_window->m_bIsMapped)
|
||||||
&& g_pCompositor->m_pLastWindow->m_bIsMapped)
|
|
||||||
{
|
{
|
||||||
opening_after = this->getNodeFromWindow(g_pCompositor->m_pLastWindow);
|
opening_after = this->getNodeFromWindow(last_window);
|
||||||
} else {
|
} else {
|
||||||
auto* mouse_window = g_pCompositor->vectorToWindowUnified(
|
auto mouse_window = g_pCompositor->vectorToWindowUnified(
|
||||||
g_pInputManager->getMouseCoordsInternal(),
|
g_pInputManager->getMouseCoordsInternal(),
|
||||||
RESERVED_EXTENTS | INPUT_EXTENTS
|
RESERVED_EXTENTS | INPUT_EXTENTS
|
||||||
);
|
);
|
||||||
|
@ -163,8 +163,8 @@ void Hy3Layout::insertNode(Hy3Node& node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opening_after != nullptr
|
if (opening_after != nullptr
|
||||||
&& ((node.data.type == Hy3NodeType::Group
|
&& ((node.data.is_group()
|
||||||
&& (opening_after == &node || node.data.as_group.hasChild(opening_after)))
|
&& (opening_after == &node || node.data.as_group().hasChild(opening_after)))
|
||||||
|| opening_after->reparenting))
|
|| opening_after->reparenting))
|
||||||
{
|
{
|
||||||
opening_after = nullptr;
|
opening_after = nullptr;
|
||||||
|
@ -202,14 +202,14 @@ void Hy3Layout::insertNode(Hy3Node& node) {
|
||||||
.layout = this,
|
.layout = this,
|
||||||
});
|
});
|
||||||
|
|
||||||
parent.data.as_group.children.push_back(&this->nodes.back());
|
parent.data.as_group().children.push_back(&this->nodes.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
opening_into = &this->nodes.back();
|
opening_into = &this->nodes.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opening_into->data.type != Hy3NodeType::Group) {
|
if (opening_into->data.is_window()) {
|
||||||
hy3_log(ERR, "opening_into node ({:x}) was not a group node", (uintptr_t) opening_into);
|
hy3_log(ERR, "opening_into node ({:x}) was not a group node", (uintptr_t) opening_into);
|
||||||
errorNotif();
|
errorNotif();
|
||||||
return;
|
return;
|
||||||
|
@ -236,7 +236,7 @@ void Hy3Layout::insertNode(Hy3Node& node) {
|
||||||
|
|
||||||
this->updateAutotileWorkspaces();
|
this->updateAutotileWorkspaces();
|
||||||
|
|
||||||
auto& target_group = opening_into->data.as_group;
|
auto& target_group = opening_into->data.as_group();
|
||||||
if (*at_enable && opening_after != nullptr && target_group.children.size() > 1
|
if (*at_enable && opening_after != nullptr && target_group.children.size() > 1
|
||||||
&& target_group.layout != Hy3GroupLayout::Tabbed
|
&& target_group.layout != Hy3GroupLayout::Tabbed
|
||||||
&& this->shouldAutotileWorkspace(opening_into->workspace))
|
&& this->shouldAutotileWorkspace(opening_into->workspace))
|
||||||
|
@ -261,9 +261,9 @@ void Hy3Layout::insertNode(Hy3Node& node) {
|
||||||
node.reparenting = false;
|
node.reparenting = false;
|
||||||
|
|
||||||
if (opening_after == nullptr) {
|
if (opening_after == nullptr) {
|
||||||
opening_into->data.as_group.children.push_back(&node);
|
opening_into->data.as_group().children.push_back(&node);
|
||||||
} else {
|
} else {
|
||||||
auto& children = opening_into->data.as_group.children;
|
auto& children = opening_into->data.as_group().children;
|
||||||
auto iter = std::find(children.begin(), children.end(), opening_after);
|
auto iter = std::find(children.begin(), children.end(), opening_after);
|
||||||
auto iter2 = std::next(iter);
|
auto iter2 = std::next(iter);
|
||||||
children.insert(iter2, &node);
|
children.insert(iter2, &node);
|
||||||
|
@ -281,7 +281,7 @@ void Hy3Layout::insertNode(Hy3Node& node) {
|
||||||
opening_into->recalcSizePosRecursive();
|
opening_into->recalcSizePosRecursive();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
|
void Hy3Layout::onWindowRemovedTiling(PHLWINDOW window) {
|
||||||
static const auto node_collapse_policy =
|
static const auto node_collapse_policy =
|
||||||
ConfigValue<Hyprlang::INT>("plugin:hy3:node_collapse_policy");
|
ConfigValue<Hyprlang::INT>("plugin:hy3:node_collapse_policy");
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
|
||||||
hy3_log(
|
hy3_log(
|
||||||
LOG,
|
LOG,
|
||||||
"removing window ({:x} as node {:x}) from node {:x}",
|
"removing window ({:x} as node {:x}) from node {:x}",
|
||||||
(uintptr_t) window,
|
(uintptr_t) window.get(),
|
||||||
(uintptr_t) node,
|
(uintptr_t) node,
|
||||||
(uintptr_t) node->parent
|
(uintptr_t) node->parent
|
||||||
);
|
);
|
||||||
|
@ -310,17 +310,16 @@ void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
|
||||||
this->nodes.remove(*node);
|
this->nodes.remove(*node);
|
||||||
if (expand_actor != nullptr) expand_actor->recalcSizePosRecursive();
|
if (expand_actor != nullptr) expand_actor->recalcSizePosRecursive();
|
||||||
|
|
||||||
auto& group = parent->data.as_group;
|
|
||||||
|
|
||||||
if (parent != nullptr) {
|
if (parent != nullptr) {
|
||||||
|
auto& group = parent->data.as_group();
|
||||||
parent->recalcSizePosRecursive();
|
parent->recalcSizePosRecursive();
|
||||||
|
|
||||||
// returns if a given node is a group that can be collapsed given the current config
|
// returns if a given node is a group that can be collapsed given the current config
|
||||||
auto node_is_collapsible = [](Hy3Node* node) {
|
auto node_is_collapsible = [](Hy3Node* node) {
|
||||||
if (node->data.type != Hy3NodeType::Group) return false;
|
if (node->data.is_window()) return false;
|
||||||
if (*node_collapse_policy == 0) return true;
|
if (*node_collapse_policy == 0) return true;
|
||||||
else if (*node_collapse_policy == 1) return false;
|
else if (*node_collapse_policy == 1) return false;
|
||||||
return node->parent->data.as_group.layout != Hy3GroupLayout::Tabbed;
|
return node->parent->data.as_group().layout != Hy3GroupLayout::Tabbed;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (group.children.size() == 1
|
if (group.children.size() == 1
|
||||||
|
@ -337,14 +336,14 @@ void Hy3Layout::onWindowRemovedTiling(CWindow* window) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::onWindowFocusChange(CWindow* window) {
|
void Hy3Layout::onWindowFocusChange(PHLWINDOW window) {
|
||||||
auto* node = this->getNodeFromWindow(window);
|
auto* node = this->getNodeFromWindow(window);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
|
|
||||||
hy3_log(
|
hy3_log(
|
||||||
TRACE,
|
TRACE,
|
||||||
"changing window focus to window {:x} as node {:x}",
|
"changing window focus to window {:x} as node {:x}",
|
||||||
(uintptr_t) window,
|
(uintptr_t) window.get(),
|
||||||
(uintptr_t) node
|
(uintptr_t) node
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -353,7 +352,7 @@ void Hy3Layout::onWindowFocusChange(CWindow* window) {
|
||||||
node->recalcSizePosRecursive();
|
node->recalcSizePosRecursive();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hy3Layout::isWindowTiled(CWindow* window) {
|
bool Hy3Layout::isWindowTiled(PHLWINDOW window) {
|
||||||
return this->getNodeFromWindow(window) != nullptr;
|
return this->getNodeFromWindow(window) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +385,7 @@ void Hy3Layout::recalculateMonitor(const int& monitor_id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::recalculateWindow(CWindow* window) {
|
void Hy3Layout::recalculateWindow(PHLWINDOW window) {
|
||||||
auto* node = this->getNodeFromWindow(window);
|
auto* node = this->getNodeFromWindow(window);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
node->recalcSizePosRecursive();
|
node->recalcSizePosRecursive();
|
||||||
|
@ -402,9 +401,9 @@ ShiftDirection reverse(ShiftDirection direction) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CWindow* pWindow) {
|
void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, PHLWINDOW pWindow) {
|
||||||
auto window = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
|
auto window = pWindow ? pWindow : g_pCompositor->m_pLastWindow.lock();
|
||||||
if (!g_pCompositor->windowValidMapped(window)) return;
|
if (!valid(window)) return;
|
||||||
|
|
||||||
auto* node = this->getNodeFromWindow(window);
|
auto* node = this->getNodeFromWindow(window);
|
||||||
|
|
||||||
|
@ -427,9 +426,9 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW
|
||||||
);
|
);
|
||||||
|
|
||||||
Vector2D resize_delta = delta;
|
Vector2D resize_delta = delta;
|
||||||
bool node_is_root = (node->data.type == Hy3NodeType::Group && node->parent == nullptr)
|
bool node_is_root =
|
||||||
|| (node->data.type == Hy3NodeType::Window
|
(node->data.is_group() && node->parent == nullptr)
|
||||||
&& (node->parent == nullptr || node->parent->parent == nullptr));
|
|| (node->data.is_window() && (node->parent == nullptr || node->parent->parent == nullptr));
|
||||||
|
|
||||||
if (node_is_root) {
|
if (node_is_root) {
|
||||||
if (display_left && display_right) resize_delta.x = 0;
|
if (display_left && display_right) resize_delta.x = 0;
|
||||||
|
@ -490,11 +489,10 @@ void Hy3Layout::resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CW
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::fullscreenRequestForWindow(
|
void Hy3Layout::fullscreenRequestForWindow(
|
||||||
CWindow* window,
|
PHLWINDOW window,
|
||||||
eFullscreenMode fullscreen_mode,
|
eFullscreenMode fullscreen_mode,
|
||||||
bool on
|
bool on
|
||||||
) {
|
) {
|
||||||
if (!g_pCompositor->windowValidMapped(window)) return;
|
|
||||||
if (on == window->m_bIsFullscreen || window->m_pWorkspace->m_bIsSpecialWorkspace) return;
|
if (on == window->m_bIsFullscreen || window->m_pWorkspace->m_bIsSpecialWorkspace) return;
|
||||||
|
|
||||||
const auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID);
|
const auto monitor = g_pCompositor->getMonitorFromID(window->m_iMonitorID);
|
||||||
|
@ -575,7 +573,7 @@ std::any Hy3Layout::layoutMessage(SLayoutMessageHeader header, std::string conte
|
||||||
if (content == "togglesplit") {
|
if (content == "togglesplit") {
|
||||||
auto* node = this->getNodeFromWindow(header.pWindow);
|
auto* node = this->getNodeFromWindow(header.pWindow);
|
||||||
if (node != nullptr && node->parent != nullptr) {
|
if (node != nullptr && node->parent != nullptr) {
|
||||||
auto& layout = node->parent->data.as_group.layout;
|
auto& layout = node->parent->data.as_group().layout;
|
||||||
|
|
||||||
switch (layout) {
|
switch (layout) {
|
||||||
case Hy3GroupLayout::SplitH:
|
case Hy3GroupLayout::SplitH:
|
||||||
|
@ -594,13 +592,13 @@ std::any Hy3Layout::layoutMessage(SLayoutMessageHeader header, std::string conte
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
SWindowRenderLayoutHints Hy3Layout::requestRenderHints(CWindow* window) { return {}; }
|
SWindowRenderLayoutHints Hy3Layout::requestRenderHints(PHLWINDOW window) { return {}; }
|
||||||
|
|
||||||
void Hy3Layout::switchWindows(CWindow* pWindowA, CWindow* pWindowB) {
|
void Hy3Layout::switchWindows(PHLWINDOW pWindowA, PHLWINDOW pWindowB) {
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::moveWindowTo(CWindow* window, const std::string& direction, bool silent) {
|
void Hy3Layout::moveWindowTo(PHLWINDOW window, const std::string& direction, bool silent) {
|
||||||
// todo: support silent
|
// todo: support silent
|
||||||
auto* node = this->getNodeFromWindow(window);
|
auto* node = this->getNodeFromWindow(window);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
|
@ -615,13 +613,13 @@ void Hy3Layout::moveWindowTo(CWindow* window, const std::string& direction, bool
|
||||||
this->shiftNode(*node, shift, false, false);
|
this->shiftNode(*node, shift, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::alterSplitRatio(CWindow* pWindow, float delta, bool exact) {
|
void Hy3Layout::alterSplitRatio(PHLWINDOW pWindow, float delta, bool exact) {
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Hy3Layout::getLayoutName() { return "hy3"; }
|
std::string Hy3Layout::getLayoutName() { return "hy3"; }
|
||||||
|
|
||||||
CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) {
|
PHLWINDOW Hy3Layout::getNextWindowCandidate(PHLWINDOW window) {
|
||||||
if (window->m_pWorkspace->m_bHasFullscreenWindow) {
|
if (window->m_pWorkspace->m_bHasFullscreenWindow) {
|
||||||
return g_pCompositor->getFullscreenWindowOnWorkspace(window->m_pWorkspace->m_iID);
|
return g_pCompositor->getFullscreenWindowOnWorkspace(window->m_pWorkspace->m_iID);
|
||||||
}
|
}
|
||||||
|
@ -631,9 +629,9 @@ CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) {
|
||||||
for (auto& w: g_pCompositor->m_vWindows | std::views::reverse) {
|
for (auto& w: g_pCompositor->m_vWindows | std::views::reverse) {
|
||||||
if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2
|
if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2
|
||||||
&& w->m_pWorkspace == window->m_pWorkspace && !w->m_bX11ShouldntFocus
|
&& w->m_pWorkspace == window->m_pWorkspace && !w->m_bX11ShouldntFocus
|
||||||
&& !w->m_sAdditionalConfigData.noFocus && w.get() != window)
|
&& !w->m_sAdditionalConfigData.noFocus && w != window)
|
||||||
{
|
{
|
||||||
return w.get();
|
return w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,26 +639,26 @@ CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) {
|
||||||
auto* node = this->getWorkspaceFocusedNode(window->m_pWorkspace, true);
|
auto* node = this->getWorkspaceFocusedNode(window->m_pWorkspace, true);
|
||||||
if (node == nullptr) return nullptr;
|
if (node == nullptr) return nullptr;
|
||||||
|
|
||||||
switch (node->data.type) {
|
if (node->data.is_window()) {
|
||||||
case Hy3NodeType::Window: return node->data.as_window;
|
return node->data.as_window();
|
||||||
case Hy3NodeType::Group: return nullptr;
|
} else {
|
||||||
default: return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::replaceWindowDataWith(CWindow* from, CWindow* to) {
|
void Hy3Layout::replaceWindowDataWith(PHLWINDOW from, PHLWINDOW to) {
|
||||||
auto* node = this->getNodeFromWindow(from);
|
auto* node = this->getNodeFromWindow(from);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
|
|
||||||
node->data.as_window = to;
|
node->data.as_window() = to;
|
||||||
this->applyNodeDataToWindow(node);
|
this->applyNodeDataToWindow(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hy3Layout::isWindowReachable(CWindow* window) {
|
bool Hy3Layout::isWindowReachable(PHLWINDOW window) {
|
||||||
return this->getNodeFromWindow(window) != nullptr || IHyprLayout::isWindowReachable(window);
|
return this->getNodeFromWindow(window) != nullptr || IHyprLayout::isWindowReachable(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::bringWindowToTop(CWindow* window) {
|
void Hy3Layout::bringWindowToTop(PHLWINDOW window) {
|
||||||
auto node = this->getNodeFromWindow(window);
|
auto node = this->getNodeFromWindow(window);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
node->bringToTop();
|
node->bringToTop();
|
||||||
|
@ -671,12 +669,17 @@ void Hy3Layout::onEnable() {
|
||||||
if (window->isHidden() || !window->m_bIsMapped || window->m_bFadingOut || window->m_bIsFloating)
|
if (window->isHidden() || !window->m_bIsMapped || window->m_bFadingOut || window->m_bIsFloating)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
this->onWindowCreatedTiling(window.get());
|
this->onWindowCreatedTiling(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHookPtr = HyprlandAPI::registerCallbackDynamic(PHANDLE, "render", &Hy3Layout::renderHook);
|
renderHookPtr = HyprlandAPI::registerCallbackDynamic(PHANDLE, "render", &Hy3Layout::renderHook);
|
||||||
windowTitleHookPtr = HyprlandAPI::registerCallbackDynamic(PHANDLE, "windowTitle", &Hy3Layout::windowGroupUpdateRecursiveHook);
|
windowTitleHookPtr = HyprlandAPI::registerCallbackDynamic(
|
||||||
urgentHookPtr = HyprlandAPI::registerCallbackDynamic(PHANDLE, "urgent", &Hy3Layout::windowGroupUrgentHook);
|
PHANDLE,
|
||||||
|
"windowTitle",
|
||||||
|
&Hy3Layout::windowGroupUpdateRecursiveHook
|
||||||
|
);
|
||||||
|
urgentHookPtr =
|
||||||
|
HyprlandAPI::registerCallbackDynamic(PHANDLE, "urgent", &Hy3Layout::windowGroupUrgentHook);
|
||||||
tickHookPtr = HyprlandAPI::registerCallbackDynamic(PHANDLE, "tick", &Hy3Layout::tickHook);
|
tickHookPtr = HyprlandAPI::registerCallbackDynamic(PHANDLE, "tick", &Hy3Layout::tickHook);
|
||||||
selection_hook::enable();
|
selection_hook::enable();
|
||||||
}
|
}
|
||||||
|
@ -689,8 +692,8 @@ void Hy3Layout::onDisable() {
|
||||||
selection_hook::disable();
|
selection_hook::disable();
|
||||||
|
|
||||||
for (auto& node: this->nodes) {
|
for (auto& node: this->nodes) {
|
||||||
if (node.data.type == Hy3NodeType::Window) {
|
if (node.data.is_window()) {
|
||||||
node.data.as_window->setHidden(false);
|
node.data.as_window()->setHidden(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,7 +760,7 @@ void Hy3Layout::makeGroupOn(
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
|
|
||||||
if (node->parent != nullptr) {
|
if (node->parent != nullptr) {
|
||||||
auto& group = node->parent->data.as_group;
|
auto& group = node->parent->data.as_group();
|
||||||
if (group.children.size() == 1) {
|
if (group.children.size() == 1) {
|
||||||
group.setLayout(layout);
|
group.setLayout(layout);
|
||||||
group.setEphemeral(ephemeral);
|
group.setEphemeral(ephemeral);
|
||||||
|
@ -778,7 +781,7 @@ void Hy3Layout::makeOppositeGroupOn(Hy3Node* node, GroupEphemeralityOption ephem
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& group = node->parent->data.as_group;
|
auto& group = node->parent->data.as_group();
|
||||||
auto layout =
|
auto layout =
|
||||||
group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH;
|
group.layout == Hy3GroupLayout::SplitH ? Hy3GroupLayout::SplitV : Hy3GroupLayout::SplitH;
|
||||||
|
|
||||||
|
@ -798,7 +801,7 @@ void Hy3Layout::changeGroupOn(Hy3Node& node, Hy3GroupLayout layout) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& group = node.parent->data.as_group;
|
auto& group = node.parent->data.as_group();
|
||||||
group.setLayout(layout);
|
group.setLayout(layout);
|
||||||
node.parent->updateTabBarRecursive();
|
node.parent->updateTabBarRecursive();
|
||||||
node.parent->recalcSizePosRecursive();
|
node.parent->recalcSizePosRecursive();
|
||||||
|
@ -807,7 +810,7 @@ void Hy3Layout::changeGroupOn(Hy3Node& node, Hy3GroupLayout layout) {
|
||||||
void Hy3Layout::untabGroupOn(Hy3Node& node) {
|
void Hy3Layout::untabGroupOn(Hy3Node& node) {
|
||||||
if (node.parent == nullptr) return;
|
if (node.parent == nullptr) return;
|
||||||
|
|
||||||
auto& group = node.parent->data.as_group;
|
auto& group = node.parent->data.as_group();
|
||||||
if (group.layout != Hy3GroupLayout::Tabbed) return;
|
if (group.layout != Hy3GroupLayout::Tabbed) return;
|
||||||
|
|
||||||
changeGroupOn(node, group.previous_nontab_layout);
|
changeGroupOn(node, group.previous_nontab_layout);
|
||||||
|
@ -816,7 +819,7 @@ void Hy3Layout::untabGroupOn(Hy3Node& node) {
|
||||||
void Hy3Layout::toggleTabGroupOn(Hy3Node& node) {
|
void Hy3Layout::toggleTabGroupOn(Hy3Node& node) {
|
||||||
if (node.parent == nullptr) return;
|
if (node.parent == nullptr) return;
|
||||||
|
|
||||||
auto& group = node.parent->data.as_group;
|
auto& group = node.parent->data.as_group();
|
||||||
if (group.layout != Hy3GroupLayout::Tabbed) changeGroupOn(node, Hy3GroupLayout::Tabbed);
|
if (group.layout != Hy3GroupLayout::Tabbed) changeGroupOn(node, Hy3GroupLayout::Tabbed);
|
||||||
else changeGroupOn(node, group.previous_nontab_layout);
|
else changeGroupOn(node, group.previous_nontab_layout);
|
||||||
}
|
}
|
||||||
|
@ -824,7 +827,7 @@ void Hy3Layout::toggleTabGroupOn(Hy3Node& node) {
|
||||||
void Hy3Layout::changeGroupToOppositeOn(Hy3Node& node) {
|
void Hy3Layout::changeGroupToOppositeOn(Hy3Node& node) {
|
||||||
if (node.parent == nullptr) return;
|
if (node.parent == nullptr) return;
|
||||||
|
|
||||||
auto& group = node.parent->data.as_group;
|
auto& group = node.parent->data.as_group();
|
||||||
|
|
||||||
if (group.layout == Hy3GroupLayout::Tabbed) {
|
if (group.layout == Hy3GroupLayout::Tabbed) {
|
||||||
group.setLayout(group.previous_nontab_layout);
|
group.setLayout(group.previous_nontab_layout);
|
||||||
|
@ -840,16 +843,16 @@ void Hy3Layout::changeGroupToOppositeOn(Hy3Node& node) {
|
||||||
void Hy3Layout::changeGroupEphemeralityOn(Hy3Node& node, bool ephemeral) {
|
void Hy3Layout::changeGroupEphemeralityOn(Hy3Node& node, bool ephemeral) {
|
||||||
if (node.parent == nullptr) return;
|
if (node.parent == nullptr) return;
|
||||||
|
|
||||||
auto& group = node.parent->data.as_group;
|
auto& group = node.parent->data.as_group();
|
||||||
group.setEphemeral(
|
group.setEphemeral(
|
||||||
ephemeral ? GroupEphemeralityOption::ForceEphemeral : GroupEphemeralityOption::Standard
|
ephemeral ? GroupEphemeralityOption::ForceEphemeral : GroupEphemeralityOption::Standard
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::shiftNode(Hy3Node& node, ShiftDirection direction, bool once, bool visible) {
|
void Hy3Layout::shiftNode(Hy3Node& node, ShiftDirection direction, bool once, bool visible) {
|
||||||
if (once && node.parent != nullptr && node.parent->data.as_group.children.size() == 1) {
|
if (once && node.parent != nullptr && node.parent->data.as_group().children.size() == 1) {
|
||||||
if (node.parent->parent == nullptr) {
|
if (node.parent->parent == nullptr) {
|
||||||
node.parent->data.as_group.setLayout(Hy3GroupLayout::SplitH);
|
node.parent->data.as_group().setLayout(Hy3GroupLayout::SplitH);
|
||||||
node.parent->recalcSizePosRecursive();
|
node.parent->recalcSizePosRecursive();
|
||||||
} else {
|
} else {
|
||||||
auto* node2 = node.parent;
|
auto* node2 = node.parent;
|
||||||
|
@ -876,13 +879,13 @@ void Hy3Layout::shiftWindow(
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::shiftFocus(const PHLWORKSPACE& workspace, ShiftDirection direction, bool visible) {
|
void Hy3Layout::shiftFocus(const PHLWORKSPACE& workspace, ShiftDirection direction, bool visible) {
|
||||||
auto* current_window = g_pCompositor->m_pLastWindow;
|
auto current_window = g_pCompositor->m_pLastWindow.lock();
|
||||||
|
|
||||||
if (current_window != nullptr) {
|
if (current_window != nullptr) {
|
||||||
if (current_window->m_pWorkspace->m_bHasFullscreenWindow) return;
|
if (current_window->m_pWorkspace->m_bHasFullscreenWindow) return;
|
||||||
|
|
||||||
if (current_window->m_bIsFloating) {
|
if (current_window->m_bIsFloating) {
|
||||||
auto* next_window = g_pCompositor->getWindowInDirection(
|
auto next_window = g_pCompositor->getWindowInDirection(
|
||||||
current_window,
|
current_window,
|
||||||
direction == ShiftDirection::Left ? 'l'
|
direction == ShiftDirection::Left ? 'l'
|
||||||
: direction == ShiftDirection::Up ? 'u'
|
: direction == ShiftDirection::Up ? 'u'
|
||||||
|
@ -910,13 +913,13 @@ void Hy3Layout::shiftFocus(const PHLWORKSPACE& workspace, ShiftDirection directi
|
||||||
void changeNodeWorkspaceRecursive(Hy3Node& node, const PHLWORKSPACE& workspace) {
|
void changeNodeWorkspaceRecursive(Hy3Node& node, const PHLWORKSPACE& workspace) {
|
||||||
node.workspace = workspace;
|
node.workspace = workspace;
|
||||||
|
|
||||||
if (node.data.type == Hy3NodeType::Window) {
|
if (node.data.is_window()) {
|
||||||
auto* window = node.data.as_window;
|
auto window = node.data.as_window();
|
||||||
window->moveToWorkspace(workspace);
|
window->moveToWorkspace(workspace);
|
||||||
window->updateToplevel();
|
window->updateToplevel();
|
||||||
window->updateDynamicRules();
|
window->updateDynamicRules();
|
||||||
} else {
|
} else {
|
||||||
for (auto* child: node.data.as_group.children) {
|
for (auto* child: node.data.as_group().children) {
|
||||||
changeNodeWorkspaceRecursive(*child, workspace);
|
changeNodeWorkspaceRecursive(*child, workspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -936,7 +939,7 @@ void Hy3Layout::moveNodeToWorkspace(const PHLWORKSPACE& origin, std::string wsna
|
||||||
if (origin == workspace) return;
|
if (origin == workspace) return;
|
||||||
|
|
||||||
auto* node = this->getWorkspaceFocusedNode(origin);
|
auto* node = this->getWorkspaceFocusedNode(origin);
|
||||||
auto* focused_window = g_pCompositor->m_pLastWindow;
|
auto focused_window = g_pCompositor->m_pLastWindow.lock();
|
||||||
auto* focused_window_node = this->getNodeFromWindow(focused_window);
|
auto* focused_window_node = this->getNodeFromWindow(focused_window);
|
||||||
|
|
||||||
auto origin_ws = node != nullptr ? node->workspace
|
auto origin_ws = node != nullptr ? node->workspace
|
||||||
|
@ -1013,14 +1016,14 @@ void Hy3Layout::changeFocus(const PHLWORKSPACE& workspace, FocusShift shift) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case FocusShift::Lower:
|
case FocusShift::Lower:
|
||||||
if (node->data.type == Hy3NodeType::Group && node->data.as_group.focused_child != nullptr)
|
if (node->data.is_group() && node->data.as_group().focused_child != nullptr)
|
||||||
node->data.as_group.focused_child->focus();
|
node->data.as_group().focused_child->focus();
|
||||||
return;
|
return;
|
||||||
case FocusShift::Tab:
|
case FocusShift::Tab:
|
||||||
// make sure we go up at least one level
|
// make sure we go up at least one level
|
||||||
if (node->parent != nullptr) node = node->parent;
|
if (node->parent != nullptr) node = node->parent;
|
||||||
while (node->parent != nullptr) {
|
while (node->parent != nullptr) {
|
||||||
if (node->data.as_group.layout == Hy3GroupLayout::Tabbed) {
|
if (node->data.as_group().layout == Hy3GroupLayout::Tabbed) {
|
||||||
node->focus();
|
node->focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1032,7 +1035,7 @@ void Hy3Layout::changeFocus(const PHLWORKSPACE& workspace, FocusShift shift) {
|
||||||
// make sure we go up at least one level
|
// make sure we go up at least one level
|
||||||
if (node->parent != nullptr) node = node->parent;
|
if (node->parent != nullptr) node = node->parent;
|
||||||
while (node->parent != nullptr) {
|
while (node->parent != nullptr) {
|
||||||
if (node->parent->data.as_group.layout == Hy3GroupLayout::Tabbed) {
|
if (node->parent->data.as_group().layout == Hy3GroupLayout::Tabbed) {
|
||||||
node->focus();
|
node->focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1043,8 +1046,8 @@ void Hy3Layout::changeFocus(const PHLWORKSPACE& workspace, FocusShift shift) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bottom:
|
bottom:
|
||||||
while (node->data.type == Hy3NodeType::Group && node->data.as_group.focused_child != nullptr) {
|
while (node->data.is_group() && node->data.as_group().focused_child != nullptr) {
|
||||||
node = node->data.as_group.focused_child;
|
node = node->data.as_group().focused_child;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->focus();
|
node->focus();
|
||||||
|
@ -1067,19 +1070,19 @@ Hy3Node* findTabBarAt(Hy3Node& node, Vector2D pos, Hy3Node** focused_node) {
|
||||||
inset += gaps_in->left;
|
inset += gaps_in->left;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.data.type == Hy3NodeType::Group) {
|
if (node.data.is_group()) {
|
||||||
if (node.hidden) return nullptr;
|
if (node.hidden) return nullptr;
|
||||||
// note: tab bar clicks ignore animations
|
// note: tab bar clicks ignore animations
|
||||||
if (node.position.x > pos.x || node.position.y > pos.y || node.position.x + node.size.x < pos.x
|
if (node.position.x > pos.x || node.position.y > pos.y || node.position.x + node.size.x < pos.x
|
||||||
|| node.position.y + node.size.y < pos.y)
|
|| node.position.y + node.size.y < pos.y)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (node.data.as_group.layout == Hy3GroupLayout::Tabbed
|
auto& group = node.data.as_group();
|
||||||
&& node.data.as_group.tab_bar != nullptr)
|
|
||||||
{
|
if (group.layout == Hy3GroupLayout::Tabbed && node.data.as_group().tab_bar != nullptr) {
|
||||||
if (pos.y < node.position.y + node.gap_topleft_offset.y + inset) {
|
if (pos.y < node.position.y + node.gap_topleft_offset.y + inset) {
|
||||||
auto& children = node.data.as_group.children;
|
auto& children = group.children;
|
||||||
auto& tab_bar = *node.data.as_group.tab_bar;
|
auto& tab_bar = *group.tab_bar;
|
||||||
|
|
||||||
auto size = tab_bar.size.value();
|
auto size = tab_bar.size.value();
|
||||||
auto x = pos.x - tab_bar.pos.value().x;
|
auto x = pos.x - tab_bar.pos.value().x;
|
||||||
|
@ -1099,11 +1102,11 @@ Hy3Node* findTabBarAt(Hy3Node& node, Vector2D pos, Hy3Node** focused_node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.data.as_group.focused_child != nullptr) {
|
if (group.focused_child != nullptr) {
|
||||||
return findTabBarAt(*node.data.as_group.focused_child, pos, focused_node);
|
return findTabBarAt(*group.focused_child, pos, focused_node);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto child: node.data.as_group.children) {
|
for (auto child: group.children) {
|
||||||
if (findTabBarAt(*child, pos, focused_node)) return child;
|
if (findTabBarAt(*child, pos, focused_node)) return child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1144,22 +1147,21 @@ void Hy3Layout::focusTab(
|
||||||
tab_node = this->getWorkspaceFocusedNode(workspace);
|
tab_node = this->getWorkspaceFocusedNode(workspace);
|
||||||
if (tab_node == nullptr) return;
|
if (tab_node == nullptr) return;
|
||||||
|
|
||||||
while (tab_node != nullptr && tab_node->data.as_group.layout != Hy3GroupLayout::Tabbed
|
while (tab_node != nullptr && tab_node->data.as_group().layout != Hy3GroupLayout::Tabbed
|
||||||
&& tab_node->parent != nullptr)
|
&& tab_node->parent != nullptr)
|
||||||
tab_node = tab_node->parent;
|
tab_node = tab_node->parent;
|
||||||
|
|
||||||
if (tab_node == nullptr || tab_node->data.type != Hy3NodeType::Group
|
if (tab_node == nullptr || tab_node->data.is_window()
|
||||||
|| tab_node->data.as_group.layout != Hy3GroupLayout::Tabbed)
|
|| tab_node->data.as_group().layout != Hy3GroupLayout::Tabbed)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hastab:
|
hastab:
|
||||||
if (target != TabFocus::MouseLocation) {
|
if (target != TabFocus::MouseLocation) {
|
||||||
if (tab_node->data.as_group.focused_child == nullptr
|
auto& group = tab_node->data.as_group();
|
||||||
|| tab_node->data.as_group.children.size() < 2)
|
if (group.focused_child == nullptr || group.children.size() < 2) return;
|
||||||
return;
|
|
||||||
|
|
||||||
auto& children = tab_node->data.as_group.children;
|
auto& children = group.children;
|
||||||
if (target == TabFocus::Index) {
|
if (target == TabFocus::Index) {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
|
@ -1175,8 +1177,7 @@ hastab:
|
||||||
return;
|
return;
|
||||||
cont:;
|
cont:;
|
||||||
} else {
|
} else {
|
||||||
auto node_iter =
|
auto node_iter = std::find(children.begin(), children.end(), group.focused_child);
|
||||||
std::find(children.begin(), children.end(), tab_node->data.as_group.focused_child);
|
|
||||||
if (node_iter == children.end()) return;
|
if (node_iter == children.end()) return;
|
||||||
if (target == TabFocus::Left) {
|
if (target == TabFocus::Left) {
|
||||||
if (node_iter == children.begin()) {
|
if (node_iter == children.begin()) {
|
||||||
|
@ -1197,9 +1198,9 @@ hastab:
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* focus = tab_focused_node;
|
auto* focus = tab_focused_node;
|
||||||
while (focus->data.type == Hy3NodeType::Group && !focus->data.as_group.group_focused
|
while (focus->data.is_group() && !focus->data.as_group().group_focused
|
||||||
&& focus->data.as_group.focused_child != nullptr)
|
&& focus->data.as_group().focused_child != nullptr)
|
||||||
focus = focus->data.as_group.focused_child;
|
focus = focus->data.as_group().focused_child;
|
||||||
|
|
||||||
focus->focus();
|
focus->focus();
|
||||||
tab_node->recalcSizePosRecursive();
|
tab_node->recalcSizePosRecursive();
|
||||||
|
@ -1209,7 +1210,7 @@ void Hy3Layout::setNodeSwallow(const PHLWORKSPACE& workspace, SetSwallowOption o
|
||||||
auto* node = this->getWorkspaceFocusedNode(workspace);
|
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||||
if (node == nullptr || node->parent == nullptr) return;
|
if (node == nullptr || node->parent == nullptr) return;
|
||||||
|
|
||||||
auto* containment = &node->parent->data.as_group.containment;
|
auto* containment = &node->parent->data.as_group().containment;
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case SetSwallowOption::NoSwallow: *containment = false; break;
|
case SetSwallowOption::NoSwallow: *containment = false; break;
|
||||||
case SetSwallowOption::Swallow: *containment = true; break;
|
case SetSwallowOption::Swallow: *containment = true; break;
|
||||||
|
@ -1218,16 +1219,17 @@ void Hy3Layout::setNodeSwallow(const PHLWORKSPACE& workspace, SetSwallowOption o
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::killFocusedNode(const PHLWORKSPACE& workspace) {
|
void Hy3Layout::killFocusedNode(const PHLWORKSPACE& workspace) {
|
||||||
if (g_pCompositor->m_pLastWindow != nullptr && g_pCompositor->m_pLastWindow->m_bIsFloating) {
|
auto last_window = g_pCompositor->m_pLastWindow.lock();
|
||||||
g_pCompositor->closeWindow(g_pCompositor->m_pLastWindow);
|
if (last_window != nullptr && last_window->m_bIsFloating) {
|
||||||
|
g_pCompositor->closeWindow(last_window);
|
||||||
} else {
|
} else {
|
||||||
auto* node = this->getWorkspaceFocusedNode(workspace);
|
auto* node = this->getWorkspaceFocusedNode(workspace);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
|
|
||||||
std::vector<CWindow*> windows;
|
std::vector<PHLWINDOW> windows;
|
||||||
node->appendAllWindows(windows);
|
node->appendAllWindows(windows);
|
||||||
|
|
||||||
for (auto* window: windows) {
|
for (auto& window: windows) {
|
||||||
window->setHidden(false);
|
window->setHidden(false);
|
||||||
g_pCompositor->closeWindow(window);
|
g_pCompositor->closeWindow(window);
|
||||||
}
|
}
|
||||||
|
@ -1241,6 +1243,7 @@ void Hy3Layout::expand(
|
||||||
) {
|
) {
|
||||||
auto* node = this->getWorkspaceFocusedNode(workspace, false, true);
|
auto* node = this->getWorkspaceFocusedNode(workspace, false, true);
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
|
PHLWINDOW window;
|
||||||
|
|
||||||
const auto monitor = g_pCompositor->getMonitorFromID(workspace->m_iMonitorID);
|
const auto monitor = g_pCompositor->getMonitorFromID(workspace->m_iMonitorID);
|
||||||
|
|
||||||
|
@ -1254,10 +1257,10 @@ void Hy3Layout::expand(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->data.type == Hy3NodeType::Group && !node->data.as_group.group_focused)
|
if (node->data.is_group() && !node->data.as_group().group_focused)
|
||||||
node->data.as_group.expand_focused = ExpandFocusType::Stack;
|
node->data.as_group().expand_focused = ExpandFocusType::Stack;
|
||||||
|
|
||||||
auto& group = node->parent->data.as_group;
|
auto& group = node->parent->data.as_group();
|
||||||
group.focused_child = node;
|
group.focused_child = node;
|
||||||
group.expand_focused = ExpandFocusType::Latch;
|
group.expand_focused = ExpandFocusType::Latch;
|
||||||
|
|
||||||
|
@ -1272,19 +1275,19 @@ void Hy3Layout::expand(
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case ExpandOption::Shrink:
|
case ExpandOption::Shrink:
|
||||||
if (node->data.type == Hy3NodeType::Group) {
|
if (node->data.is_group()) {
|
||||||
auto& group = node->data.as_group;
|
auto& group = node->data.as_group();
|
||||||
|
|
||||||
group.expand_focused = ExpandFocusType::NotExpanded;
|
group.expand_focused = ExpandFocusType::NotExpanded;
|
||||||
if (group.focused_child->data.type == Hy3NodeType::Group)
|
if (group.focused_child->data.is_group())
|
||||||
group.focused_child->data.as_group.expand_focused = ExpandFocusType::Latch;
|
group.focused_child->data.as_group().expand_focused = ExpandFocusType::Latch;
|
||||||
|
|
||||||
node->recalcSizePosRecursive();
|
node->recalcSizePosRecursive();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ExpandOption::Base: {
|
case ExpandOption::Base: {
|
||||||
if (node->data.type == Hy3NodeType::Group) {
|
if (node->data.is_group()) {
|
||||||
node->data.as_group.collapseExpansions();
|
node->data.as_group().collapseExpansions();
|
||||||
node->recalcSizePosRecursive();
|
node->recalcSizePosRecursive();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1295,10 +1298,9 @@ void Hy3Layout::expand(
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CWindow* window;
|
|
||||||
fullscreen:
|
fullscreen:
|
||||||
if (node->data.type != Hy3NodeType::Window) return;
|
if (node->data.is_group()) return;
|
||||||
window = node->data.as_window;
|
window = node->data.as_window();
|
||||||
if (!window->m_bIsFullscreen || window->m_pWorkspace->m_bIsSpecialWorkspace) return;
|
if (!window->m_bIsFullscreen || window->m_pWorkspace->m_bIsSpecialWorkspace) return;
|
||||||
|
|
||||||
if (workspace->m_bHasFullscreenWindow) return;
|
if (workspace->m_bHasFullscreenWindow) return;
|
||||||
|
@ -1322,31 +1324,30 @@ fsupdate:
|
||||||
this->recalculateMonitor(monitor->ID);
|
this->recalculateMonitor(monitor->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hy3Layout::shouldRenderSelected(CWindow* window) {
|
bool Hy3Layout::shouldRenderSelected(const PHLWINDOW& window) {
|
||||||
if (window == nullptr) return false;
|
if (window == nullptr) return false;
|
||||||
auto* root = this->getWorkspaceRootGroup(window->m_pWorkspace);
|
auto* root = this->getWorkspaceRootGroup(window->m_pWorkspace);
|
||||||
if (root == nullptr || root->data.as_group.focused_child == nullptr) return false;
|
if (root == nullptr || root->data.as_group().focused_child == nullptr) return false;
|
||||||
auto* focused = root->getFocusedNode();
|
auto* focused = root->getFocusedNode();
|
||||||
if (focused == nullptr
|
if (focused == nullptr
|
||||||
|| (focused->data.type == Hy3NodeType::Window
|
|| (focused->data.is_window()
|
||||||
&& focused->data.as_window != g_pCompositor->m_pLastWindow))
|
&& focused->data.as_window() != g_pCompositor->m_pLastWindow.lock()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (focused->data.type) {
|
switch (focused->data.type()) {
|
||||||
case Hy3NodeType::Window: return focused->data.as_window == window;
|
case Hy3NodeType::Window: return focused->data.as_window() == window;
|
||||||
case Hy3NodeType::Group: {
|
case Hy3NodeType::Group: {
|
||||||
auto* node = this->getNodeFromWindow(window);
|
auto* node = this->getNodeFromWindow(window);
|
||||||
if (node == nullptr) return false;
|
if (node == nullptr) return false;
|
||||||
return focused->data.as_group.hasChild(node);
|
return focused->data.as_group().hasChild(node);
|
||||||
}
|
}
|
||||||
default: return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node* Hy3Layout::getWorkspaceRootGroup(const PHLWORKSPACE& workspace) {
|
Hy3Node* Hy3Layout::getWorkspaceRootGroup(const PHLWORKSPACE& workspace) {
|
||||||
for (auto& node: this->nodes) {
|
for (auto& node: this->nodes) {
|
||||||
if (node.workspace == workspace && node.parent == nullptr
|
if (node.workspace == workspace && node.parent == nullptr && node.data.is_group()
|
||||||
&& node.data.type == Hy3NodeType::Group && !node.reparenting)
|
&& !node.reparenting)
|
||||||
{
|
{
|
||||||
return &node;
|
return &node;
|
||||||
}
|
}
|
||||||
|
@ -1380,7 +1381,7 @@ void Hy3Layout::renderHook(void*, SCallbackInfo&, std::any data) {
|
||||||
if (!rendering_normally) break;
|
if (!rendering_normally) break;
|
||||||
|
|
||||||
for (auto& entry: g_Hy3Layout->tab_groups) {
|
for (auto& entry: g_Hy3Layout->tab_groups) {
|
||||||
if (!entry.hidden && entry.target_window == g_pHyprOpenGL->m_pCurrentWindow
|
if (!entry.hidden && entry.target_window == g_pHyprOpenGL->m_pCurrentWindow.lock()
|
||||||
&& std::find(rendered_groups.begin(), rendered_groups.end(), &entry)
|
&& std::find(rendered_groups.begin(), rendered_groups.end(), &entry)
|
||||||
== rendered_groups.end())
|
== rendered_groups.end())
|
||||||
{
|
{
|
||||||
|
@ -1409,18 +1410,17 @@ void Hy3Layout::renderHook(void*, SCallbackInfo&, std::any data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::windowGroupUrgentHook(void* p, SCallbackInfo& callback_info, std::any data) {
|
void Hy3Layout::windowGroupUrgentHook(void* p, SCallbackInfo& callback_info, std::any data) {
|
||||||
CWindow* window = std::any_cast<CWindow*>(data);
|
auto window = std::any_cast<PHLWINDOW>(data);
|
||||||
if (window == nullptr) return;
|
if (window == nullptr) return;
|
||||||
window->m_bIsUrgent = true;
|
window->m_bIsUrgent = true;
|
||||||
Hy3Layout::windowGroupUpdateRecursiveHook(p, callback_info, data);
|
Hy3Layout::windowGroupUpdateRecursiveHook(p, callback_info, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::windowGroupUpdateRecursiveHook(void*, SCallbackInfo&, std::any data) {
|
void Hy3Layout::windowGroupUpdateRecursiveHook(void*, SCallbackInfo&, std::any data) {
|
||||||
CWindow* window = std::any_cast<CWindow*>(data);
|
auto window = std::any_cast<PHLWINDOW>(data);
|
||||||
if (window == nullptr) return;
|
if (window == nullptr) return;
|
||||||
auto* node = g_Hy3Layout->getNodeFromWindow(window);
|
auto* node = g_Hy3Layout->getNodeFromWindow(window);
|
||||||
|
|
||||||
// it is UB for `this` to be null
|
|
||||||
if (node == nullptr) return;
|
if (node == nullptr) return;
|
||||||
node->updateTabBarRecursive();
|
node->updateTabBarRecursive();
|
||||||
}
|
}
|
||||||
|
@ -1435,9 +1435,9 @@ void Hy3Layout::tickHook(void*, SCallbackInfo&, std::any) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node* Hy3Layout::getNodeFromWindow(CWindow* window) {
|
Hy3Node* Hy3Layout::getNodeFromWindow(const PHLWINDOW& window) {
|
||||||
for (auto& node: this->nodes) {
|
for (auto& node: this->nodes) {
|
||||||
if (node.data.type == Hy3NodeType::Window && node.data.as_window == window) {
|
if (node.data.is_window() && node.data.as_window() == window) {
|
||||||
return &node;
|
return &node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1446,8 +1446,8 @@ Hy3Node* Hy3Layout::getNodeFromWindow(CWindow* window) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) {
|
void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) {
|
||||||
if (node->data.type != Hy3NodeType::Window) return;
|
if (node->data.is_group()) return;
|
||||||
auto* window = node->data.as_window;
|
auto window = node->data.as_window();
|
||||||
auto root_node = this->getWorkspaceRootGroup(window->m_pWorkspace);
|
auto root_node = this->getWorkspaceRootGroup(window->m_pWorkspace);
|
||||||
|
|
||||||
CMonitor* monitor = nullptr;
|
CMonitor* monitor = nullptr;
|
||||||
|
@ -1480,13 +1480,13 @@ void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) {
|
||||||
static const auto no_gaps_when_only = ConfigValue<Hyprlang::INT>("plugin:hy3:no_gaps_when_only");
|
static const auto no_gaps_when_only = ConfigValue<Hyprlang::INT>("plugin:hy3:no_gaps_when_only");
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
if (!g_pCompositor->windowExists(window) || !window->m_bIsMapped) {
|
if (!valid(window) || !window->m_bIsMapped) {
|
||||||
hy3_log(
|
hy3_log(
|
||||||
ERR,
|
ERR,
|
||||||
"node {:x} is an unmapped window ({:x}), cannot apply node data, removing from tiled "
|
"node {:x} is an unmapped window ({:x}), cannot apply node data, removing from tiled "
|
||||||
"layout",
|
"layout",
|
||||||
(uintptr_t) node,
|
(uintptr_t) node,
|
||||||
(uintptr_t) window
|
(uintptr_t) window.get()
|
||||||
);
|
);
|
||||||
errorNotif();
|
errorNotif();
|
||||||
this->onWindowRemovedTiling(window);
|
this->onWindowRemovedTiling(window);
|
||||||
|
@ -1501,8 +1501,8 @@ void Hy3Layout::applyNodeDataToWindow(Hy3Node* node, bool no_animation) {
|
||||||
window->m_vSize = nodeBox.size();
|
window->m_vSize = nodeBox.size();
|
||||||
window->m_vPosition = nodeBox.pos();
|
window->m_vPosition = nodeBox.pos();
|
||||||
|
|
||||||
auto only_node = root_node != nullptr && root_node->data.as_group.children.size() == 1
|
auto only_node = root_node != nullptr && root_node->data.as_group().children.size() == 1
|
||||||
&& root_node->data.as_group.children.front()->data.type == Hy3NodeType::Window;
|
&& root_node->data.as_group().children.front()->data.is_window();
|
||||||
|
|
||||||
if (!window->m_pWorkspace->m_bIsSpecialWorkspace
|
if (!window->m_pWorkspace->m_bIsSpecialWorkspace
|
||||||
&& ((*no_gaps_when_only != 0 && (only_node || window->m_bIsFullscreen))
|
&& ((*no_gaps_when_only != 0 && (only_node || window->m_bIsFullscreen))
|
||||||
|
@ -1589,7 +1589,7 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
while (true) {
|
while (true) {
|
||||||
if (break_parent == nullptr) return nullptr;
|
if (break_parent == nullptr) return nullptr;
|
||||||
|
|
||||||
auto& group = break_parent->data.as_group; // must be a group in order to be a parent
|
auto& group = break_parent->data.as_group(); // must be a group in order to be a parent
|
||||||
|
|
||||||
if (shiftMatchesLayout(group.layout, direction)
|
if (shiftMatchesLayout(group.layout, direction)
|
||||||
&& (!visible || group.layout != Hy3GroupLayout::Tabbed))
|
&& (!visible || group.layout != Hy3GroupLayout::Tabbed))
|
||||||
|
@ -1636,9 +1636,10 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
|
|
||||||
auto* newChild = &this->nodes.back();
|
auto* newChild = &this->nodes.back();
|
||||||
Hy3Node::swapData(*break_parent, *newChild);
|
Hy3Node::swapData(*break_parent, *newChild);
|
||||||
break_parent->data.as_group.children.push_back(newChild);
|
auto& group = break_parent->data.as_group();
|
||||||
break_parent->data.as_group.group_focused = false;
|
group.children.push_back(newChild);
|
||||||
break_parent->data.as_group.focused_child = newChild;
|
group.group_focused = false;
|
||||||
|
group.focused_child = newChild;
|
||||||
break_origin = newChild;
|
break_origin = newChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1649,7 +1650,7 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& parent_group = break_parent->data.as_group;
|
auto& parent_group = break_parent->data.as_group();
|
||||||
Hy3Node* target_group = break_parent;
|
Hy3Node* target_group = break_parent;
|
||||||
std::list<Hy3Node*>::iterator insert;
|
std::list<Hy3Node*>::iterator insert;
|
||||||
|
|
||||||
|
@ -1660,15 +1661,15 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
if (!shift) return nullptr;
|
if (!shift) return nullptr;
|
||||||
insert = parent_group.children.end();
|
insert = parent_group.children.end();
|
||||||
} else {
|
} else {
|
||||||
auto& group_data = target_group->data.as_group;
|
auto& group_data = target_group->data.as_group();
|
||||||
|
|
||||||
auto iter = std::find(group_data.children.begin(), group_data.children.end(), break_origin);
|
auto iter = std::find(group_data.children.begin(), group_data.children.end(), break_origin);
|
||||||
if (shiftIsForward(direction)) iter = std::next(iter);
|
if (shiftIsForward(direction)) iter = std::next(iter);
|
||||||
else iter = std::prev(iter);
|
else iter = std::prev(iter);
|
||||||
|
|
||||||
if ((*iter)->data.type == Hy3NodeType::Window
|
if ((*iter)->data.is_window()
|
||||||
|| ((*iter)->data.type == Hy3NodeType::Group
|
|| ((*iter)->data.is_group()
|
||||||
&& (*iter)->data.as_group.expand_focused != ExpandFocusType::NotExpanded)
|
&& (*iter)->data.as_group().expand_focused != ExpandFocusType::NotExpanded)
|
||||||
|| (shift && once && has_broken_once))
|
|| (shift && once && has_broken_once))
|
||||||
{
|
{
|
||||||
if (shift) {
|
if (shift) {
|
||||||
|
@ -1684,7 +1685,7 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
// break into neighboring groups until we hit a window
|
// break into neighboring groups until we hit a window
|
||||||
while (true) {
|
while (true) {
|
||||||
target_group = *iter;
|
target_group = *iter;
|
||||||
auto& group_data = target_group->data.as_group;
|
auto& group_data = target_group->data.as_group();
|
||||||
|
|
||||||
if (group_data.children.empty()) return nullptr; // in theory this would never happen
|
if (group_data.children.empty()) return nullptr; // in theory this would never happen
|
||||||
|
|
||||||
|
@ -1735,9 +1736,9 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*iter)->data.type == Hy3NodeType::Window
|
if ((*iter)->data.is_window()
|
||||||
|| ((*iter)->data.type == Hy3NodeType::Group
|
|| ((*iter)->data.is_group()
|
||||||
&& (*iter)->data.as_group.expand_focused != ExpandFocusType::NotExpanded))
|
&& (*iter)->data.as_group().expand_focused != ExpandFocusType::NotExpanded))
|
||||||
{
|
{
|
||||||
if (shift) {
|
if (shift) {
|
||||||
if (shift_after) insert = std::next(iter);
|
if (shift_after) insert = std::next(iter);
|
||||||
|
@ -1751,18 +1752,19 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& group_data = target_group->data.as_group;
|
auto& group_data = target_group->data.as_group();
|
||||||
|
|
||||||
if (target_group == node.parent) {
|
if (target_group == node.parent) {
|
||||||
// nullptr is used as a signal value instead of removing it first to avoid
|
// nullptr is used as a signal value instead of removing it first to avoid
|
||||||
// iterator invalidation.
|
// iterator invalidation.
|
||||||
auto iter = std::find(group_data.children.begin(), group_data.children.end(), &node);
|
auto iter = std::find(group_data.children.begin(), group_data.children.end(), &node);
|
||||||
*iter = nullptr;
|
*iter = nullptr;
|
||||||
target_group->data.as_group.children.insert(insert, &node);
|
auto& group = target_group->data.as_group();
|
||||||
target_group->data.as_group.children.remove(nullptr);
|
group.children.insert(insert, &node);
|
||||||
|
group.children.remove(nullptr);
|
||||||
target_group->recalcSizePosRecursive();
|
target_group->recalcSizePosRecursive();
|
||||||
} else {
|
} else {
|
||||||
target_group->data.as_group.children.insert(insert, &node);
|
target_group->data.as_group().children.insert(insert, &node);
|
||||||
|
|
||||||
// must happen AFTER `insert` is used
|
// must happen AFTER `insert` is used
|
||||||
auto* old_parent = node.removeFromParentRecursive(nullptr);
|
auto* old_parent = node.removeFromParentRecursive(nullptr);
|
||||||
|
@ -1770,7 +1772,7 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
||||||
node.size_ratio = 1.0;
|
node.size_ratio = 1.0;
|
||||||
|
|
||||||
if (old_parent != nullptr) {
|
if (old_parent != nullptr) {
|
||||||
auto& group = old_parent->data.as_group;
|
auto& group = old_parent->data.as_group();
|
||||||
if (old_parent->parent != nullptr && group.ephemeral && group.children.size() == 1
|
if (old_parent->parent != nullptr && group.ephemeral && group.children.size() == 1
|
||||||
&& !group.hasChild(&node))
|
&& !group.hasChild(&node))
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,30 +70,30 @@ enum class ExpandFullscreenOption {
|
||||||
|
|
||||||
class Hy3Layout: public IHyprLayout {
|
class Hy3Layout: public IHyprLayout {
|
||||||
public:
|
public:
|
||||||
virtual void onWindowCreated(CWindow*, eDirection = DIRECTION_DEFAULT);
|
void onWindowCreated(PHLWINDOW, eDirection = DIRECTION_DEFAULT) override;
|
||||||
virtual void onWindowCreatedTiling(CWindow*, eDirection = DIRECTION_DEFAULT);
|
void onWindowCreatedTiling(PHLWINDOW, eDirection = DIRECTION_DEFAULT) override;
|
||||||
virtual void onWindowRemovedTiling(CWindow*);
|
void onWindowRemovedTiling(PHLWINDOW) override;
|
||||||
virtual void onWindowFocusChange(CWindow*);
|
void onWindowFocusChange(PHLWINDOW) override;
|
||||||
virtual bool isWindowTiled(CWindow*);
|
bool isWindowTiled(PHLWINDOW) override;
|
||||||
virtual void recalculateMonitor(const int& monitor_id);
|
void recalculateMonitor(const int& monitor_id) override;
|
||||||
virtual void recalculateWindow(CWindow*);
|
void recalculateWindow(PHLWINDOW) override;
|
||||||
virtual void
|
void resizeActiveWindow(const Vector2D& delta, eRectCorner corner, PHLWINDOW pWindow = nullptr)
|
||||||
resizeActiveWindow(const Vector2D& delta, eRectCorner corner, CWindow* pWindow = nullptr);
|
override;
|
||||||
virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool enable_fullscreen);
|
void fullscreenRequestForWindow(PHLWINDOW, eFullscreenMode, bool enable_fullscreen) override;
|
||||||
virtual std::any layoutMessage(SLayoutMessageHeader header, std::string content);
|
std::any layoutMessage(SLayoutMessageHeader header, std::string content) override;
|
||||||
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
|
SWindowRenderLayoutHints requestRenderHints(PHLWINDOW) override;
|
||||||
virtual void switchWindows(CWindow*, CWindow*);
|
void switchWindows(PHLWINDOW, PHLWINDOW) override;
|
||||||
virtual void moveWindowTo(CWindow*, const std::string& direction, bool silent);
|
void moveWindowTo(PHLWINDOW, const std::string& direction, bool silent) override;
|
||||||
virtual void alterSplitRatio(CWindow*, float, bool);
|
void alterSplitRatio(PHLWINDOW, float, bool) override;
|
||||||
virtual std::string getLayoutName();
|
std::string getLayoutName() override;
|
||||||
virtual CWindow* getNextWindowCandidate(CWindow*);
|
PHLWINDOW getNextWindowCandidate(PHLWINDOW) override;
|
||||||
virtual void replaceWindowDataWith(CWindow* from, CWindow* to);
|
void replaceWindowDataWith(PHLWINDOW from, PHLWINDOW to) override;
|
||||||
virtual bool isWindowReachable(CWindow*);
|
bool isWindowReachable(PHLWINDOW) override;
|
||||||
virtual void bringWindowToTop(CWindow*);
|
void bringWindowToTop(PHLWINDOW) override;
|
||||||
virtual Vector2D predictSizeForNewWindowTiled() { return Vector2D(); }
|
Vector2D predictSizeForNewWindowTiled() override { return Vector2D(); }
|
||||||
|
|
||||||
virtual void onEnable();
|
void onEnable() override;
|
||||||
virtual void onDisable();
|
void onDisable() override;
|
||||||
|
|
||||||
void insertNode(Hy3Node& node);
|
void insertNode(Hy3Node& node);
|
||||||
void makeGroupOnWorkspace(const PHLWORKSPACE& workspace, Hy3GroupLayout, GroupEphemeralityOption);
|
void makeGroupOnWorkspace(const PHLWORKSPACE& workspace, Hy3GroupLayout, GroupEphemeralityOption);
|
||||||
|
@ -126,7 +126,7 @@ public:
|
||||||
void killFocusedNode(const PHLWORKSPACE& workspace);
|
void killFocusedNode(const PHLWORKSPACE& workspace);
|
||||||
void expand(const PHLWORKSPACE& workspace, ExpandOption, ExpandFullscreenOption);
|
void expand(const PHLWORKSPACE& workspace, ExpandOption, ExpandFullscreenOption);
|
||||||
|
|
||||||
bool shouldRenderSelected(CWindow*);
|
bool shouldRenderSelected(const PHLWINDOW&);
|
||||||
|
|
||||||
Hy3Node* getWorkspaceRootGroup(const PHLWORKSPACE& workspace);
|
Hy3Node* getWorkspaceRootGroup(const PHLWORKSPACE& workspace);
|
||||||
Hy3Node* getWorkspaceFocusedNode(
|
Hy3Node* getWorkspaceFocusedNode(
|
||||||
|
@ -144,7 +144,7 @@ public:
|
||||||
std::list<Hy3TabGroup> tab_groups;
|
std::list<Hy3TabGroup> tab_groups;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Hy3Node* getNodeFromWindow(CWindow*);
|
Hy3Node* getNodeFromWindow(const PHLWINDOW&);
|
||||||
void applyNodeDataToWindow(Hy3Node*, bool no_animation = false);
|
void applyNodeDataToWindow(Hy3Node*, bool no_animation = false);
|
||||||
|
|
||||||
// if shift is true, shift the window in the given direction, returning
|
// if shift is true, shift the window in the given direction, returning
|
||||||
|
|
362
src/Hy3Node.cpp
362
src/Hy3Node.cpp
|
@ -1,6 +1,10 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
#include <bits/ranges_util.h>
|
||||||
#include <hyprland/src/Compositor.hpp>
|
#include <hyprland/src/Compositor.hpp>
|
||||||
|
#include <hyprland/src/defines.hpp>
|
||||||
#include <hyprland/src/helpers/Box.hpp>
|
#include <hyprland/src/helpers/Box.hpp>
|
||||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
#include <hyprland/src/plugins/PluginAPI.hpp>
|
||||||
|
|
||||||
|
@ -37,8 +41,8 @@ bool Hy3GroupData::hasChild(Hy3Node* node) {
|
||||||
for (auto child: this->children) {
|
for (auto child: this->children) {
|
||||||
if (child == node) return true;
|
if (child == node) return true;
|
||||||
|
|
||||||
if (child->data.type == Hy3NodeType::Group) {
|
if (child->data.is_group()) {
|
||||||
if (child->data.as_group.hasChild(node)) return true;
|
if (child->data.as_group().hasChild(node)) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +55,10 @@ void Hy3GroupData::collapseExpansions() {
|
||||||
|
|
||||||
Hy3Node* node = this->focused_child;
|
Hy3Node* node = this->focused_child;
|
||||||
|
|
||||||
while (node->data.type == Hy3NodeType::Group
|
while (node->data.is_group() && node->data.as_group().expand_focused == ExpandFocusType::Stack) {
|
||||||
&& node->data.as_group.expand_focused == ExpandFocusType::Stack)
|
auto& group = node->data.as_group();
|
||||||
{
|
group.expand_focused = ExpandFocusType::NotExpanded;
|
||||||
node->data.as_group.expand_focused = ExpandFocusType::NotExpanded;
|
node = group.focused_child;
|
||||||
node = node->data.as_group.focused_child;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,64 +82,83 @@ void Hy3GroupData::setEphemeral(GroupEphemeralityOption ephemeral) {
|
||||||
|
|
||||||
// Hy3NodeData //
|
// Hy3NodeData //
|
||||||
|
|
||||||
Hy3NodeData::Hy3NodeData(): Hy3NodeData((CWindow*) nullptr) {}
|
Hy3NodeData::Hy3NodeData(Hy3GroupLayout layout) { this->data.emplace<1>(layout); }
|
||||||
|
|
||||||
Hy3NodeData::Hy3NodeData(CWindow* window): type(Hy3NodeType::Window) { this->as_window = window; }
|
Hy3NodeData::Hy3NodeData(PHLWINDOW window) { this->data.emplace<0>(window); }
|
||||||
|
|
||||||
Hy3NodeData::Hy3NodeData(Hy3GroupLayout layout): Hy3NodeData(Hy3GroupData(layout)) {}
|
Hy3NodeData::Hy3NodeData(Hy3GroupData group) { this->data.emplace<1>(std::move(group)); }
|
||||||
|
|
||||||
Hy3NodeData::Hy3NodeData(Hy3GroupData group): type(Hy3NodeType::Group) {
|
Hy3NodeData::Hy3NodeData(Hy3NodeData&& node) {
|
||||||
new (&this->as_group) Hy3GroupData(std::move(group));
|
if (std::holds_alternative<PHLWINDOWREF>(node.data)) {
|
||||||
}
|
this->data.emplace<0>(std::get<PHLWINDOWREF>(node.data));
|
||||||
|
} else if (std::holds_alternative<Hy3GroupData>(node.data)) {
|
||||||
Hy3NodeData::Hy3NodeData(Hy3NodeData&& from): type(from.type) {
|
this->data.emplace<1>(std::move(std::get<Hy3GroupData>(node.data)));
|
||||||
switch (from.type) {
|
|
||||||
case Hy3NodeType::Window: this->as_window = from.as_window; break;
|
|
||||||
case Hy3NodeType::Group: new (&this->as_group) Hy3GroupData(std::move(from.as_group)); break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3NodeData::~Hy3NodeData() {
|
Hy3NodeData& Hy3NodeData::operator=(PHLWINDOW window) {
|
||||||
switch (this->type) {
|
|
||||||
case Hy3NodeType::Window: break;
|
|
||||||
case Hy3NodeType::Group:
|
|
||||||
this->as_group.~Hy3GroupData();
|
|
||||||
|
|
||||||
// who ever thought calling the dtor after a move was a good idea?
|
|
||||||
this->type = Hy3NodeType::Window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Hy3NodeData& Hy3NodeData::operator=(CWindow* window) {
|
|
||||||
*this = Hy3NodeData(window);
|
*this = Hy3NodeData(window);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3NodeData& Hy3NodeData::operator=(Hy3GroupLayout layout) {
|
Hy3NodeData& Hy3NodeData::operator=(Hy3GroupLayout layout) {
|
||||||
*this = Hy3NodeData(layout);
|
*this = Hy3NodeData(layout);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3NodeData& Hy3NodeData::operator=(Hy3NodeData&& from) {
|
Hy3NodeData& Hy3NodeData::operator=(Hy3NodeData&& from) {
|
||||||
if (this->type == Hy3NodeType::Group) {
|
this->~Hy3NodeData();
|
||||||
this->as_group.~Hy3GroupData();
|
new (this) Hy3NodeData(std::move(from));
|
||||||
}
|
|
||||||
|
|
||||||
this->type = from.type;
|
|
||||||
|
|
||||||
switch (this->type) {
|
|
||||||
case Hy3NodeType::Window: this->as_window = from.as_window; break;
|
|
||||||
case Hy3NodeType::Group: new (&this->as_group) Hy3GroupData(std::move(from.as_group)); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hy3NodeData::operator==(const Hy3NodeData& rhs) const { return this == &rhs; }
|
bool Hy3NodeData::operator==(const Hy3NodeData& rhs) const { return this == &rhs; }
|
||||||
|
|
||||||
|
bool Hy3NodeData::valid() const {
|
||||||
|
if (std::holds_alternative<Hy3GroupData>(this->data)) {
|
||||||
|
return true;
|
||||||
|
} else if (std::holds_alternative<PHLWINDOWREF>(this->data)) {
|
||||||
|
return !std::get<PHLWINDOWREF>(this->data).expired();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Hy3NodeType Hy3NodeData::type() const {
|
||||||
|
if (std::holds_alternative<Hy3GroupData>(this->data)) {
|
||||||
|
return Hy3NodeType::Group;
|
||||||
|
} else if (std::holds_alternative<PHLWINDOWREF>(this->data)) {
|
||||||
|
return Hy3NodeType::Window;
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Attempted to get Hy3NodeType of uninitialized Hy3NodeData");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Hy3NodeData::is_group() const { return this->type() == Hy3NodeType::Group; }
|
||||||
|
|
||||||
|
bool Hy3NodeData::is_window() const { return this->type() == Hy3NodeType::Window; }
|
||||||
|
|
||||||
|
Hy3GroupData& Hy3NodeData::as_group() {
|
||||||
|
if (std::holds_alternative<Hy3GroupData>(this->data)) {
|
||||||
|
return std::get<Hy3GroupData>(this->data);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Attempted to get group value of a non-group Hy3NodeData");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PHLWINDOW Hy3NodeData::as_window() {
|
||||||
|
if (std::holds_alternative<PHLWINDOWREF>(this->data)) {
|
||||||
|
auto& ref = std::get<PHLWINDOWREF>(this->data);
|
||||||
|
if (ref.expired()) {
|
||||||
|
throw std::runtime_error("Attempted to upgrade an expired Hy3NodeData of a window");
|
||||||
|
} else {
|
||||||
|
return ref.lock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Attempted to get window value of a non-window Hy3NodeData");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Hy3Node //
|
// Hy3Node //
|
||||||
|
|
||||||
bool Hy3Node::operator==(const Hy3Node& rhs) const { return this->data == rhs.data; }
|
bool Hy3Node::operator==(const Hy3Node& rhs) const { return this->data == rhs.data; }
|
||||||
|
@ -144,10 +166,10 @@ bool Hy3Node::operator==(const Hy3Node& rhs) const { return this->data == rhs.da
|
||||||
void Hy3Node::focus() {
|
void Hy3Node::focus() {
|
||||||
this->markFocused();
|
this->markFocused();
|
||||||
|
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window:
|
case Hy3NodeType::Window:
|
||||||
this->data.as_window->setHidden(false);
|
this->data.as_window()->setHidden(false);
|
||||||
g_pCompositor->focusWindow(this->data.as_window);
|
g_pCompositor->focusWindow(this->data.as_window());
|
||||||
break;
|
break;
|
||||||
case Hy3NodeType::Group:
|
case Hy3NodeType::Group:
|
||||||
g_pCompositor->focusWindow(nullptr);
|
g_pCompositor->focusWindow(nullptr);
|
||||||
|
@ -156,39 +178,41 @@ void Hy3Node::focus() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CWindow* Hy3Node::bringToTop() {
|
PHLWINDOW Hy3Node::bringToTop() {
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window:
|
case Hy3NodeType::Window: {
|
||||||
this->markFocused();
|
this->markFocused();
|
||||||
this->data.as_window->setHidden(false);
|
auto window = this->data.as_window();
|
||||||
|
window->setHidden(false);
|
||||||
return this->data.as_window;
|
return window;
|
||||||
case Hy3NodeType::Group:
|
}
|
||||||
if (this->data.as_group.layout == Hy3GroupLayout::Tabbed) {
|
case Hy3NodeType::Group: {
|
||||||
if (this->data.as_group.focused_child != nullptr) {
|
auto& group = this->data.as_group();
|
||||||
return this->data.as_group.focused_child->bringToTop();
|
if (group.layout == Hy3GroupLayout::Tabbed) {
|
||||||
|
if (group.focused_child != nullptr) {
|
||||||
|
return group.focused_child->bringToTop();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto* node: this->data.as_group.children) {
|
for (auto* node: group.children) {
|
||||||
auto* window = node->bringToTop();
|
auto window = node->bringToTop();
|
||||||
if (window != nullptr) return window;
|
if (window != nullptr) return window;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
default: return nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Node::focusWindow() {
|
void Hy3Node::focusWindow() {
|
||||||
auto* window = this->bringToTop();
|
auto window = this->bringToTop();
|
||||||
if (window != nullptr) g_pCompositor->focusWindow(window);
|
if (window != nullptr) g_pCompositor->focusWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void markGroupFocusedRecursive(Hy3GroupData& group) {
|
void markGroupFocusedRecursive(Hy3GroupData& group) {
|
||||||
group.group_focused = true;
|
group.group_focused = true;
|
||||||
for (auto& child: group.children) {
|
for (auto& child: group.children) {
|
||||||
if (child->data.type == Hy3NodeType::Group) markGroupFocusedRecursive(child->data.as_group);
|
if (child->data.is_group()) markGroupFocusedRecursive(child->data.as_group());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,14 +224,15 @@ void Hy3Node::markFocused() {
|
||||||
while (root->parent != nullptr) root = root->parent;
|
while (root->parent != nullptr) root = root->parent;
|
||||||
|
|
||||||
// update focus
|
// update focus
|
||||||
if (this->data.type == Hy3NodeType::Group) {
|
if (this->data.is_group()) {
|
||||||
markGroupFocusedRecursive(this->data.as_group);
|
markGroupFocusedRecursive(this->data.as_group());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* node2 = node;
|
auto* node2 = node;
|
||||||
while (node2->parent != nullptr) {
|
while (node2->parent != nullptr) {
|
||||||
node2->parent->data.as_group.focused_child = node2;
|
auto& group = node2->parent->data.as_group();
|
||||||
node2->parent->data.as_group.group_focused = false;
|
group.focused_child = node2;
|
||||||
|
group.group_focused = false;
|
||||||
node2 = node2->parent;
|
node2 = node2->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,10 +240,10 @@ void Hy3Node::markFocused() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Node::raiseToTop() {
|
void Hy3Node::raiseToTop() {
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window: g_pCompositor->changeWindowZOrder(this->data.as_window, true); break;
|
case Hy3NodeType::Window: g_pCompositor->changeWindowZOrder(this->data.as_window(), true); break;
|
||||||
case Hy3NodeType::Group:
|
case Hy3NodeType::Group:
|
||||||
for (auto* child: this->data.as_group.children) {
|
for (auto* child: this->data.as_group().children) {
|
||||||
child->raiseToTop();
|
child->raiseToTop();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -226,21 +251,19 @@ void Hy3Node::raiseToTop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node* Hy3Node::getFocusedNode(bool ignore_group_focus, bool stop_at_expanded) {
|
Hy3Node* Hy3Node::getFocusedNode(bool ignore_group_focus, bool stop_at_expanded) {
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window: return this;
|
case Hy3NodeType::Window: return this;
|
||||||
case Hy3NodeType::Group:
|
case Hy3NodeType::Group: {
|
||||||
if (this->data.as_group.focused_child == nullptr
|
auto& group = this->data.as_group();
|
||||||
|| (!ignore_group_focus && this->data.as_group.group_focused)
|
|
||||||
|| (stop_at_expanded && this->data.as_group.expand_focused != ExpandFocusType::NotExpanded))
|
if (group.focused_child == nullptr || (!ignore_group_focus && group.group_focused)
|
||||||
|
|| (stop_at_expanded && group.expand_focused != ExpandFocusType::NotExpanded))
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
return this->data.as_group.focused_child->getFocusedNode(
|
return group.focused_child->getFocusedNode(ignore_group_focus, stop_at_expanded);
|
||||||
ignore_group_focus,
|
|
||||||
stop_at_expanded
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
default: return nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,9 +271,8 @@ bool Hy3Node::isIndirectlyFocused() {
|
||||||
Hy3Node* node = this;
|
Hy3Node* node = this;
|
||||||
|
|
||||||
while (node->parent != nullptr) {
|
while (node->parent != nullptr) {
|
||||||
if (!node->parent->data.as_group.group_focused
|
auto& group = node->parent->data.as_group();
|
||||||
&& node->parent->data.as_group.focused_child != node)
|
if (!group.group_focused && group.focused_child != node) return false;
|
||||||
return false;
|
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +284,7 @@ Hy3Node& Hy3Node::getExpandActor() {
|
||||||
Hy3Node* node = this;
|
Hy3Node* node = this;
|
||||||
|
|
||||||
while (node->parent != nullptr
|
while (node->parent != nullptr
|
||||||
&& node->parent->data.as_group.expand_focused != ExpandFocusType::NotExpanded)
|
&& node->parent->data.as_group().expand_focused != ExpandFocusType::NotExpanded)
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
|
|
||||||
return *node;
|
return *node;
|
||||||
|
@ -289,17 +311,18 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
);
|
);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
if (this->data.type == Hy3NodeType::Window && this->data.as_window->m_bIsFullscreen) {
|
if (this->data.is_window() && this->data.as_window()->m_bIsFullscreen) {
|
||||||
|
auto window = this->data.as_window();
|
||||||
auto* monitor = g_pCompositor->getMonitorFromID(this->workspace->m_iMonitorID);
|
auto* monitor = g_pCompositor->getMonitorFromID(this->workspace->m_iMonitorID);
|
||||||
|
|
||||||
if (this->workspace->m_efFullscreenMode == FULLSCREEN_FULL) {
|
if (this->workspace->m_efFullscreenMode == FULLSCREEN_FULL) {
|
||||||
this->data.as_window->m_vRealPosition = monitor->vecPosition;
|
window->m_vRealPosition = monitor->vecPosition;
|
||||||
this->data.as_window->m_vRealSize = monitor->vecSize;
|
window->m_vRealSize = monitor->vecSize;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node fake_node = {
|
Hy3Node fake_node = {
|
||||||
.data = this->data.as_window,
|
.data = window,
|
||||||
.position = monitor->vecPosition + monitor->vecReservedTopLeft,
|
.position = monitor->vecPosition + monitor->vecReservedTopLeft,
|
||||||
.size = monitor->vecSize - monitor->vecReservedTopLeft - monitor->vecReservedBottomRight,
|
.size = monitor->vecSize - monitor->vecReservedTopLeft - monitor->vecReservedBottomRight,
|
||||||
.gap_topleft_offset = gap_topleft_offset,
|
.gap_topleft_offset = gap_topleft_offset,
|
||||||
|
@ -321,16 +344,16 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
|
|
||||||
double tab_height_offset = *tab_bar_height + *tab_bar_padding;
|
double tab_height_offset = *tab_bar_height + *tab_bar_padding;
|
||||||
|
|
||||||
if (this->data.type == Hy3NodeType::Window) {
|
if (this->data.is_window()) {
|
||||||
this->data.as_window->setHidden(this->hidden);
|
this->data.as_window()->setHidden(this->hidden);
|
||||||
this->layout->applyNodeDataToWindow(this, no_animation);
|
this->layout->applyNodeDataToWindow(this, no_animation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* group = &this->data.as_group;
|
auto& group = this->data.as_group();
|
||||||
|
|
||||||
double constraint;
|
double constraint;
|
||||||
switch (group->layout) {
|
switch (group.layout) {
|
||||||
case Hy3GroupLayout::SplitH:
|
case Hy3GroupLayout::SplitH:
|
||||||
constraint = tsize.x - gap_topleft_offset.x - gap_bottomright_offset.x;
|
constraint = tsize.x - gap_topleft_offset.x - gap_bottomright_offset.x;
|
||||||
break;
|
break;
|
||||||
|
@ -340,34 +363,34 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
case Hy3GroupLayout::Tabbed: break;
|
case Hy3GroupLayout::Tabbed: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto expand_focused = group->expand_focused != ExpandFocusType::NotExpanded;
|
auto expand_focused = group.expand_focused != ExpandFocusType::NotExpanded;
|
||||||
bool directly_contains_expanded =
|
bool directly_contains_expanded =
|
||||||
expand_focused
|
expand_focused
|
||||||
&& (group->focused_child->data.type == Hy3NodeType::Window
|
&& (group.focused_child->data.is_window()
|
||||||
|| group->focused_child->data.as_group.expand_focused == ExpandFocusType::NotExpanded);
|
|| group.focused_child->data.as_group().expand_focused == ExpandFocusType::NotExpanded);
|
||||||
|
|
||||||
auto child_count = group->children.size();
|
auto child_count = group.children.size();
|
||||||
double ratio_mul =
|
double ratio_mul =
|
||||||
group->layout != Hy3GroupLayout::Tabbed ? child_count <= 0 ? 0 : constraint / child_count : 0;
|
group.layout != Hy3GroupLayout::Tabbed ? child_count <= 0 ? 0 : constraint / child_count : 0;
|
||||||
|
|
||||||
double offset = 0;
|
double offset = 0;
|
||||||
|
|
||||||
if (group->layout == Hy3GroupLayout::Tabbed && group->focused_child != nullptr
|
if (group.layout == Hy3GroupLayout::Tabbed && group.focused_child != nullptr
|
||||||
&& !group->focused_child->hidden)
|
&& !group.focused_child->hidden)
|
||||||
{
|
{
|
||||||
group->focused_child->setHidden(false);
|
group.focused_child->setHidden(false);
|
||||||
|
|
||||||
auto box = CBox {tpos.x, tpos.y, tsize.x, tsize.y};
|
auto box = CBox {tpos.x, tpos.y, tsize.x, tsize.y};
|
||||||
g_pHyprRenderer->damageBox(&box);
|
g_pHyprRenderer->damageBox(&box);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group->expand_focused == ExpandFocusType::Latch) {
|
if (group.expand_focused == ExpandFocusType::Latch) {
|
||||||
auto* expanded_node = group->focused_child;
|
auto* expanded_node = group.focused_child;
|
||||||
|
|
||||||
while (expanded_node != nullptr && expanded_node->data.type == Hy3NodeType::Group
|
while (expanded_node != nullptr && expanded_node->data.is_group()
|
||||||
&& expanded_node->data.as_group.expand_focused != ExpandFocusType::NotExpanded)
|
&& expanded_node->data.as_group().expand_focused != ExpandFocusType::NotExpanded)
|
||||||
{
|
{
|
||||||
expanded_node = expanded_node->data.as_group.focused_child;
|
expanded_node = expanded_node->data.as_group().focused_child;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expanded_node == nullptr) {
|
if (expanded_node == nullptr) {
|
||||||
|
@ -390,9 +413,9 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
expanded_node->recalcSizePosRecursive(no_animation);
|
expanded_node->recalcSizePosRecursive(no_animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* child: group->children) {
|
for (auto* child: group.children) {
|
||||||
if (directly_contains_expanded && child == group->focused_child) {
|
if (directly_contains_expanded && child == group.focused_child) {
|
||||||
switch (group->layout) {
|
switch (group.layout) {
|
||||||
case Hy3GroupLayout::SplitH: offset += child->size_ratio * ratio_mul; break;
|
case Hy3GroupLayout::SplitH: offset += child->size_ratio * ratio_mul; break;
|
||||||
case Hy3GroupLayout::SplitV: offset += child->size_ratio * ratio_mul; break;
|
case Hy3GroupLayout::SplitV: offset += child->size_ratio * ratio_mul; break;
|
||||||
case Hy3GroupLayout::Tabbed: break;
|
case Hy3GroupLayout::Tabbed: break;
|
||||||
|
@ -401,7 +424,7 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (group->layout) {
|
switch (group.layout) {
|
||||||
case Hy3GroupLayout::SplitH:
|
case Hy3GroupLayout::SplitH:
|
||||||
child->position.x = tpos.x + offset;
|
child->position.x = tpos.x + offset;
|
||||||
child->size.x = child->size_ratio * ratio_mul;
|
child->size.x = child->size_ratio * ratio_mul;
|
||||||
|
@ -410,17 +433,17 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
child->size.y = tsize.y;
|
child->size.y = tsize.y;
|
||||||
child->hidden = this->hidden || expand_focused;
|
child->hidden = this->hidden || expand_focused;
|
||||||
|
|
||||||
if (group->children.size() == 1) {
|
if (group.children.size() == 1) {
|
||||||
child->gap_topleft_offset = gap_topleft_offset;
|
child->gap_topleft_offset = gap_topleft_offset;
|
||||||
child->gap_bottomright_offset = gap_bottomright_offset;
|
child->gap_bottomright_offset = gap_bottomright_offset;
|
||||||
child->size.x = tsize.x;
|
child->size.x = tsize.x;
|
||||||
if (this->parent != nullptr) child->gap_bottomright_offset.x += *group_inset;
|
if (this->parent != nullptr) child->gap_bottomright_offset.x += *group_inset;
|
||||||
} else if (child == group->children.front()) {
|
} else if (child == group.children.front()) {
|
||||||
child->gap_topleft_offset = gap_topleft_offset;
|
child->gap_topleft_offset = gap_topleft_offset;
|
||||||
child->gap_bottomright_offset = Vector2D(0, gap_bottomright_offset.y);
|
child->gap_bottomright_offset = Vector2D(0, gap_bottomright_offset.y);
|
||||||
child->size.x += gap_topleft_offset.x;
|
child->size.x += gap_topleft_offset.x;
|
||||||
offset += gap_topleft_offset.x;
|
offset += gap_topleft_offset.x;
|
||||||
} else if (child == group->children.back()) {
|
} else if (child == group.children.back()) {
|
||||||
child->gap_topleft_offset = Vector2D(0, gap_topleft_offset.y);
|
child->gap_topleft_offset = Vector2D(0, gap_topleft_offset.y);
|
||||||
child->gap_bottomright_offset = gap_bottomright_offset;
|
child->gap_bottomright_offset = gap_bottomright_offset;
|
||||||
child->size.x += gap_bottomright_offset.x;
|
child->size.x += gap_bottomright_offset.x;
|
||||||
|
@ -439,17 +462,17 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
child->size.x = tsize.x;
|
child->size.x = tsize.x;
|
||||||
child->hidden = this->hidden || expand_focused;
|
child->hidden = this->hidden || expand_focused;
|
||||||
|
|
||||||
if (group->children.size() == 1) {
|
if (group.children.size() == 1) {
|
||||||
child->gap_topleft_offset = gap_topleft_offset;
|
child->gap_topleft_offset = gap_topleft_offset;
|
||||||
child->gap_bottomright_offset = gap_bottomright_offset;
|
child->gap_bottomright_offset = gap_bottomright_offset;
|
||||||
child->size.y = tsize.y;
|
child->size.y = tsize.y;
|
||||||
if (this->parent != nullptr) child->gap_bottomright_offset.y += *group_inset;
|
if (this->parent != nullptr) child->gap_bottomright_offset.y += *group_inset;
|
||||||
} else if (child == group->children.front()) {
|
} else if (child == group.children.front()) {
|
||||||
child->gap_topleft_offset = gap_topleft_offset;
|
child->gap_topleft_offset = gap_topleft_offset;
|
||||||
child->gap_bottomright_offset = Vector2D(gap_bottomright_offset.x, 0);
|
child->gap_bottomright_offset = Vector2D(gap_bottomright_offset.x, 0);
|
||||||
child->size.y += gap_topleft_offset.y;
|
child->size.y += gap_topleft_offset.y;
|
||||||
offset += gap_topleft_offset.y;
|
offset += gap_topleft_offset.y;
|
||||||
} else if (child == group->children.back()) {
|
} else if (child == group.children.back()) {
|
||||||
child->gap_topleft_offset = Vector2D(gap_topleft_offset.x, 0);
|
child->gap_topleft_offset = Vector2D(gap_topleft_offset.x, 0);
|
||||||
child->gap_bottomright_offset = gap_bottomright_offset;
|
child->gap_bottomright_offset = gap_bottomright_offset;
|
||||||
child->size.y += gap_bottomright_offset.y;
|
child->size.y += gap_bottomright_offset.y;
|
||||||
|
@ -463,7 +486,7 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
case Hy3GroupLayout::Tabbed:
|
case Hy3GroupLayout::Tabbed:
|
||||||
child->position = tpos;
|
child->position = tpos;
|
||||||
child->size = tsize;
|
child->size = tsize;
|
||||||
child->hidden = this->hidden || expand_focused || group->focused_child != child;
|
child->hidden = this->hidden || expand_focused || group.focused_child != child;
|
||||||
|
|
||||||
child->gap_topleft_offset =
|
child->gap_topleft_offset =
|
||||||
Vector2D(gap_topleft_offset.x, gap_topleft_offset.y + tab_height_offset);
|
Vector2D(gap_topleft_offset.x, gap_topleft_offset.y + tab_height_offset);
|
||||||
|
@ -478,18 +501,18 @@ void Hy3Node::recalcSizePosRecursive(bool no_animation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FindTopWindowInNodeResult {
|
struct FindTopWindowInNodeResult {
|
||||||
CWindow* window = nullptr;
|
PHLWINDOW window = nullptr;
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void findTopWindowInNode(Hy3Node& node, FindTopWindowInNodeResult& result) {
|
void findTopWindowInNode(Hy3Node& node, FindTopWindowInNodeResult& result) {
|
||||||
switch (node.data.type) {
|
switch (node.data.type()) {
|
||||||
case Hy3NodeType::Window: {
|
case Hy3NodeType::Window: {
|
||||||
auto* window = node.data.as_window;
|
auto window = node.data.as_window();
|
||||||
auto& windows = g_pCompositor->m_vWindows;
|
auto& windows = g_pCompositor->m_vWindows;
|
||||||
|
|
||||||
for (; result.index < windows.size(); result.index++) {
|
for (; result.index < windows.size(); result.index++) {
|
||||||
if (&*windows[result.index] == window) {
|
if (windows[result.index] == window) {
|
||||||
result.window = window;
|
result.window = window;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -497,7 +520,7 @@ void findTopWindowInNode(Hy3Node& node, FindTopWindowInNodeResult& result) {
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Hy3NodeType::Group: {
|
case Hy3NodeType::Group: {
|
||||||
auto& group = node.data.as_group;
|
auto& group = node.data.as_group();
|
||||||
|
|
||||||
if (group.layout == Hy3GroupLayout::Tabbed) {
|
if (group.layout == Hy3GroupLayout::Tabbed) {
|
||||||
if (group.focused_child != nullptr) findTopWindowInNode(*group.focused_child, result);
|
if (group.focused_child != nullptr) findTopWindowInNode(*group.focused_child, result);
|
||||||
|
@ -511,8 +534,8 @@ void findTopWindowInNode(Hy3Node& node, FindTopWindowInNodeResult& result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Node::updateTabBar(bool no_animation) {
|
void Hy3Node::updateTabBar(bool no_animation) {
|
||||||
if (this->data.type == Hy3NodeType::Group) {
|
if (this->data.type() == Hy3NodeType::Group) {
|
||||||
auto& group = this->data.as_group;
|
auto& group = this->data.as_group();
|
||||||
|
|
||||||
if (group.layout == Hy3GroupLayout::Tabbed) {
|
if (group.layout == Hy3GroupLayout::Tabbed) {
|
||||||
if (group.tab_bar == nullptr) group.tab_bar = &this->layout->tab_groups.emplace_back(*this);
|
if (group.tab_bar == nullptr) group.tab_bar = &this->layout->tab_groups.emplace_back(*this);
|
||||||
|
@ -539,13 +562,12 @@ void Hy3Node::updateTabBarRecursive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Node::updateDecos() {
|
void Hy3Node::updateDecos() {
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window:
|
case Hy3NodeType::Window:
|
||||||
if (this->data.as_window->m_bIsMapped)
|
g_pCompositor->updateWindowAnimatedDecorationValues(this->data.as_window());
|
||||||
g_pCompositor->updateWindowAnimatedDecorationValues(this->data.as_window);
|
|
||||||
break;
|
break;
|
||||||
case Hy3NodeType::Group:
|
case Hy3NodeType::Group:
|
||||||
for (auto* child: this->data.as_group.children) {
|
for (auto* child: this->data.as_group().children) {
|
||||||
child->updateDecos();
|
child->updateDecos();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,21 +576,22 @@ void Hy3Node::updateDecos() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Hy3Node::getTitle() {
|
std::string Hy3Node::getTitle() {
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window: return this->data.as_window->m_szTitle;
|
case Hy3NodeType::Window: return this->data.as_window()->m_szTitle;
|
||||||
case Hy3NodeType::Group:
|
case Hy3NodeType::Group:
|
||||||
std::string title;
|
std::string title;
|
||||||
|
auto& group = this->data.as_group();
|
||||||
|
|
||||||
switch (this->data.as_group.layout) {
|
switch (group.layout) {
|
||||||
case Hy3GroupLayout::SplitH: title = "[H] "; break;
|
case Hy3GroupLayout::SplitH: title = "[H] "; break;
|
||||||
case Hy3GroupLayout::SplitV: title = "[V] "; break;
|
case Hy3GroupLayout::SplitV: title = "[V] "; break;
|
||||||
case Hy3GroupLayout::Tabbed: title = "[T] "; break;
|
case Hy3GroupLayout::Tabbed: title = "[T] "; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->data.as_group.focused_child == nullptr) {
|
if (group.focused_child == nullptr) {
|
||||||
title += "Group";
|
title += "Group";
|
||||||
} else {
|
} else {
|
||||||
title += this->data.as_group.focused_child->getTitle();
|
title += group.focused_child->getTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
return title;
|
return title;
|
||||||
|
@ -578,33 +601,31 @@ std::string Hy3Node::getTitle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hy3Node::isUrgent() {
|
bool Hy3Node::isUrgent() {
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window: return this->data.as_window->m_bIsUrgent;
|
case Hy3NodeType::Window: return this->data.as_window()->m_bIsUrgent;
|
||||||
case Hy3NodeType::Group:
|
case Hy3NodeType::Group:
|
||||||
for (auto* child: this->data.as_group.children) {
|
for (auto* child: this->data.as_group().children) {
|
||||||
if (child->isUrgent()) return true;
|
if (child->isUrgent()) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
default: return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Node::setHidden(bool hidden) {
|
void Hy3Node::setHidden(bool hidden) {
|
||||||
this->hidden = hidden;
|
this->hidden = hidden;
|
||||||
|
|
||||||
if (this->data.type == Hy3NodeType::Group) {
|
if (this->data.is_group()) {
|
||||||
for (auto* child: this->data.as_group.children) {
|
for (auto* child: this->data.as_group().children) {
|
||||||
child->setHidden(hidden);
|
child->setHidden(hidden);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node* Hy3Node::findNodeForTabGroup(Hy3TabGroup& tab_group) {
|
Hy3Node* Hy3Node::findNodeForTabGroup(Hy3TabGroup& tab_group) {
|
||||||
if (this->data.type == Hy3NodeType::Group) {
|
if (this->data.is_group()) {
|
||||||
if (this->hidden) return nullptr;
|
if (this->hidden) return nullptr;
|
||||||
|
auto& group = this->data.as_group();
|
||||||
auto& group = this->data.as_group;
|
|
||||||
|
|
||||||
if (group.layout == Hy3GroupLayout::Tabbed && group.tab_bar == &tab_group) {
|
if (group.layout == Hy3GroupLayout::Tabbed && group.tab_bar == &tab_group) {
|
||||||
return this;
|
return this;
|
||||||
|
@ -619,11 +640,11 @@ Hy3Node* Hy3Node::findNodeForTabGroup(Hy3TabGroup& tab_group) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hy3Node::appendAllWindows(std::vector<CWindow*>& list) {
|
void Hy3Node::appendAllWindows(std::vector<PHLWINDOW>& list) {
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window: list.push_back(this->data.as_window); break;
|
case Hy3NodeType::Window: list.push_back(this->data.as_window()); break;
|
||||||
case Hy3NodeType::Group:
|
case Hy3NodeType::Group:
|
||||||
for (auto* child: this->data.as_group.children) {
|
for (auto* child: this->data.as_group().children) {
|
||||||
child->appendAllWindows(list);
|
child->appendAllWindows(list);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -633,12 +654,12 @@ void Hy3Node::appendAllWindows(std::vector<CWindow*>& list) {
|
||||||
std::string Hy3Node::debugNode() {
|
std::string Hy3Node::debugNode() {
|
||||||
std::stringstream buf;
|
std::stringstream buf;
|
||||||
std::string addr = "0x" + std::to_string((size_t) this);
|
std::string addr = "0x" + std::to_string((size_t) this);
|
||||||
switch (this->data.type) {
|
switch (this->data.type()) {
|
||||||
case Hy3NodeType::Window:
|
case Hy3NodeType::Window:
|
||||||
buf << "window(";
|
buf << "window(";
|
||||||
buf << std::hex << this;
|
buf << std::hex << this;
|
||||||
buf << ") [hypr ";
|
buf << ") [hypr ";
|
||||||
buf << this->data.as_window;
|
buf << this->data.as_window();
|
||||||
buf << "] size ratio: ";
|
buf << "] size ratio: ";
|
||||||
buf << this->size_ratio;
|
buf << this->size_ratio;
|
||||||
break;
|
break;
|
||||||
|
@ -647,7 +668,8 @@ std::string Hy3Node::debugNode() {
|
||||||
buf << std::hex << this;
|
buf << std::hex << this;
|
||||||
buf << ") [";
|
buf << ") [";
|
||||||
|
|
||||||
switch (this->data.as_group.layout) {
|
auto& group = this->data.as_group();
|
||||||
|
switch (group.layout) {
|
||||||
case Hy3GroupLayout::SplitH: buf << "splith"; break;
|
case Hy3GroupLayout::SplitH: buf << "splith"; break;
|
||||||
case Hy3GroupLayout::SplitV: buf << "splitv"; break;
|
case Hy3GroupLayout::SplitV: buf << "splitv"; break;
|
||||||
case Hy3GroupLayout::Tabbed: buf << "tabs"; break;
|
case Hy3GroupLayout::Tabbed: buf << "tabs"; break;
|
||||||
|
@ -656,19 +678,19 @@ std::string Hy3Node::debugNode() {
|
||||||
buf << "] size ratio: ";
|
buf << "] size ratio: ";
|
||||||
buf << this->size_ratio;
|
buf << this->size_ratio;
|
||||||
|
|
||||||
if (this->data.as_group.expand_focused != ExpandFocusType::NotExpanded) {
|
if (group.expand_focused != ExpandFocusType::NotExpanded) {
|
||||||
buf << ", has-expanded";
|
buf << ", has-expanded";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->data.as_group.ephemeral) {
|
if (group.ephemeral) {
|
||||||
buf << ", ephemeral";
|
buf << ", ephemeral";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->data.as_group.containment) {
|
if (group.containment) {
|
||||||
buf << ", containment";
|
buf << ", containment";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* child: this->data.as_group.children) {
|
for (auto* child: group.children) {
|
||||||
buf << "\n|-";
|
buf << "\n|-";
|
||||||
if (child == nullptr) {
|
if (child == nullptr) {
|
||||||
buf << "nullptr";
|
buf << "nullptr";
|
||||||
|
@ -694,8 +716,8 @@ Hy3Node* Hy3Node::removeFromParentRecursive(Hy3Node** expand_actor) {
|
||||||
|
|
||||||
if (this->parent != nullptr) {
|
if (this->parent != nullptr) {
|
||||||
auto& actor = this->getExpandActor();
|
auto& actor = this->getExpandActor();
|
||||||
if (actor.data.type == Hy3NodeType::Group) {
|
if (actor.data.is_group()) {
|
||||||
actor.data.as_group.collapseExpansions();
|
actor.data.as_group().collapseExpansions();
|
||||||
if (expand_actor != nullptr) *expand_actor = &actor;
|
if (expand_actor != nullptr) *expand_actor = &actor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -708,7 +730,7 @@ Hy3Node* Hy3Node::removeFromParentRecursive(Hy3Node** expand_actor) {
|
||||||
|
|
||||||
auto* child = parent;
|
auto* child = parent;
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
auto& group = parent->data.as_group;
|
auto& group = parent->data.as_group();
|
||||||
|
|
||||||
if (group.children.size() > 2) {
|
if (group.children.size() > 2) {
|
||||||
auto iter = std::find(group.children.begin(), group.children.end(), child);
|
auto iter = std::find(group.children.begin(), group.children.end(), child);
|
||||||
|
@ -778,11 +800,12 @@ Hy3Node* Hy3Node::intoGroup(Hy3GroupLayout layout, GroupEphemeralityOption ephem
|
||||||
swapData(*this, *node);
|
swapData(*this, *node);
|
||||||
|
|
||||||
this->data = layout;
|
this->data = layout;
|
||||||
this->data.as_group.children.push_back(node);
|
auto& group = this->data.as_group();
|
||||||
this->data.as_group.group_focused = false;
|
group.children.push_back(node);
|
||||||
this->data.as_group.focused_child = node;
|
group.group_focused = false;
|
||||||
this->data.as_group.ephemeral = ephemeral == GroupEphemeralityOption::Ephemeral
|
group.focused_child = node;
|
||||||
|| ephemeral == GroupEphemeralityOption::ForceEphemeral;
|
group.ephemeral = ephemeral == GroupEphemeralityOption::Ephemeral
|
||||||
|
|| ephemeral == GroupEphemeralityOption::ForceEphemeral;
|
||||||
this->recalcSizePosRecursive();
|
this->recalcSizePosRecursive();
|
||||||
this->updateTabBarRecursive();
|
this->updateTabBarRecursive();
|
||||||
|
|
||||||
|
@ -790,15 +813,14 @@ Hy3Node* Hy3Node::intoGroup(Hy3GroupLayout layout, GroupEphemeralityOption ephem
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hy3Node::swallowGroups(Hy3Node* into) {
|
bool Hy3Node::swallowGroups(Hy3Node* into) {
|
||||||
if (into == nullptr || into->data.type != Hy3NodeType::Group
|
if (into == nullptr || into->data.is_window() || into->data.as_group().children.size() != 1)
|
||||||
|| into->data.as_group.children.size() != 1)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto* child = into->data.as_group.children.front();
|
auto* child = into->data.as_group().children.front();
|
||||||
|
|
||||||
// a lot of segfaulting happens once the assumption that the root node is a
|
// a lot of segfaulting happens once the assumption that the root node is a
|
||||||
// group is wrong.
|
// group is wrong.
|
||||||
if (into->parent == nullptr && child->data.type != Hy3NodeType::Group) return false;
|
if (into->parent == nullptr && child->data.is_window()) return false;
|
||||||
|
|
||||||
hy3_log(TRACE, "swallowing node {:x} into node {:x}", (uintptr_t) child, (uintptr_t) into);
|
hy3_log(TRACE, "swallowing node {:x} into node {:x}", (uintptr_t) child, (uintptr_t) into);
|
||||||
|
|
||||||
|
@ -819,7 +841,7 @@ Hy3Node* getOuterChild(Hy3GroupData& group, ShiftDirection direction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Hy3Node* Hy3Node::getImmediateSibling(ShiftDirection direction) {
|
Hy3Node* Hy3Node::getImmediateSibling(ShiftDirection direction) {
|
||||||
const auto& group = this->parent->data.as_group;
|
const auto& group = this->parent->data.as_group();
|
||||||
|
|
||||||
auto iter = std::find(group.children.begin(), group.children.end(), this);
|
auto iter = std::find(group.children.begin(), group.children.end(), this);
|
||||||
|
|
||||||
|
@ -864,7 +886,7 @@ Hy3Node* Hy3Node::findNeighbor(ShiftDirection direction) {
|
||||||
Hy3Node* sibling = nullptr;
|
Hy3Node* sibling = nullptr;
|
||||||
|
|
||||||
while (sibling == nullptr && current_node->parent != nullptr) {
|
while (sibling == nullptr && current_node->parent != nullptr) {
|
||||||
auto& parent_group = current_node->parent->data.as_group;
|
auto& parent_group = current_node->parent->data.as_group();
|
||||||
|
|
||||||
if (parent_group.layout != Hy3GroupLayout::Tabbed
|
if (parent_group.layout != Hy3GroupLayout::Tabbed
|
||||||
&& getAxis(parent_group.layout) == getAxis(direction))
|
&& getAxis(parent_group.layout) == getAxis(direction))
|
||||||
|
@ -895,7 +917,7 @@ int directionToIteratorIncrement(ShiftDirection direction) {
|
||||||
|
|
||||||
void Hy3Node::resize(ShiftDirection direction, double delta, bool no_animation) {
|
void Hy3Node::resize(ShiftDirection direction, double delta, bool no_animation) {
|
||||||
auto& parent_node = this->parent;
|
auto& parent_node = this->parent;
|
||||||
auto& containing_group = parent_node->data.as_group;
|
auto& containing_group = parent_node->data.as_group();
|
||||||
|
|
||||||
if (containing_group.layout != Hy3GroupLayout::Tabbed
|
if (containing_group.layout != Hy3GroupLayout::Tabbed
|
||||||
&& getAxis(direction) == getAxis(containing_group.layout))
|
&& getAxis(direction) == getAxis(containing_group.layout))
|
||||||
|
@ -936,14 +958,14 @@ void Hy3Node::swapData(Hy3Node& a, Hy3Node& b) {
|
||||||
a.data = std::move(b.data);
|
a.data = std::move(b.data);
|
||||||
b.data = std::move(aData);
|
b.data = std::move(aData);
|
||||||
|
|
||||||
if (a.data.type == Hy3NodeType::Group) {
|
if (a.data.is_group()) {
|
||||||
for (auto child: a.data.as_group.children) {
|
for (auto child: a.data.as_group().children) {
|
||||||
child->parent = &a;
|
child->parent = &a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b.data.type == Hy3NodeType::Group) {
|
if (b.data.is_group()) {
|
||||||
for (auto child: b.data.as_group.children) {
|
for (auto child: b.data.as_group().children) {
|
||||||
child->parent = &b;
|
child->parent = &b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@ struct Hy3Node;
|
||||||
struct Hy3GroupData;
|
struct Hy3GroupData;
|
||||||
enum class Hy3GroupLayout;
|
enum class Hy3GroupLayout;
|
||||||
|
|
||||||
#include <list>
|
#include <variant>
|
||||||
|
|
||||||
|
#include <hyprland/src/defines.hpp>
|
||||||
#include <hyprland/src/desktop/Window.hpp>
|
#include <hyprland/src/desktop/Window.hpp>
|
||||||
|
|
||||||
#include "Hy3Layout.hpp"
|
#include "Hy3Layout.hpp"
|
||||||
|
@ -47,7 +48,6 @@ struct Hy3GroupData {
|
||||||
void setLayout(Hy3GroupLayout layout);
|
void setLayout(Hy3GroupLayout layout);
|
||||||
void setEphemeral(GroupEphemeralityOption ephemeral);
|
void setEphemeral(GroupEphemeralityOption ephemeral);
|
||||||
|
|
||||||
private:
|
|
||||||
Hy3GroupData(Hy3GroupData&&);
|
Hy3GroupData(Hy3GroupData&&);
|
||||||
Hy3GroupData(const Hy3GroupData&) = delete;
|
Hy3GroupData(const Hy3GroupData&) = delete;
|
||||||
|
|
||||||
|
@ -56,26 +56,28 @@ private:
|
||||||
|
|
||||||
class Hy3NodeData {
|
class Hy3NodeData {
|
||||||
public:
|
public:
|
||||||
Hy3NodeType type;
|
Hy3NodeData() = default;
|
||||||
union {
|
Hy3NodeData(Hy3GroupData);
|
||||||
Hy3GroupData as_group;
|
Hy3NodeData(PHLWINDOW window);
|
||||||
CWindow* as_window;
|
|
||||||
};
|
|
||||||
|
|
||||||
Hy3NodeData();
|
|
||||||
Hy3NodeData(CWindow* window);
|
|
||||||
Hy3NodeData(Hy3GroupLayout layout);
|
Hy3NodeData(Hy3GroupLayout layout);
|
||||||
~Hy3NodeData();
|
Hy3NodeData(Hy3NodeData&&);
|
||||||
|
~Hy3NodeData() = default;
|
||||||
|
|
||||||
Hy3NodeData& operator=(CWindow*);
|
Hy3NodeData& operator=(PHLWINDOW);
|
||||||
Hy3NodeData& operator=(Hy3GroupLayout);
|
Hy3NodeData& operator=(Hy3GroupLayout);
|
||||||
|
Hy3NodeData& operator=(Hy3NodeData&&);
|
||||||
|
|
||||||
bool operator==(const Hy3NodeData&) const;
|
bool operator==(const Hy3NodeData&) const;
|
||||||
|
|
||||||
// private: - I give up, C++ wins
|
bool valid() const;
|
||||||
Hy3NodeData(Hy3GroupData);
|
Hy3NodeType type() const;
|
||||||
Hy3NodeData(Hy3NodeData&&);
|
bool is_window() const;
|
||||||
Hy3NodeData& operator=(Hy3NodeData&&);
|
bool is_group() const;
|
||||||
|
Hy3GroupData& as_group();
|
||||||
|
PHLWINDOW as_window();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::variant<PHLWINDOWREF, Hy3GroupData> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Hy3Node {
|
struct Hy3Node {
|
||||||
|
@ -95,7 +97,7 @@ struct Hy3Node {
|
||||||
|
|
||||||
void focus();
|
void focus();
|
||||||
void focusWindow();
|
void focusWindow();
|
||||||
CWindow* bringToTop();
|
PHLWINDOW bringToTop();
|
||||||
void markFocused();
|
void markFocused();
|
||||||
void raiseToTop();
|
void raiseToTop();
|
||||||
Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false);
|
Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false);
|
||||||
|
@ -115,7 +117,7 @@ struct Hy3Node {
|
||||||
void setHidden(bool);
|
void setHidden(bool);
|
||||||
|
|
||||||
Hy3Node* findNodeForTabGroup(Hy3TabGroup&);
|
Hy3Node* findNodeForTabGroup(Hy3TabGroup&);
|
||||||
void appendAllWindows(std::vector<CWindow*>&);
|
void appendAllWindows(std::vector<PHLWINDOW>&);
|
||||||
std::string debugNode();
|
std::string debugNode();
|
||||||
|
|
||||||
// Remove this node from its parent, deleting the parent if it was
|
// Remove this node from its parent, deleting the parent if it was
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
namespace selection_hook {
|
namespace selection_hook {
|
||||||
inline CFunctionHook* g_LastSelectionHook = nullptr;
|
inline CFunctionHook* g_LastSelectionHook = nullptr;
|
||||||
|
|
||||||
void hook_updateDecos(void* thisptr, CWindow* window) {
|
void hook_updateDecos(void* thisptr, PHLWINDOW window) {
|
||||||
bool explicitly_selected = g_Hy3Layout->shouldRenderSelected(window);
|
bool explicitly_selected = g_Hy3Layout->shouldRenderSelected(window);
|
||||||
|
|
||||||
auto* lastWindow = g_pCompositor->m_pLastWindow;
|
auto lastWindow = g_pCompositor->m_pLastWindow;
|
||||||
if (explicitly_selected) {
|
if (explicitly_selected) {
|
||||||
g_pCompositor->m_pLastWindow = window;
|
g_pCompositor->m_pLastWindow = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
((void (*)(void*, CWindow*)) g_LastSelectionHook->m_pOriginal)(thisptr, window);
|
((void (*)(void*, PHLWINDOW)) g_LastSelectionHook->m_pOriginal)(thisptr, window);
|
||||||
|
|
||||||
if (explicitly_selected) {
|
if (explicitly_selected) {
|
||||||
g_pCompositor->m_pLastWindow = lastWindow;
|
g_pCompositor->m_pLastWindow = lastWindow;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
#include <hyprland/src/Compositor.hpp>
|
#include <hyprland/src/Compositor.hpp>
|
||||||
|
#include <hyprland/src/desktop/DesktopTypes.hpp>
|
||||||
|
#include <hyprland/src/desktop/Workspace.hpp>
|
||||||
#include <hyprland/src/helpers/Box.hpp>
|
#include <hyprland/src/helpers/Box.hpp>
|
||||||
#include <hyprland/src/helpers/Color.hpp>
|
#include <hyprland/src/helpers/Color.hpp>
|
||||||
#include <hyprland/src/render/OpenGL.hpp>
|
#include <hyprland/src/render/OpenGL.hpp>
|
||||||
|
@ -328,7 +330,7 @@ exitloop:
|
||||||
|
|
||||||
// set stats from node data
|
// set stats from node data
|
||||||
auto* parent = (*node)->parent;
|
auto* parent = (*node)->parent;
|
||||||
auto& parent_group = parent->data.as_group;
|
auto& parent_group = parent->data.as_group();
|
||||||
|
|
||||||
entry->setFocused(
|
entry->setFocused(
|
||||||
parent_group.focused_child == *node
|
parent_group.focused_child == *node
|
||||||
|
@ -433,11 +435,11 @@ void Hy3TabGroup::updateWithGroup(Hy3Node& node, bool warp) {
|
||||||
if (warp) this->size.warp();
|
if (warp) this->size.warp();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->bar.updateNodeList(node.data.as_group.children);
|
this->bar.updateNodeList(node.data.as_group().children);
|
||||||
this->bar.updateAnimations(warp);
|
this->bar.updateAnimations(warp);
|
||||||
|
|
||||||
if (node.data.as_group.focused_child != nullptr) {
|
if (node.data.as_group().focused_child != nullptr) {
|
||||||
this->updateStencilWindows(*node.data.as_group.focused_child);
|
this->updateStencilWindows(*node.data.as_group().focused_child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,8 +541,9 @@ void Hy3TabGroup::renderTabBar() {
|
||||||
|
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
|
||||||
for (auto* window: this->stencil_windows) {
|
for (auto windowref: this->stencil_windows) {
|
||||||
if (!g_pCompositor->windowExists(window)) continue;
|
if (!valid(windowref)) continue;
|
||||||
|
auto window = windowref.lock();
|
||||||
|
|
||||||
auto wpos = window->m_vRealPosition.value() - monitor->vecPosition;
|
auto wpos = window->m_vRealPosition.value() - monitor->vecPosition;
|
||||||
auto wsize = window->m_vRealSize.value();
|
auto wsize = window->m_vRealSize.value();
|
||||||
|
@ -603,11 +606,11 @@ void Hy3TabGroup::renderTabBar() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void findOverlappingWindows(Hy3Node& node, float height, std::vector<CWindow*>& windows) {
|
void findOverlappingWindows(Hy3Node& node, float height, std::vector<PHLWINDOWREF>& windows) {
|
||||||
switch (node.data.type) {
|
switch (node.data.type()) {
|
||||||
case Hy3NodeType::Window: windows.push_back(node.data.as_window); break;
|
case Hy3NodeType::Window: windows.push_back(node.data.as_window()); break;
|
||||||
case Hy3NodeType::Group:
|
case Hy3NodeType::Group:
|
||||||
auto& group = node.data.as_group;
|
auto& group = node.data.as_group();
|
||||||
|
|
||||||
switch (group.layout) {
|
switch (group.layout) {
|
||||||
case Hy3GroupLayout::SplitH:
|
case Hy3GroupLayout::SplitH:
|
||||||
|
|
|
@ -85,7 +85,7 @@ private:
|
||||||
|
|
||||||
class Hy3TabGroup {
|
class Hy3TabGroup {
|
||||||
public:
|
public:
|
||||||
CWindow* target_window = nullptr;
|
PHLWINDOW target_window = nullptr;
|
||||||
PHLWORKSPACE workspace = nullptr;
|
PHLWORKSPACE workspace = nullptr;
|
||||||
bool hidden = false;
|
bool hidden = false;
|
||||||
Hy3TabBar bar;
|
Hy3TabBar bar;
|
||||||
|
@ -102,7 +102,7 @@ public:
|
||||||
void renderTabBar();
|
void renderTabBar();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CWindow*> stencil_windows;
|
std::vector<PHLWINDOWREF> stencil_windows;
|
||||||
Vector2D last_pos;
|
Vector2D last_pos;
|
||||||
Vector2D last_size;
|
Vector2D last_size;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue