feat(hyprshell): add hyprshell window switcher with Super+Tab - #893
Conversation
Install hyprshell from flake input and configure the switch mode with Super as the modifier key, replacing the previous hyprexpo binding on Super+Tab. Hold Super and press Tab/Shift+Tab to cycle through windows sorted by recent access. https://claude.ai/code/session_018dkHdESaqmYHpJRvuk6Lts
This reverts commit b3f8b1e.
|
You do not have enough credits to review this pull request. Please purchase more credits to continue. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis pull request integrates hyprshell, a window-switching utility, into the Hyprland desktop environment. Changes include adding hyprshell to the desktop configuration branch, setting up an exec-once autostart entry in Hyprland, removing the previous Super+Tab keybinding for hyprexpo, creating a new hyprshell configuration directory with TOML and Nix config files, and adding hyprshell to home-manager desktop packages. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @shunkakinoki, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Mesa DescriptionTL;DRReplaced What changed?
Description generated by Mesa. Update settings |
- Start hyprshell daemon via exec-once in hyprland config - Replace hyprexpo Super+Tab binding with hyprshell window switching https://claude.ai/code/session_018dkHdESaqmYHpJRvuk6Lts
There was a problem hiding this comment.
Pull request overview
This PR aims to add hyprshell as a window switcher for Hyprland with a Super+Tab keybinding, intended to replace the existing hyprexpo workspace overview functionality. However, the current implementation is incomplete and only includes the package installation.
Changes:
- Adds hyprshell package to the Linux desktop package list in alphabetical order
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| hypridle | ||
| hyprlock | ||
| hyprpicker | ||
| hyprshell |
There was a problem hiding this comment.
The PR description states "Install hyprshell from flake input", but there is no corresponding flake input for hyprshell added to flake.nix. This means the package will be pulled from nixpkgs directly rather than from a dedicated flake input. If hyprshell requires a specific version or custom build not available in nixpkgs, you'll need to add it as a flake input in flake.nix and reference it appropriately (similar to how agenix is used on line 10).
| hypridle | ||
| hyprlock | ||
| hyprpicker | ||
| hyprshell |
There was a problem hiding this comment.
The PR description states that Super+Tab will be configured to use hyprshell's switch mode, replacing the previous hyprexpo binding. However, this PR only adds the package - it doesn't include the necessary configuration changes. The hyprland configuration file (config/hyprland/hyprland.conf line 261) still has the binding "bind = $mod, TAB, hyprexpo:expo, toggle" which needs to be updated to use hyprshell instead. Additionally, any hyprshell configuration for the switch mode needs to be added.
| hyprshell |
- Create config/hyprshell with config.toml for window switch mode - Import hyprshell module in desktop config - Configure Super modifier for window switching https://claude.ai/code/session_018dkHdESaqmYHpJRvuk6Lts
There was a problem hiding this comment.
Code Review
This pull request aims to replace hyprexpo with hyprshell. While the hyprshell package is correctly added, the configuration changes to enable it and remove hyprexpo seem to be missing. The provided files for config/hyprland/default.nix and config/hyprland/hyprland.conf still contain the old hyprexpo setup.
To complete this feature, you would need to:
- Remove the
hyprexpoPluginfromconfig/hyprland/default.nix. - In
config/hyprland/hyprland.conf:- Add
exec-once = hyprshell. - Replace the
hyprexpokeybinding withhyprshell-clientbindings forSuper+TabandSuper+Shift+Tab. - Remove the
plugin { hyprexpo ... }section.
- Add
Please add these changes to the pull request.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
config/hyprland/hyprland.conf (1)
261-261: Super+Tab binding removed correctly; the hyprexpo plugin block (lines 437–446) now serves gesture-only purposes.The keyboard binding is gone and hyprshell takes over Super+Tab. Just note that the
hyprexpoplugin is still loaded indefault.nix(viaplugin = ${hyprexpoPlugin}/lib/libhyprexpo.so) and the configuration block below still exists. Sincegesture_fingers = 3is configured, this is presumably intentional gesture-only retention — a brief comment there would make the intent clear to future readers.✏️ Suggested comment for the plugin block
plugin { + # hyprexpo retained for 3-finger swipe gesture only (Super+Tab is now hyprshell) hyprexpo {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/hyprland/hyprland.conf` at line 261, Add a short clarifying comment inside the hyprexpo plugin block noting that the plugin is intentionally kept loaded for touch gestures only (e.g., gesture_fingers = 3) while Super+Tab window switching has been moved to hyprshell and the keyboard binding removed; reference the hyprexpo plugin block and the gesture_fingers setting and mention that the plugin is still pulled in from default.nix via plugin = ${hyprexpoPlugin}/lib/libhyprexpo.so so future readers understand it’s retained for gestures only.config/hyprshell/default.nix (1)
1-1:pkgsis destructured but unused — remove it to keep the signature minimal.✏️ Suggested cleanup
-{ pkgs, ... }: +{ ... }:🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/hyprshell/default.nix` at line 1, The function argument currently destructures "{ pkgs, ... }" but never uses pkgs; remove pkgs from the parameter list to keep the signature minimal (e.g., change the parameter from "{ pkgs, ... }" to "{ ... }" or an equivalent unused-params form) and ensure no other references to the symbol "pkgs" remain in the file (update any related exports/imports if necessary).config/hyprland/default.nix (1)
17-18: Trailing&on the hyprshell line is inconsistent with the hyprpanel line above it.Both are
exec-onceentries — Hyprland already forks them. The&is redundant and creates a style inconsistency:✏️ Suggested cleanup
exec-once = ${pkgs.hyprpanel}/bin/hyprpanel - exec-once = ${pkgs.hyprshell}/bin/hyprshell run & + exec-once = ${pkgs.hyprshell}/bin/hyprshell run🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/hyprland/default.nix` around lines 17 - 18, The second exec-once entry uses a trailing ampersand which is redundant and inconsistent with the first exec-once line; remove the trailing '&' from the exec-once = ${pkgs.hyprshell}/bin/hyprshell run entry so both exec-once lines (the one launching ${pkgs.hyprpanel}/bin/hyprpanel and the one launching ${pkgs.hyprshell}/bin/hyprshell) follow the same style and rely on Hyprland to fork them.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@config/hyprland/default.nix`:
- Line 18: The exec-once line launches hyprshell and can cause runtime crashes
due to hyprshell building a plugin against mismatched Hyprland headers; add an
explicit hyprshell input that follows your pinned hyprland version (so hyprshell
uses the same hyprland headers) — e.g. create an input named hyprshell with
inputs.hyprland.follows set to the same channel as your hyprland pin — or, as a
temporary workaround, ensure the environment variable HYPRSHELL_NO_USE_PLUGIN=1
is exported before the exec-once = ${pkgs.hyprshell}/bin/hyprshell run &
invocation to disable plugin building.
- Line 18: The exec-once invocation uses "${pkgs.hyprshell}/bin/hyprshell run &"
which ignores your TOML and falls back to RON defaults; fix by either renaming
the config file to the hyprshell default (move config/hyprshell/config.toml →
config/hyprshell/config.ron and update the xdg configFile key to point to
config.ron) or by keeping the TOML and changing the exec-once command to include
an explicit config flag (invoke hyprshell with -c /path/to/config.toml) so
hyprshell loads your intended modifier ("super").
---
Nitpick comments:
In `@config/hyprland/default.nix`:
- Around line 17-18: The second exec-once entry uses a trailing ampersand which
is redundant and inconsistent with the first exec-once line; remove the trailing
'&' from the exec-once = ${pkgs.hyprshell}/bin/hyprshell run entry so both
exec-once lines (the one launching ${pkgs.hyprpanel}/bin/hyprpanel and the one
launching ${pkgs.hyprshell}/bin/hyprshell) follow the same style and rely on
Hyprland to fork them.
In `@config/hyprland/hyprland.conf`:
- Line 261: Add a short clarifying comment inside the hyprexpo plugin block
noting that the plugin is intentionally kept loaded for touch gestures only
(e.g., gesture_fingers = 3) while Super+Tab window switching has been moved to
hyprshell and the keyboard binding removed; reference the hyprexpo plugin block
and the gesture_fingers setting and mention that the plugin is still pulled in
from default.nix via plugin = ${hyprexpoPlugin}/lib/libhyprexpo.so so future
readers understand it’s retained for gestures only.
In `@config/hyprshell/default.nix`:
- Line 1: The function argument currently destructures "{ pkgs, ... }" but never
uses pkgs; remove pkgs from the parameter list to keep the signature minimal
(e.g., change the parameter from "{ pkgs, ... }" to "{ ... }" or an equivalent
unused-params form) and ensure no other references to the symbol "pkgs" remain
in the file (update any related exports/imports if necessary).
| extraConfig = '' | ||
| plugin = ${hyprexpoPlugin}/lib/libhyprexpo.so | ||
| exec-once = ${pkgs.hyprpanel}/bin/hyprpanel | ||
| exec-once = ${pkgs.hyprshell}/bin/hyprshell run & |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for flake.nix and check its hyprshell configuration
fd -e nix "flake.nix" -x cat {} -n \; 2>/dev/nullRepository: shunkakinoki/dotfiles
Length of output: 9025
🏁 Script executed:
#!/bin/bash
# Also check if there's any hyprland input defined in flake.nix
fd -e nix "flake.nix" -x grep -n "hyprland\|hyprshell" {} \; 2>/dev/nullRepository: shunkakinoki/dotfiles
Length of output: 47
🏁 Script executed:
#!/bin/bash
# Check the structure of the repo to understand the context
git ls-files | grep -E "(flake|hyprland)" | head -20Repository: shunkakinoki/dotfiles
Length of output: 361
Add explicit hyprland version pinning for hyprshell to prevent header mismatch crashes.
Hyprshell builds a Hyprland plugin at runtime which requires C headers matching the running Hyprland instance. Since flake.nix doesn't currently pin hyprland, hyprshell may receive headers from a different version than your system runs, causing runtime crashes.
Add a hyprshell input that follows your hyprland version (or use nixpkgs-unstable consistently):
hyprshell = {
url = "github:H3rmt/hyprshell?ref=hyprshell-release";
inputs.hyprland.follows = "nixpkgs-unstable";
};If version pinning isn't immediately practical, set HYPRSHELL_NO_USE_PLUGIN=1 as a temporary workaround.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@config/hyprland/default.nix` at line 18, The exec-once line launches
hyprshell and can cause runtime crashes due to hyprshell building a plugin
against mismatched Hyprland headers; add an explicit hyprshell input that
follows your pinned hyprland version (so hyprshell uses the same hyprland
headers) — e.g. create an input named hyprshell with inputs.hyprland.follows set
to the same channel as your hyprland pin — or, as a temporary workaround, ensure
the environment variable HYPRSHELL_NO_USE_PLUGIN=1 is exported before the
exec-once = ${pkgs.hyprshell}/bin/hyprshell run & invocation to disable plugin
building.
🧩 Analysis chain
🌐 Web query:
hyprshell config file auto-detection TOML RON ~/.config/hyprshell
💡 Result:
Hyprshell does not auto-detect between TOML and RON.
- Default config path:
~/.config/hyprshell/config.ron(loaded on startup and auto-reloaded on change). You can override the path with-c. Hyprshell also supports.jsonand.json5config files. [1] - TOML status: TOML was dropped (it couldn’t represent
Nonevalues). Hyprshell added a TOML → RON migration around v4.6.0. [2]
What to do: put your config at ~/.config/hyprshell/config.ron (or point Hyprshell at a specific file via hyprshell -c /path/to/config.ron).
Sources: [1] [2]
🌐 Web query:
hyprshell run command default config file location format
💡 Result:
- Default config file path (used by
hyprshell run):~/.config/hyprshell/config.ron.[1][2] - Default format: RON (
.ron).[1][2] - Other supported config formats:
.tomland.json/.json5.[1] - Override config path: pass
-c <path>.[1]
Sources: [1] [2]
🌐 Web query:
hyprshell github repository config loading behavior
💡 Result:
Hyprshell’s config-loading behavior (per the upstream GitHub repo):
- Default config path:
~/.config/hyprshell/config.ron. You can override this with the-cCLI argument. The config is loaded at startup and auto-reloaded when the file changes. [1] - Supported config formats:
.ron(default); the docs also state you can use.json(5)and.tomlformats (depending on build/features/version). [1] - Config versioning/migrations: the config has a
versionfield; on load, Hyprshell checks it to migrate the file if needed. [1] - Reload/watch behavior controls: Hyprshell has file/listener-based hot reload; you can disable listeners with
HYPRSHELL_NO_LISTENERS, and adjust the reload debounce/timeout viaHYPRSHELL_RELOAD_TIMEOUT(default1500ms). [2] - CSS is similar: default CSS at
~/.config/hyprshell/styles.css, overridable with-s, also loaded at startup and reloaded on change. [1]
Sources:
[1] Hyprshell docs/CONFIGURE.md (raw)
[2] Hyprshell README.md (raw)
hyprshell run requires an explicit config path — config.toml will be silently ignored.
Hyprshell defaults to ~/.config/hyprshell/config.ron (RON format) and does not auto-detect .toml files. Without a -c flag pointing to your config.toml, hyprshell starts with built-in defaults, leaving modifier as "alt" instead of "super" — breaking Super+Tab.
Choose one fix:
-
Rename to RON (the default format):
- Move
config/hyprshell/config.toml→config/hyprshell/config.ron - Update the xdg configFile key accordingly
- Move
-
Or pass
-cexplicitly:
Option 2 — point to TOML via -c flag
- exec-once = ${pkgs.hyprshell}/bin/hyprshell run &
+ exec-once = ${pkgs.hyprshell}/bin/hyprshell -c ${config.xdg.configHome}/hyprshell/config.toml run &📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| exec-once = ${pkgs.hyprshell}/bin/hyprshell run & | |
| exec-once = ${pkgs.hyprshell}/bin/hyprshell -c ${config.xdg.configHome}/hyprshell/config.toml run & |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@config/hyprland/default.nix` at line 18, The exec-once invocation uses
"${pkgs.hyprshell}/bin/hyprshell run &" which ignores your TOML and falls back
to RON defaults; fix by either renaming the config file to the hyprshell default
(move config/hyprshell/config.toml → config/hyprshell/config.ron and update the
xdg configFile key to point to config.ron) or by keeping the TOML and changing
the exec-once command to include an explicit config flag (invoke hyprshell with
-c /path/to/config.toml) so hyprshell loads your intended modifier ("super").
Install hyprshell from flake input and configure the switch mode
with Super as the modifier key, replacing the previous hyprexpo
binding on Super+Tab. Hold Super and press Tab/Shift+Tab to cycle
through windows sorted by recent access.
https://claude.ai/code/session_018dkHdESaqmYHpJRvuk6Lts
Summary by cubic
Super+Tab now switches windows by recent access in Hyprland. Hold Super and press Tab/Shift+Tab to move forward or backward.
Written for commit f139a4a. Summary will update on new commits.