mirror of
https://github.com/Trensa-Organization/hy3.git
synced 2025-03-15 10:43:40 +01:00
feat: add cursor warping support to hy3:movefocus
This commit is contained in:
parent
bc25b2a87f
commit
311939d443
7 changed files with 72 additions and 22 deletions
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
## Upcoming
|
||||
|
||||
- Added cursor warping options for `hy3:movefocus`.
|
||||
|
||||
## hl0.37.1 and before
|
||||
|
||||
- Added `no_gaps_when_only = 2`
|
||||
|
|
|
@ -317,8 +317,10 @@ plugin {
|
|||
- `toggletab` will untab if group is tabbed, and tab if group is untabbed
|
||||
- `opposite` will toggle between horizontal and vertical layouts if the group is not tabbed.
|
||||
- `hy3:setephemeral, <true | false>` - change the ephemerality of the group the node belongs to
|
||||
- `hy3:movefocus, <l | u | d | r | left | down | up | right>, [visible]` - move the focus left, up, down, or right
|
||||
- `hy3:movefocus, <l | u | d | r | left | down | up | right>, [visible], [warp | nowarp]` - move the focus left, up, down, or right
|
||||
- `visible` - only move between visible nodes, not hidden tabs
|
||||
- `warp` - warp the mouse to the selected window, even if `general:no_cursor_warps` is true.
|
||||
- `nowarp` - does not warp the mouse to the selected window, even if `general:no_cursor_warps` is false.
|
||||
- `hy3:movewindow, <l | u | d | r | left | down | up | right>, [once], [visible]` - move a window left, up, down, or right
|
||||
- `once` - only move directly to the neighboring group, without moving into any of its subgroups
|
||||
- `visible` - only move between visible nodes, not hidden tabs
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <ranges>
|
||||
|
||||
#include "Hy3Layout.hpp"
|
||||
#include "Hy3Node.hpp"
|
||||
#include "SelectionHook.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
|
@ -878,7 +879,12 @@ void Hy3Layout::shiftWindow(
|
|||
this->shiftNode(*node, direction, once, visible);
|
||||
}
|
||||
|
||||
void Hy3Layout::shiftFocus(const PHLWORKSPACE& workspace, ShiftDirection direction, bool visible) {
|
||||
void Hy3Layout::shiftFocus(
|
||||
const PHLWORKSPACE& workspace,
|
||||
ShiftDirection direction,
|
||||
bool visible,
|
||||
bool warp
|
||||
) {
|
||||
auto current_window = g_pCompositor->m_pLastWindow.lock();
|
||||
|
||||
if (current_window != nullptr) {
|
||||
|
@ -893,7 +899,10 @@ void Hy3Layout::shiftFocus(const PHLWORKSPACE& workspace, ShiftDirection directi
|
|||
: 'r'
|
||||
);
|
||||
|
||||
if (next_window != nullptr) g_pCompositor->focusWindow(next_window);
|
||||
if (next_window != nullptr) {
|
||||
g_pCompositor->focusWindow(next_window);
|
||||
if (warp) Hy3Layout::warpCursorToBox(next_window->m_vPosition, next_window->m_vSize);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -904,7 +913,13 @@ void Hy3Layout::shiftFocus(const PHLWORKSPACE& workspace, ShiftDirection directi
|
|||
auto* target = this->shiftOrGetFocus(*node, direction, false, false, visible);
|
||||
|
||||
if (target != nullptr) {
|
||||
target->focus();
|
||||
if (warp) {
|
||||
// don't warp for nodes in the same tab
|
||||
warp = node->parent == nullptr || target->parent == nullptr || node->parent != target->parent
|
||||
|| node->parent->data.as_group().layout != Hy3GroupLayout::Tabbed;
|
||||
}
|
||||
|
||||
target->focus(warp);
|
||||
while (target->parent != nullptr) target = target->parent;
|
||||
target->recalcSizePosRecursive();
|
||||
}
|
||||
|
@ -1007,24 +1022,24 @@ void Hy3Layout::changeFocus(const PHLWORKSPACE& workspace, FocusShift shift) {
|
|||
node = node->parent;
|
||||
}
|
||||
|
||||
node->focus();
|
||||
node->focus(false);
|
||||
return;
|
||||
case FocusShift::Raise:
|
||||
if (node->parent == nullptr) goto bottom;
|
||||
else {
|
||||
node->parent->focus();
|
||||
node->parent->focus(false);
|
||||
}
|
||||
return;
|
||||
case FocusShift::Lower:
|
||||
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(false);
|
||||
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();
|
||||
node->focus(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1036,7 +1051,7 @@ void Hy3Layout::changeFocus(const PHLWORKSPACE& workspace, FocusShift shift) {
|
|||
if (node->parent != nullptr) node = node->parent;
|
||||
while (node->parent != nullptr) {
|
||||
if (node->parent->data.as_group().layout == Hy3GroupLayout::Tabbed) {
|
||||
node->focus();
|
||||
node->focus(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1065,7 @@ bottom:
|
|||
node = node->data.as_group().focused_child;
|
||||
}
|
||||
|
||||
node->focus();
|
||||
node->focus(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1202,7 +1217,7 @@ hastab:
|
|||
&& focus->data.as_group().focused_child != nullptr)
|
||||
focus = focus->data.as_group().focused_child;
|
||||
|
||||
focus->focus();
|
||||
focus->focus(false);
|
||||
tab_node->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
|
@ -1324,6 +1339,16 @@ fsupdate:
|
|||
this->recalculateMonitor(monitor->ID);
|
||||
}
|
||||
|
||||
void Hy3Layout::warpCursorToBox(const Vector2D& pos, const Vector2D& size) {
|
||||
auto cursorpos = Vector2D(g_pCompositor->m_sWLRCursor->x, g_pCompositor->m_sWLRCursor->y);
|
||||
|
||||
if (cursorpos.x < pos.x || cursorpos.x >= pos.x + size.x || cursorpos.y < pos.y
|
||||
|| cursorpos.y >= pos.y + size.y)
|
||||
{
|
||||
g_pCompositor->warpCursorTo(pos + size / 2, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool Hy3Layout::shouldRenderSelected(const PHLWINDOW& window) {
|
||||
if (window == nullptr) return false;
|
||||
auto* root = this->getWorkspaceRootGroup(window->m_pWorkspace);
|
||||
|
@ -1791,7 +1816,7 @@ Hy3Node* Hy3Layout::shiftOrGetFocus(
|
|||
}
|
||||
|
||||
node.updateTabBarRecursive();
|
||||
node.focus();
|
||||
node.focus(false);
|
||||
|
||||
if (target_parent != target_group && target_parent != nullptr)
|
||||
target_parent->recalcSizePosRecursive();
|
||||
|
|
|
@ -112,7 +112,7 @@ public:
|
|||
void changeGroupEphemeralityOn(Hy3Node&, bool ephemeral);
|
||||
void shiftNode(Hy3Node&, ShiftDirection, bool once, bool visible);
|
||||
void shiftWindow(const PHLWORKSPACE& workspace, ShiftDirection, bool once, bool visible);
|
||||
void shiftFocus(const PHLWORKSPACE& workspace, ShiftDirection, bool visible);
|
||||
void shiftFocus(const PHLWORKSPACE& workspace, ShiftDirection, bool visible, bool warp);
|
||||
void moveNodeToWorkspace(const PHLWORKSPACE& origin, std::string wsname, bool follow);
|
||||
void changeFocus(const PHLWORKSPACE& workspace, FocusShift);
|
||||
void focusTab(
|
||||
|
@ -125,6 +125,7 @@ public:
|
|||
void setNodeSwallow(const PHLWORKSPACE& workspace, SetSwallowOption);
|
||||
void killFocusedNode(const PHLWORKSPACE& workspace);
|
||||
void expand(const PHLWORKSPACE& workspace, ExpandOption, ExpandFullscreenOption);
|
||||
static void warpCursorToBox(const Vector2D& pos, const Vector2D& size);
|
||||
|
||||
bool shouldRenderSelected(const PHLWINDOW&);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <hyprland/src/helpers/Box.hpp>
|
||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
||||
|
||||
#include "Hy3Layout.hpp"
|
||||
#include "Hy3Node.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
|
@ -163,19 +164,25 @@ PHLWINDOW Hy3NodeData::as_window() {
|
|||
|
||||
bool Hy3Node::operator==(const Hy3Node& rhs) const { return this->data == rhs.data; }
|
||||
|
||||
void Hy3Node::focus() {
|
||||
void Hy3Node::focus(bool warp) {
|
||||
this->markFocused();
|
||||
|
||||
switch (this->data.type()) {
|
||||
case Hy3NodeType::Window:
|
||||
this->data.as_window()->setHidden(false);
|
||||
g_pCompositor->focusWindow(this->data.as_window());
|
||||
case Hy3NodeType::Window: {
|
||||
auto window = this->data.as_window();
|
||||
window->setHidden(false);
|
||||
g_pCompositor->focusWindow(window);
|
||||
if (warp) Hy3Layout::warpCursorToBox(window->m_vPosition, window->m_vSize);
|
||||
break;
|
||||
case Hy3NodeType::Group:
|
||||
}
|
||||
case Hy3NodeType::Group: {
|
||||
g_pCompositor->focusWindow(nullptr);
|
||||
this->raiseToTop();
|
||||
|
||||
if (warp) Hy3Layout::warpCursorToBox(this->position, this->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PHLWINDOW Hy3Node::bringToTop() {
|
||||
|
|
|
@ -95,7 +95,7 @@ struct Hy3Node {
|
|||
|
||||
bool operator==(const Hy3Node&) const;
|
||||
|
||||
void focus();
|
||||
void focus(bool warp);
|
||||
void focusWindow();
|
||||
PHLWINDOW bringToTop();
|
||||
void markFocused();
|
||||
|
|
|
@ -113,9 +113,20 @@ void dispatch_movefocus(std::string value) {
|
|||
|
||||
auto args = CVarList(value);
|
||||
|
||||
if (auto shift = parseShiftArg(args[0])) {
|
||||
g_Hy3Layout->shiftFocus(workspace, shift.value(), args[1] == "visible");
|
||||
}
|
||||
static const auto no_cursor_warps = ConfigValue<Hyprlang::INT>("general:no_cursor_warps");
|
||||
auto warp_cursor = !*no_cursor_warps;
|
||||
|
||||
int argi = 0;
|
||||
auto shift = parseShiftArg(args[argi++]);
|
||||
if (!shift) return;
|
||||
|
||||
auto visible = args[argi] == "visible";
|
||||
if (visible) argi++;
|
||||
|
||||
if (args[argi] == "nowarp") warp_cursor = false;
|
||||
else if (args[argi] == "warp") warp_cursor = true;
|
||||
|
||||
g_Hy3Layout->shiftFocus(workspace, shift.value(), visible, warp_cursor);
|
||||
}
|
||||
|
||||
void dispatch_move_to_workspace(std::string value) {
|
||||
|
|
Loading…
Add table
Reference in a new issue