mirror of
https://github.com/hyprwm/hyprland-plugins.git
synced 2025-10-29 19:58:49 +00:00
Hyprscrolling: focus left/right moves to the best vertical neighbour (#482)
* Hyprscrolling: feat: focus left/right moves to the best vertical neighbour (closes #473) When moving focus horizontally between columns we now pick the window whose vertical span overlaps the current window the most. If no overlap exists we fall back to the top-most window of the target column. This makes `layoutmsg focus l/r` behave intuitively in multi-column setups: from the bottom-left terminal you land on the bottom-left terminal of the neighbouring column instead of always jumping to the top. * Hyprscrolling: fix: remove `{}` from short ifs in `findBestNeighbor()` * Hyprscrolling: fix: Simplify nested ifs
This commit is contained in:
parent
5ff379f4e5
commit
ebb4040cac
@ -773,6 +773,30 @@ void CScrollingLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFull
|
||||
g_pCompositor->changeWindowZOrder(pWindow, true);
|
||||
}
|
||||
|
||||
SP<SScrollingWindowData> CScrollingLayout::findBestNeighbor(SP<SScrollingWindowData> pCurrent, SP<SColumnData> pTargetCol) {
|
||||
if (!pCurrent || !pTargetCol || pTargetCol->windowDatas.empty())
|
||||
return nullptr;
|
||||
|
||||
const double currentTop = pCurrent->layoutBox.y;
|
||||
const double currentBottom = pCurrent->layoutBox.y + pCurrent->layoutBox.h;
|
||||
SP<SScrollingWindowData> bestMatch = nullptr;
|
||||
|
||||
for (const auto& candidate : pTargetCol->windowDatas) {
|
||||
const double candidateTop = candidate->layoutBox.y;
|
||||
const double candidateBottom = candidate->layoutBox.y + candidate->layoutBox.h;
|
||||
|
||||
const bool overlaps = (candidateTop < currentBottom) && (candidateBottom > currentTop);
|
||||
|
||||
if (overlaps && (!bestMatch || candidateTop < bestMatch->layoutBox.y))
|
||||
bestMatch = candidate;
|
||||
}
|
||||
|
||||
if (!bestMatch && !pTargetCol->windowDatas.empty())
|
||||
return pTargetCol->windowDatas.front();
|
||||
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
std::any CScrollingLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
|
||||
static auto centerOrFit = [](const SP<SWorkspaceData> WS, const SP<SColumnData> COL) -> void {
|
||||
static const auto PFITMETHOD = CConfigValue<Hyprlang::INT>("plugin:hyprscrolling:focus_fit_method");
|
||||
@ -1108,7 +1132,8 @@ std::any CScrollingLayout::layoutMessage(SLayoutMessageHeader header, std::strin
|
||||
PREV = WDATA->column->workspace->columns.back();
|
||||
}
|
||||
|
||||
g_pCompositor->focusWindow(PREV->windowDatas.front()->window.lock());
|
||||
auto pTargetWindowData = findBestNeighbor(WDATA, PREV);
|
||||
g_pCompositor->focusWindow(pTargetWindowData->window.lock());
|
||||
centerOrFit(WDATA->column->workspace.lock(), PREV);
|
||||
WDATA->column->workspace->recalculate();
|
||||
g_pCompositor->warpCursorTo(PREV->windowDatas.front()->window.lock()->middle());
|
||||
@ -1127,7 +1152,8 @@ std::any CScrollingLayout::layoutMessage(SLayoutMessageHeader header, std::strin
|
||||
NEXT = WDATA->column->workspace->columns.front();
|
||||
}
|
||||
|
||||
g_pCompositor->focusWindow(NEXT->windowDatas.front()->window.lock());
|
||||
auto pTargetWindowData = findBestNeighbor(WDATA, NEXT);
|
||||
g_pCompositor->focusWindow(pTargetWindowData->window.lock());
|
||||
centerOrFit(WDATA->column->workspace.lock(), NEXT);
|
||||
WDATA->column->workspace->recalculate();
|
||||
g_pCompositor->warpCursorTo(NEXT->windowDatas.front()->window.lock()->middle());
|
||||
|
||||
@ -114,6 +114,7 @@ class CScrollingLayout : public IHyprLayout {
|
||||
std::vector<float> configuredWidths;
|
||||
} m_config;
|
||||
|
||||
SP<SScrollingWindowData> findBestNeighbor(SP<SScrollingWindowData> pCurrent, SP<SColumnData> pTargetCol);
|
||||
SP<SWorkspaceData> dataFor(PHLWORKSPACE ws);
|
||||
SP<SScrollingWindowData> dataFor(PHLWINDOW w);
|
||||
SP<SWorkspaceData> currentWorkspaceData();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user