fix(UI): improve theme management UI flow#1933
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughOverhauls the Themes tab and save/create flows in the settings UI, adds filename sanitization and preset-awareness to ThemeManager, exposes shipped preset names at build time via a generated header, and surfaces theme-save guidance across related settings tabs. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as SettingsTabRenderer (UI)
participant TM as ThemeManager
participant FS as Filesystem
participant LOG as Logger
UI->>TM: Request SaveTheme(selectedName or newName, settings)
TM->>TM: SanitizeThemeFileName(name)
TM->>TM: IsPresetTheme(sanitizedName)?
alt Preset selected
TM->>LOG: Log "cannot overwrite preset"
TM-->>UI: return failure
else Not a preset
TM->>FS: Write theme JSON (safeFileName)
alt Write success
TM-->>UI: return success + changed-settings list
else Write failure
TM->>LOG: Log save/write error
TM-->>UI: return failure
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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 |
|
No actionable suggestions for changed features. |
Automated formatting by clang-format, prettier, and other hooks. See https://pre-commit.ci for details.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
src/Menu/SettingsTabRenderer.cpp (3)
566-587:showUpdateFeedbackhas no dismissal mechanism — persists indefinitelyOnce set to
true, the diff/success block stays visible forever (across theme switches, tab changes, and session restarts until the next save attempt). Consider adding a "Dismiss" button or an auto-hide timer usingImGui::GetTime()to avoid stale feedback misleading the user.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` around lines 566 - 587, The feedback block controlled by showUpdateFeedback (used with updateSuccess and changedSettings in the SettingsTabRenderer rendering code) lacks a dismissal mechanism; update the render logic to allow the user to remove stale messages by adding either a "Dismiss" button (that sets showUpdateFeedback = false) next to the feedback area or implement an auto-hide timeout using ImGui::GetTime() (store a float like updateFeedbackTimestamp when setting showUpdateFeedback and compare current ImGui::GetTime() to hide after X seconds). Ensure the change is applied in the same rendering function that draws the block so that both manual dismissal and/or the timeout clear showUpdateFeedback and stop displaying changedSettings/updateSuccess.
373-375: Add issue reference to PR descriptionPer project conventions, since this PR addresses a reported issue, the description should include
Addresses#1919(or `Closes `#1919if it fully resolves the issue) so the issue is linked and closed automatically on merge. As per coding guidelines, suggest addingAddresses#1919or `Related to `#1919to the PR description.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` around lines 373 - 375, The PR is missing the issue reference in its description per project conventions; update the PR description to include an issue link like "Addresses `#1919`" (or "Closes `#1919`" if it fully resolves it) so the issue is automatically linked/closed on merge—this change is administrative and unrelated to code in SettingsTabRenderer::RenderThemesTab or BeginTabItemWithFont, just add the appropriate "Addresses `#1919`" or "Related to `#1919`" line to the PR description.
696-699:Cancel(and success path) should callImGui::CloseCurrentPopup()Setting
showCreateThemePopup = falserelies onBeginPopupModal'sp_opencheck on the next frame to close the popup. The popup remains visible for an extra frame (the frame in which Cancel is clicked). AddingImGui::CloseCurrentPopup()closes it immediately and is the documented ImGui idiom for closing a modal from within its own render block.♻️ Proposed fix
if (ImGui::Button("Cancel")) { showCreateThemePopup = false; + ImGui::CloseCurrentPopup(); }Apply the same fix to the success path (line 685):
showCreateThemePopup = false; + ImGui::CloseCurrentPopup(); logger::info("Theme creation complete. ...");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` around lines 696 - 699, The popup is being closed by setting showCreateThemePopup = false which delays actual closure one frame; update both the Cancel button handler and the success/creation path (the branch that currently sets showCreateThemePopup = false after creating the theme) to call ImGui::CloseCurrentPopup() in addition to clearing showCreateThemePopup (i.e., call ImGui::CloseCurrentPopup() before or alongside setting showCreateThemePopup = false) so the modal closes immediately; look for the ImGui::Button("Cancel") handler and the theme-success branch in SettingsTabRenderer:: (where the new theme is accepted) and add the ImGui::CloseCurrentPopup() call there.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 482-488: The code reads themes[currentItem] without checking for
an empty themes vector; change SettingsTabRenderer.cpp to guard against empty
results from DiscoverThemes() by checking themes.empty() before indexing and by
clamping or resetting currentItem when themes is non-empty (e.g., reset
currentItem to 0 or min(currentItem, themes.size()-1)), and render a fallback
message (e.g., "No themes found") instead of accessing selectedTheme, ensuring
any uses of selectedTheme and themeSettings.StatusPalette.InfoColor only occur
when themes is non-empty.
In `@src/Menu/ThemeManager.cpp`:
- Around line 675-685: IsPresetTheme currently uses a hard-coded array of preset
names which can drift from the shipped .json files; update it to derive the
protected/preset set at discovery time instead: when themes are discovered
populate a std::unordered_set<std::string> (or mark a bool on ThemeInfo) for
themes that live in the base install path (not the overwrite/MO2 path) and have
IsPresetTheme consult that set/ThemeInfo flag; alternatively, if you must keep a
compile-time check add a clear comment/static_assert linking this list to the
authoritative source, but preferred fix is to populate ThemeManager::presetNames
(or ThemeInfo::isBuiltin) during theme discovery and replace the hard-coded
array in IsPresetTheme with a lookup against that runtime set/flag.
- Around line 555-558: SanitizeThemeFileName currently only strips illegal path
chars but doesn't guard Windows reserved device names; update
ThemeManager::SanitizeThemeFileName to, after the replace_if step, do a
case-insensitive comparison of the sanitized base name against the reserved set
{NUL, CON, PRN, AUX, COM1..COM9, LPT1..LPT9} and if it matches exactly, modify
the name (e.g., append an underscore or prefix "theme_") so it no longer equals
a device name, then return that safe name.
---
Nitpick comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 566-587: The feedback block controlled by showUpdateFeedback (used
with updateSuccess and changedSettings in the SettingsTabRenderer rendering
code) lacks a dismissal mechanism; update the render logic to allow the user to
remove stale messages by adding either a "Dismiss" button (that sets
showUpdateFeedback = false) next to the feedback area or implement an auto-hide
timeout using ImGui::GetTime() (store a float like updateFeedbackTimestamp when
setting showUpdateFeedback and compare current ImGui::GetTime() to hide after X
seconds). Ensure the change is applied in the same rendering function that draws
the block so that both manual dismissal and/or the timeout clear
showUpdateFeedback and stop displaying changedSettings/updateSuccess.
- Around line 373-375: The PR is missing the issue reference in its description
per project conventions; update the PR description to include an issue link like
"Addresses `#1919`" (or "Closes `#1919`" if it fully resolves it) so the issue is
automatically linked/closed on merge—this change is administrative and unrelated
to code in SettingsTabRenderer::RenderThemesTab or BeginTabItemWithFont, just
add the appropriate "Addresses `#1919`" or "Related to `#1919`" line to the PR
description.
- Around line 696-699: The popup is being closed by setting showCreateThemePopup
= false which delays actual closure one frame; update both the Cancel button
handler and the success/creation path (the branch that currently sets
showCreateThemePopup = false after creating the theme) to call
ImGui::CloseCurrentPopup() in addition to clearing showCreateThemePopup (i.e.,
call ImGui::CloseCurrentPopup() before or alongside setting showCreateThemePopup
= false) so the modal closes immediately; look for the ImGui::Button("Cancel")
handler and the theme-success branch in SettingsTabRenderer:: (where the new
theme is accepted) and add the ImGui::CloseCurrentPopup() call there.
|
Background blur toggle and font scaling shouldn't be tied to themes anyways. That might be the better fix. Changes listed look good still by its own. |
|
✅ A pre-release build is available for this PR: |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
cmake/ThemePresets.h.in (1)
7-9: Preferinline constexproverstatic constfor the namespace-scope array
static constat namespace scope gives the array internal linkage, meaning each translation unit that includes this header gets its own copy.conston a global/namespace-scope variable impliesstatic(internal linkage), and memory for that static is only going to be allocated if an address or reference is taken — with a different address in each translation unit. If your compiler is C++17 capable, prefer defininginline constexprglobal variables in a header file.♻️ Proposed fix
- static const std::array<const char*, `@THEME_PRESET_COUNT`@> names = { + inline constexpr std::array<const char*, `@THEME_PRESET_COUNT`@> names = {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmake/ThemePresets.h.in` around lines 7 - 9, The namespace-scope array currently defined as "static const std::array<const char*, `@THEME_PRESET_COUNT`@> names" should be changed to use inline constexpr to provide a single definition across TUs; update the declaration for the symbol names to "inline constexpr std::array<const char*, `@THEME_PRESET_COUNT`@> names = { `@THEME_PRESET_NAMES`@ }" (remove static/const-only pattern) so it has external linkage under C++17 and above.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmake/ThemePresets.h.in`:
- Line 1: The PR currently references issue `#1919` inline but doesn't use a
GitHub keyword; update the PR description body to include a linking keyword such
as "Addresses `#1919`" (or "Related to `#1919`") so GitHub will automatically
associate the issue with the PR—locate the PR description for the branch that
modifies cmake/ThemePresets.h.in (the change showing "#pragma once") and add the
chosen keyword line to the PR body.
In `@CMakeLists.txt`:
- Around line 238-241: The loop that builds THEME_PRESET_NAMES appends raw
preset stems (THEME_PRESET_NAMES_LIST -> THEME_PRESET_NAMES) into C++ string
literals, which will break if a name contains " or \; fix by escaping
backslashes and double quotes before appending: inside the foreach over
THEME_PRESET_NAMES_LIST, create a local variable (e.g., esc_p) and run
string(REPLACE "\\" "\\\\" esc_p "${p}") then string(REPLACE "\"" "\\\"" esc_p
"${esc_p}"), then append esc_p to THEME_PRESET_NAMES as before; keep the
trailing string(REGEX REPLACE ",\n$" "" THEME_PRESET_NAMES ...) unchanged.
In `@src/Menu/ThemeManager.cpp`:
- Around line 676-683: IsPresetTheme currently does a case-sensitive compare and
should perform a case-insensitive check to match UI behavior; update
ThemeManager::IsPresetTheme to compare themeName against each entry in
ThemePresets::names using the existing case-insensitive comparator (iequals) or
an equivalent case-folding routine (e.g., std::tolower-based compare) so that
"default", "Default", and "DEFAULT" all detect as a preset and prevent
overwriting shipped files.
---
Duplicate comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 489-495: The code reads themes[currentItem] without checking
whether themes is empty, causing a crash when DiscoverThemes() found no themes;
update the rendering logic in SettingsTabRenderer (use the variables
currentItem, themes, selectedTheme, and themeSettings.StatusPalette.InfoColor)
to first check if themes.empty() and handle that case (e.g., display a "No
themes found" message or skip accessing themes/currentItem), only index
themes[currentItem] when non-empty, and ensure currentItem is clamped/reset
appropriately after discovery to avoid out-of-bounds access.
In `@src/Menu/ThemeManager.cpp`:
- Around line 556-560: SanitizeThemeFileName currently only replaces illegal
path chars but must also guard against Windows reserved device names; update
ThemeManager::SanitizeThemeFileName to, after normalizing characters, check the
base filename (case-insensitive, without extension) against the reserved set
{CON, PRN, NUL, AUX, COM1..COM9, LPT1..LPT9} and if it matches, alter the name
(for example prefix or suffix with an underscore or append "_file") so it no
longer equals a reserved device name before returning; ensure the check is
applied regardless of letter case and preserves file extension handling expected
by SaveTheme/RefreshThemes.
---
Nitpick comments:
In `@cmake/ThemePresets.h.in`:
- Around line 7-9: The namespace-scope array currently defined as "static const
std::array<const char*, `@THEME_PRESET_COUNT`@> names" should be changed to use
inline constexpr to provide a single definition across TUs; update the
declaration for the symbol names to "inline constexpr std::array<const char*,
`@THEME_PRESET_COUNT`@> names = { `@THEME_PRESET_NAMES`@ }" (remove
static/const-only pattern) so it has external linkage under C++17 and above.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/Menu/SettingsTabRenderer.cpp (3)
1-1: Consider adding a GitHub issue-closing keyword to the PR descriptionThe PR mentions issue
#1919but doesn't use a linking keyword. AddingCloses#1919or `Addresses `#1919to the PR description will auto-link and optionally auto-close the issue on merge.As per coding guidelines, issue references should use appropriate GitHub keywords (
Closes#123, `Addresses `#123, etc.).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` at line 1, Update the PR description to include a GitHub issue-closing keyword for the referenced issue (e.g., add "Closes `#1919`" or "Addresses `#1919`" in the PR body) so GitHub will auto-link/auto-close the issue when merged; ensure the PR description that mentions SettingsTabRenderer (file SettingsTabRenderer.h / SettingsTabRenderer.cpp) contains the exact keyword phrase and the issue number.
450-450: Redundant self-assignment afterLoadThemePreset
themeSettingsisauto& themeSettings = globals::menu->GetSettings().Theme— a reference to the actual settings member.LoadThemePresetupdates that member in-place, sothemeSettingsalready reflects the new state. The assignment on this line reassigns the struct to itself.♻️ Proposed fix
- themeSettings = globals::menu->GetSettings().Theme;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` at line 450, The line reassigning themeSettings is redundant because themeSettings is declared as auto& themeSettings = globals::menu->GetSettings().Theme and LoadThemePreset mutates that object in-place; remove the assignment "themeSettings = globals::menu->GetSettings().Theme" (or stop reassigning the referenced struct) so the code relies on the existing reference updated by LoadThemePreset (locate where themeSettings and LoadThemePreset are used in SettingsTabRenderer.cpp to remove the redundant self-assignment).
386-396:showUpdateFeedbackpersists across theme switches, showing stale save results
showUpdateFeedbackandchangedSettingsarestaticand never reset whencurrentThemePresetchanges. After saving theme A, switching to theme B via the dropdown keeps the old "Theme updated successfully" message visible for theme B.♻️ Proposed fix — reset on selection change
+ static std::string lastFeedbackTheme; // Theme preset dropdown if (ComboWithFont("##ThemePreset", ¤tItem, items.data(), static_cast<int>(items.size()), Menu::FontRole::Body)) { std::string selectedTheme = themes[currentItem].name; if (globals::menu->LoadThemePreset(selectedTheme)) { themeSettings = globals::menu->GetSettings().Theme; + showUpdateFeedback = false; + changedSettings.clear(); + lastFeedbackTheme = selectedTheme; } }Also applies to: 576-596
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` around lines 386 - 396, showUpdateFeedback, changedSettings and updateSuccess are declared static and never cleared when the theme preset selection changes, causing stale feedback to persist across presets; modify the theme preset selection handler (the code that updates currentThemePreset from the dropdown) to reset showUpdateFeedback = false, clear changedSettings (e.g., changedSettings.clear()) and set updateSuccess = false whenever currentThemePreset is changed, and apply the same reset logic in the other selection-change location noted (the block around the second occurrence) so feedback is cleared on every preset switch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 608-621: The code validates newThemeName before sanitization which
lets names that sanitize to empty pass; after generating safeNewThemeName via
themeManager->SanitizeThemeFileName, re-evaluate emptiness and duplicates using
the sanitized value: set isThemeNameEmpty = strlen(safeNewThemeName) == 0
(instead of checking raw newThemeName), and compare existing theme names against
safeNewThemeName (iequals(t.name, safeNewThemeName)); keep display-name
duplicate logic as-is but ensure isThemeNameError uses the sanitized check so
SaveTheme is blocked when the sanitized filename is empty or duplicates an
existing theme.
- Line 509: currentThemeInfo->themeData is const so using json::operator[] on a
potentially missing "Theme" key is UB; update the code around currentThemeInfo
(e.g., where json savedThemeJson = currentThemeInfo->themeData["Theme"]; is
used) to first check for the key via
currentThemeInfo->themeData.contains("Theme") and then use
currentThemeInfo->themeData.at("Theme") (or
currentThemeInfo->themeData.value("Theme", defaultValue) if a fallback is
acceptable), and handle the missing-key case (log/report error or skip loading)
instead of indexing unconditionally.
---
Duplicate comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 480-497: No change needed: the current code correctly displays the
info text and guards the selected theme display against out-of-bounds access;
keep the ImGui calls as-is (the info message around RenderSaveInfoText, the
bounds check using currentItem and themes.size(), and the Selected Theme UI that
uses selectedTheme.displayName and selectedTheme.description).
---
Nitpick comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Line 1: Update the PR description to include a GitHub issue-closing keyword
for the referenced issue (e.g., add "Closes `#1919`" or "Addresses `#1919`" in the
PR body) so GitHub will auto-link/auto-close the issue when merged; ensure the
PR description that mentions SettingsTabRenderer (file SettingsTabRenderer.h /
SettingsTabRenderer.cpp) contains the exact keyword phrase and the issue number.
- Line 450: The line reassigning themeSettings is redundant because
themeSettings is declared as auto& themeSettings =
globals::menu->GetSettings().Theme and LoadThemePreset mutates that object
in-place; remove the assignment "themeSettings =
globals::menu->GetSettings().Theme" (or stop reassigning the referenced struct)
so the code relies on the existing reference updated by LoadThemePreset (locate
where themeSettings and LoadThemePreset are used in SettingsTabRenderer.cpp to
remove the redundant self-assignment).
- Around line 386-396: showUpdateFeedback, changedSettings and updateSuccess are
declared static and never cleared when the theme preset selection changes,
causing stale feedback to persist across presets; modify the theme preset
selection handler (the code that updates currentThemePreset from the dropdown)
to reset showUpdateFeedback = false, clear changedSettings (e.g.,
changedSettings.clear()) and set updateSuccess = false whenever
currentThemePreset is changed, and apply the same reset logic in the other
selection-change location noted (the block around the second occurrence) so
feedback is cleared on every preset switch.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/Menu/SettingsTabRenderer.cpp (1)
436-451:isPresetis stale for one frame after a combo selection
isPresetis computed at line 436 fromSelectedThemePresetbefore the combo at line 446 can change it. WhenLoadThemePresetupdatesSelectedThemePresetinside the combo block,isPresetandcurrentThemePresetremain the pre-change values for the rest of the current frame. This means the Save button can appear (or be hidden) incorrectly for one frame after a theme switch.Moving the
isPresetcomputation — and refreshingcurrentThemePreset— to after the combo block eliminates the stale-state window:♻️ Proposed refactor
- const bool isPreset = IsPresetThemeSelected(); - for (size_t i = 0; i < themes.size(); ++i) { if (themes[i].name == currentThemePreset) { currentItem = static_cast<int>(i); break; } } // Theme preset dropdown if (ComboWithFont("##ThemePreset", ¤tItem, items.data(), static_cast<int>(items.size()), Menu::FontRole::Body)) { - std::string selectedTheme = themes[currentItem].name; - if (globals::menu->LoadThemePreset(selectedTheme)) { - // Theme loaded successfully, update UI + currentThemePreset = themes[currentItem].name; + if (globals::menu->LoadThemePreset(currentThemePreset)) { themeSettings = globals::menu->GetSettings().Theme; } } + + const bool isPreset = !currentThemePreset.empty() && + ThemeManager::GetSingleton()->IsPresetTheme(currentThemePreset);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` around lines 436 - 451, The bool isPreset returned by IsPresetThemeSelected() and the currentThemePreset variable are computed before the ComboWithFont selection and thus become stale for one frame when LoadThemePreset(selectedTheme) inside the combo changes the selected preset; move the IsPresetThemeSelected() call and any refresh of currentThemePreset to after the ComboWithFont block (and after you call globals::menu->LoadThemePreset and update themeSettings via globals::menu->GetSettings().Theme) so the saved/preset UI (e.g., Save button visibility) uses the post-selection state; specifically update the logic around IsPresetThemeSelected(), currentThemePreset, ComboWithFont, LoadThemePreset, and themeSettings/GetSettings().Theme to recompute isPreset and currentThemePreset after handling the combo result.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 608-609: The code calls strlen on safeNewThemeName returned by
ThemeManager::SanitizeThemeFileName (a std::string), causing a compile error;
change the emptiness check to use std::string::empty() (e.g., set
isThemeNameEmpty = safeNewThemeName.empty()) so SanitizeThemeFileName,
safeNewThemeName and isThemeNameEmpty are used correctly without C-style strlen.
---
Duplicate comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Line 509: The code uses currentThemeInfo->themeData["Theme"] which can invoke
undefined behavior if the "Theme" key is missing; change the access to a safe
form: first check currentThemeInfo->themeData.contains("Theme") (or use
value("Theme", json{})) and then assign savedThemeJson from
currentThemeInfo->themeData.at("Theme") (or from value) so you don’t call the
const operator[] on a possibly-missing key; update the assignment to use
contains/at or value and keep the target variable savedThemeJson.
---
Nitpick comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 436-451: The bool isPreset returned by IsPresetThemeSelected() and
the currentThemePreset variable are computed before the ComboWithFont selection
and thus become stale for one frame when LoadThemePreset(selectedTheme) inside
the combo changes the selected preset; move the IsPresetThemeSelected() call and
any refresh of currentThemePreset to after the ComboWithFont block (and after
you call globals::menu->LoadThemePreset and update themeSettings via
globals::menu->GetSettings().Theme) so the saved/preset UI (e.g., Save button
visibility) uses the post-selection state; specifically update the logic around
IsPresetThemeSelected(), currentThemePreset, ComboWithFont, LoadThemePreset, and
themeSettings/GetSettings().Theme to recompute isPreset and currentThemePreset
after handling the combo result.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/Menu/SettingsTabRenderer.cpp (2)
575-596:⚠️ Potential issue | 🟡 Minor
showUpdateFeedbackis never cleared on theme selection change — stale feedback persists
showUpdateFeedbackis astatic boolthat is set totrueon any Save attempt but never reset when the user selects a different theme from the dropdown or switches away from and back to the Themes tab. A previous "Failed to update theme" message will remain visible while the user is viewing a different (possibly healthy) theme, and vice versa.🐛 Proposed fix — reset feedback when selection changes
for (size_t i = 0; i < themes.size(); ++i) { if (themes[i].name == currentThemePreset) { + if (currentItem != static_cast<int>(i)) { + showUpdateFeedback = false; + changedSettings.clear(); + } currentItem = static_cast<int>(i); break; } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` around lines 575 - 596, The feedback flag showUpdateFeedback (a static bool used with updateSuccess and changedSettings) is never cleared when the user changes the selected theme or leaves/returns to the Themes tab, causing stale success/error messages to persist; fix this by resetting showUpdateFeedback = false (and optionally clear changedSettings and reset updateSuccess) whenever the theme selection is changed (the dropdown/selection handler in SettingsTabRenderer.cpp) and when the Themes tab is (re)entered, so feedback only reflects the latest save action.
686-692:⚠️ Potential issue | 🟡 MinorUpdate logging to show the actual sanitized filename being saved
SaveThemesanitizes the theme name internally viaSanitizeThemeFileName, so the file is correctly written with the sanitized name andLoadThemePresetwill successfully find it. However, thelogger::infoat line 687 logs the raw unsanitized name, which is misleading about what was actually saved.♻️ Proposed fix
- logger::info("Attempting to save new theme: '{}' with display name: '{}'", newThemeName, displayName); + logger::info("Attempting to save new theme: '{}' with display name: '{}'", safeNewThemeName, displayName);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` around lines 686 - 692, The info log uses the raw newThemeName but SaveTheme sanitizes it (via SanitizeThemeFileName) so the saved file uses a different name; update the logging to report the sanitized filename instead of the raw input: obtain the sanitized name (the same value passed to LoadThemePreset, e.g., safeNewThemeName or by calling the same SanitizeThemeFileName used by SaveTheme) and use that sanitized name in the logger::info messages around SaveTheme, so the log accurately reflects the actual file written and matches the argument passed to globals::menu->LoadThemePreset.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 575-596: The feedback flag showUpdateFeedback (a static bool used
with updateSuccess and changedSettings) is never cleared when the user changes
the selected theme or leaves/returns to the Themes tab, causing stale
success/error messages to persist; fix this by resetting showUpdateFeedback =
false (and optionally clear changedSettings and reset updateSuccess) whenever
the theme selection is changed (the dropdown/selection handler in
SettingsTabRenderer.cpp) and when the Themes tab is (re)entered, so feedback
only reflects the latest save action.
- Around line 686-692: The info log uses the raw newThemeName but SaveTheme
sanitizes it (via SanitizeThemeFileName) so the saved file uses a different
name; update the logging to report the sanitized filename instead of the raw
input: obtain the sanitized name (the same value passed to LoadThemePreset,
e.g., safeNewThemeName or by calling the same SanitizeThemeFileName used by
SaveTheme) and use that sanitized name in the logger::info messages around
SaveTheme, so the log accurately reflects the actual file written and matches
the argument passed to globals::menu->LoadThemePreset.
---
Duplicate comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Line 509: currentThemeInfo is a const pointer so using
currentThemeInfo->themeData["Theme"] will throw if the "Theme" key is missing;
change the access to a non-throwing lookup (e.g., use
currentThemeInfo->themeData.value("Theme", json{}) or check contains/find on
themeData before indexing) and handle the missing-key case (use an empty/default
json or bail gracefully) so the save path won't crash when third-party/malformed
theme files omit "Theme"; update the use site where json savedThemeJson is
created to use this safe lookup.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/Menu/ThemeManager.cpp (1)
670-677:IsPresetThemestill uses case-sensitive comparison — accepted design trade-off.The UI layer enforces case-insensitive duplicate detection before calling
SaveTheme, so a user can't reach this path with a case-variant name through the normal flow. Direct API callers (e.g.,SaveTheme("default", ...)) could still bypass it on a case-insensitive NTFS filesystem.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/ThemeManager.cpp` around lines 670 - 677, IsPresetTheme currently compares themeName to ThemePresets::names using case-sensitive equality which allows API callers to bypass the preset check on case-insensitive filesystems; update ThemeManager::IsPresetTheme to perform a case-insensitive comparison (e.g., normalize both themeName and each preset name to a common case or use a locale-independent case-insensitive compare) against ThemePresets::names and return true if any match, ensuring direct SaveTheme calls can't slip past the preset check.src/Menu/SettingsTabRenderer.cpp (1)
491-498:⚠️ Potential issue | 🟡 Minor
const json::operator[]— prefer.at()for explicitness.
currentThemeInfo->themeDataisconst json(via a const pointer).operator[]on a constnlohmann::jsonobject throwsstd::out_of_rangefor missing keys; in debug builds it also asserts. In practice the"Theme"key is guaranteed to exist becauseDiscoverThemesonly populatesthemeswith entries that passValidateThemeData, but using.at()makes that contract explicit and removes the ambiguity.🛡️ Proposed fix
- json savedThemeJson = currentThemeInfo->themeData["Theme"]; + if (!currentThemeInfo->themeData.contains("Theme")) { + logger::warn("Theme '{}' has no 'Theme' key — skipping save", currentThemePreset); + updateSuccess = false; + showUpdateFeedback = true; + return; + } + json savedThemeJson = currentThemeInfo->themeData.at("Theme");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/SettingsTabRenderer.cpp` around lines 491 - 498, Replace the use of operator[] on the const json themeData with .at() to make the required "Theme" key access explicit: change the assignment to savedThemeJson to use currentThemeInfo->themeData.at("Theme") (locate the code around currentThemeInfo, themeData and savedThemeJson in SettingsTabRenderer.cpp) so the intent and bounds checking are clear and avoid debug assertions from operator[] on const json.
🧹 Nitpick comments (2)
src/Menu/ThemeManager.cpp (1)
556-569:LoadThemesanitizes the lookup key butGetThemeInfodoes not — consider aligning.
LoadTheme(line 567) derivessafeFileName = SanitizeFileName(themeName)and searches by that sanitized name, whileGetThemeInfo(line 654) searches by the rawthemeName. If the same unsanitized string is passed to both (e.g.,"My:Theme"),LoadThemefinds"My_Theme"whileGetThemeInforeturnsnullptr. Today all callers use clean filename stems, but the inconsistency is a maintenance footgun.♻️ Proposed fix
const ThemeManager::ThemeInfo* ThemeManager::GetThemeInfo(const std::string& themeName) const { + const std::string safeFileName = Util::FileHelpers::SanitizeFileName(themeName); auto it = std::find_if(themes.begin(), themes.end(), - [&themeName](const ThemeInfo& theme) { return theme.name == themeName; }); + [&safeFileName](const ThemeInfo& theme) { return theme.name == safeFileName; }); return (it != themes.end()) ? &(*it) : nullptr; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Menu/ThemeManager.cpp` around lines 556 - 569, LoadTheme sanitizes the lookup key (safeFileName = Util::FileHelpers::SanitizeFileName(themeName)) but GetThemeInfo does not, causing inconsistent lookups; update GetThemeInfo to apply the same SanitizeFileName to its incoming themeName before comparing to ThemeInfo::name (or alternatively move sanitization into a shared helper used by both functions) so both LoadTheme and GetThemeInfo use the same normalized key when searching the themes vector.src/Utils/FileSystem.cpp (1)
213-234:SanitizeFileNamedoesn't strip leading/trailing spaces or trailing dots.Windows silently removes trailing spaces and trailing dots from filenames (and leading spaces are Windows-invalid). A name like
"Theme "passed tostd::ofstreamwould actually create"Theme.json", not"Theme .json", creating a silent path mismatch —SaveThemereturnstruebutRefreshThemessees a different stem than expected.♻️ Proposed fix
std::string SanitizeFileName(std::string name) { // Replace invalid characters std::replace_if(name.begin(), name.end(), [](char c) { auto u = static_cast<unsigned char>(c); return c == '\\' || c == '/' || c == ':' || c == '*' || c == '?' || c == '"' || c == '<' || c == '>' || c == '|' || u < 32u || u == 127u; }, '_'); + + // Windows disallows filenames that end in a space or dot + while (!name.empty() && (name.back() == ' ' || name.back() == '.')) + name.pop_back(); + while (!name.empty() && name.front() == ' ') + name.erase(name.begin()); + if (name.empty()) + name = "_"; // Windows reserved device names ...🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Utils/FileSystem.cpp` around lines 213 - 234, SanitizeFileName currently replaces invalid chars but doesn't trim leading/trailing spaces or remove trailing dots (which Windows silently strips), so update SanitizeFileName to first trim leading and trailing spaces and then remove any trailing '.' characters from name (e.g., while (!name.empty() && name.back() == '.') name.pop_back();), then continue with the existing invalid-char replacement and reserved-name check (use the same Util::IEquals reserved-name logic after trimming); also ensure an empty result is handled (e.g., replace with '_' or a default name) before returning.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 441-448: The refresh path resets SelectedThemePreset to "Default"
but never applies it, so when themeManager->GetThemeInfo(currentThemePreset)
returns null you should call the codepath that actually loads/applies the preset
(e.g., invoke LoadThemePreset("Default") or the equivalent apply method on
themeManager or settings) after setting currentThemePreset and
globals::menu->GetSettings().SelectedThemePreset so the ImGui style is updated
immediately; update the block in SettingsTabRenderer (around the Refresh button
handling) to set the preset strings and then call the theme loading/apply
function (LoadThemePreset) to ensure the default theme is applied.
---
Duplicate comments:
In `@src/Menu/SettingsTabRenderer.cpp`:
- Around line 491-498: Replace the use of operator[] on the const json themeData
with .at() to make the required "Theme" key access explicit: change the
assignment to savedThemeJson to use currentThemeInfo->themeData.at("Theme")
(locate the code around currentThemeInfo, themeData and savedThemeJson in
SettingsTabRenderer.cpp) so the intent and bounds checking are clear and avoid
debug assertions from operator[] on const json.
In `@src/Menu/ThemeManager.cpp`:
- Around line 670-677: IsPresetTheme currently compares themeName to
ThemePresets::names using case-sensitive equality which allows API callers to
bypass the preset check on case-insensitive filesystems; update
ThemeManager::IsPresetTheme to perform a case-insensitive comparison (e.g.,
normalize both themeName and each preset name to a common case or use a
locale-independent case-insensitive compare) against ThemePresets::names and
return true if any match, ensuring direct SaveTheme calls can't slip past the
preset check.
---
Nitpick comments:
In `@src/Menu/ThemeManager.cpp`:
- Around line 556-569: LoadTheme sanitizes the lookup key (safeFileName =
Util::FileHelpers::SanitizeFileName(themeName)) but GetThemeInfo does not,
causing inconsistent lookups; update GetThemeInfo to apply the same
SanitizeFileName to its incoming themeName before comparing to ThemeInfo::name
(or alternatively move sanitization into a shared helper used by both functions)
so both LoadTheme and GetThemeInfo use the same normalized key when searching
the themes vector.
In `@src/Utils/FileSystem.cpp`:
- Around line 213-234: SanitizeFileName currently replaces invalid chars but
doesn't trim leading/trailing spaces or remove trailing dots (which Windows
silently strips), so update SanitizeFileName to first trim leading and trailing
spaces and then remove any trailing '.' characters from name (e.g., while
(!name.empty() && name.back() == '.') name.pop_back();), then continue with the
existing invalid-char replacement and reserved-name check (use the same
Util::IEquals reserved-name logic after trimming); also ensure an empty result
is handled (e.g., replace with '_' or a default name) before returning.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
cmake/ThemePresets.h.insrc/Menu/SettingsTabRenderer.cppsrc/Menu/ThemeManager.cppsrc/Menu/ThemeManager.hsrc/Utils/FileSystem.cppsrc/Utils/FileSystem.hsrc/Utils/Format.cppsrc/Utils/Format.h
🚧 Files skipped from review as they are similar to previous changes (1)
- cmake/ThemePresets.h.in
|
Refactors mean there were no actual changes. This looks like a fix. |
* fix(weather overrides): ensure json format for features (community-shaders#1748) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * perf(terrain blending): tweak defaults (community-shaders#1771) * fix(lighting): vanilla envcolor mult the correct value (community-shaders#1775) * fix(water): remove final colour saturate (community-shaders#1778) * fix(unified-water): LOD water cache mismatch (community-shaders#1779) * fix(weather editor): override desync with weather transitions (community-shaders#1782) * fix(weather editor): no-override weather file deletion (community-shaders#1777) * fix(weather editor): apply weather settings post-load (community-shaders#1776) * fix(weather editor): handling of weathers without overrides (community-shaders#1773) * feat(UI): feature headings (community-shaders#1786) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(VR): add wand pointing (community-shaders#1790) * chore(UI): theme consistency (community-shaders#1787) * fix(upscaling): warn about max nvidia resolution (community-shaders#1795) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore(linear lighting): UI settings changes (community-shaders#1785) Co-authored-by: Jiaye <l936249247@hotmail.com> * fix(grass-lighting) better basic grass brightness default (community-shaders#1780) * chore(UI): remove settings and about tabs (community-shaders#1794) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(terrain shadows): fix compiler warnings (community-shaders#1798) * fix: fix flickering particles (community-shaders#1791) * fix(terrain blending): disable vr support (community-shaders#1799) * refactor(upscaling): standardize behavior and tune settings (community-shaders#1783) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(UI): add auto-hide featurelist option (community-shaders#1793) * fix: match grass brightness of vanilla (community-shaders#1801) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor(perfoverlay): remove color from "Other" and "Total" (community-shaders#1806) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(unified water): fix for mesh water jitter (community-shaders#1809) * fix: clear shader cache on plugin version change (community-shaders#1739) * feat(filewatcher): add hlsli tracking (community-shaders#1796) * feat(linear lighting): add ambient multiplier (community-shaders#1805) * fix(unified-water): underwater fog flicker (community-shaders#1807) * fix(UI): conflicting esc key on welcome hotkey dialogue (community-shaders#1811) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * chore(UI): add subtext font to tooltips (community-shaders#1810) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * build: bump streamline to 2.10.3 (community-shaders#1813) * build: resolve shader warnings (community-shaders#1818) * feat(ui): add combo hotkey support (community-shaders#1808) * feat: add feature constraints (community-shaders#1804) * build: update version to 1.4.8 (community-shaders#1802) * fix(VR): apply per eye upscaling (community-shaders#1819) - Split upscaling across each eye for correctness and to avoid DLSS failing over 8k x 8k limit - Changes HMD mask color to black to hide artifacts with fast movement * build: bump common lib to 4.2.0 (community-shaders#1821) Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> * fix(grass collision): catch trashed actor pointers (community-shaders#1765) * fix(weather editor): desynced override transitions (community-shaders#1820) * fix(upscaling): fix preset and allocation handling (community-shaders#1824) Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * build: remove linear lighting from core whilst in development (community-shaders#1826) * chore: bump version to 1.4.9 (community-shaders#1827) * fix: add back LLF core file and remove LL core file (community-shaders#1828) * fix: dont save shader debug toggles (community-shaders#1831) * fix: remove IBL from core, unfinished (community-shaders#1830) * chore: update version to 1.4.10 (community-shaders#1832) * chore(dynamic cubemaps): lessen normalisation darkening (community-shaders#1833) * chore(llf): remove LightsVisualisationMode settings loading (community-shaders#1834) * revert: "fix: dont save shader debug toggles (community-shaders#1831)" This reverts commit f55f195. * revert: "chore(llf): remove LightsVisualisationMode settings loading (community-shaders#1834)" This reverts commit b3db5a7. * fix: default enabledClasses true * build: bump version * feat(upscaling): custom DLSS preset (community-shaders#1837) * fix(weather editor): sync UI for full transition (community-shaders#1822) * fix(linearlighting): return correct buffer when ll feature off (community-shaders#1838) * fix(PBR): skip IrradianceToLinear on specular in vanilla (community-shaders#1839) * feat(weather editor): adjust slider ranges (community-shaders#1847) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(weather editor): replace volumetric Lighting RGB sliders with color picker (community-shaders#1846) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * fix(grass collision): collision radius math (community-shaders#1849) * chore: move new feature information into docs (community-shaders#1848) Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> * fix(ui): background blur with upscaling (community-shaders#1815) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor: move some features to core (community-shaders#1852) * fix: fix blown out water specular (community-shaders#1853) * feat(weather editor): toggle hotkey (community-shaders#1856) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(color picker): add an original color reference to all color pickers (community-shaders#1857) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * perf(emat): alternate tweaks (community-shaders#1850) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather-editor): merge weather picker and editor (community-shaders#1845) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * chore(llf): remove LLF settings loading (community-shaders#1859) * feat: exponential height fog (community-shaders#1708) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather editor): block editor access in loading screens (community-shaders#1871) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(weather editor): improve weather picker UI and functionality (community-shaders#1863) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather editor): repurpose unsaved changes tracking (community-shaders#1860) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix: sync grass lighting defaults to match ENB (community-shaders#1844) * fix: stop shader compilation on game exit (community-shaders#1867) closes community-shaders#1130 * fix(weather editor): prevent inputs when editor is open (community-shaders#1872) * fix(weather editor): add ctd guards (community-shaders#1864) * feat(weather editor): remove WorldSpace widget and associated code (community-shaders#1878) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(vr): add OpenComposite menu support (community-shaders#1880) * revert: "feat(vr): add OpenComposite VR menu" (community-shaders#1881) * revert: "fix: stop shader compilation on game exit" (community-shaders#1882) * feat(vr): add OpenComposite menu support (community-shaders#1883) * feat(weather editor): add time controls (community-shaders#1877) * feat: add shadowmap rasterizer override (community-shaders#1690) * fix(weather editor): clear feature overrides with revert (community-shaders#1884) * feat(UI): Interior Only (community-shaders#1854) * fix(VR): fix Shadowmap Cascade Rasterizer (community-shaders#1888) * fix(unified water): distance calculation for raindrops & LOD fade (community-shaders#1890) * refactor: clarify core feature version mismatch text (community-shaders#1886) * fix: stop shader compilation on game exit (community-shaders#1885) * build: exclude hlsl tests from packaging (community-shaders#1894) * chore: disable feature constraints in dev mode (community-shaders#1893) * fix(vr): improve stereo UV handling (community-shaders#1899) * fix(weather editor): move esc key to native input system (community-shaders#1897) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * fix: move ResolveMonoUVForEye outside VR guard (community-shaders#1906) * fix(grass collision): validate actor (community-shaders#1905) Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> * fix(terrain shadows): height map regression (community-shaders#1911) * fix: util vertical fov math (community-shaders#1904) Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> * test: add float4 overload test (community-shaders#1902) * refactor: move all features to globals::game::calendar (community-shaders#1909) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(UI): resolution based font (community-shaders#1907) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather editor): make objects window be independently scrollable (community-shaders#1908) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(UI): consolidate searchbar to util and add to weather editor (community-shaders#1898) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather editor): add filled star for favourites. (community-shaders#1913) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(weather editor): add delete json button to objects window (community-shaders#1914) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(VR): resolution-based font (community-shaders#1923) * refactor: use depthbuffer helper (community-shaders#1925) * refactor: move TurboColormap into Color.hlsli (community-shaders#1924) * fix(weather editor): expand clickable area of feature override (community-shaders#1921) * feat(weather editor): enable snapping to viewport (community-shaders#1917) * feat(weather editor): highlight enabled cloud layers (community-shaders#1916) * fix(VR): SSGI discrepancies (community-shaders#1926) * feat: volumetric shadows (community-shaders#1874) * ci: enhance feature version audit (community-shaders#1927) * feat(weather editor): add filter options for objects window (community-shaders#1922) * feat(weather editor): sticky headers and scrollable content (community-shaders#1930) * fix(UI): ImGui scaling for borderless mode (community-shaders#1929) * ci: don't fail on feature audits (community-shaders#1934) * fix(pbr): use scrap heap allocation (community-shaders#1928) * chore(UI): add subsurface scattering to Interior Only (community-shaders#1932) * fix(weather editor): align highlights, fix tooltip (community-shaders#1918) * fix(ssgi): guard VR only compilation (community-shaders#1938) * build: update template to avoid extra directory (community-shaders#1812) * style: fix hlsl formatting (community-shaders#1939) * fix(UI): improve theme management UI flow (community-shaders#1933) closes community-shaders#1919 * build(deps): update pre-commit hooks (community-shaders#1768) * feat(UI): delete theme button (community-shaders#1940) * feat(UI): open log file button (community-shaders#1942) * fix(hair): marschner volumetric shadow tint (community-shaders#1944) * fix(VR): screen space shadows desync (community-shaders#1946) closes community-shaders#1840 * fix(VR): depth culling during upscaling/Terrain Blending (community-shaders#1858) * feat(VR): add edge detection for stereo blending (community-shaders#1948) * refactor: allocate trampoline once (community-shaders#1951) * fix(UI): PBR MATO color scale RGB settings corrected (community-shaders#1957) * fix(weather editor): guard against loadorder changes (community-shaders#1953) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: davo0411 <davidkehoe0411@outlook.com> * fix(UI): feature description text wrapping (community-shaders#1960) * fix(VR): exponential height fog stereo mismatch (community-shaders#1961) * chore: pbr consistency changes (community-shaders#1841) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: jiayev <l936249247@hotmail.com> * fix(skylighting): remove PBR lighting scale (community-shaders#1963) * fix(skysync): effect mesh blackout during shadow caster transitions (community-shaders#1965) * ci: fix wiki deletion with buffer update (community-shaders#1967) * feat(weather-editor): option to hide viewport (community-shaders#1970) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * test(shader): fallback to warp on invalidarg (community-shaders#1956) Co-authored-by: LukeFrankio <loren@example.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat: triplanar projected materials (community-shaders#1950) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(ao): better ao calculations (community-shaders#1968) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(pbr): fix improper kD terms (community-shaders#1971) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * perf(emat): tweak fade and shadow intensity (community-shaders#1892) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(ibl): revamp ibl and dalc sh (community-shaders#1947) * build: bump commonlib to 4.7.1 (community-shaders#1977) * fix: upscaling monitor detection fixes (community-shaders#1978) * fix(weather editor): prevent overrides resetting settings (community-shaders#1980) * fix(VR): bad llf offset (community-shaders#1984) * perf: cache frequent ui checks (community-shaders#1985) * fix: preserve vanilla water TAA when no upscaler is active (community-shaders#1986) Co-authored-by: jturnley <jturnley@users.noreply.github.com> * fix(UI): first-time dialog fade affects all overlays (community-shaders#1976) * fix(skysync): remove sunlight fade and volumetric lighting overrides (community-shaders#1966) * refactor(HLSL): standardize epsilon constants (community-shaders#1992) closes community-shaders#1227 * feat(UI): require Shift to dock windows (community-shaders#1989) * fix(UI): input spam after alt-tab (community-shaders#1993) * fix(sky sync): early return for invalid cells (community-shaders#1991) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: jiayev <l936249247@hotmail.com> * fix(sky sync): remove undeclared variable (community-shaders#1994) * refactor(pbr): clear up semantics (community-shaders#1995) * fix(UI): scale layout values for high-DPI (community-shaders#1987) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(water): hdr water taa blend (community-shaders#1988) * refactor(color): clarify gamma conversion functions (community-shaders#1996) * feat(ISL-editor): add light counters and fix filtering (community-shaders#1997) * fix(UI): DPI-aware window layouts (community-shaders#2000) * fix(weather-editor): save color palette window (community-shaders#2001) * refactor: centralize feature category names (community-shaders#2007) closes community-shaders#1265 Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * chore: bump versions (community-shaders#2010) * fix(water): sample history mask from current mask (community-shaders#2011) * chore(wetness-effects): set default MaxPuddleWetness to 1.5 (community-shaders#1981) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(weather-editor): add free camera and play mode (community-shaders#2008) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * build: bump versions and reduce false positives (community-shaders#2013) * fix(VR): LLF cluster building and culling (community-shaders#2012) * build: update to VS 2026 (community-shaders#1990) * ci: fix preset in vs2022 mode (community-shaders#2015) * ci: remove v2022 from shader jobs (community-shaders#2016) * feat(upscaling): integrate Streamline Reflex controls (community-shaders#1958) * fix(unified-water): BSWaterShaderProperty.plane (community-shaders#1998) --------- Co-authored-by: Skrubby Skrub In A Shrub <87662196+SkrubbySkrubInAShrub@users.noreply.github.com> Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> Co-authored-by: jiayev <l936249247@hotmail.com> Co-authored-by: Dlizzio <77717521+Dlizzio@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Alan Tse <alandtse@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Bruce <44987693+brucenguyen@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Dawntic <197450198+Dawntic@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Alan Tse <alandtse@gmail.com> Co-authored-by: Vanni Giachin <vanni.giachin@qlik.com> Co-authored-by: zxcvbn <66063766+zndxcvbn@users.noreply.github.com> Co-authored-by: ParticleTroned <248299730+ParticleTroned@users.noreply.github.com> Co-authored-by: soda <130315225+soda3000@users.noreply.github.com> Co-authored-by: YtzyFvra <59631290+YtzyFvra@users.noreply.github.com> Co-authored-by: LukeFrankio <lorenzogrutzmann@gmail.com> Co-authored-by: LukeFrankio <loren@example.com> Co-authored-by: jturnley <32892261+jturnley@users.noreply.github.com> Co-authored-by: jturnley <jturnley@users.noreply.github.com> Co-authored-by: Igor Alan Albuquerque de Sousa <50077829+IgorAlanAlbuquerque@users.noreply.github.com> Co-authored-by: Matt Van Horn <mvanhorn@users.noreply.github.com> Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(weather overrides): ensure json format for features (community-shaders#1748) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * perf(terrain blending): tweak defaults (community-shaders#1771) * fix(lighting): vanilla envcolor mult the correct value (community-shaders#1775) * fix(water): remove final colour saturate (community-shaders#1778) * fix(unified-water): LOD water cache mismatch (community-shaders#1779) * fix(weather editor): override desync with weather transitions (community-shaders#1782) * fix(weather editor): no-override weather file deletion (community-shaders#1777) * fix(weather editor): apply weather settings post-load (community-shaders#1776) * fix(weather editor): handling of weathers without overrides (community-shaders#1773) * feat(UI): feature headings (community-shaders#1786) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(VR): add wand pointing (community-shaders#1790) * chore(UI): theme consistency (community-shaders#1787) * fix(upscaling): warn about max nvidia resolution (community-shaders#1795) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore(linear lighting): UI settings changes (community-shaders#1785) Co-authored-by: Jiaye <l936249247@hotmail.com> * fix(grass-lighting) better basic grass brightness default (community-shaders#1780) * chore(UI): remove settings and about tabs (community-shaders#1794) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(terrain shadows): fix compiler warnings (community-shaders#1798) * fix: fix flickering particles (community-shaders#1791) * fix(terrain blending): disable vr support (community-shaders#1799) * refactor(upscaling): standardize behavior and tune settings (community-shaders#1783) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(UI): add auto-hide featurelist option (community-shaders#1793) * fix: match grass brightness of vanilla (community-shaders#1801) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor(perfoverlay): remove color from "Other" and "Total" (community-shaders#1806) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(unified water): fix for mesh water jitter (community-shaders#1809) * fix: clear shader cache on plugin version change (community-shaders#1739) * feat(filewatcher): add hlsli tracking (community-shaders#1796) * feat(linear lighting): add ambient multiplier (community-shaders#1805) * fix(unified-water): underwater fog flicker (community-shaders#1807) * fix(UI): conflicting esc key on welcome hotkey dialogue (community-shaders#1811) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * chore(UI): add subtext font to tooltips (community-shaders#1810) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * build: bump streamline to 2.10.3 (community-shaders#1813) * build: resolve shader warnings (community-shaders#1818) * feat(ui): add combo hotkey support (community-shaders#1808) * feat: add feature constraints (community-shaders#1804) * build: update version to 1.4.8 (community-shaders#1802) * fix(VR): apply per eye upscaling (community-shaders#1819) - Split upscaling across each eye for correctness and to avoid DLSS failing over 8k x 8k limit - Changes HMD mask color to black to hide artifacts with fast movement * build: bump common lib to 4.2.0 (community-shaders#1821) Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> * fix(grass collision): catch trashed actor pointers (community-shaders#1765) * fix(weather editor): desynced override transitions (community-shaders#1820) * fix(upscaling): fix preset and allocation handling (community-shaders#1824) Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * build: remove linear lighting from core whilst in development (community-shaders#1826) * chore: bump version to 1.4.9 (community-shaders#1827) * fix: add back LLF core file and remove LL core file (community-shaders#1828) * fix: dont save shader debug toggles (community-shaders#1831) * fix: remove IBL from core, unfinished (community-shaders#1830) * chore: update version to 1.4.10 (community-shaders#1832) * chore(dynamic cubemaps): lessen normalisation darkening (community-shaders#1833) * chore(llf): remove LightsVisualisationMode settings loading (community-shaders#1834) * revert: "fix: dont save shader debug toggles (community-shaders#1831)" This reverts commit f55f195. * revert: "chore(llf): remove LightsVisualisationMode settings loading (community-shaders#1834)" This reverts commit b3db5a7. * fix: default enabledClasses true * build: bump version * feat(upscaling): custom DLSS preset (community-shaders#1837) * fix(weather editor): sync UI for full transition (community-shaders#1822) * fix(linearlighting): return correct buffer when ll feature off (community-shaders#1838) * fix(PBR): skip IrradianceToLinear on specular in vanilla (community-shaders#1839) * feat(weather editor): adjust slider ranges (community-shaders#1847) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(weather editor): replace volumetric Lighting RGB sliders with color picker (community-shaders#1846) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * fix(grass collision): collision radius math (community-shaders#1849) * chore: move new feature information into docs (community-shaders#1848) Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> * fix(ui): background blur with upscaling (community-shaders#1815) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor: move some features to core (community-shaders#1852) * fix: fix blown out water specular (community-shaders#1853) * feat(weather editor): toggle hotkey (community-shaders#1856) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(color picker): add an original color reference to all color pickers (community-shaders#1857) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * perf(emat): alternate tweaks (community-shaders#1850) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather-editor): merge weather picker and editor (community-shaders#1845) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * chore(llf): remove LLF settings loading (community-shaders#1859) * feat: exponential height fog (community-shaders#1708) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather editor): block editor access in loading screens (community-shaders#1871) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(weather editor): improve weather picker UI and functionality (community-shaders#1863) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather editor): repurpose unsaved changes tracking (community-shaders#1860) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix: sync grass lighting defaults to match ENB (community-shaders#1844) * fix: stop shader compilation on game exit (community-shaders#1867) closes community-shaders#1130 * fix(weather editor): prevent inputs when editor is open (community-shaders#1872) * fix(weather editor): add ctd guards (community-shaders#1864) * feat(weather editor): remove WorldSpace widget and associated code (community-shaders#1878) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(vr): add OpenComposite menu support (community-shaders#1880) * revert: "feat(vr): add OpenComposite VR menu" (community-shaders#1881) * revert: "fix: stop shader compilation on game exit" (community-shaders#1882) * feat(vr): add OpenComposite menu support (community-shaders#1883) * feat(weather editor): add time controls (community-shaders#1877) * feat: add shadowmap rasterizer override (community-shaders#1690) * fix(weather editor): clear feature overrides with revert (community-shaders#1884) * feat(UI): Interior Only (community-shaders#1854) * fix(VR): fix Shadowmap Cascade Rasterizer (community-shaders#1888) * fix(unified water): distance calculation for raindrops & LOD fade (community-shaders#1890) * refactor: clarify core feature version mismatch text (community-shaders#1886) * fix: stop shader compilation on game exit (community-shaders#1885) * build: exclude hlsl tests from packaging (community-shaders#1894) * chore: disable feature constraints in dev mode (community-shaders#1893) * fix(vr): improve stereo UV handling (community-shaders#1899) * fix(weather editor): move esc key to native input system (community-shaders#1897) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * fix: move ResolveMonoUVForEye outside VR guard (community-shaders#1906) * fix(grass collision): validate actor (community-shaders#1905) Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> * fix(terrain shadows): height map regression (community-shaders#1911) * fix: util vertical fov math (community-shaders#1904) Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> * test: add float4 overload test (community-shaders#1902) * refactor: move all features to globals::game::calendar (community-shaders#1909) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(UI): resolution based font (community-shaders#1907) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather editor): make objects window be independently scrollable (community-shaders#1908) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(UI): consolidate searchbar to util and add to weather editor (community-shaders#1898) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(weather editor): add filled star for favourites. (community-shaders#1913) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(weather editor): add delete json button to objects window (community-shaders#1914) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(VR): resolution-based font (community-shaders#1923) * refactor: use depthbuffer helper (community-shaders#1925) * refactor: move TurboColormap into Color.hlsli (community-shaders#1924) * fix(weather editor): expand clickable area of feature override (community-shaders#1921) * feat(weather editor): enable snapping to viewport (community-shaders#1917) * feat(weather editor): highlight enabled cloud layers (community-shaders#1916) * fix(VR): SSGI discrepancies (community-shaders#1926) * feat: volumetric shadows (community-shaders#1874) * ci: enhance feature version audit (community-shaders#1927) * feat(weather editor): add filter options for objects window (community-shaders#1922) * feat(weather editor): sticky headers and scrollable content (community-shaders#1930) * fix(UI): ImGui scaling for borderless mode (community-shaders#1929) * ci: don't fail on feature audits (community-shaders#1934) * fix(pbr): use scrap heap allocation (community-shaders#1928) * chore(UI): add subsurface scattering to Interior Only (community-shaders#1932) * fix(weather editor): align highlights, fix tooltip (community-shaders#1918) * fix(ssgi): guard VR only compilation (community-shaders#1938) * build: update template to avoid extra directory (community-shaders#1812) * style: fix hlsl formatting (community-shaders#1939) * fix(UI): improve theme management UI flow (community-shaders#1933) closes community-shaders#1919 * build(deps): update pre-commit hooks (community-shaders#1768) * feat(UI): delete theme button (community-shaders#1940) * feat(UI): open log file button (community-shaders#1942) * fix(hair): marschner volumetric shadow tint (community-shaders#1944) * fix(VR): screen space shadows desync (community-shaders#1946) closes community-shaders#1840 * fix(VR): depth culling during upscaling/Terrain Blending (community-shaders#1858) * feat(VR): add edge detection for stereo blending (community-shaders#1948) * refactor: allocate trampoline once (community-shaders#1951) * fix(UI): PBR MATO color scale RGB settings corrected (community-shaders#1957) * fix(weather editor): guard against loadorder changes (community-shaders#1953) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: davo0411 <davidkehoe0411@outlook.com> * fix(UI): feature description text wrapping (community-shaders#1960) * fix(VR): exponential height fog stereo mismatch (community-shaders#1961) * chore: pbr consistency changes (community-shaders#1841) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: jiayev <l936249247@hotmail.com> * fix(skylighting): remove PBR lighting scale (community-shaders#1963) * fix(skysync): effect mesh blackout during shadow caster transitions (community-shaders#1965) * ci: fix wiki deletion with buffer update (community-shaders#1967) * feat(weather-editor): option to hide viewport (community-shaders#1970) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * test(shader): fallback to warp on invalidarg (community-shaders#1956) Co-authored-by: LukeFrankio <loren@example.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat: triplanar projected materials (community-shaders#1950) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(ao): better ao calculations (community-shaders#1968) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(pbr): fix improper kD terms (community-shaders#1971) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * perf(emat): tweak fade and shadow intensity (community-shaders#1892) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(ibl): revamp ibl and dalc sh (community-shaders#1947) * build: bump commonlib to 4.7.1 (community-shaders#1977) * fix: upscaling monitor detection fixes (community-shaders#1978) * fix(weather editor): prevent overrides resetting settings (community-shaders#1980) * fix(VR): bad llf offset (community-shaders#1984) * perf: cache frequent ui checks (community-shaders#1985) * fix: preserve vanilla water TAA when no upscaler is active (community-shaders#1986) Co-authored-by: jturnley <jturnley@users.noreply.github.com> * fix(UI): first-time dialog fade affects all overlays (community-shaders#1976) * fix(skysync): remove sunlight fade and volumetric lighting overrides (community-shaders#1966) * refactor(HLSL): standardize epsilon constants (community-shaders#1992) closes community-shaders#1227 * feat(UI): require Shift to dock windows (community-shaders#1989) * fix(UI): input spam after alt-tab (community-shaders#1993) * fix(sky sync): early return for invalid cells (community-shaders#1991) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: jiayev <l936249247@hotmail.com> * fix(sky sync): remove undeclared variable (community-shaders#1994) * refactor(pbr): clear up semantics (community-shaders#1995) * fix(UI): scale layout values for high-DPI (community-shaders#1987) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(water): hdr water taa blend (community-shaders#1988) * refactor(color): clarify gamma conversion functions (community-shaders#1996) * feat(ISL-editor): add light counters and fix filtering (community-shaders#1997) * fix(UI): DPI-aware window layouts (community-shaders#2000) * fix(weather-editor): save color palette window (community-shaders#2001) * refactor: centralize feature category names (community-shaders#2007) closes community-shaders#1265 Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * chore: bump versions (community-shaders#2010) * fix(water): sample history mask from current mask (community-shaders#2011) * chore(wetness-effects): set default MaxPuddleWetness to 1.5 (community-shaders#1981) Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> * feat(weather-editor): add free camera and play mode (community-shaders#2008) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * build: bump versions and reduce false positives (community-shaders#2013) * fix(VR): LLF cluster building and culling (community-shaders#2012) * build: update to VS 2026 (community-shaders#1990) * ci: fix preset in vs2022 mode (community-shaders#2015) * ci: remove v2022 from shader jobs (community-shaders#2016) * feat(upscaling): integrate Streamline Reflex controls (community-shaders#1958) * fix(unified-water): BSWaterShaderProperty.plane (community-shaders#1998) --------- Co-authored-by: Skrubby Skrub In A Shrub <87662196+SkrubbySkrubInAShrub@users.noreply.github.com> Co-authored-by: SkrubbySkrubInAShrub <skrubbyskrubinashrub@gmail.com> Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com> Co-authored-by: jiayev <l936249247@hotmail.com> Co-authored-by: Dlizzio <77717521+Dlizzio@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Alan Tse <alandtse@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Bruce <44987693+brucenguyen@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Dawntic <197450198+Dawntic@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Alan Tse <alandtse@gmail.com> Co-authored-by: Vanni Giachin <vanni.giachin@qlik.com> Co-authored-by: zxcvbn <66063766+zndxcvbn@users.noreply.github.com> Co-authored-by: ParticleTroned <248299730+ParticleTroned@users.noreply.github.com> Co-authored-by: soda <130315225+soda3000@users.noreply.github.com> Co-authored-by: YtzyFvra <59631290+YtzyFvra@users.noreply.github.com> Co-authored-by: LukeFrankio <lorenzogrutzmann@gmail.com> Co-authored-by: LukeFrankio <loren@example.com> Co-authored-by: jturnley <32892261+jturnley@users.noreply.github.com> Co-authored-by: jturnley <jturnley@users.noreply.github.com> Co-authored-by: Igor Alan Albuquerque de Sousa <50077829+IgorAlanAlbuquerque@users.noreply.github.com> Co-authored-by: Matt Van Horn <mvanhorn@users.noreply.github.com> Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
closes community-shaders#1919 (cherry picked from commit 8804d94)
Addresses #1919.
There are significant number of whitespace-only changes, hiding whitespace is recommended for review.
The UI flow for theme management is a bit convoluted. You can modify the settings but clicking the global save button does not save it. The user should instead be saving the theme via the theme tab.
This PR admittedly does a bit more than add messages. As a summary:
When I say "moved things" around, it includes removing the weird dropdown create flow that was used to create themes. It makes the implementation over-complicated and the UX also over-complicated. There's now a distinct "Save As New" button.
As for removing the ability to save to preset themes, this is for user protection. Whenever a CS update rolls out, these themes are reset anyway. By forcing the user to create their own theme, this doesn't happen.
Example of the new info text:

New theme selection tab (save button is not available for preset themes):

Future improvements (todo):
Summary by CodeRabbit
New Features
Bug Fixes / Reliability
UX