Allow focusing tab groups via mouse click

This commit is contained in:
outfoxxed 2023-06-04 20:26:22 -07:00
parent 0b56b11d38
commit 6331f32d1f
No known key found for this signature in database
GPG key ID: 4C88A185FB89301E
4 changed files with 62 additions and 0 deletions

View file

@ -98,6 +98,7 @@ plugin {
- `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:focustab` - focus a tab under the mouse (bind to `mouse:272` for left click)
- `hy3:debugnodes` - print the node tree into the hyprland log
## Installing

View file

@ -1544,6 +1544,57 @@ void Hy3Layout::raiseFocus(int workspace) {
}
}
Hy3Node* Hy3Node::findNodeForTabGroup(Hy3TabGroup& tab_group) {
if (this->data.type == Hy3NodeData::Group) {
auto& group = this->data.as_group;
if (group.layout == Hy3GroupLayout::Tabbed && group.tab_bar == &tab_group) {
return this;
}
for (auto& node: group.children) {
auto* r = node->findNodeForTabGroup(tab_group);
if (r != nullptr) return r;
}
} else return nullptr;
return nullptr;
}
void Hy3Layout::focusTab(int workspace) {
auto* node = this->getWorkspaceRootGroup(workspace);
if (node == nullptr) return;
auto mouse_pos = g_pInputManager->getMouseCoordsInternal();
for (auto& tab_group: this->tab_groups) {
auto pos = tab_group.pos.vec();
if (pos.x > mouse_pos.x || pos.y > mouse_pos.y) continue;
auto size = tab_group.size.vec();
if (pos.x + size.x < mouse_pos.x || pos.y + size.y < mouse_pos.y) continue;
Debug::log(LOG, "!!! tab group clicked: %f %f, %f %f [%f %f]", pos.x, pos.y, size.x, size.y, mouse_pos.x, mouse_pos.y);
auto* group = node->findNodeForTabGroup(tab_group);
if (group == nullptr) continue;
auto delta = mouse_pos - pos;
auto& node_list = group->data.as_group.children;
auto node_iter = node_list.begin();
for (auto& tab: tab_group.bar.entries) {
if (node_iter == node_list.end()) break;
if (delta.x > tab.offset.fl() * size.x && delta.x < (tab.offset.fl() + tab.width.fl()) * size.x) {
(*node_iter)->focus();
break;
}
node_iter = std::next(node_iter);
}
}
}
bool Hy3Layout::shouldRenderSelected(CWindow* window) {
if (window == nullptr) return false;
auto* root = this->getWorkspaceRootGroup(window->m_iWorkspaceID);

View file

@ -88,6 +88,7 @@ struct Hy3Node {
void updateTabBarRecursive();
bool isUrgent();
bool isIndirectlyFocused();
Hy3Node* findNodeForTabGroup(Hy3TabGroup&);
std::string getTitle();
bool operator==(const Hy3Node&) const;
@ -133,6 +134,7 @@ public:
void shiftWindow(int, ShiftDirection, bool);
void shiftFocus(int, ShiftDirection);
void raiseFocus(int);
void focusTab(int);
bool shouldRenderSelected(CWindow*);

View file

@ -88,6 +88,13 @@ void dispatch_raisefocus(std::string arg) {
g_Hy3Layout->raiseFocus(workspace);
}
void dispatch_focustab(std::string arg) {
int workspace = workspace_for_action();
if (workspace == -1) return;
g_Hy3Layout->focusTab(workspace);
}
void dispatch_debug(std::string arg) {
int workspace = workspace_for_action();
if (workspace == -1) return;
@ -128,6 +135,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
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:focustab", dispatch_focustab);
HyprlandAPI::addDispatcher(PHANDLE, "hy3:debugnodes", dispatch_debug);
return {"hy3", "i3 like layout for hyprland", "outfoxxed", "0.1"};