Skip to content

[iOS/MacCatalyst] Fix Entry clear button appearing dimmed compared to TextColor - #36472

Merged
kubaflo merged 5 commits into
dotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:fix-35517-entry-clearbutton-dimmed
Jul 26, 2026
Merged

[iOS/MacCatalyst] Fix Entry clear button appearing dimmed compared to TextColor#36472
kubaflo merged 5 commits into
dotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:fix-35517-entry-clearbutton-dimmed

Conversation

@SyedAbdulAzeemSF4852

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Issue Details

  • When an Entry control has a TextColor set and ClearButtonVisibility is enabled, the clear button (✕) appears faded/dimmed compared to the TextColor.

Root Cause

  • The clear button's image was being drawn directly into the tinting context at reduced opacity, and because CGBlendMode.SourceIn compositing caps the final color's alpha at the alpha of the shape it's masking against, that reduced opacity carried through to the final tinted color — making the clear button appear dim instead of matching TextColor at full opacity.

Description of Change

  • In GetClearButtonTintImage (TextFieldExtensions.cs), the code now builds a plain UIImage from the clear button image's underlying CGImage (preserving CurrentScale and Orientation) and draws that bitmap-backed copy instead of drawing the original image directly, before the existing SourceIn color-fill step — the clear button image now renders with full opacity.

Issues Fixed

Fixes #35517

Validated the behaviour in the following platforms

  • Windows
  • Android
  • iOS
  • Mac

Output

Platform Before After
iOS
Mac

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 36472

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 36472"

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label Jul 9, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Hey there @@SyedAbdulAzeemSF4852! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@dotnet-policy-service dotnet-policy-service Bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Jul 9, 2026
@vishnumenon2684

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 3 pipeline(s).

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jul 10, 2026
@MauiBot MauiBot added s/agent-gate-failed AI could not verify tests catch the bug s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Jul 10, 2026
MauiBot

This comment was marked as outdated.

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 10, 2026

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you please check the ai's suggestions?

kubaflo pushed a commit that referenced this pull request Jul 11, 2026
Surveyed all 42 maui-copilot (def 27723) builds on improved-reviewer and
found two classes of false-FAILED gate verdicts that should be INCONCLUSIVE:

1. New-snapshot VisualTest PRs (e.g. PR #36448, build 14627406): a run that
   reports SOME real passes AND failures where every failure is a brand-new
   VerifyScreenshot with no committed baseline ("Baseline snapshot not yet
   created") took the trust-the-counts path in Get-TestResultFromOutput and
   returned a plain N-test FAIL, never reaching the baseline-missing check
   lower in the function (Passed=2, Failed=30 -> FAILED). Now, inside that
   path, if baseline-missing occurrences >= failCount the run is classified
   SnapshotBaselineMissing (INCONCLUSIVE). A real pixel diff against an
   EXISTING baseline prints 'Snapshot different than baseline' (not 'not yet
   created'), so mixed/real-diff runs still correctly FAIL.

2. Device-test APP_CRASH (PR #36472, build 14627403): both without-fix and
   with-fix crashed identically with 'XHarness exit code: 80 (APP_CRASH)'
   and Failed=0 (app died during instrumentation, no test result) yet the
   pair was scored a genuine FAILED. Added exit-80 to the env-error patterns
   so an app crash is treated as infra/INCONCLUSIVE, consistent with the
   existing exit-83/78 and 'Application test run crashed' handling.

Both convert false-FAILED -> non-blocking INCONCLUSIVE. Unit-tested 6
scenarios (new-snapshots, real-diff guard, mixed guard, clean pass, exit-80,
exit-83 regression) — all pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 15d2af20-e4ab-4e88-9011-cfbd83513bc0

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 3 findings

See inline comments for details.

Comment thread src/Core/src/Platform/iOS/TextFieldExtensions.cs
Comment thread src/Core/src/Platform/iOS/TextFieldExtensions.cs
Comment thread src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs
@MauiBot MauiBot added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates and removed s/agent-fix-win AI found a better alternative fix than the PR labels Jul 11, 2026
MauiBot

This comment was marked as outdated.

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jul 12, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 2 findings

See inline comments for details.

Comment thread src/Core/src/Platform/iOS/TextFieldExtensions.cs
Comment thread src/Core/src/Platform/iOS/TextFieldExtensions.cs
MauiBot

This comment was marked as outdated.

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 12, 2026
@SyedAbdulAzeemSF4852

Copy link
Copy Markdown
Contributor Author

@SyedAbdulAzeemSF4852 — I downloaded and compared every screenshot failure from UI build 1511860.

Classification Result
PR-related unresolved 7 screenshots still differ from the tested PR baselines; do not baseline these blindly.

PR-related unresolved visual differences — do not update these baselines yet

EntryClearButtonColorShouldUpdateOnThemeChange — iOS — PR-related unresolved
This current-head iOS UI build fails a snapshot that the PR directly modifies, while changing the iOS clear-button renderer. The same exact test passed in base build 1503618 at the merge base, and the merge-base/current-main baseline files are byte-identical. The full-resolution CI actual still differs from the PR baseline in 3235 pixels (0.370891%), so the intended baseline/rendering alignment remains unresolved.

CI baseline Fresh PR actual CI diff
EntryClearButtonColorShouldUpdateOnThemeChange baseline EntryClearButtonColorShouldUpdateOnThemeChange actual EntryClearButtonColorShouldUpdateOnThemeChange diff
VerifyTextWhenReturnTypeSet — iOS — PR-related unresolved
This current-head iOS UI build fails a snapshot that the PR directly modifies, while changing the iOS clear-button renderer. The same exact test passed in base build 1503618 at the merge base, and the merge-base/current-main baseline files are byte-identical. The full-resolution CI actual still differs from the PR baseline in 26241 pixels (3.008516%), so the intended baseline/rendering alignment remains unresolved.

CI baseline Fresh PR actual CI diff
VerifyTextWhenReturnTypeSet baseline VerifyTextWhenReturnTypeSet actual VerifyTextWhenReturnTypeSet diff
VerifyClearButtonVisiblityWhenTextAlignedVertically — iOS — PR-related unresolved
This current-head iOS UI build fails a snapshot that the PR directly modifies, while changing the iOS clear-button renderer. The same exact test passed in base build 1503618 at the merge base, and the merge-base/current-main baseline files are byte-identical. The full-resolution CI actual still differs from the PR baseline in 25015 pixels (2.867956%), so the intended baseline/rendering alignment remains unresolved.

CI baseline Fresh PR actual CI diff
VerifyClearButtonVisiblityWhenTextAlignedVertically baseline VerifyClearButtonVisiblityWhenTextAlignedVertically actual VerifyClearButtonVisiblityWhenTextAlignedVertically diff
VerifyClearButtonVisiblityWhenTextAlignedHorizontally — iOS — PR-related unresolved
This current-head iOS UI build fails a snapshot that the PR directly modifies, while changing the iOS clear-button renderer. The same exact test passed in base build 1503618 at the merge base, and the merge-base/current-main baseline files are byte-identical. The full-resolution CI actual still differs from the PR baseline in 26146 pixels (2.997624%), so the intended baseline/rendering alignment remains unresolved.

CI baseline Fresh PR actual CI diff
VerifyClearButtonVisiblityWhenTextAlignedHorizontally baseline VerifyClearButtonVisiblityWhenTextAlignedHorizontally actual VerifyClearButtonVisiblityWhenTextAlignedHorizontally diff
EntryClearButtonColorShouldMatchTextColor — iOS — PR-related unresolved
This current-head iOS UI build fails a snapshot that the PR directly modifies, while changing the iOS clear-button renderer. The same exact test passed in base build 1503618 at the merge base, and the merge-base/current-main baseline files are byte-identical. The full-resolution CI actual still differs from the PR baseline in 1893 pixels (0.14957%), so the intended baseline/rendering alignment remains unresolved.

CI baseline Fresh PR actual CI diff
EntryClearButtonColorShouldMatchTextColor baseline EntryClearButtonColorShouldMatchTextColor actual EntryClearButtonColorShouldMatchTextColor diff
VerifyTextWhenKeyboardTypeSet — iOS — PR-related unresolved
This current-head iOS UI build fails a snapshot that the PR directly modifies, while changing the iOS clear-button renderer. The same exact test passed in base build 1503618 at the merge base, and the merge-base/current-main baseline files are byte-identical. The full-resolution CI actual still differs from the PR baseline in 26145 pixels (2.99751%), so the intended baseline/rendering alignment remains unresolved.

CI baseline Fresh PR actual CI diff
VerifyTextWhenKeyboardTypeSet baseline VerifyTextWhenKeyboardTypeSet actual VerifyTextWhenKeyboardTypeSet diff
ClearButtonVisiblityButton_TextPresent — iOS — PR-related unresolved
This current-head iOS UI build fails a snapshot that the PR directly modifies, while changing the iOS clear-button renderer. The same exact test passed in base build 1503618 at the merge base, and the merge-base/current-main baseline files are byte-identical. The full-resolution CI actual still differs from the PR baseline in 26146 pixels (2.997624%), so the intended baseline/rendering alignment remains unresolved.

CI baseline Fresh PR actual CI diff
ClearButtonVisiblityButton_TextPresent baseline ClearButtonVisiblityButton_TextPresent actual ClearButtonVisiblityButton_TextPresent diff
The screenshot evidence shows PR-related visual failures remain unresolved.

🤖 AI-generated screenshot analysis by GitHub Copilot CLI for @kubaflo.

@kubaflo , I've verified the failures and resaved the valid ios-26 snapshots.

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jul 20, 2026
@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) and removed s/agent-gate-failed AI could not verify tests catch the bug labels Jul 20, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

AI Review Summary

@SyedAbdulAzeemSF4852 — new AI review results are available based on this last commit: ea5c5fb. To request a fresh review after new comments or commits, comment /review rerun.

Gate Passed Confidence Low Platform iOS


🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix

Gate Result: ✅ PASSED

Platform: IOS · Base: main · Merge base: 76c77c03

Test Without Fix (expect FAIL) With Fix (expect PASS)
📱 EntryHandlerTests (ClearButtonTintMatchesTextColorAtFullOpacity) Category=Entry ✅ FAIL — 197s ✅ PASS — 68s
🔴 Without fix — 📱 EntryHandlerTests (ClearButtonTintMatchesTextColorAtFullOpacity): FAIL ✅ · 197s

(no coded error found; showing last 1200 chars)

,
        "exitCode": 1,
        "exitCodeName": "TESTS_FAILED",
        "platform": "apple",
        "device": "iPhone 11 Pro",
        "deviceOsVersion": "26.5",
        "files": [
          {
            "name": "test-ios-simulator-64_26.5-991E30C3-4746-420C-9874-F267A4326F45.log",
            "type": "executionlog"
          },
          {
            "name": "list-ios-simulator-64_26.5-20260720_150232.log",
            "type": "devicelist"
          },
          {
            "name": "test-ios-simulator-64_26.5-20260720_150239.log",
            "type": "testlog"
          },
          {
            "name": "iPhone 11 Pro.log",
            "type": "systemlog"
          },
          {
            "name": "Microsoft.Maui.Core.DeviceTests.log",
            "type": "systemlog"
          },
          {
            "name": "com.microsoft.maui.core.devicetests.log",
            "type": "applicationlog"
          },
          {
            "name": "xunit-test-ios-simulator-64_26.5-20260720_150239.xml",
            "type": "xmllog"
          }
        ]
      }
      <<XHARNESS_RESULT_END>>
XHarness exit code: 1 (TESTS_FAILED)
  Passed: 0
  Failed: 0
  Tests completed with exit code: 1

🟢 With fix — 📱 EntryHandlerTests (ClearButtonTintMatchesTextColorAtFullOpacity): PASS ✅ · 68s

(no coded error found; showing last 1200 chars)

neName": "Q67QJ3X3NH-1",
        "exitCode": 0,
        "exitCodeName": "SUCCESS",
        "platform": "apple",
        "device": "iPhone 11 Pro",
        "deviceOsVersion": "26.5",
        "files": [
          {
            "name": "test-ios-simulator-64_26.5-991E30C3-4746-420C-9874-F267A4326F45.log",
            "type": "executionlog"
          },
          {
            "name": "list-ios-simulator-64_26.5-20260720_150408.log",
            "type": "devicelist"
          },
          {
            "name": "test-ios-simulator-64_26.5-20260720_150413.log",
            "type": "testlog"
          },
          {
            "name": "iPhone 11 Pro.log",
            "type": "systemlog"
          },
          {
            "name": "Microsoft.Maui.Core.DeviceTests.log",
            "type": "systemlog"
          },
          {
            "name": "com.microsoft.maui.core.devicetests.log",
            "type": "applicationlog"
          },
          {
            "name": "xunit-test-ios-simulator-64_26.5-20260720_150413.xml",
            "type": "xmllog"
          }
        ]
      }
      <<XHARNESS_RESULT_END>>
XHarness exit code: 0
  Passed: 233
  Failed: 0
  Tests completed successfully

📁 Fix files reverted (1 files)
  • src/Core/src/Platform/iOS/TextFieldExtensions.cs

📱 UI Tests — Entry,ViewBaseTests

Detected UI test categories: Entry,ViewBaseTests

Deep UI tests — 221 passed, 3 failed across 2 categories on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
Entry 109/113 (3 ❌)
ViewBaseTests 112/112 ✓
🔍 AI analysis of failures — PR-related vs unrelated

🔍 AI-generated triage (GitHub Copilot CLI) — a heuristic judgement of whether each deep UI test failure is connected to this PR's changes. Verify before relying on it.

Likely unrelated: the failures appear pre-existing, flaky, or infrastructure.

  • ● Unrelated — iOS Entry/Editor element lookup timeouts (3 tests): although this PR touches iOS Entry clear-button tinting and related snapshot baselines, these failures are Appium NoSuchElementException/Timed out waiting for element during test-page element discovery in keyboard/placeholder-theme scenarios, not clear-button rendering or the modified TextFieldExtensions.UpdateClearButtonColor path.

Strongest signal: all failures are missing-element/timeouts, while the PR changes only clear-button image tint opacity and snapshots for clear-button/text-keyboard visuals.

Entry — 3 failed tests
KeepEditorCursorAboveKeyboardInScrollView
OpenQA.Selenium.NoSuchElementException : An element could not be located on the page using the given search parameters.; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception
at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
   at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Appium.AppiumDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.FindElement(String mechanism, String value)
   at OpenQA.Selenium.Appium.AppiumDriver.FindElement(String by, String value)
   at OpenQA.Selenium.Appium.MobileBy.FindElement(ISearchContext context)
   at OpenQA.Selenium.WebDriver.FindElement(By by)
   at OpenQA.Selenium.Appium.AppiumDriver.FindElement(By by)
   at Microsoft.Maui.TestCases.Tests.KeyboardScrolling.CloseiOSEditorKeyboard(AppiumDr
...
EntryAndEditorPlaceholderTextColorAppThemeBindingUpdatesOnThemeChange
System.TimeoutException : Timed out waiting for element...
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests.Issues.Issue31889.EntryAndEditorPlaceholderTextColorAppThemeBindingUpdatesOnThemeChange() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31889.cs:line 50
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, 
...
KeepEditorCursorAboveKeyboardInGrid
OpenQA.Selenium.NoSuchElementException : An element could not be located on the page using the given search parameters.; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception
at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
   at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Appium.AppiumDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.FindElement(String mechanism, String value)
   at OpenQA.Selenium.Appium.AppiumDriver.FindElement(String by, String value)
   at OpenQA.Selenium.Appium.MobileBy.FindElement(ISearchContext context)
   at OpenQA.Selenium.WebDriver.FindElement(By by)
   at OpenQA.Selenium.Appium.AppiumDriver.FindElement(By by)
   at Microsoft.Maui.TestCases.Tests.KeyboardScrolling.CloseiOSEditorKeyboard(AppiumDr
...

📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)


🔗 Regression Cross-Reference

🔍 Regression Cross-Reference

Overlaps with prior bug-fix PRs — same files modified, but no exact line revert detected.

File Fix PR Fixed issue(s)
src/Core/src/Platform/iOS/TextFieldExtensions.cs #32889 #32886

🧪 Regression Tests to Verify

These tests were added by the overlapping fix PRs. Running them to verify no side-effect regressions:

Fix PR Type Test Filter
#32889 UITest Issue32886 Issue32886

🧪 Regression Test Results

FAILED — 0 passed, 1 failed, 0 skipped

Fix PR Test Type Result
#32889 Issue32886 UITest ❌ FAILED

📋 Pre-Flight — Context & Validation

Issue: #35517 - [MacCatalyst] [Entry] ClearButtonVisibility color appears dimmed compared to TextColor
PR: #36472 - [WIP][iOS/MacCatalyst] Fix Entry clear button appearing dimmed compared to TextColor
Platforms Affected: iOS, MacCatalyst
Files Changed: 1 implementation, 1 device-test, 15 iOS snapshot files

Key Findings

  • The PR changes src/Core/src/Platform/iOS/TextFieldExtensions.cs, which compiles for both iOS and MacCatalyst, to tint the Entry clear-button image from a CGImage-backed copy before applying CGBlendMode.SourceIn.
  • The linked issue is MacCatalyst-focused, but the requested try-fix validation platform is iOS. Regression testing must also run BuildAndRunHostApp.ps1 -Platform ios -TestFilter "Issue32886" after any candidate's primary test passes.
  • The PR adds an iOS device test (ClearButtonTintMatchesTextColorAtFullOpacity) and updates iOS/iOS-26 snapshots, but public review context indicates MacCatalyst snapshot coverage remains a concern.
  • Local checkout contents did not match PR #36472; PR-specific context was gathered from the public PR ref refs/remotes/origin/pr/36472 and public GitHub REST metadata.

Code Review Summary

Verdict: NEEDS_CHANGES
Confidence: low
Errors: 2 | Warnings: 0 | Suggestions: 0

Key code review findings:

  • src/Core/src/Platform/iOS/TextFieldExtensions.cs:284-291 falls back to drawing the original UIImage when image.CGImage is null, preserving the old reduced-alpha path for symbol/vector/CI-backed images.
  • src/Core/src/Platform/iOS/TextFieldExtensions.cs:284 affects MacCatalyst too, but only iOS/iOS-26 snapshots were updated even though the linked issue and PR validation claim MacCatalyst behavior.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #36472 Draw a CGImage-backed UIImage copy of the clear-button glyph, center it, then fill with TextColor using SourceIn. ✅ PASSED (Gate) src/Core/src/Platform/iOS/TextFieldExtensions.cs, src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs, iOS snapshots Original PR; gate result supplied by caller.

🔬 Code Review — Deep Analysis

Code Review — PR #36472

Independent Assessment

What this changes: Re-tints the iOS/MacCatalyst Entry clear button by drawing a CGImage-backed copy before the SourceIn fill, adds an iOS device test asserting full alpha, and updates iOS/iOS-26 UI snapshots.
Inferred motivation: Fix the clear button looking dimmer than Entry.TextColor.

Reconciliation with PR Narrative

Author claims: Fixes dim clear-button tint on iOS/MacCatalyst by avoiding reduced-alpha drawing.
Agreement/disagreement: The intent matches the code, but the implementation still falls back to the old draw path when UIImage.CGImage is null, and MacCatalyst snapshot coverage is not updated despite the PR claiming Mac validation.

Prior Review Reconciliation

Prior ❌ Error Finding Source Status Evidence
CGImage == null fallback preserves old dim-alpha path MauiBot inline [major] ❌ Unresolved TextFieldExtensions.cs:284-286 still uses : image, then bitmapImage.Draw(...).
MacCatalyst snapshot/baseline coverage missing MauiBot inline [major]/[moderate], expert reviewer ❌ Unresolved PR updates only TestCases.iOS.Tests/snapshots/...; existing TestCases.Mac.Tests/snapshots/mac/EntryClearButtonColor...png files are unchanged.
iOS-26 snapshots missing MauiBot inline [major] ✅ Fixed Latest diff includes snapshots/ios-26/* updates.

Blast Radius Assessment

  • Runs for all instances: No; only Entries with ClearButtonVisibility.WhileEditing and non-null TextColor.
  • Startup impact: No.
  • Static/shared state: No.
  • Platform scope: iOS and MacCatalyst shared platform code.

CI Status

  • Required-check result: gh pr checks --required unavailable due missing auth.
  • Supplemental status: public GitHub checks show maui-pr and Build Analysis failed on head ea5c5fb; AzDO timeline shows RunOniOS_BlazorDebug ARM64 timed out after 45 minutes.
  • Classification: failure appears infrastructure/timeout, but CI is not green.
  • Action taken: invoked azdo-build-investigator; ci-analysis unavailable; confidence capped low.

Findings

❌ Error — Null-CGImage fallback leaves the original bug unfixed

src/Core/src/Platform/iOS/TextFieldExtensions.cs:284-291

The new code only avoids reduced-alpha drawing when image.CGImage is non-null. If UIKit supplies the clear-button glyph as a symbol/vector/CI-backed UIImage, bitmapImage becomes image, and bitmapImage.Draw(...) is exactly the old behavior the PR is trying to avoid. Please rasterize the non-CGImage case too, or prove/guard that this clear-button image is always CGImage-backed on supported iOS/MacCatalyst versions.

❌ Error — MacCatalyst baselines are not updated for shared MacCatalyst rendering change

src/Core/src/Platform/iOS/TextFieldExtensions.cs:284

This file compiles for both iOS and MacCatalyst, and the PR body claims Mac validation, but only iOS/iOS-26 snapshots are updated. Existing Mac snapshots for clear-button color scenarios under src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ remain unchanged. Given the previous fix in this area was reverted for Mac Entry snapshot failures, please update/validate MacCatalyst baselines or scope the behavior away from MacCatalyst.

Failure-Mode Probing

  • Null CGImage: the code falls back to image.Draw, so dim alpha can persist.
  • MacCatalyst UI tests: shared platform change can alter Mac clear-button screenshots while Mac baselines remain stale.
  • TextColor reset: existing null reset path remains intact and covered by prior test.
  • Handler reconnect: no new subscriptions/static state; no lifecycle accumulation seen.

Verdict: NEEDS_CHANGES

Confidence: low
Summary: The fix is directionally correct but still has an unresolved fallback path that can preserve the bug, and MacCatalyst coverage is incomplete for shared platform code. CI is also not green, though the observed failure appears to be an infrastructure timeout.


🛠️ Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix-1 Alpha-normalized raster tint: render source image to RGBA, normalize glyph alpha, recolor pixels to TextColor. ⚠️ Blocked 1 file Directly handles null-CGImage fallback, but is more complex and could not be validated because the isolated worktree failed the MAUI build-task guard.
2 try-fix-2 Native-sized vector clear glyph: ignore source image alpha and draw a full-opacity vector X with CGContext. ⚠️ Blocked 1 file Avoids inherited alpha entirely, but risks visual drift from UIKit's private clear glyph.
3 try-fix-3 UIKit template clear-button tint: use AlwaysTemplate image plus UIButton.TintColor at the call site. ⚠️ Blocked 1 file Avoids custom bitmap generation, but likely conflicts with the PR's pixel/rendering-mode device-test assertions.
PR PR #36472 Draw a CGImage-backed UIImage copy, center it, then tint with SourceIn. ✅ PASSED (Gate) 17 files Original PR; gate result supplied by caller. Code review still flags null-CGImage fallback and MacCatalyst baseline certainty.

Cross-Pollination

Model Round New Ideas? Details
maui-expert-reviewer 2 No NO NEW IDEAS: remaining viable fixes collapse into raster recoloring, vector replacement, template tinting, or CGImage/CoreGraphics mask compositing variants.

Mandatory Regression Tests

Candidate Primary Test Regression Test BuildAndRunHostApp.ps1 -Platform ios -TestFilter "Issue32886" Result
try-fix-1 Blocked before test execution by missing/out-of-date MAUI build tasks in isolated worktree. Not run because primary did not pass. ⚠️ Blocked
try-fix-2 Blocked before test execution by missing/out-of-date MAUI build tasks in isolated worktree. Not run because primary did not pass. ⚠️ Blocked
try-fix-3 Blocked before test execution by missing/out-of-date MAUI build tasks in isolated worktree. Not run because primary did not pass. ⚠️ Blocked

Exhausted: Yes
Selected Fix: PR #36472 by default — no alternative candidate passed tests or was demonstrably better. However, code review recommends improving the PR's null-CGImage fallback and validating/updating MacCatalyst coverage before merge.


📝 Recommended PR Title & Description

Assessment: ✏️ Recommend updating — the current title still has a [WIP] prefix and the description should reflect the winning pr-plus-reviewer hardening/coverage requirements.

Recommended title

[iOS/MacCatalyst] Entry: Fix dimmed clear button tint

Recommended description

### Issue Details
- When an Entry control has a TextColor set and ClearButtonVisibility is enabled, the clear button (✕) appears faded/dimmed compared to the TextColor.

### Root Cause
- The clear button's image was being drawn directly into the tinting context at reduced opacity, and because CGBlendMode.SourceIn compositing caps the final color's alpha at the alpha of the shape it's masking against, that reduced opacity carried through to the final tinted color — making the clear button appear dim instead of matching TextColor at full opacity.

### Description of Change
- In GetClearButtonTintImage (TextFieldExtensions.cs), the code now builds a plain UIImage from the clear button image's underlying CGImage (preserving CurrentScale and Orientation) and draws that bitmap-backed copy instead of drawing the original image directly, before the existing SourceIn color-fill step — the clear button image now renders with full opacity.
- The fix also hardens the non-CGImage-backed UIImage path so it does not fall back to the old reduced-alpha drawing behavior.
- Because TextFieldExtensions.cs compiles for both iOS and MacCatalyst, the MacCatalyst clear-button baselines are validated and updated for the affected color scenarios.

### Issues Fixed
Fixes #35517

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Platform | Before | After |
|----------|----------|----------|
| iOS | <img src="https://github.com/user-attachments/assets/3f4ac9be-0ec8-429b-8bdd-d381163d8119"> | <img src="https://github.com/user-attachments/assets/4a8897c3-0fc0-4ebf-9bf7-0aef1d359dff"> |
| Mac | <img src="https://github.com/user-attachments/assets/2a6c890a-7a72-4d5c-b7c8-fbbd6fa4cb32"> | <img src="https://github.com/user-attachments/assets/2a2318a4-b1dd-4ef5-8907-20befb57c907"> |

🏁 Report — Final Recommendation

Comparative Report — PR #36472

Candidates compared

Rank Candidate Result Assessment
1 pr-plus-reviewer Not regression-failed; based on the gate-passing PR fix plus expert feedback Best technical candidate. It preserves the PR's successful CGImage-backed tinting behavior while requiring the non-CGImage fallback to be hardened and MacCatalyst baselines to be validated/updated.
2 pr ✅ Gate passed on iOS Best empirically validated candidate as submitted, but it leaves two major expert-review issues unresolved: fallback to the old dim path when UIImage.CGImage is null, and missing MacCatalyst baseline validation for a MacCatalyst-focused issue.
3 try-fix-1 ⚠️ Blocked before tests; regression not run Strongest independent alternative because it directly normalizes raster alpha and handles the null-CGImage concern, but it is more complex than the PR and was not validated due the isolated worktree build-task guard.
4 try-fix-3 ⚠️ Blocked before tests; regression not run Simpler UIKit-template approach, but likely conflicts with the PR's image/rendering-mode assertions and changes how tinting is represented in ImageForState.
5 try-fix-2 ⚠️ Blocked before tests; regression not run Avoids inherited source alpha entirely, but replaces UIKit's private clear-button glyph with custom vector geometry, making it the highest visual-drift risk.

Regression-test rule

No try-fix-* candidate passed its primary test, so none reached the mandatory Issue32886 regression run. The raw PR is the only candidate with supplied passing gate evidence. No candidate is known to have failed the regression test, but all blocked/unvalidated alternatives rank below the PR-derived candidates.

Winning candidate

Winner: pr-plus-reviewer.

The winning path is to keep the PR's validated implementation strategy and apply the expert reviewer's required hardening/coverage feedback. This is preferable to switching to an unvalidated independent try-fix because all try-fix candidates were blocked before tests, and preferable to merging the raw PR unchanged because the expert review identified concrete remaining correctness and coverage gaps.

Required follow-up before merge

pr-plus-reviewer should be validated in a clean environment after applying the reviewer feedback, especially the MacCatalyst snapshot/baseline update. If that validation cannot be completed, the raw pr candidate remains the only empirically passing implementation but should not be treated as review-clean.


🧭 Next Steps — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 2 findings

See inline comments for details.

Comment thread src/Core/src/Platform/iOS/TextFieldExtensions.cs
Comment thread src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs
@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 20, 2026
@kubaflo
kubaflo marked this pull request as ready for review July 21, 2026 20:06
Copilot AI review requested due to automatic review settings July 21, 2026 20:06
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

@kubaflo
kubaflo changed the base branch from main to inflight/current July 21, 2026 20:06

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If it ready? It has [wip] in the title, so I'd rather ask :)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes iOS/MacCatalyst Entry clear button (✕) tinting so it no longer appears dimmed when TextColor is set, aligning the rendered glyph opacity with the entry text.

Changes:

  • Adjusts clear-button tint image generation to draw a bitmap-backed UIImage before applying the SourceIn tint fill, avoiding unintended alpha reduction.
  • Adds an iOS/MacCatalyst device test that asserts the tinted clear-button image contains fully opaque pixels (max alpha = 255).

Reviewed changes

Copilot reviewed 2 out of 17 changed files in this pull request and generated 2 comments.

File Description
src/Core/src/Platform/iOS/TextFieldExtensions.cs Updates clear-button tint rendering to avoid reduced-alpha rasterization and preserve the expected visual intensity.
src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs Adds a regression test validating clear-button tint opacity when TextColor is applied.

Comment on lines +284 to +288
var bitmapImage = image.CGImage is CGImage cgImage
? new UIImage(cgImage, image.CurrentScale, image.Orientation)
: image;
// bitmapImage's Size can be smaller than the original image's Size, so drawing it at
// CGPoint.Empty shifts it to the top-left instead of centering it. Center it manually
Comment on lines +924 to +941
const int bitsPerComponent = 8;
const int bytesPerPixel = 4; // R, G, B, A (CGImageAlphaInfo.PremultipliedLast)
const int alphaByteOffset = 3; // A is the 4th byte within each RGBA pixel

var cgImage = image.CGImage;
Assert.NotNull(cgImage);

var width = (int)cgImage.Width;
var height = (int)cgImage.Height;
var bytesPerRow = width * bytesPerPixel;
var pixels = new byte[height * bytesPerRow];

using var colorSpace = CGColorSpace.CreateDeviceRGB();
using (var context = new CGBitmapContext(pixels, width, height, bitsPerComponent, bytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedLast))
{
context.DrawImage(new CGRect(0, 0, width, height), cgImage);
}

@kubaflo
kubaflo force-pushed the inflight/current branch from a4223bb to c4e03cc Compare July 22, 2026 21:04
@SyedAbdulAzeemSF4852 SyedAbdulAzeemSF4852 changed the title [WIP][iOS/MacCatalyst] Fix Entry clear button appearing dimmed compared to TextColor [iOS/MacCatalyst] Fix Entry clear button appearing dimmed compared to TextColor Jul 23, 2026
@kubaflo
kubaflo merged commit 9beab5f into dotnet:inflight/current Jul 26, 2026
4 of 36 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR10 milestone Jul 26, 2026
kubaflo pushed a commit that referenced this pull request Jul 28, 2026
… TextColor (#36472)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
- When an Entry control has a TextColor set and ClearButtonVisibility is
enabled, the clear button (✕) appears faded/dimmed compared to the
TextColor.

### Root Cause

- The clear button's image was being drawn directly into the tinting
context at reduced opacity, and because CGBlendMode.SourceIn compositing
caps the final color's alpha at the alpha of the shape it's masking
against, that reduced opacity carried through to the final tinted color
— making the clear button appear dim instead of matching TextColor at
full opacity.

### Description of Change
- In GetClearButtonTintImage (TextFieldExtensions.cs), the code now
builds a plain UIImage from the clear button image's underlying CGImage
(preserving CurrentScale and Orientation) and draws that bitmap-backed
copy instead of drawing the original image directly, before the existing
SourceIn color-fill step — the clear button image now renders with full
opacity.

### Issues Fixed
Fixes #35517

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Platform | Before | After |
|----------|----------|----------|
| iOS | <img
src="https://github.com/user-attachments/assets/3f4ac9be-0ec8-429b-8bdd-d381163d8119">
| <img
src="https://github.com/user-attachments/assets/4a8897c3-0fc0-4ebf-9bf7-0aef1d359dff">
|
| Mac | <img
src="https://github.com/user-attachments/assets/2a6c890a-7a72-4d5c-b7c8-fbbd6fa4cb32">
| <img
src="https://github.com/user-attachments/assets/2a2318a4-b1dd-4ef5-8907-20befb57c907">
|
kubaflo pushed a commit that referenced this pull request Jul 29, 2026
… TextColor (#36472)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
- When an Entry control has a TextColor set and ClearButtonVisibility is
enabled, the clear button (✕) appears faded/dimmed compared to the
TextColor.

### Root Cause

- The clear button's image was being drawn directly into the tinting
context at reduced opacity, and because CGBlendMode.SourceIn compositing
caps the final color's alpha at the alpha of the shape it's masking
against, that reduced opacity carried through to the final tinted color
— making the clear button appear dim instead of matching TextColor at
full opacity.

### Description of Change
- In GetClearButtonTintImage (TextFieldExtensions.cs), the code now
builds a plain UIImage from the clear button image's underlying CGImage
(preserving CurrentScale and Orientation) and draws that bitmap-backed
copy instead of drawing the original image directly, before the existing
SourceIn color-fill step — the clear button image now renders with full
opacity.

### Issues Fixed
Fixes #35517

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Platform | Before | After |
|----------|----------|----------|
| iOS | <img
src="https://github.com/user-attachments/assets/3f4ac9be-0ec8-429b-8bdd-d381163d8119">
| <img
src="https://github.com/user-attachments/assets/4a8897c3-0fc0-4ebf-9bf7-0aef1d359dff">
|
| Mac | <img
src="https://github.com/user-attachments/assets/2a6c890a-7a72-4d5c-b7c8-fbbd6fa4cb32">
| <img
src="https://github.com/user-attachments/assets/2a2318a4-b1dd-4ef5-8907-20befb57c907">
|
kubaflo pushed a commit that referenced this pull request Aug 7, 2026
… TextColor (#36472)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
- When an Entry control has a TextColor set and ClearButtonVisibility is
enabled, the clear button (✕) appears faded/dimmed compared to the
TextColor.

### Root Cause

- The clear button's image was being drawn directly into the tinting
context at reduced opacity, and because CGBlendMode.SourceIn compositing
caps the final color's alpha at the alpha of the shape it's masking
against, that reduced opacity carried through to the final tinted color
— making the clear button appear dim instead of matching TextColor at
full opacity.

### Description of Change
- In GetClearButtonTintImage (TextFieldExtensions.cs), the code now
builds a plain UIImage from the clear button image's underlying CGImage
(preserving CurrentScale and Orientation) and draws that bitmap-backed
copy instead of drawing the original image directly, before the existing
SourceIn color-fill step — the clear button image now renders with full
opacity.

### Issues Fixed
Fixes #35517

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Platform | Before | After |
|----------|----------|----------|
| iOS | <img
src="https://github.com/user-attachments/assets/3f4ac9be-0ec8-429b-8bdd-d381163d8119">
| <img
src="https://github.com/user-attachments/assets/4a8897c3-0fc0-4ebf-9bf7-0aef1d359dff">
|
| Mac | <img
src="https://github.com/user-attachments/assets/2a6c890a-7a72-4d5c-b7c8-fbbd6fa4cb32">
| <img
src="https://github.com/user-attachments/assets/2a2318a4-b1dd-4ef5-8907-20befb57c907">
|
kubaflo pushed a commit that referenced this pull request Aug 12, 2026
… TextColor (#36472)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
- When an Entry control has a TextColor set and ClearButtonVisibility is
enabled, the clear button (✕) appears faded/dimmed compared to the
TextColor.

### Root Cause

- The clear button's image was being drawn directly into the tinting
context at reduced opacity, and because CGBlendMode.SourceIn compositing
caps the final color's alpha at the alpha of the shape it's masking
against, that reduced opacity carried through to the final tinted color
— making the clear button appear dim instead of matching TextColor at
full opacity.

### Description of Change
- In GetClearButtonTintImage (TextFieldExtensions.cs), the code now
builds a plain UIImage from the clear button image's underlying CGImage
(preserving CurrentScale and Orientation) and draws that bitmap-backed
copy instead of drawing the original image directly, before the existing
SourceIn color-fill step — the clear button image now renders with full
opacity.

### Issues Fixed
Fixes #35517

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Platform | Before | After |
|----------|----------|----------|
| iOS | <img
src="https://github.com/user-attachments/assets/3f4ac9be-0ec8-429b-8bdd-d381163d8119">
| <img
src="https://github.com/user-attachments/assets/4a8897c3-0fc0-4ebf-9bf7-0aef1d359dff">
|
| Mac | <img
src="https://github.com/user-attachments/assets/2a6c890a-7a72-4d5c-b7c8-fbbd6fa4cb32">
| <img
src="https://github.com/user-attachments/assets/2a2318a4-b1dd-4ef5-8907-20befb57c907">
|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MacCatalyst] [Entry] ClearButtonVisibility color appears dimmed compared to TextColor

5 participants