Skip to content

Refactor drop shadow handling for window border style#4318

Open
Jack251970 wants to merge 5 commits intodevfrom
DropShadowEffect
Open

Refactor drop shadow handling for window border style#4318
Jack251970 wants to merge 5 commits intodevfrom
DropShadowEffect

Conversation

@Jack251970
Copy link
Member

@Jack251970 Jack251970 commented Mar 4, 2026

CHANGES

Refactor drop shadow effect logic to create a new Style instance instead of modifying the existing one in-place.

Separated from #4302.

TEST

  • Query window shadow effect still works.

Summary by cubic

Refactored drop shadow handling to build and apply a new window border Style instead of editing the existing one. Added ThemeHelper.ReplaceSetter to avoid duplicate Margin/Effect/Background setters and make theme switching more reliable.

  • Summary of changes
    • Changed: Create a new Style(typeof(Border)) via ThemeHelper.CopyStyle (copies setters/resources/triggers; BasedOn set directly). Apply with Application.Current.Resources["WindowBorderStyle"]. Use GetThemeResourceDictionary(_settings.Theme) and return early if WindowBorderStyle is missing. Use ThemeHelper.ReplaceSetter when updating Background in SetBlurForWindow for Mica/Acrylic.
    • Added: Margin and Effect are set via ThemeHelper.ReplaceSetter to ensure only one of each. Margin math preserves existing values and adds/subtracts ShadowExtraMargin on add/remove. Update SetResizeBoarderThickness with the new margin (add) or null (remove).
    • Removed: In-place mutation of style setters and UpdateResourceDictionary calls. Recursive base-style copying in ThemeHelper. Direct remove/add of setters in blur code (now replaced by ReplaceSetter).
    • Memory: Minimal. One new Style and DropShadowEffect per change; old instances are GC-eligible. No duplicate setters, no sustained growth.
    • Security: No impact. UI-only.
    • Unit tests: None added. Manual checks for add/remove, theme switching, and blur backgrounds.

Written for commit 3c82661. Summary will update on new commits.

Refactor drop shadow effect logic to create a new Style instance instead of modifying the existing one in-place. This approach copies all relevant resources, triggers, and setters, updating only the Margin and Effect as needed. The new Style is applied at the application level, improving robustness for theme switching and preventing issues with sealed or shared Style objects.
Copilot AI review requested due to automatic review settings March 4, 2026 04:44
@prlabeler prlabeler bot added Code Refactor enhancement New feature or request labels Mar 4, 2026
@github-actions github-actions bot added this to the 2.2.0 milestone Mar 4, 2026
@gitstream-cm
Copy link

gitstream-cm bot commented Mar 4, 2026

🥷 Code experts: no user but you matched threshold 10

Jack251970 has most 👩‍💻 activity in the files.
Jack251970 has most 🧠 knowledge in the files.

See details

Flow.Launcher.Core/Resource/Theme.cs

Activity based on git-commit:

Jack251970
MAR 64 additions & 79 deletions
FEB
JAN
DEC
NOV
OCT 12 additions & 2 deletions

Knowledge based on git-blame:
Jack251970: 100%

Flow.Launcher.Core/Resource/ThemeHelper.cs

Activity based on git-commit:

Jack251970
MAR 32 additions & 2 deletions
FEB
JAN
DEC
NOV
OCT

Knowledge based on git-blame:
Jack251970: 100%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

@gitstream-cm
Copy link

gitstream-cm bot commented Mar 4, 2026

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

@coderabbitai coderabbitai bot removed the enhancement New feature or request label Mar 4, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors how the WindowBorderStyle drop shadow is applied/removed by attempting to create a new Style instance rather than mutating the existing one in-place.

Changes:

  • Reworked AddDropShadowEffectToCurrentTheme to construct a new WindowBorderStyle and add Margin + DropShadowEffect setters.
  • Reworked RemoveDropShadowEffectFromCurrentTheme to construct a new WindowBorderStyle without the Effect setter and with adjusted Margin.
  • Switched from updating the merged theme ResourceDictionary to assigning Application.Current.Resources["WindowBorderStyle"].

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

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

Choose a reason for hiding this comment

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

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Flow.Launcher.Core/Resource/Theme.cs">

<violation number="1" location="Flow.Launcher.Core/Resource/Theme.cs:508">
P2: This re-adds setters that were already copied by `CopyStyle`, creating duplicate property setters in `WindowBorderStyle`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@Jack251970 Jack251970 enabled auto-merge March 4, 2026 04:49
@prlabeler prlabeler bot added the enhancement New feature or request label Mar 4, 2026
@Jack251970 Jack251970 marked this pull request as draft March 4, 2026 04:51
auto-merge was automatically disabled March 4, 2026 04:51

Pull request was converted to draft

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

Per-theme resource dictionaries are used for WindowBorderStyle changes: styles are cloned into unsealed instances, Margin and DropShadowEffect setters are updated/removed, resize border thickness is recalculated, and ThemeHelper gained a ReplaceSetter API while CopyStyle stops recursively copying BasedOn.

Changes

Cohort / File(s) Summary
Theme — drop shadow, margins, blur handling
Flow.Launcher.Core/Resource/Theme.cs
Switches to per-theme resource dictionary retrieval, clones sealed WindowBorderStyle into a new unsealed Style, preserves non-margin setters, recalculates and replaces Margin setter, adds/removes a DropShadowEffect setter, updates resize-border thickness, and uses ThemeHelper.ReplaceSetter for blur/backdrop setter changes.
Theme helper — style copy & setter replacement
Flow.Launcher.Core/Resource/ThemeHelper.cs
CopyStyle no longer recursively copies BasedOn; it assigns targetStyle.BasedOn = originalStyle.BasedOn. Adds public static void ReplaceSetter(Style style, Setter setter) to replace an existing setter by Property before adding the new one.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • taooceros
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: refactoring drop shadow handling for window border style, which is the primary focus of the changeset.
Description check ✅ Passed The description is directly related to the changeset, explaining the refactoring approach, changes made, and testing performed.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch DropShadowEffect

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Flow.Launcher.Core/Resource/Theme.cs`:
- Around line 569-577: The code is incorrectly subtracting ShadowExtraMargin
from any theme-defined margin (in the block handling setter.Property ==
FrameworkElement.MarginProperty), which shrinks or can make margins negative
when shadows are disabled; instead, preserve the theme's original margin by
adding the existing setter.Value (currentMargin) to newWindowBorderStyle.Setters
unchanged (i.e., remove the subtraction/creation of newMargin and simply call
newWindowBorderStyle.Setters.Add(new Setter(FrameworkElement.MarginProperty,
setter.Value))); keep this change local to the margin-handling branch that
processes setters from GetThemeResourceDictionary(theme).

ℹ️ Review info
Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3bf9cff6-290e-49a0-a770-d5eefac7da26

📥 Commits

Reviewing files that changed from the base of the PR and between dda9000 and c3b3b5f.

📒 Files selected for processing (1)
  • Flow.Launcher.Core/Resource/Theme.cs

Replaced direct calls to CopyStyle with ThemeHelper.CopyStyle in Theme.cs. This centralizes style copying logic and improves code organization and maintainability.
Refactored ThemeHelper.CopyStyle to assign the target style's BasedOn property directly from the original style, instead of recursively copying base style properties. This reduces complexity and ensures correct style inheritance.
@Jack251970 Jack251970 marked this pull request as ready for review March 9, 2026 10:21
@coderabbitai coderabbitai bot removed the enhancement New feature or request label Mar 9, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Flow.Launcher.Core/Resource/Theme.cs`:
- Around line 486-509: ThemeHelper.CopyStyle already copies all setters from
windowBorderStyle into newWindowBorderStyle, so the foreach loop that iterates
windowBorderStyle.Setters and re-adds setters causes duplicates; fix by keeping
the CopyStyle call and instead modify the copied setters on
newWindowBorderStyle: locate and remove any Setter with Property ==
FrameworkElement.MarginProperty and any with Property ==
UIElement.EffectProperty from newWindowBorderStyle.Setters, then add the new
computed Margin Setter (and any new Effect) once — refer to
ThemeHelper.CopyStyle, newWindowBorderStyle, windowBorderStyle, Setter,
FrameworkElement.MarginProperty, and UIElement.EffectProperty to locate and
change the code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cdd1bf01-dcb2-4b01-af14-5b5be8106e10

📥 Commits

Reviewing files that changed from the base of the PR and between c3b3b5f and 2bf6e26.

📒 Files selected for processing (2)
  • Flow.Launcher.Core/Resource/Theme.cs
  • Flow.Launcher.Core/Resource/ThemeHelper.cs

Copy link
Contributor

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

Choose a reason for hiding this comment

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

2 issues found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Flow.Launcher.Core/Resource/Theme.cs">

<violation number="1" location="Flow.Launcher.Core/Resource/Theme.cs:488">
P2: `CopyStyle` already clones the setters, so this second setter-copy pass leaves duplicate setters and does not truly replace/remove `Margin` or `Effect`.</violation>

<violation number="2" location="Flow.Launcher.Core/Resource/Theme.cs:571">
P2: Remove the shadow from the active `WindowBorderStyle`, not a freshly reloaded theme style. As written, a theme-defined border margin is restored 32px too small after a shadow toggle.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Ensure existing Margin and Effect setters are removed from
newWindowBorderStyle before adding new ones. This prevents
duplicate property setters and ensures only the latest values
are applied.
@prlabeler prlabeler bot added the enhancement New feature or request label Mar 9, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Flow.Launcher.Core/Resource/ThemeHelper.cs (1)

9-22: ⚠️ Potential issue | 🟠 Major

CopyStyle helper omits Style.Resources and Style.Triggers during cloning.

The CopyStyle method (lines 9–22) copies only BasedOn and direct Setters from the original style. It does not preserve Style.Resources or Style.Triggers. If WindowBorderStyle (referenced by AddDropShadowEffectToCurrentTheme() at line 486 and ApplyPreviewBackground() at line 836) defines local resources or triggers, these will be lost in the cloned replacement style.

Verify whether the original WindowBorderStyle definition in theme XAML files contains <Style.Resources> or <Style.Triggers> blocks that must be preserved.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Flow.Launcher.Core/Resource/ThemeHelper.cs` around lines 9 - 22, CopyStyle
currently only copies BasedOn and Setters and therefore drops Style.Resources
and Style.Triggers (which can break WindowBorderStyle used by
AddDropShadowEffectToCurrentTheme and ApplyPreviewBackground). Update CopyStyle
to also preserve originalStyle.Resources and originalStyle.Triggers: if
originalStyle.Resources is non-null, ensure targetStyle.Resources exists and
merge/clone entries from originalStyle.Resources into it (preserving keys and
values or creating a copy of the ResourceDictionary), and if
originalStyle.Triggers contains Trigger/BaseTrigger items, clone each trigger
into targetStyle.Triggers (preserving bindings/enter/exit actions). Keep the
existing BasedOn and Setter copying logic and ensure you handle null checks to
avoid exceptions when resources or triggers are absent.
♻️ Duplicate comments (1)
Flow.Launcher.Core/Resource/Theme.cs (1)

486-509: ⚠️ Potential issue | 🟠 Major

CopyStyle + manual re-add still duplicates every non-special setter.

ThemeHelper.CopyStyle() already clones all direct setters into newWindowBorderStyle. The loop here then adds every setter again except Margin/Effect, so Background, BorderThickness, etc. are duplicated here and again in RemoveDropShadowEffectFromCurrentTheme().

#!/bin/bash
rg -n -C4 'CopyStyle\(windowBorderStyle, newWindowBorderStyle\)|newWindowBorderStyle\.Setters\.Add\(setterBase\)' \
  Flow.Launcher.Core/Resource/Theme.cs \
  Flow.Launcher.Core/Resource/ThemeHelper.cs

Expected: both shadow paths show CopyStyle(...) followed by Setters.Add(setterBase), confirming the same setters are copied and then re-added.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Flow.Launcher.Core/Resource/Theme.cs` around lines 486 - 509,
ThemeHelper.CopyStyle(windowBorderStyle, newWindowBorderStyle) already clones
the style setters, so the foreach that iterates windowBorderStyle.Setters and
calls newWindowBorderStyle.Setters.Add(setterBase) causes duplicate setters;
remove the code that re-adds non-special setters and instead operate on the
cloned setters in newWindowBorderStyle (e.g., locate and update the Margin
Setter in newWindowBorderStyle to adjust margins, and ensure only one Effect
setter exists by removing/adding on newWindowBorderStyle), referencing
ThemeHelper.CopyStyle, newWindowBorderStyle, and the existing loop that inspects
setter.Property.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Flow.Launcher.Core/Resource/Theme.cs`:
- Line 545: The app-level vs merged-dictionary writes for WindowBorderStyle
create precedence bugs; unify to a single update path by changing
AddDropShadowEffectToCurrentTheme and RemoveDropShadowEffectFromCurrentTheme to
modify the same merged ResourceDictionary that SetBlurForWindow updates (via
UpdateResourceDictionary) OR alternatively make SetBlurForWindow write to
Application.Current.Resources like the others and have UpdateResourceDictionary
clear any duplicate app-level entry; modify the code in
AddDropShadowEffectToCurrentTheme, RemoveDropShadowEffectFromCurrentTheme,
SetBlurForWindow and UpdateResourceDictionary so all four reference and update
the same ResourceDictionary instance (or ensure duplicates are removed) to
guarantee predictable DynamicResource resolution.

---

Outside diff comments:
In `@Flow.Launcher.Core/Resource/ThemeHelper.cs`:
- Around line 9-22: CopyStyle currently only copies BasedOn and Setters and
therefore drops Style.Resources and Style.Triggers (which can break
WindowBorderStyle used by AddDropShadowEffectToCurrentTheme and
ApplyPreviewBackground). Update CopyStyle to also preserve
originalStyle.Resources and originalStyle.Triggers: if originalStyle.Resources
is non-null, ensure targetStyle.Resources exists and merge/clone entries from
originalStyle.Resources into it (preserving keys and values or creating a copy
of the ResourceDictionary), and if originalStyle.Triggers contains
Trigger/BaseTrigger items, clone each trigger into targetStyle.Triggers
(preserving bindings/enter/exit actions). Keep the existing BasedOn and Setter
copying logic and ensure you handle null checks to avoid exceptions when
resources or triggers are absent.

---

Duplicate comments:
In `@Flow.Launcher.Core/Resource/Theme.cs`:
- Around line 486-509: ThemeHelper.CopyStyle(windowBorderStyle,
newWindowBorderStyle) already clones the style setters, so the foreach that
iterates windowBorderStyle.Setters and calls
newWindowBorderStyle.Setters.Add(setterBase) causes duplicate setters; remove
the code that re-adds non-special setters and instead operate on the cloned
setters in newWindowBorderStyle (e.g., locate and update the Margin Setter in
newWindowBorderStyle to adjust margins, and ensure only one Effect setter exists
by removing/adding on newWindowBorderStyle), referencing ThemeHelper.CopyStyle,
newWindowBorderStyle, and the existing loop that inspects setter.Property.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2f25b2f0-5b24-4ba7-87c2-47f438a69317

📥 Commits

Reviewing files that changed from the base of the PR and between 2bf6e26 and 3c82661.

📒 Files selected for processing (2)
  • Flow.Launcher.Core/Resource/Theme.cs
  • Flow.Launcher.Core/Resource/ThemeHelper.cs

@Jack251970 Jack251970 mentioned this pull request Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants