Skip to content

feat(connections): add custom icon support in tabs for extensions and SSH - #438

Merged
feigeCode merged 1 commit into
feigeCode:mainfrom
keenser:extentions-custom-icons
Oct 21, 2026
Merged

feigeCode merged 1 commit into
feigeCode:mainfrom
keenser:extentions-custom-icons

Conversation

@keenser

@keenser keenser commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Description

This PR makes custom connection icons actually show up in terminal tabs.

Custom icons already existed for SSH connections, but they were only displayed in the Connections tab and the Open Connection menu. When you actually connected to a host, the tab icon stayed at the default connection-kind icon.

For extension connections, there was previously no way at all to pick a custom icon — no Icon field existed. Now extensions can declare one, and the selected icon is displayed consistently.

What changed

  1. SSH tab icon now respects the chosen icon (crates/terminal_view/...)

    • Terminal tabs now prefer the connection-selected icon (SSH custom image/built-in icon) and fall back to the connection-kind icon only when nothing is selected.
    • TerminalWorkspace::icon delegates to the active pane so duplicate tabs and workspaces stay consistent.
  2. New Icon field type for extensions (crates/connection_form, crates/extension-runtime)

    • Extensions can now declare an Icon field in their connection form via contributes.connections[].form, rendered by a new icon picker in the declarative form: Auto, a grid of built-in OS icons, and a local image upload tile.
    • Stored as {"icon": "<built-in id>"} or {"file": "<local absolute path>"} (mutually exclusive; Auto omits the key).
    • Validation guarantees at most one icon field per connection and rejects defaultValue/options/secret on it.
  3. Centralized icon resolution (crates/core/src/storage/connection_icon.rs, crates/universal-plugins/src/connection_icon.rs)

    • A single shared resolver so lists, cards, and tabs agree on the same icon.
    • Priority: user selection (local image → built-in icon) → manifest-declared extension icon → caller fallback (generic extension icon).
    • Extension terminal-type connections resolve the icon once and pass it through when launching the tab; duplicated (Launched) tabs carry the icon too.

Screenshot

Before After
Screenshot 2026-10-21 at 12 10 46 Screenshot 2026-10-21 at 12 19 32
Screenshot 2026-10-21 at 12 17 39 Screenshot 2026-10-21 at 12 21 46

How to Test

  1. Build and run the app (cargo run).
  2. SSH connection: pick a built-in icon or upload a local image in the SSH connection form and save. Connect to the host and confirm the tab now shows the chosen icon (previously it stayed default even though the list/menu showed it).
  3. Extension connection: create/enable an extension whose manifest declares an Icon field in contributes.connections[].form. Choose an icon (or leave Auto) and confirm the list, card, and tab show the user selection, otherwise the manifest-declared icon, otherwise the generic extension icon.
  4. Verify no regressions: connections left on Auto still show the auto-detected / manifest icon as before.

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

Implement icon picker for connection forms, allowing users to select
built-in OS icons or upload local images. Add Icon field type to
declarative forms and extension manifests. Centralize icon resolution
logic in core storage and universal plugins to ensure consistent
display across connection lists, cards, and terminal tabs.
@feigeCode
feigeCode merged commit 28ab54c into feigeCode:main Oct 21, 2026
8 checks passed
@feigeCode feigeCode mentioned this pull request Oct 22, 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.

2 participants