Skip to content

feat(hyprshell): add hyprshell window switcher with Super+Tab - #893

Merged
shunkakinoki merged 5 commits into
mainfrom
claude/install-hyprshell-zx7dC
Feb 22, 2026
Merged

feat(hyprshell): add hyprshell window switcher with Super+Tab#893
shunkakinoki merged 5 commits into
mainfrom
claude/install-hyprshell-zx7dC

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Feb 22, 2026

Copy link
Copy Markdown
Owner

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.

  • New Features
    • Install hyprshell, autostart it via exec-once, and replace the hyprexpo Super+Tab binding.
    • Add a hyprshell config module and set Super as the window switch modifier.

Written for commit f139a4a. Summary will update on new commits.

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
Copilot AI review requested due to automatic review settings February 22, 2026 05:51
@mesa-dot-dev

mesa-dot-dev Bot commented Feb 22, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@coderabbitai

coderabbitai Bot commented Feb 22, 2026

Copy link
Copy Markdown
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Integrated hyprshell window switcher to the desktop environment with customizable window scaling and modifier key configurations
  • Changes

    • Reassigned window switching key bindings to use hyprshell

Walkthrough

This 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

Cohort / File(s) Summary
Base Configuration Integration
config/default.nix, home-manager/packages/default.nix
Added hyprshell to the isDesktop configuration branch and included it in the desktop Linux optional packages list.
Hyprland Integration
config/hyprland/default.nix, config/hyprland/hyprland.conf
Added exec-once invocation to start hyprshell at boot; removed Super+Tab keybinding for hyprexpo with clarifying comment that hyprshell now handles window switching.
Hyprshell Configuration
config/hyprshell/config.toml, config/hyprshell/default.nix
Introduced new configuration directory with TOML settings (version 1, windows scale 8.0, super modifier for switch) and Nix module binding hyprshell/config.toml to XDG config.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 A window switcher hops into the fold,
Super+Tab now dances with hyprshell's gold,
Hyprland awakens with exec-once cheer,
Configuration files bloom, crystal and clear! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title accurately describes the main change: adding hyprshell as a window switcher with Super+Tab keybinding for Hyprland, which is clearly supported by the changeset across multiple files.
Description check ✅ Passed The pull request description is directly related to the changeset, explaining the installation of hyprshell, its configuration with Super as the modifier key, and its role in replacing the previous hyprexpo binding.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/install-hyprshell-zx7dC

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @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 hyprshell into the system, providing a more robust and configurable window switching experience for Hyprland users. It updates the Super+Tab keybinding to leverage hyprshell's functionality, allowing for efficient navigation through windows sorted by recent access.

Highlights

  • New Feature: Hyprshell Integration: Introduced hyprshell for advanced window switching capabilities within the Hyprland environment.
  • Keybinding Update: Configured hyprshell to use Super+Tab for window switching, replacing the previous hyprexpo binding.
  • Enhanced Window Navigation: Enabled cycling through recently accessed windows by holding Super and pressing Tab or Shift+Tab.
Changelog
  • home-manager/packages/default.nix
    • Added hyprshell to the list of installed packages.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@mesa-dot-dev

mesa-dot-dev Bot commented Feb 22, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Replaced hyprexpo with hyprshell for Super+Tab window switching in Hyprland, enabling cycling through windows by recent access.

What changed?

  • home-manager/packages/default.nix: Added hyprshell to the list of packages.
  • config/hyprland/default.nix: Configured Hyprland to execute hyprshell on startup using exec-once.
  • config/hyprland/hyprland.conf: Removed the hyprexpo:expo toggle binding, as hyprshell now handles Super+Tab and Super+Shift+Tab for window switching.

Description generated by Mesa. Update settings

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

- Start hyprshell daemon via exec-once in hyprland config
- Replace hyprexpo Super+Tab binding with hyprshell window switching

https://claude.ai/code/session_018dkHdESaqmYHpJRvuk6Lts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copilot AI Feb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
hypridle
hyprlock
hyprpicker
hyprshell

Copilot AI Feb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
hyprshell

Copilot uses AI. Check for mistakes.
- 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

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 hyprexpoPlugin from config/hyprland/default.nix.
  • In config/hyprland/hyprland.conf:
    • Add exec-once = hyprshell.
    • Replace the hyprexpo keybinding with hyprshell-client bindings for Super+Tab and Super+Shift+Tab.
    • Remove the plugin { hyprexpo ... } section.

Please add these changes to the pull request.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 hyprexpo plugin is still loaded in default.nix (via plugin = ${hyprexpoPlugin}/lib/libhyprexpo.so) and the configuration block below still exists. Since gesture_fingers = 3 is 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: pkgs is 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-once entries — 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 &

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ 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/null

Repository: 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/null

Repository: 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 -20

Repository: 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.

⚠️ Potential issue | 🟠 Major

🧩 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 .json and .json5 config files. [1]
  • TOML status: TOML was dropped (it couldn’t represent None values). 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: .toml and .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 -c CLI 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 .toml formats (depending on build/features/version). [1]
  • Config versioning/migrations: the config has a version field; 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 via HYPRSHELL_RELOAD_TIMEOUT (default 1500 ms). [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:

  1. Rename to RON (the default format):

    • Move config/hyprshell/config.tomlconfig/hyprshell/config.ron
    • Update the xdg configFile key accordingly
  2. Or pass -c explicitly:

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.

Suggested change
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").

@shunkakinoki
shunkakinoki merged commit d99fd2a into main Feb 22, 2026
27 of 30 checks passed
@shunkakinoki
shunkakinoki deleted the claude/install-hyprshell-zx7dC branch February 22, 2026 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants