Hyprscrolling: (feat) Add togglefit command (#498)

* Hyprscrolling: (feat) Add `togglefit` command

* fix multi-workspaces bugs and focus change bug.

* fix center to fitcol bug

* remove "fullyvisible" logic to simplify the logic
This commit is contained in:
Ralph Zhou 2025-10-06 19:00:49 +08:00 committed by GitHub
parent 4d940a10af
commit 7be897d6ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 0 deletions

View File

@ -39,6 +39,7 @@ plugin {
| promote | moves a window to its own new column | none |
| swapcol | Swaps the current column with its neighbor to the left (`l`) or right (`r`). The swap wraps around (e.g., swapping the first column left moves it to the end). | `l` or `r` |
| movecoltoworkspace | Moves the entire current column to the specified workspace, preserving its internal layout. Works with existing, new, and special workspaces. e.g. like `1`, `2`, `-1`, `+2`, `special`, etc. | workspace identifier|
| togglefit | Toggle the focus_fit_method (center, fit) | none |
Example key bindings for your Hyprland config:
```

View File

@ -1344,6 +1344,66 @@ std::any CScrollingLayout::layoutMessage(SLayoutMessageHeader header, std::strin
g_pCompositor->focusWindow(windowsToMove.front());
g_pCompositor->warpCursorTo(windowsToMove.front()->middle());
} else if (ARGS[0] == "togglefit") {
static const auto PFITMETHOD = CConfigValue<Hyprlang::INT>("plugin:hyprscrolling:focus_fit_method");
auto& fitMethod = *PFITMETHOD.ptr();
const int toggled = fitMethod ^ 1;
fitMethod = toggled;
const auto focusedData = dataFor(g_pCompositor->m_lastWindow.lock());
static const auto PFSONONE = CConfigValue<Hyprlang::INT>("plugin:hyprscrolling:fullscreen_on_one_column");
for (const auto& ws : m_workspaceDatas) {
if (!ws || ws->columns.empty())
continue;
const auto monitor = ws->workspace->m_monitor.lock();
if (!monitor)
continue;
const auto USABLE = usableAreaFor(monitor);
const auto focusedColumn = (focusedData && focusedData->column && focusedData->column->workspace.lock() == ws) ? focusedData->column.lock() : nullptr;
const auto fallbackColumn = ws->atCenter();
if (toggled == 1) {
const auto columnToFit = focusedColumn ? focusedColumn : fallbackColumn;
if (!columnToFit)
continue;
double currentLeft = 0.0;
for (const auto& col : ws->columns) {
const double itemWidth = *PFSONONE && ws->columns.size() == 1 ? USABLE.w : USABLE.w * col->columnWidth;
if (col == columnToFit) {
const double colLeft = currentLeft;
const double colRight = currentLeft + itemWidth;
const double scrollMax = std::max(ws->maxWidth() - USABLE.w, 0.0);
double desiredOffset;
if (col == ws->columns.front())
desiredOffset = 0.0;
else
desiredOffset = std::clamp(colRight - USABLE.w, 0.0, scrollMax);
ws->leftOffset = desiredOffset;
break;
}
currentLeft += itemWidth;
}
} else {
const auto columnToCenter = focusedColumn ? focusedColumn : fallbackColumn;
if (!columnToCenter)
continue;
ws->centerCol(columnToCenter);
}
ws->recalculate();
}
}
return {};
}