Skip to content

Conversation

@jmylchreest
Copy link
Contributor

When parsing multiple special category blocks with different key values, the second block would incorrectly overwrite the first instead of creating a separate category entry.

Root cause:
When parsing a block like:

wallpaper {
    monitor =
    path = /path/image.png
}
wallpaper {
    monitor = DP-1
    path = /path/image.png
}
  1. After closing the first block, currentSpecialKey resets to ""
  2. When parsing monitor = DP-1 in the second block, the code looks for an existing category where key value == currentSpecialKey ("")
  3. The first category's key value IS "", so it matches incorrectly
  4. The second block overwrites the first, leaving only one category

The fix:
When looking for an existing category to reuse, check what field we're parsing:

  • If parsing the KEY field itself, match by the VALUE being set
  • If parsing other fields, match by currentSpecialKey (existing behavior)

This ensures monitor = DP-1 looks for a category with monitor == "DP-1", not monitor == "", allowing empty string keys to work correctly alongside non-empty keys.

This bug affects any hyprlang consumer using keyed special categories where empty string is a valid key value (e.g., hyprpaper's wallpaper category with monitor = for default/wildcard). A quick query in copilot claimed these (it's the keyed callers which would be impacted):

Project Category Key Type
Hyprland device "name" Keyed
Hyprland monitorv2 "output" Keyed
Hyprland windowrule "name" Keyed
Hyprland layerrule "name" Keyed
hyprlock background, shape, image, etc. N/A Anonymous
hypridle listener N/A Anonymous
hyprsunset profile N/A Anonymous
hyprpaper wallpaper "monitor" Keyed

When parsing multiple special category blocks with different key values,
the second block would incorrectly overwrite the first instead of creating
a separate category entry.

Root cause:
When parsing a block like:

    wallpaper {
        monitor =
        path = /path/image.png
    }
    wallpaper {
        monitor = DP-1
        path = /path/image.png
    }

1. After closing the first block, `currentSpecialKey` resets to ""
2. When parsing `monitor = DP-1` in the second block, the code looks
   for an existing category where key value == currentSpecialKey ("")
3. The first category's key value IS "", so it matches incorrectly
4. The second block overwrites the first, leaving only one category

The fix:
When looking for an existing category to reuse, check what field we're
parsing:
- If parsing the KEY field itself, match by the VALUE being set
- If parsing other fields, match by currentSpecialKey (existing behavior)

This ensures `monitor = DP-1` looks for a category with `monitor == "DP-1"`,
not `monitor == ""`, allowing empty string keys to work correctly alongside
non-empty keys.

This bug affects any hyprlang consumer using keyed special categories where
empty string is a valid key value (e.g., hyprpaper's wallpaper category
with `monitor =` for default/wildcard).
Copy link
Member

@vaxerski vaxerski left a comment

Choose a reason for hiding this comment

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

thanks!

@jmylchreest
Copy link
Contributor Author

It may be worth noting I first put together this fix (which is what led me to this) hyprwm/hyprpaper#315 - which is technically redundant but might still be worthwhile if you're happy to support the asterisk.

@vaxerski vaxerski merged commit 0567ba7 into hyprwm:main Jan 4, 2026
7 checks passed
@jmylchreest jmylchreest deleted the bug/fix-empty-specialkey branch January 4, 2026 13:47
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.

2 participants