A standalone workspace overview module for Hyprland using Quickshell - shows all workspaces with live window previews, drag-and-drop support, and Super+Tab keybind.
output.mp4
Workspace overview showing live window previews with drag-and-drop support
- 🖼️ Visual workspace overview showing all workspaces and windows
- 🖥️ Multi-monitor support with proper scaling and vertical/rotated monitors [in experimental branch]
- 📐 Smart row hiding - optionally hide empty workspace rows
- 🎯 Click windows to focus them
- 🖱️ Middle-click windows to close them
- 🔄 Drag and drop windows between workspaces
- ⌨️ Keyboard navigation (Arrow keys, vim keys, number shortcuts)
- 🖱️ Auto-close on focus loss / outside click
- 💡 Hover tooltips showing window information
- 🎨 Material Design 3 theming
- ⚡ Smooth animations and transitions
For Arch Linux users, you can install directly from the AUR:
# Using yay
yay -S quickshell-overview-git
# Using paru
paru -S quickshell-overview-gitOn AUR installs, module files are package-managed under:
/etc/xdg/quickshell/overview/
Put your custom settings in:
~/.config/quickshell/overview/config.json
Then add the keybind and auto-start to your Hyprland config (see Setup steps 2-4 below).
- Hyprland compositor
- Quickshell (installation guide)
- Qt 6 with modules: QtQuick, QtQuick.Controls
-
Install module files (choose one):
- Git clone (manual install):
git clone https://github.com/Shanu-Kumawat/quickshell-overview ~/.config/quickshell/overview- AUR package: use the command above (
yay -S quickshell-overview-gitorparu -S ...)
-
Add keybind to your Hyprland config (
~/.config/hypr/hyprland.conf):bind = Super, TAB, exec, qs ipc -c overview call overview toggle -
Auto-start the overview (add to Hyprland config):
exec-once = qs -c overview -
Reload Hyprland:
hyprctl reload
qs -c overview &For NixOS users, ensure Quickshell has access to required Qt6 modules:
# In your configuration.nix or home-manager config
environment.systemPackages = with pkgs; [
quickshell
qt6.qtwayland
];If you're using home-manager:
home.packages = with pkgs; [
quickshell
qt6.qtwayland
];| Action | Description |
|---|---|
| Super + Tab | Toggle the overview |
| Arrow Keys / h/l | Navigate left/right within current row* |
| Up/Down / j/k | Navigate between workspace rows |
| 1-9, 0 | Jump to Nth workspace in current group (0 = 10th) |
| Mouse wheel on grid | Move across all normal workspaces, wrapping from last to first |
| Escape / Enter | Close the overview |
| Click outside overview | Close the overview when overview.closeOnFocusLoss is enabled (default) |
| Click workspace | Switch to that workspace |
| Click window | Focus that window |
| Middle-click window | Close that window |
| Drag window | Move window to different workspace |
*When
hideEmptyRowsis enabled, left/right navigation wraps within the current visible row for better UX
⚠️ Want to change size, position, workspace count, or toggles? Create/edit~/.config/quickshell/overview/config.json.
Config.qml inside the module is now treated as defaults. User overrides are read from:
$XDG_CONFIG_HOME/quickshell/overview/config.json- fallback:
~/.config/quickshell/overview/config.json
Note: After editing
config.json, manually restart overview for changes to apply:qs ipc -c overview call overview close && qs -c overview
mkdir -p ~/.config/quickshell/overview
cp /etc/xdg/quickshell/overview/config.example.json ~/.config/quickshell/overview/config.jsonIf you installed from git clone instead of AUR, copy from your repo path:
cp ~/.config/quickshell/overview/config.example.json ~/.config/quickshell/overview/config.jsonEdit ~/.config/quickshell/overview/config.json:
{
"overview": {
"rows": 2,
"columns": 5,
"scale": 0.16,
"enable": true,
"hideEmptyRows": true,
"closeOnFocusLoss": true,
"useWorkspaceMap": false,
"workspaceMap": [0, 10],
"orderRightLeft": false,
"orderBottomUp": false,
"previewsEnabled": true,
"previewMode": "live",
"includeInactiveMonitorPreviews": true,
"previewRecaptureDelayMs": 60,
"showSpecialWorkspaces": true,
"specialWorkspaces": [],
"specialWorkspaceColumns": 5,
"emptyWorkspaceWallpaper": "",
"specialEmptyWorkspaceWallpaper": "",
"effects": {
"enableBackdrop": false,
"backdropOpacity": 0.28,
"panelOpacity": 0.92,
"workspaceOpacity": 0.86,
"emptyWorkspaceWallpaperOverlayOpacity": 0.18,
"windowOverlayOpacity": 0.22,
"enableBlur": false,
"glassMode": false,
"glassTintStrength": 0.35,
"glassBorderOpacity": 0.72,
"glassShineOpacity": 0.14
},
"workspaceSpacing": 5,
"backgroundPadding": 10,
"workspaceNumberBaseSize": 250
}
}Common adjustments:
- Too small? Increase
scale(try 0.20 or 0.25) - Too big? Decrease
scale(try 0.12 or 0.14) - More workspaces? Change
rowsandcolumns(e.g., 3 rows × 4 columns = 12 workspaces) - Reverse order? Set
orderRightLeftand/ororderBottomUptotrue - Prefer the overview to stay open after outside clicks/focus changes? Set
closeOnFocusLosstofalse - Per-monitor workspace groups? Enable
useWorkspaceMapand setworkspaceMap(e.g.[0,10]) - Show special workspaces below grid? Keep
showSpecialWorkspaces: trueand optionally prefillspecialWorkspaces - Lower memory use? Set
previewModetoeventandincludeInactiveMonitorPreviewstofalse - Transparency / blur? Tune
overview.effects.*(details below)
Hide empty workspace rows:
- Set
hideEmptyRows: trueto automatically hide rows that have no windows - Keeps your overview clean by only showing rows with active workspaces
- The current workspace row is always visible, even if empty
- Arrow key navigation (left/right) stays within the current row when enabled
- Great for 2-row setups where you rarely use workspaces 6-10
Close on focus loss / outside click:
closeOnFocusLossdefaults totrue- When enabled, clicking outside the overview closes it, similar to menus, dropdowns, and launchers
- The overview also closes when its Hyprland focus grab is cleared
- Set
closeOnFocusLoss: falseif you want the previous behavior where the overview can remain open after focus changes
Edit ~/.config/quickshell/overview/config.json:
{
"position": {
"topMargin": 100
}
}Increase topMargin to move the overview down. Decrease it to move up.
{
"windowPreview": {
"showIcons": true,
"iconToWindowRatio": 0.25,
"iconToWindowRatioCompact": 0.45,
"xwaylandIndicatorToIconRatio": 0.35,
"inactiveMonitorOpacity": 0.4,
"cropToFill": false
}
}cropToFill: crop full-screen windows to fill the workspace preview whentrue; keep the full window in preview with possible horizontal/vertical "padding" bars whenfalse
{
"overview": {
"previewsEnabled": true,
"previewMode": "live",
"includeInactiveMonitorPreviews": true,
"previewRecaptureDelayMs": 60
},
"hacks": {
"hyprlandEventDebounceMs": 40
}
}overview.previewsEnabled: turn all window screencopy previews on/offoverview.previewMode:live(best visuals, more RAM) orevent(lower RAM, refreshes on window events)overview.includeInactiveMonitorPreviews: whenfalse, only current monitor windows get preview captureoverview.previewRecaptureDelayMs: delay used for event-mode snapshot refresh (lower = faster updates)hacks.hyprlandEventDebounceMs: coalesces Hyprland event refreshes to reduce command churn
{
"overview": {
"showSpecialWorkspaces": true,
"specialWorkspaces": ["stash", "music", "scratch"],
"specialWorkspaceColumns": 5
}
}showSpecialWorkspaces: renders special workspaces in a strip under the normal gridspecialWorkspaces: optional preconfigured special workspace names (without thespecial:prefix)specialWorkspaceColumns: how many special tiles per row before wrappingemptyWorkspaceWallpaper: optional image path used as the background for normal workspace tilesspecialEmptyWorkspaceWallpaper: optional image path used as the background for special workspace tiles
Interaction behavior:
- Preconfigured special workspaces appear in the overview even when they are empty
- The special strip shows active special workspaces plus any names you preconfigure
- This is useful for fixed workflows like
stash,music, orscratch - Click a special tile to run
togglespecialworkspace <name> - Click the
+tile to create and open a new special workspace - Drag a window onto a special tile to move it with
movetoworkspacesilent special:<name> - Drag a window onto the
+tile to auto-create a new special workspace (stash,stash-2, ...), even when no special workspace is currently open or preconfigured - Special windows are visible directly in those tiles
- Restart Quickshell after changing
config.json, otherwise the special workspace list will not refresh immediately
Normal workspace scrolling:
- Scroll on the normal workspace grid to move the active workspace/highlighter across all normal workspaces
- Scrolling wraps from the last workspace back to
1, and from1back to the last
{
"overview": {
"emptyWorkspaceWallpaper": "/home/your-user/Pictures/wallpaper.png",
"specialEmptyWorkspaceWallpaper": "/home/your-user/Pictures/special-wallpaper.png",
"effects": {
"emptyWorkspaceWallpaperOverlayOpacity": 0.12
}
}
}- Normal workspaces can use a wallpaper as their background
- Special workspaces can use a different wallpaper as their background
- The wallpaper remains visible behind floating or partially covered windows
- If no special workspaces exist yet, that special wallpaper is also used for the
+create tile emptyWorkspaceWallpaperOverlayOpacitycontrols how much tint is applied over that wallpaper- Use an absolute path for the image for the most reliable behavior
- Restart Quickshell after changing
config.json, otherwise the wallpaper path will not refresh immediately
Demo:
{
"overview": {
"effects": {
"enableBackdrop": false,
"backdropOpacity": 0.28,
"panelOpacity": 0.92,
"workspaceOpacity": 0.86,
"emptyWorkspaceWallpaperOverlayOpacity": 0.18,
"windowOverlayOpacity": 0.22,
"enableBlur": false,
"glassMode": false,
"glassTintStrength": 0.35,
"glassBorderOpacity": 0.72,
"glassShineOpacity": 0.14
}
}
}enableBackdrop: show/hide full-screen dim backdrop behind overviewbackdropOpacity: opacity of backdrop dim layer (0to1)panelOpacity: opacity of overview panel container (0to1)workspaceOpacity: opacity of each workspace tile (0to1)emptyWorkspaceWallpaperOverlayOpacity: tint strength over empty-workspace wallpaper (0to1)windowOverlayOpacity: opacity of the color tint over window previews (0to1)enableBlur: switches layer namespace toquickshell:overview-blurglassMode: enables a glass-like tint + softer transparency preset for panel/workspaces/windowsglassTintStrength: tint mixing strength for glass mode (0to1)glassBorderOpacity: border alpha used by glass mode (0to1)glassShineOpacity: top highlight strength for glass reflections (0to1)
Stronger glass preset:
{
"overview": {
"effects": {
"enableBackdrop": true,
"enableBlur": true,
"panelOpacity": 0.55,
"workspaceOpacity": 0.48,
"emptyWorkspaceWallpaperOverlayOpacity": 0.10,
"windowOverlayOpacity": 0.08,
"glassMode": true,
"glassTintStrength": 0.55,
"glassBorderOpacity": 0.85,
"glassShineOpacity": 0.32
}
}
}For Hyprland blur, add layer rules (example):
layerrule = blur true, match:namespace quickshell:overview-blur
layerrule = ignore_alpha 0.2, match:namespace quickshell:overview-blurIf enableBlur is false, namespace remains quickshell:overview.
Low-memory preset:
{
"overview": {
"previewMode": "event",
"includeInactiveMonitorPreviews": false
},
"hacks": {
"hyprlandEventDebounceMs": 80
}
}{
"appearance": {
"colorSource": "default",
"caelestia": {
"autoRefresh": true,
"refreshInterval": 2000,
"accentProfile": "vibrant"
},
"rounding": {
"unsharpen": 2,
"verysmall": 8,
"small": 12,
"normal": 17,
"large": 23,
"full": 9999,
"screenRounding": 23,
"windowRounding": 18
},
"font": {
"family": {
"main": "sans-serif",
"title": "sans-serif",
"expressive": "sans-serif"
},
"pixelSize": {
"smaller": 12,
"small": 15,
"normal": 16,
"larger": 19,
"huge": 22
}
},
"animation": {
"duration": {
"elementMove": 500,
"elementMoveEnter": 400,
"elementMoveFast": 200
}
},
"sizes": {
"elevationMargin": 10
}
},
"overview": {
"rows": 2,
"columns": 5,
"scale": 0.16,
"enable": true,
"hideEmptyRows": true,
"closeOnFocusLoss": true,
"useWorkspaceMap": false,
"workspaceMap": [0, 10],
"orderRightLeft": false,
"orderBottomUp": false,
"previewsEnabled": true,
"previewMode": "live",
"includeInactiveMonitorPreviews": true,
"previewRecaptureDelayMs": 60,
"showSpecialWorkspaces": true,
"specialWorkspaces": [],
"specialWorkspaceColumns": 5,
"emptyWorkspaceWallpaper": "",
"specialEmptyWorkspaceWallpaper": "",
"effects": {
"enableBackdrop": false,
"backdropOpacity": 0.28,
"panelOpacity": 0.92,
"workspaceOpacity": 0.86,
"emptyWorkspaceWallpaperOverlayOpacity": 0.18,
"windowOverlayOpacity": 0.22,
"enableBlur": false,
"glassMode": false,
"glassTintStrength": 0.35,
"glassBorderOpacity": 0.72,
"glassShineOpacity": 0.14
},
"workspaceSpacing": 5,
"backgroundPadding": 10,
"workspaceNumberBaseSize": 250
},
"position": {
"topMargin": 100
},
"windowPreview": {
"showIcons": true,
"iconToWindowRatio": 0.25,
"iconToWindowRatioCompact": 0.45,
"xwaylandIndicatorToIconRatio": 0.35,
"inactiveMonitorOpacity": 0.4,
"cropToFill": false
},
"hacks": {
"arbitraryRaceConditionDelay": 150,
"hyprlandEventDebounceMs": 40
}
}Most theme sizing/timing options are now configurable via config.json:
appearance.colorSource(default,matugen,caelestia)appearance.caelestia.*(autoRefresh,refreshInterval,accentProfile)appearance.rounding.*appearance.font.*appearance.animation.duration.*appearance.sizes.elevationMargin
For full color palette customization, edit ~/.config/quickshell/overview/common/Appearance.qml.
Matugen lets you generate Material You colors from your wallpaper and apply them to the overview automatically.
1. Install matugen - follow matugen's install guide
2. Copy the template from this repo to matugen's templates folder:
mkdir -p ~/.config/matugen/templates
cp ~/.config/quickshell/overview/quickshell-overview.qml ~/.config/matugen/templates/3. Add this to ~/.config/matugen/config.toml (create the file if it doesn't exist):
[templates.quickshell_overview]
input_path = "./templates/quickshell-overview.qml"
output_path = "~/.config/quickshell/overview/common/Appearance.colors.qml"4. Enable it in ~/.config/quickshell/overview/config.json:
{
"appearance": {
"colorSource": "matugen"
}
}5. Run matugen with your wallpaper to generate colors:
matugen image /path/to/your/wallpaper.jpgThis generates Appearance.colors.qml which the overview loads automatically. Re-run step 5 whenever you change your wallpaper.
If you use Caelestia, set the source to caelestia:
{
"appearance": {
"colorSource": "caelestia",
"caelestia": {
"autoRefresh": true,
"refreshInterval": 2000,
"accentProfile": "vibrant"
}
}
}Overview reads the active palette from caelestia scheme get and refreshes it live when autoRefresh is enabled, so wallpaper/scheme changes can apply without restarting overview.
- Hyprland compositor (tested on latest versions)
- Quickshell (Qt6-based shell framework)
- Qt 6 with the following modules:
- QtQuick
- QtQuick.Controls
- QtQuick.Layouts
- Quickshell.Wayland
- Quickshell.Hyprland
The following features were removed to make it standalone:
- App search functionality
- Emoji picker
- Clipboard history integration
- Search widget
- Integration with the full illogical-impulse shell ecosystem
~/.config/quickshell/overview/
├── shell.qml # Main entry point
├── README.md # This file
├── config.example.json # User override template
├── hyprland-config.conf # Configuration reference
├── common/
│ ├── Appearance.qml # Theme and styling
│ ├── Config.qml # Default config + user override loader
│ ├── functions/
│ │ └── ColorUtils.qml # Color manipulation utilities
│ └── widgets/
│ ├── StyledText.qml # Styled text component
│ ├── StyledRectangularShadow.qml
│ ├── StyledToolTip.qml
│ └── StyledToolTipContent.qml
├── services/
│ ├── GlobalStates.qml # Global state management
│ └── HyprlandData.qml # Hyprland data provider
└── modules/
└── overview/
├── Overview.qml # Main overview component
├── OverviewWidget.qml # Workspace grid widget
└── OverviewWindow.qml # Individual window preview
# Toggle overview
qs ipc -c overview call overview toggle
# Open overview
qs ipc -c overview call overview open
# Close overview
qs ipc -c overview call overview close- Window icons may fallback to generic icon if app class name doesn't match icon theme
- Potential crashes during rapid window state changes due to Wayland screencopy buffer management
If this project helps your setup and you want to support continued maintenance, you can sponsor here:
https://github.com/sponsors/Shanu-Kumawat
Extracted from the overview feature in illogical-impulse by end-4.
Adapted as a standalone component for Hyprland + Quickshell users who want just the overview functionality.
Note: Maintenance will be limited due to time constraints, but PRs and code improvements are welcome! Feel free to contribute or fork for your own needs.
Made with ❤️ for the Hyprland community

