Change hy3:raisefocus to hy3:changefocus and add more options

This commit is contained in:
outfoxxed 2023-06-11 22:19:43 -07:00
parent 3107efb73e
commit ea43c60991
No known key found for this signature in database
GPG key ID: 4C88A185FB89301E
4 changed files with 88 additions and 36 deletions

View file

@ -94,7 +94,13 @@ plugin {
- `hy3:movefocus, <l | u | d | r | left | down | up | right>` - move the focus left, up, down, or right
- `hy3:movewindow, <l | u | d | r | left | down | up | right> [, once]` - move a window left, up, down, or right
- `once` - only move directly to the neighboring group, without moving into any of its subgroups
- `hy3:raisefocus` - raise the active focus one level
- `hy3:changefocus <top | bottom | raise | lower | tab | tabnode>`
- `top` - focus all nodes in the workspace
- `bottom` - focus the single root selection window
- `raise` - raise focus one level
- `lower` - lower focus one level
- `tab` - raise focus to the nearest tab
- `tabnode` - raise focus to the nearest node under the tab
- `hy3:debugnodes` - print the node tree into the hyprland log
## Installing

View file

@ -264,7 +264,9 @@ bool Hy3Node::isIndirectlyFocused() {
Hy3Node* node = this;
while (node->parent != nullptr) {
if (node->parent->data.as_group.focused_child != node) return false;
if (!node->parent->data.as_group.group_focused
&& node->parent->data.as_group.focused_child != node)
return false;
node = node->parent;
}
@ -295,17 +297,23 @@ std::string Hy3Node::getTitle() {
return "";
}
void markGroupFocusedRecursive(Hy3GroupData& group) {
group.group_focused = true;
for (auto& child: group.children) {
if (child->data.type == Hy3NodeData::Group) markGroupFocusedRecursive(child->data.as_group);
}
}
void Hy3Node::markFocused() {
Hy3Node* node = this;
// undo decos for root focus
auto* root = node;
while (root->parent != nullptr) root = root->parent;
auto* oldfocus = root->getFocusedNode();
// update focus
if (this->data.type == Hy3NodeData::Group) {
this->data.as_group.group_focused = true;
markGroupFocusedRecursive(this->data.as_group);
}
auto* node2 = node;
@ -315,26 +323,7 @@ void Hy3Node::markFocused() {
node2 = node2->parent;
}
while (node->parent != nullptr) {
node->parent->updateTabBar();
node = node->parent;
}
while (node2->parent != nullptr) {
node2->parent->data.as_group.focused_child = node2;
node2->parent->data.as_group.group_focused = false;
node2->parent->updateTabBar();
node2 = node2->parent;
}
if (oldfocus != nullptr) {
oldfocus->updateDecos();
while (oldfocus != nullptr) {
oldfocus->updateTabBar();
oldfocus = oldfocus->parent;
}
}
root->updateDecos();
}
void Hy3Node::focus() {
@ -615,6 +604,8 @@ void Hy3Node::updateDecos() {
for (auto* child: this->data.as_group.children) {
child->updateDecos();
}
this->updateTabBar();
}
}
@ -1616,21 +1607,62 @@ Hy3Layout::shiftOrGetFocus(Hy3Node& node, ShiftDirection direction, bool shift,
return nullptr;
}
void Hy3Layout::raiseFocus(int workspace) {
void Hy3Layout::changeFocus(int workspace, FocusShift shift) {
auto* node = this->getWorkspaceFocusedNode(workspace);
if (node == nullptr) return;
if (node->parent != nullptr) {
node->parent->focus();
node->parent->updateDecos();
} else {
// trace focus as far as possible
while (node->data.type == Hy3NodeData::Group && node->data.as_group.focused_child != nullptr) {
node = node->data.as_group.focused_child;
switch (shift) {
case FocusShift::Bottom: goto bottom;
case FocusShift::Top:
while (node->parent != nullptr) {
node = node->parent;
}
node->focus();
return;
case FocusShift::Raise:
if (node->parent == nullptr) goto bottom;
else {
node->parent->focus();
}
return;
case FocusShift::Lower:
if (node->data.type == Hy3NodeData::Group && node->data.as_group.focused_child != nullptr)
node->data.as_group.focused_child->focus();
return;
case FocusShift::Tab:
// make sure we go up at least one level
if (node->parent != nullptr) node = node->parent;
while (node->parent != nullptr) {
if (node->data.as_group.layout == Hy3GroupLayout::Tabbed) {
node->focus();
return;
}
node = node->parent;
}
return;
case FocusShift::TabNode:
// make sure we go up at least one level
if (node->parent != nullptr) node = node->parent;
while (node->parent != nullptr) {
if (node->parent->data.as_group.layout == Hy3GroupLayout::Tabbed) {
node->focus();
return;
}
node = node->parent;
}
return;
}
bottom:
while (node->data.type == Hy3NodeData::Group && node->data.as_group.focused_child != nullptr) {
node = node->data.as_group.focused_child;
}
node->focus();
return;
}
Hy3Node* Hy3Node::findNodeForTabGroup(Hy3TabGroup& tab_group) {

View file

@ -22,6 +22,15 @@ enum class ShiftDirection {
Right,
};
enum class FocusShift {
Top,
Bottom,
Raise,
Lower,
Tab,
TabNode,
};
struct Hy3GroupData {
Hy3GroupLayout layout = Hy3GroupLayout::SplitH;
std::list<Hy3Node*> children;
@ -136,7 +145,7 @@ public:
void makeOppositeGroupOn(Hy3Node*);
void shiftWindow(int, ShiftDirection, bool);
void shiftFocus(int, ShiftDirection);
void raiseFocus(int);
void changeFocus(int, FocusShift);
void focusTab(int);
bool shouldRenderSelected(CWindow*);

View file

@ -79,11 +79,16 @@ void dispatch_movefocus(std::string arg) {
}
}
void dispatch_raisefocus(std::string arg) {
void dispatch_changefocus(std::string arg) {
int workspace = workspace_for_action();
if (workspace == -1) return;
g_Hy3Layout->raiseFocus(workspace);
if (arg == "top") g_Hy3Layout->changeFocus(workspace, FocusShift::Top);
else if (arg == "bottom") g_Hy3Layout->changeFocus(workspace, FocusShift::Bottom);
else if (arg == "raise") g_Hy3Layout->changeFocus(workspace, FocusShift::Raise);
else if (arg == "lower") g_Hy3Layout->changeFocus(workspace, FocusShift::Lower);
else if (arg == "tab") g_Hy3Layout->changeFocus(workspace, FocusShift::Tab);
else if (arg == "tabnode") g_Hy3Layout->changeFocus(workspace, FocusShift::TabNode);
}
void dispatch_focustab(std::string arg) {
@ -169,7 +174,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
HyprlandAPI::addDispatcher(PHANDLE, "hy3:makegroup", dispatch_makegroup);
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movefocus", dispatch_movefocus);
HyprlandAPI::addDispatcher(PHANDLE, "hy3:movewindow", dispatch_movewindow);
HyprlandAPI::addDispatcher(PHANDLE, "hy3:raisefocus", dispatch_raisefocus);
HyprlandAPI::addDispatcher(PHANDLE, "hy3:changefocus", dispatch_changefocus);
HyprlandAPI::addDispatcher(PHANDLE, "hy3:focustab", dispatch_focustab);
HyprlandAPI::addDispatcher(PHANDLE, "hy3:debugnodes", dispatch_debug);