Skip to content

Commit 7be897d

Browse files
authored
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
1 parent 4d940a1 commit 7be897d

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

hyprscrolling/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ plugin {
3939
| promote | moves a window to its own new column | none |
4040
| 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` |
4141
| 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|
42+
| togglefit | Toggle the focus_fit_method (center, fit) | none |
4243

4344
Example key bindings for your Hyprland config:
4445
```

hyprscrolling/Scrolling.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,66 @@ std::any CScrollingLayout::layoutMessage(SLayoutMessageHeader header, std::strin
13441344

13451345
g_pCompositor->focusWindow(windowsToMove.front());
13461346
g_pCompositor->warpCursorTo(windowsToMove.front()->middle());
1347+
} else if (ARGS[0] == "togglefit") {
1348+
static const auto PFITMETHOD = CConfigValue<Hyprlang::INT>("plugin:hyprscrolling:focus_fit_method");
1349+
auto& fitMethod = *PFITMETHOD.ptr();
1350+
const int toggled = fitMethod ^ 1;
1351+
1352+
fitMethod = toggled;
1353+
1354+
const auto focusedData = dataFor(g_pCompositor->m_lastWindow.lock());
1355+
static const auto PFSONONE = CConfigValue<Hyprlang::INT>("plugin:hyprscrolling:fullscreen_on_one_column");
1356+
1357+
for (const auto& ws : m_workspaceDatas) {
1358+
if (!ws || ws->columns.empty())
1359+
continue;
1360+
1361+
const auto monitor = ws->workspace->m_monitor.lock();
1362+
if (!monitor)
1363+
continue;
1364+
1365+
const auto USABLE = usableAreaFor(monitor);
1366+
1367+
const auto focusedColumn = (focusedData && focusedData->column && focusedData->column->workspace.lock() == ws) ? focusedData->column.lock() : nullptr;
1368+
1369+
const auto fallbackColumn = ws->atCenter();
1370+
1371+
if (toggled == 1) {
1372+
const auto columnToFit = focusedColumn ? focusedColumn : fallbackColumn;
1373+
if (!columnToFit)
1374+
continue;
1375+
1376+
double currentLeft = 0.0;
1377+
for (const auto& col : ws->columns) {
1378+
const double itemWidth = *PFSONONE && ws->columns.size() == 1 ? USABLE.w : USABLE.w * col->columnWidth;
1379+
1380+
if (col == columnToFit) {
1381+
const double colLeft = currentLeft;
1382+
const double colRight = currentLeft + itemWidth;
1383+
const double scrollMax = std::max(ws->maxWidth() - USABLE.w, 0.0);
1384+
double desiredOffset;
1385+
1386+
if (col == ws->columns.front())
1387+
desiredOffset = 0.0;
1388+
else
1389+
desiredOffset = std::clamp(colRight - USABLE.w, 0.0, scrollMax);
1390+
1391+
ws->leftOffset = desiredOffset;
1392+
break;
1393+
}
1394+
1395+
currentLeft += itemWidth;
1396+
}
1397+
} else {
1398+
const auto columnToCenter = focusedColumn ? focusedColumn : fallbackColumn;
1399+
if (!columnToCenter)
1400+
continue;
1401+
1402+
ws->centerCol(columnToCenter);
1403+
}
1404+
1405+
ws->recalculate();
1406+
}
13471407
}
13481408
return {};
13491409
}

0 commit comments

Comments
 (0)