Fix #364 - Use image registries#365
Open
travkin79 wants to merge 9 commits into
Open
Conversation
- Add CopilotImages, a facade for the ui plug-in's images - Add CopilotJobsImages, a facade for the jobs plug-in's images - Add unit tests to ensure the resources can be loaded - Improve plug-in instantiation Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ft#364) Use image registries to access static images, no longer dispose them, since the registries handle Image disposals. Keep dynamic image loading and disposal as it was. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…rosoft#364) Re-direct calls of PlatformUI.getWorkbench().getSharedImages().getImage(...) to the image registry. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…#364) Drop the icon-path/shared-image factory variants of WrappableIconLink in favor of a single create(...) that accepts an already-resolved Image. Callers now pass registry images (CopilotImages.IMG_INFORMATION) or shared workbench images directly, and the widget no longer owns or disposes the icon. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
All icon lookups now go through the image registries (CopilotImages / CopilotJobsImages), so the raw PNG-path helpers are no longer referenced. Drop them from the ui-bundle UiUtils and delete the jobs-bundle UiUtils, whose sole purpose was these two methods. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ons (microsoft#364) Add an Image Registries subsection under Resource Management. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
travkin79
requested review from
duzitong,
ethanyhou,
jdneo and
xinyi-gong
as code owners
July 22, 2026 09:44
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses issue #364 by centralizing image loading in the ui and ui.jobs bundles via plugin ImageRegistry-backed facades (CopilotImages, CopilotJobsImages), replacing ad-hoc image creation/disposal at call sites and adding tests to catch missing icon resources.
Changes:
- Introduces
CopilotImages(UI) andCopilotJobsImages(Jobs) registries and migrates many call sites to registry/shared-image access. - Removes
UiUtils.buildImage*FromPngPath(...)usage patterns and associated manual disposal logic across UI widgets/handlers/dialogs. - Adds reflection-based unit tests to validate that all
IMG_*constants map to real bundle resources; adjusts plugin/test initialization accordingly.
Reviewed changes
Copilot reviewed 64 out of 64 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/utils/UiUtils.java | Removes ad-hoc PNG image helper APIs to push callers toward registries. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/utils/MenuUtils.java | Switches quota/blank icon descriptors to CopilotImages keys. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/utils/McpUtils.java | Uses shared default MCP icon from CopilotImages. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/swt/SpinnerAnimator.java | Uses registry spinner frames instead of per-frame image creation/disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/swt/ModelHoverContentProvider.java | Replaces static cached/disposed icons with themed registry images. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/swt/DropdownPopup.java | Replaces static cached/disposed icons with themed registry images. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/swt/DropdownButton.java | Replaces static cached/disposed arrow icon with themed registry images. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/quickstart/FeaturePage.java | Converts quickstart icons to registry-managed images and removes manual disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/WrappableIconLink.java | Changes API to accept Image (non-owned) instead of path/shared-image variants. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/McpPreferencePage.java | Uses CopilotImages for info/red-notice icons and shared images. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/GlobalAutoApproveSection.java | Uses CopilotImages for shared warning icon. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/CustomModesPreferencePage.java | Uses CopilotImages for information icon. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/ByokPreferencePage.java | Uses CopilotImages for keep/delete icons and removes image disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/AutoApprovePreferencePage.java | Uses CopilotImages for shared info icon. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/AddByokModelDialog.java | Uses themed registry eye/eye-closed icons (no manual disposal). |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/AddApiKeyDialog.java | Uses themed registry eye/eye-closed icons (no manual disposal). |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/nes/RulerColumn.java | Uses CopilotImages for gutter-arrow descriptor source. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/nes/ActionMenu.java | Uses CopilotImages for menu action icon descriptors. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/handlers/ToolConfigurationContextMenuHandler.java | Uses CopilotImages for context menu icon descriptors. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/handlers/ShowStatusBarMenuHandler.java | Uses CopilotImages descriptors (including spinner frames) instead of path literals. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/handlers/ShowMenuBarMenuHandler.java | Uses CopilotImages icon descriptors instead of path literals. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/handlers/ShowContextMenuHandler.java | Uses CopilotImages for context menu icon descriptor. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/dialogs/MissingTerminalDependenciesDialog.java | Uses registry Copilot icon (no manual disposal). |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/dialogs/mcp/McpServerItem.java | Uses themed registry images for MCP meta-row icons (no manual disposal). |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/dialogs/mcp/McpServerDetailDialog.java | Uses registry/themed images and removes label-level disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/dialogs/mcp/McpRegistryDialog.java | Uses registry images for dialog/buttons/banner icons and removes disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/dialogs/mcp/McpApprovalDialog.java | Uses registry/shared images for approve/deny icons (no manual disposal). |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/dialogs/jobs/BaseCopilotDialog.java | Uses registry Copilot icon (no manual disposal). |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/CopilotUi.java | Initializes image registry via CopilotImages and adjusts plugin singleton lifecycle. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/CopilotImages.java | New UI image facade defining keys + registry/shared-image access helpers. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/WorkingSetBar.java | Switches arrows/keep/undo/file icons to registry/shared images. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/WarnWidget.java | Uses shared warning icon via CopilotImages. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/viewers/NoSubscriptionViewer.java | Switches main icon to registry image and removes disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/viewers/LoadingViewer.java | Switches main icon to registry image and removes disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/viewers/ChatHistoryViewer.java | Switches navigation/edit icons to registry images; shared delete icon via facade. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/viewers/BeforeLoginWelcomeViewer.java | Switches welcome/feature icons to registry images and removes disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/viewers/AgentModeViewer.java | Switches welcome/tools/attach-context icons to registry images and removes disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/viewers/AfterLoginWelcomeViewer.java | Switches welcome/attach-context icons to registry images and removes disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/tools/RunInTerminalToolAdapter.java | Uses registry Copilot icon descriptor for terminal integration. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/TodoListBar.java | Switches status/arrow/clear icons to registry images and removes disposal code paths. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ThinkingBlock.java | Uses registry cancel/arrow icons and removes disposal helper. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/StaticBanner.java | Uses shared severity/close icons via CopilotImages. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/SourceViewerComposite.java | Uses shared copy/paste icons via CopilotImages. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/services/AvatarService.java | Uses registry default avatars and stops disposing them in service dispose(). |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ReferencedFile.java | Uses registry close icon and shared warning icon via CopilotImages. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ModelPickerGroupsBuilder.java | Uses themed warning icon via CopilotImages instead of static cache/dispose. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ErrorWidget.java | Uses shared error icon via CopilotImages. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/dialogs/DynamicOauthDialog.java | Uses registry Copilot icon and removes manual disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/CurrentReferencedFile.java | Replaces static never-disposed eye icons with registry images. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/AgentToolCancelLabel.java | Uses registry cancel icon and removes disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/AgentStatusLabel.java | Uses registry status icons and shared error icon; removes disposal of registry images. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/AgentMessageWidget.java | Uses themed jobs PR icons via CopilotImages (no disposal). |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/AddContextButton.java | Uses registry attach-context icon and removes disposal. |
| com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ActionBar.java | Uses registry/shared images for action bar icons and removes disposal blocks. |
| com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/jobs/CopilotJobsImagesTest.java | New reflection-based test to validate jobs bundle icon resources exist. |
| com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/CopilotUiTests.java | Updates UI plugin test startup approach (needs adjustment per review). |
| com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/ui/CopilotImagesTest.java | New reflection-based test to validate UI bundle icon resources exist. |
| com.microsoft.copilot.eclipse.ui.test/META-INF/MANIFEST.MF | Adds dependency on com.microsoft.copilot.eclipse.ui.jobs for new tests. |
| com.microsoft.copilot.eclipse.ui.jobs/src/com/microsoft/copilot/eclipse/ui/jobs/views/JobsView.java | Migrates jobs view icons to CopilotJobsImages and removes disposal. |
| com.microsoft.copilot.eclipse.ui.jobs/src/com/microsoft/copilot/eclipse/ui/jobs/utils/UiUtils.java | Deletes ad-hoc jobs image helper in favor of registry facade. |
| com.microsoft.copilot.eclipse.ui.jobs/src/com/microsoft/copilot/eclipse/ui/jobs/CopilotJobsImages.java | New jobs image facade defining keys + registry/shared-image access helpers. |
| com.microsoft.copilot.eclipse.ui.jobs/src/com/microsoft/copilot/eclipse/ui/jobs/CopilotJobs.java | Initializes image registry via CopilotJobsImages and adds plugin singleton accessor. |
| com.microsoft.copilot.eclipse.ui.jobs/META-INF/MANIFEST.MF | Exports jobs package (visibility consideration raised in review). |
| .github/copilot-instructions.md | Documents the new “prefer image registries; don’t dispose registry images” guideline. |
Comment on lines
+151
to
+167
| private static volatile ImageRegistry imageRegistry; | ||
|
|
||
| private CopilotImages() { | ||
| // prevent instantiation | ||
| } | ||
|
|
||
| /** | ||
| * Returns the plugin's image registry, initializing it on first access. | ||
| * Called by {@link CopilotUi#initializeImageRegistry(ImageRegistry)} to pre-register descriptors. | ||
| */ | ||
| static ImageRegistry getImageRegistry() { | ||
| ImageRegistry registry = imageRegistry; | ||
| if (registry == null) { | ||
| registry = imageRegistry = CopilotUi.getPlugin().getImageRegistry(); | ||
| } | ||
| return registry; | ||
| } |
Comment on lines
+32
to
+48
| private static volatile ImageRegistry imageRegistry; | ||
|
|
||
| private CopilotJobsImages() { | ||
| // prevent instantiation | ||
| } | ||
|
|
||
| /** | ||
| * Returns the plugin's image registry, initializing it on first access. | ||
| * Called by {@link CopilotJobs#initializeImageRegistry(ImageRegistry)} to pre-register descriptors. | ||
| */ | ||
| static ImageRegistry getImageRegistry() { | ||
| ImageRegistry registry = imageRegistry; | ||
| if (registry == null) { | ||
| registry = imageRegistry = CopilotJobs.getPlugin().getImageRegistry(); | ||
| } | ||
| return registry; | ||
| } |
Comment on lines
22
to
25
| BundleContext context = FrameworkUtil.getBundle(CopilotUi.class).getBundleContext(); | ||
| CopilotUi ui = new CopilotUi(); | ||
| ui.start(null); | ||
| ui.start(context); | ||
|
|
| Bundle-Localization: plugin | ||
| Automatic-Module-Name: com.microsoft.copilot.eclipse.ui.jobs | ||
| Bundle-ActivationPolicy: lazy | ||
| Export-Package: com.microsoft.copilot.eclipse.ui.jobs |
Apply suggested improvement: check plug-in availability, retrieve the plug-in's registry, do no longer cache the registry in a static variable since it is already cached.
Apply suggested improvement: The ui.jobs package is exported only so the test bundle can access CopilotJobsImages. Limit its visibility with x-friends to avoid exposing it as public OSGi API, matching the existing convention used for ui.chat.confirmation.
Apply suggested improvement: Start the UI bundle through the OSGi framework so the framework-owned activator runs as it would at runtime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes issue #364.
CopilotImages, a facade for the ui plug-in's imagesCopilotJobsImages, a facade for the jobs plug-in's images