Skip to content

CmdPal: Enhance font icon classification and visuals#41573

Merged
michaeljolley merged 1 commit intomicrosoft:mainfrom
jiripolasek:feature/41489-cmdpal-fix-multi-codepoint-emoji-icons
Sep 3, 2025
Merged

CmdPal: Enhance font icon classification and visuals#41573
michaeljolley merged 1 commit intomicrosoft:mainfrom
jiripolasek:feature/41489-cmdpal-fix-multi-codepoint-emoji-icons

Conversation

@jiripolasek
Copy link
Collaborator

@jiripolasek jiripolasek commented Sep 3, 2025

Summary of the Pull Request

  • Introduces FontIconGlyphClassifier for classifying emojis and symbols.

    • Correctly recognizes multi-codepoint glyphs (e.g., 🧙🏼‍♀️ woman mage with medium-light skin tone).
    • Explicitly disallows multi-glyph icons (they would overflow anyway).
    • Distinguishes between emojis and regular text characters (letters, numbers, symbols), since emojis are slightly larger and require different padding.
    • Recognizes Unicode Variation Selectors to enforce specific styles: VS15 (U+FE0E) for text style (monochrome) and VS16 (U+FE0F) for emoji style (color). This lets developers choose which variant to display. By default, characters with both representations render as text/monochrome (e.g., ▶ \u25B6):
      image
    • Invalid icons are displayed as a dashed circle so extension developers can spot issues, without being overly distracting if they slip into production.
  • Updates IconPathConverter to use the new classifier for improved icon handling.

  • Adds SampleIconPage to demonstrate various icon usages and classifications.

  • Adjusts icon alignment in IconBox so icons are centered.

  • Scales negative padding for emojis in IconBox with control size, fixing misalignment and clipping (noticeable in tags and the details pane hero image).

  • Applies negative padding to all font icons. This removes the need for classification in these cases and ensures symbols rendered below the baseline remain visible.

Based on microsoft/terminal#19143:
Co-authored-by: Dustin L. Howett [email protected]

Pictures? Pictures!

image

Keyboard and flag/country emojis may look a bit off, but that’s how they’re actually rendered:
image

PR Checklist

Detailed Description of the Pull Request / Additional comments

Validation Steps Performed

- Introduce `FontIconGlyphClassifier` for classifying emojis and symbols.
- Update `IconPathConverter` to utilize the classifier for better handling.
- Add `SampleIconPage` with new test cases, including symbols with both text and emoji representations.
- Simplify `IconBox` padding logic by removing classification and expanding padding for font icons by default.
- Add alignment properties and improve icon source management in `IconBox`.
- Support Unicode Variation Selectors VS15 (force text) and VS16 (force emoji).
- Update default emoji classification to exclude Extended Pictographic characters.
@zadjii-msft
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@michaeljolley michaeljolley added the Product-Command Palette Refers to the Command Palette utility label Sep 3, 2025
@michaeljolley michaeljolley merged commit 347c3f1 into microsoft:main Sep 3, 2025
10 checks passed
@michaeljolley michaeljolley moved this from Todo to Done in CmdPal Roadmap Sep 3, 2025
@michaeljolley michaeljolley added this to the PowerToys 0.95 milestone Sep 4, 2025
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

This PR enhances font icon classification and visual handling in the Command Palette by introducing sophisticated emoji and symbol detection capabilities. The changes improve how icons are categorized, displayed, and aligned across the UI.

Key changes:

  • Introduces FontIconGlyphClassifier for accurate classification of emojis, symbols, and text characters using ICU Unicode boundary detection
  • Updates IconPathConverter to use the new classifier for better font family selection and invalid icon handling
  • Adds comprehensive icon demonstration page with various Unicode examples

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
SamplesListPage.cs Adds navigation to new sample icon demonstration page
SampleIconPage.cs New comprehensive demo page showcasing various icon types and Unicode classifications
Microsoft.Terminal.UI.vcxproj Project file updates to include new FontIconGlyphClassifier components
IconPathConverter.cpp Updated to use new classifier for improved icon handling and font selection
FontIconGlyphClassifier.idl IDL interface definition for the new glyph classification system
FontIconGlyphClassifier.h Header file for the classifier implementation
FontIconGlyphClassifier.cpp Core implementation of Unicode-based glyph classification using ICU
IconBox.cs Enhanced icon alignment and padding calculations with error handling
expect.txt Spell check additions for new Unicode-related terms

#include "IconPathConverter.g.cpp"

// #include "Utils.h"
#include "FontIconGlyphClassifier.h"
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

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

[nitpick] The commented line // #include \"Utils.h\" should be removed rather than left as a comment if it's no longer needed.

Copilot uses AI. Check for mistakes.
// Switching back to EnqueueAsync has broken icons in tags (they don't show)
// _ = @this._queue.EnqueueAsync(() =>
@this._queue.TryEnqueue(new(async () =>
@this._queue.TryEnqueue(async void () =>
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

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

Using async void is generally discouraged except for event handlers as it makes error handling and testing difficult. Consider using async Task and handling the task appropriately, or use a fire-and-forget pattern with proper error handling.

Suggested change
@this._queue.TryEnqueue(async void () =>
@this._queue.TryEnqueue(async () =>

Copilot uses AI. Check for mistakes.

if (iconData is not null &&
@this.Source is FontIconSource)
@this.Padding = new Thickness(Math.Round(iconSize * -0.2));
Copy link

Copilot AI Sep 29, 2025

Choose a reason for hiding this comment

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

The magic number 0.2 should be extracted to a named constant to improve code maintainability and make the scaling factor's purpose clear.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Product-Command Palette Refers to the Command Palette utility

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

CmdPal: IconBox doesn’t scale emoji compensation correctly across icon sizes CmdPal: Icon doesn't recognize grapheme clusters

4 participants