Experimental Hyprland plugin for treating numeric workspaces as a fixed 10x10 grid.
The plugin registers Lua callbacks under hl.plugin.grid and maps grid coordinates to workspace IDs:
workspace_id = (row - 1) * 10 + col
Alpha / personal-use ready. Hyprland plugins are ABI-sensitive, so rebuild this plugin after Hyprland updates and use it with the Hyprland version it was compiled against.
- Switch to a column while keeping the current row.
- Switch to a row while keeping the current column.
- Move horizontally by a relative column delta.
- Move the focused window to a column in the current row.
- Direction-aware animation styles for horizontal/vertical movement.
- Hyprland headers / development package
pkg-config- C++ compiler with C++23 support
- Development packages used by Hyprland headers, including
pixman-1,libdrm,pangocairo,libinput,libudev,wayland-server,xkbcommon, and Lua headers
hyprpm add https://github.com/lostf1sh/hyprgrid
hyprpm enable hyprgrid
hyprpm reloadAfter Hyprland updates, rebuild/update plugins:
hyprpm update
hyprpm reloadmakeThis creates:
gridworkspace.so
make installBy default this installs to:
~/.config/hypr/plugins/gridworkspace.so
You can override the install directory:
make install INSTALL_DIR=/absolute/path/to/pluginsThen load the plugin from your Hyprland config using an absolute path, for example:
plugin = /home/you/.config/hypr/plugins/gridworkspace.soRestart or reload Hyprland after changing plugin configuration.
After the plugin is loaded, these callbacks are available from Hyprland's Lua config environment:
hl.plugin.grid.col(col) -- switch to column col in the active row, col: 1..10
hl.plugin.grid.row(row) -- switch to row row in the active column, row: 1..10
hl.plugin.grid.col_rel(delta) -- move horizontally by delta columns, clamped to 1..10
hl.plugin.grid.move(col) -- move focused window to column col in the active row, col: 1..10Examples:
hl.plugin.grid.row(2)
hl.plugin.grid.col(5)
hl.plugin.grid.col_rel(-1)
hl.plugin.grid.move(4)These examples are for Hyprland's Lua config (hyprland.lua). Wrap plugin calls in functions so they run when the keybind is pressed, not while the config is loading.
local mainMod = "SUPER"
-- SUPER + [1-0]: switch column in the current row.
-- SUPER + SHIFT + [1-0]: move focused window to column in the current row.
-- SUPER + CTRL + [1-0]: switch row while keeping the current column.
for i = 1, 10 do
local key = i % 10 -- 10 maps to key 0
hl.bind(mainMod .. " + " .. key, function()
hl.plugin.grid.col(i)
end)
hl.bind(mainMod .. " + SHIFT + " .. key, function()
hl.plugin.grid.move(i)
end)
hl.bind(mainMod .. " + CTRL + " .. key, function()
hl.plugin.grid.row(i)
end)
end
-- Horizontal movement across columns.
hl.bind(mainMod .. " + left", function()
hl.plugin.grid.col_rel(-1)
end)
hl.bind(mainMod .. " + right", function()
hl.plugin.grid.col_rel(1)
end)Possible future improvements:
- Add
row_rel(delta)for vertical relative movement. - Add
goto(row, col)for direct coordinate-based workspace switching. - Add
move_to(row, col)for moving the focused window to an exact grid coordinate. - Add
move_row(row)for moving the focused window to another row while keeping the current column. - Add optional wrap mode instead of clamping at grid edges.
- Make grid dimensions configurable instead of hard-coded 10x10.
- Make horizontal/vertical animation styles configurable.
- Track grid state per monitor for better multi-monitor behavior.
- Remember the last column per row.
- Publish release artifacts tied to specific Hyprland ABI versions.
make clean
makeBuild artifacts such as *.so are intentionally ignored by git. Publish source in the repository and attach compiled .so files to GitHub releases only when they are tied to a specific Hyprland version / ABI.
MIT