HyprExpo is a maintained Hyprland plugin for expose-style workspace overview with keyboard selection, drag-drop window movement, labels, configurable gaps and borders, multi-monitor placement, and Lua gestures.
If you experience any bugs, you are encouraged to open an issue. Information I can use to reproduce a bug is appreciated.
Docs (markdown) - Docs (website) - Announcement Post
HyprExpo continues the original expose-style workspace overview plugin from the Hyprland plugins ecosystem. After the upstream plugin was retired from official plugins, this fork signaled contiuation and intends to chase Hyprland releases.
Born from a PR to the old official HyprExpo and formerly known as HyperExpo+ (hyprexpo-plus), has become the home for practical additions that made the
overview more usable day to day: keyboard navigation, visible workspace labels, configurable gaps and borders, multi-monitor placement, and Lua gesture setup.
See the upstream retirement context
and the original launch announcement of this plugin
for the project's well established background.
- https://github.com/colonelpanic8/hyprexpo - Another HyprExpo fork
hyprpm add https://github.com/sandwichfarm/hyprexpo
hyprpm enable hyprexpo
hyprpm reloadThe repository name in hyprpm.toml is hyprexpo, and the built plugin output is hyprexpo.so.
Install a C++23 compiler, pkg-config, Hyprland development headers, and these pkg-config packages:
hyprland pixman-1 libdrm pangocairo libinput libudev wayland-server xkbcommon lua5.4
Build with the Makefile:
git clone https://github.com/sandwichfarm/hyprexpo
cd hyprexpo
make allInstall the local build over the hyprpm-managed copy:
make install
hyprpm reloadUse install or make install, not plain cp, when replacing a loaded .so. Hyprland maps plugin files into the running process, and overwriting that file in place can corrupt the live mapping.
Other build entry points:
meson setup build
meson compile -C buildcmake -S . -B build
cmake --build buildNix users should build HyprExpo through the Nix Hyprland plugin path instead of mixing a hyprpm artifact into a Nix-managed Hyprland session. This repository includes default.nix, which uses hyprlandPlugins.mkHyprlandPlugin so the plugin follows the Hyprland input supplied by the caller.
Hyprland plugins are ABI-sensitive. Keep the plugin build and running Hyprland revision aligned.
Add the plugin block to your Hyprland config:
plugin {
hyprexpo {
columns = 3
gaps_in = 5
gaps_out = 0
bg_col = rgb(111111)
workspace_method = center current
gesture_distance = 200
cancel_key = escape
show_cursor = 1
}
}Add a dispatcher binding:
bind = SUPER, g, hyprexpo:expo, toggleOptional keyboard navigation:
plugin {
hyprexpo {
keynav_enable = 1
keynav_wrap_h = 1
keynav_wrap_v = 1
keynav_reading_order = 0
}
}
submap = hyprexpo
bind = , left, hyprexpo:kb_focus, left
bind = , right, hyprexpo:kb_focus, right
bind = , up, hyprexpo:kb_focus, up
bind = , down, hyprexpo:kb_focus, down
bind = , return, hyprexpo:kb_confirm
bind = , escape, hyprexpo:expo, cancel
bind = , 1, hyprexpo:kb_selecti, 1
bind = , 2, hyprexpo:kb_selecti, 2
bind = , 3, hyprexpo:kb_selecti, 3
bind = , 4, hyprexpo:kb_selecti, 4
bind = , 5, hyprexpo:kb_selecti, 5
bind = , 6, hyprexpo:kb_selecti, 6
bind = , 7, hyprexpo:kb_selecti, 7
bind = , 8, hyprexpo:kb_selecti, 8
bind = , 9, hyprexpo:kb_selecti, 9
bind = , 0, hyprexpo:kb_selecti, 10
submap = resetFor hyprland.lua, define the same active submap in Lua instead of adding a
submap = hyprexpo block to hyprland.conf:
hl.define_submap("hyprexpo", function()
hl.bind("h", function() hl.plugin.hyprexpo.kb_focus("left") end)
hl.bind("l", function() hl.plugin.hyprexpo.kb_focus("right") end)
hl.bind("k", function() hl.plugin.hyprexpo.kb_focus("up") end)
hl.bind("j", function() hl.plugin.hyprexpo.kb_focus("down") end)
hl.bind("return", function() hl.plugin.hyprexpo.kb_confirm() end)
hl.bind("escape", function() hl.plugin.hyprexpo.expo("cancel") end)
end)