Skip to content

Add Glassdock mod - #5037

Closed
Onuello wants to merge 2 commits into
ramensoftware:mainfrom
Onuello:main
Closed

Add Glassdock mod#5037
Onuello wants to merge 2 commits into
ramensoftware:mainfrom
Onuello:main

Conversation

@Onuello

@Onuello Onuello commented Aug 7, 2026

Copy link
Copy Markdown

Changelog

N/A - New mod introduction.

Mod authorship

If this pull request introduces a new mod, please complete the section below.

This mod was created by:

  • The submitter, without AI assistance
  • The submitter, with AI assistance
  • Claude
  • ChatGPT
  • Gemini
  • Another AI (please specify):
  • Other (please specify):

Please select the options that best apply. Your selection does not affect the acceptance criteria, but it helps reviewers understand the context of the code and provide relevant feedback.

@windhawk-reviewer windhawk-reviewer Bot added the waiting-for-author The author's turn: request an AI review, or respond to one that was posted. label Aug 7, 2026
@windhawk-reviewer

Copy link
Copy Markdown

Thanks for the pull request! This repository uses a two-stage review: an AI review that you run yourself, followed by a human review.

To get started, comment /ai-review. Once you're happy with the result, comment /ready-for-reviewer to hand it over to a human reviewer.

See the pull request review process for the full details.

@Onuello

Onuello commented Aug 7, 2026

Copy link
Copy Markdown
Author

/ai-review

@windhawk-reviewer windhawk-reviewer Bot added waiting-for-ai-review An AI review was requested and is being prepared. and removed waiting-for-author The author's turn: request an AI review, or respond to one that was posted. labels Aug 7, 2026
@windhawk-reviewer

Copy link
Copy Markdown

Submission review

Note: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding.

Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it.

Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them.


The biggest question here is whether this should be a mod at all rather than a theme; below that there are several rules that silently don't apply, and leftover code from the mod it was forked from.

1. This is a fork of Windows 11 Taskbar Styler — it should be a theme, not a new mod.

Of the 8,022 lines, roughly 7,300 are m417z's windows-11-taskbar-styler engine copied verbatim (VisualTreeWatcher/TAP, XamlBlurBrush, the whole style/selector/style-variable engine, PromptToRestartExplorer, the hooks, the lifecycle). The actual contribution is namespace glassdock (lines 184–907), which builds one hard-coded Theme out of settings — i.e. exactly the data that the styler already takes as a theme.

That's the mechanism the repo already has for this: themes live in ramensoftware/windows-11-taskbar-styling-guide and get integrated into the styler's theme list (Surface, WindowGlass, LiquidGlass, Lucent, … — the same themes this file's comments cite as sources). Duplicating an existing mod instead of extending it is something the maintainer consistently pushes back on.

Concrete downsides of the fork beyond catalog duplication:

  • It's already behind upstream. The copied engine is an older revision. For example, upstream changed undefined style variables inside an expression to evaluate to the empty string so a style can supply its own default and numeric operators fail closed; this copy still returns 0 (line 5169). Upstream is at stats-v5, this copy has stats-v4. Every future engine fix and every fix for a new Windows build will land upstream and not here.
  • It conflicts with the styler in the same process. Both mods target explorer.exe and both inject an XAML diagnostics TAP and hook InitializeXamlDiagnosticsEx, so a user running both gets the "The following module is trying to use XAML diagnostics… Do you want to block it?" prompt — from a dialog titled "Windows 11 Taskbar Styler - Windhawk" in both mods, so it's not even clear which one is asking.

If the point is the per-knob settings UI (opacity, radii, colors as individual settings rather than a style list), that's a feature request for the styler, not a reason to fork it. I'd suggest submitting Glassdock as a theme and, separately, proposing the settings idea upstream.

2. Remove the copied stats/telemetry timer.

StartStatsTimer (lines 7722–7835) is m417z's theme-usage counter, copied as-is, and it reports to his repo:

static constexpr WCHAR kStatsBaseUrl[] =
    L"https://github.com/ramensoftware/"
    L"windows-11-taskbar-styling-guide/"
    L"releases/download/stats-v4/";

It's also dead here: the callback starts with Wh_GetStringSetting(L"theme") (line 7760), and there is no theme setting in this mod's settings block. Wh_GetStringSetting returns L"" when unset, so the callback always returns immediately — all the code does is create a thread-pool timer that wakes every 24 h and does nothing, plus write statsTimerLastTime to the mod's storage. Delete StartStatsTimer/StopStatsTimer and the calls at lines 7901 and 7946.

3. The persistent glassy icon background never applies — a later duplicate rule overrides it.

Taskbar.TaskListLabeledButtonPanel@CommonStates > Border#BackgroundElement is declared twice: once at lines 465–477 (the base Background glass + Margin + CornerRadius) and again at lines 580–589 (the attention-flash Background@RequestingAttention* values).

The engine does not merge those. FindElementPropertyOverrides walks the rule list in reverse and skips any property already claimed by a later rule (lines 4705–4708):

bool propertyInserted = propertiesAdded.insert(property).second;
if (!propertyInserted) {
    continue;
}

The claim is per DependencyProperty, not per visual state — so the attention-flash rule claims Background outright and the base glass from the earlier rule is dropped. Net effect: iconBackgroundOpacity has no effect on app buttons, while Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel (Start/Search/Task View/Widgets), which has no second rule, does get the glass — so the taskbar ends up visibly inconsistent.

Same bug on the search button: the "defensive alternate" at lines 496–502 (SearchUx.SearchUI.SearchButtonRootGrid@CommonStates > Border#BackgroundElement) matches the same element as the deep chain at lines 484–491, and being declared later it wins Background and CornerRadius — so only Background@InactiveNormal survives and the unconditional glass is dropped. It isn't a fallback; when both match, it replaces the primary.

Fix: merge each set of styles for a given target into a single targetStyles entry. Note this also means the comment at lines 651–657 has the model backwards — a duplicate declaration doesn't "double-apply" the background, the later one simply wins.

4. Fill on a Border target silently discards the whole rule.

Lines 556–564:

theme.targetStyles.push_back({
    L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border",
    {
        L"Fill@RequestingAttentionRunningIndicator:=<SolidColorBrush .../>",
        L"Background@RequestingAttentionRunningIndicator:=<SolidColorBrush .../>",
        L"Width@RequestingAttentionRunningIndicator=" + w,
        L"Margin=0,0,0," + Num(s.indicatorOffset),
    }
});

Windows.UI.Xaml.Controls.Border has no Fill property. The engine resolves all of a rule's setters in one synthetic <Style TargetType="…"> parse, and a single unresolvable setter throws out of XamlReader::Load; GetResolvedPropertyOverrides catches it and stores an empty ResolvedRules (lines 4256–4262), which is then cached. So the entire rule is dropped — including the Margin that is supposed to position the indicator — and the only trace is a log line.

Also, the matcher is a bare Border, so even without the Fill setter it would match every Border child of the panel (Border#BackgroundElement, Border#MultiWindowElement, …), not just the intended one. Drop Fill and target the Border by name.

5. User-facing dialogs still say "Windows 11 Taskbar Styler - Windhawk".

Line 917 (kRestartExplorerPromptTitle) and line 7585 (the XAML-diagnostics prompt) are both shown to the user and both name the wrong mod. Rename to Glassdock.

6. Dead code and stale comments left over from the fork.

  • g_settings.clickThroughTaskbar is hard-coded to false (lines 7846–7850), which makes the entire click-through subsystem unreachable — ClickThroughTaskbarState, UpdateClickThroughRegion, HandleClickThroughElement, HandleClickThroughIslandRoot, ClearClickThroughRegions, ResolveClickThroughIslandHwnd, IsTaskbarTopLevelWindow, QuantizeLayoutSize (~300 lines), and the only user of -lgdi32. Either expose the setting again or remove the subsystem.
  • MakeArgb (line 190) is never called.
  • ProcessSingleTargetStylesFromSettings, LoadStyleConstants and ProcessResourceVariablesFromSettings read controlStyles[%d].target, controlStyles[%d].styles[%d], styleConstants[%d] and themeResourceVariables[%d] (lines 6485, 6794, 6809, 7053) — none of which exist in this mod's settings block, so those loops always exit on the first iteration. Same for theme (see item 2).
  • The header comment at lines 170–180 says the built-in theme table "is kept as inert reference/legacy code" and that "every selector used below has a direct precedent in one of the themes further down this file" — the table was deleted, so both statements are wrong and the reader can't check the claim.

7. README needs a screenshot and settings documentation.

The README is four lines for a purely visual mod with 30+ settings. A screenshot or GIF is what users pick a theming mod by; images must be hosted on i.imgur.com or raw.githubusercontent.com. Please also document what the settings do (especially the value ranges — see item 8) and state plainly in the README that the mod is derived from Windows 11 Taskbar Styler under GPLv3; the current "Inspired by the Surface theme" line understates it considerably.

8. Numeric settings aren't validated, and one bad value can hide the taskbar.

dockMaxWidth has no lower bound, and it goes straight into the expression at line 420:

L"MaxWidth={{min(" + Num(s.dockMaxWidth) + L", max(glassDockContainerWidth - 250, 100))}}",

Setting it to 0 (a natural reading of "cap") yields MaxWidth=0 and the dock disappears, with nothing to indicate the mod caused it. The opacity settings are likewise unbounded; they're fed to Frac (line 207), which formats into wchar_t buf[8], so a value of 1000000 or more overruns the buffer and trips swprintf_s's invalid-parameter handler rather than producing a wrong-but-harmless result. Clamp dockMaxWidth to a sane minimum, clamp the opacity settings to 0..100, and state the ranges in $description (only a few settings currently do).

9. MaxWidth has no fallback if the width capture doesn't match.

The dock width depends on capturing ActualWidth from :root > ScrollViewer > ScrollContentPresenter > Border > Grid (lines 411–414). In this engine revision an undefined variable evaluates to 0 inside an expression (line 5169), so before the capture fires — or permanently, if that chain doesn't match on some Windows build — min(dockMaxWidth, max(0 - 250, 100)) resolves to 100 and the dock is a 100 px stub. Current upstream deliberately changed this so an undefined variable makes the numeric operators fail and the style is skipped instead (see the "Style variables" section of the styler README); the {{v == `` ? default : v}} guard documented there can't be expressed in this copy, because ValuesEqual throws on a number-vs-string comparison in a live branch. Another reason to build on the current engine rather than a fork of an old one.

Optional improvements

Minor polish — none of this affects users, so it's your call.

  • LoadSettingsFromWindhawk (lines 274–294) uses raw Wh_GetStringSetting + Wh_FreeStringSetting. The file already has string_setting_unique_ptr, and WindhawkUtils::StringSetting exists for this; either is less error-prone.
  • BuildGlassBlur(L"", …).substr(2) (lines 499, 510, 511, 766) builds the property-assignment form only to slice the := back off. An overload that returns just the brush XAML would be clearer.
  • #include <algorithm> sits at line 182, in the middle of the file, rather than in the include block at the top; its comment mentions only std::min while std::max is used too.
  • dockBorderColorManual and indicatorColorManual are interpolated straight into XAML attribute values (lines 350, 546). The file already has EscapeXmlAttribute — worth running them through it, and/or validating the #RRGGBB shape so a typo produces a clear log line instead of a silently skipped style.
  • -lgdi32 (and, as far as I can tell, -lcomctl32) become unused once the dead click-through code goes.
  • Many comments narrate the development history rather than the code — "ROOT CAUSE FOUND", "REVERTED", "per feedback", "confirmed real technique", "Scrapped the custom recolor/hijack attempts". Several are now stale (items 3 and 6). A comment saying what the rule does is more useful than one saying how it was arrived at.

Functionality notes

Non-critical observations and ideas about the feature behavior itself.

  • dockShadowEnabled emits Shadow:=<ThemeShadow/> (lines 449–454, 899–901) with no Translation Z-offset and no Receivers, on an element inside a window that clips to its own bounds. Worth checking that the setting actually produces a visible shadow — I'd expect it to be a no-op as written. Compare island-media-controls.wh.cpp, which appends a receiver and sets Translation.
  • HorizontalAlignment=Center on Taskbar.TaskbarFrame (line 419) overrides the user's taskbar-alignment setting, so left-aligned taskbars get silently re-centered. Worth a setting or at least a README note.
  • The layout constants assume a bottom taskbar and a particular tray width: Margin=0,0,0,10 (lines 425, 447), the - 250 in the width expression (line 420), and the right-side-only tray corner radius (lines 882, 891). Anything that moves or resizes the taskbar (another mod, a different tray configuration) will look off.
  • iconBackgroundOpacity's $description says "Hover/focus intensify this automatically", but the only rule that actually adds @PointerOver/@Pressed variants is the overflow chevron (lines 505–513); the app buttons rely on the native hover storyboard. Once item 3 is fixed it'd be worth confirming hover still reads as an intensification of the glass rather than fighting it.


Next steps:

  • /ai-review - after pushing fixes, to get a review of the updated code. You can repeat this as many times as you need, but each review is thorough and usually there's no need for more than 2-3 iterations.
  • /ready-for-reviewer - once you're satisfied with the state of the pull request, to hand it over to a human reviewer. If some findings above are left unaddressed, add a short note explaining why.

See the review process for details.

@windhawk-reviewer windhawk-reviewer Bot added waiting-for-author The author's turn: request an AI review, or respond to one that was posted. and removed waiting-for-ai-review An AI review was requested and is being prepared. labels Aug 7, 2026
@Onuello Onuello closed this Aug 8, 2026
@windhawk-reviewer windhawk-reviewer Bot removed the waiting-for-author The author's turn: request an AI review, or respond to one that was posted. label Aug 8, 2026
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.

1 participant