suppressApplicationTitle doesn't work #23746

Open
opened 2026-01-31 08:51:18 +00:00 by claunia · 9 comments
Owner

Originally created by @cool-RR on GitHub (Oct 23, 2025).

Windows Terminal version

1.23.12811.0

Windows build number

10.0.19045.6456

Other Software

No response

Steps to reproduce

The problem can't be reliably reproduced, but sometimes when I SSH into some server, even though I explicitly set the title to "Server (SSH)" it later changes to zsh.

I have "suppressApplicationTitle": true in my settings. My full settings.json.

Expected Behavior

No response

Actual Behavior

The problem can't be reliably reproduced, but sometimes when I SSH into some server, even though I explicitly set the title to "Server (SSH)" it later changes to zsh.

I have "suppressApplicationTitle": true in my settings. My full settings.json.

Originally created by @cool-RR on GitHub (Oct 23, 2025). ### Windows Terminal version 1.23.12811.0 ### Windows build number 10.0.19045.6456 ### Other Software _No response_ ### Steps to reproduce The problem can't be reliably reproduced, but sometimes when I SSH into some server, even though I explicitly set the title to "Server (SSH)" it later changes to `zsh`. I have `"suppressApplicationTitle": true` in my settings. [My full settings.json](https://gist.github.com/cool-RR/e209dae05cc8de659de13c2f7698b5f1). ### Expected Behavior _No response_ ### Actual Behavior The problem can't be reliably reproduced, but sometimes when I SSH into some server, even though I explicitly set the title to "Server (SSH)" it later changes to `zsh`. I have `"suppressApplicationTitle": true` in my settings. [My full settings.json](https://gist.github.com/cool-RR/e209dae05cc8de659de13c2f7698b5f1).
claunia added the Issue-BugProduct-TerminalArea-Commandline labels 2026-01-31 08:51:19 +00:00
Author
Owner

@zadjii-msft commented on GitHub (Oct 29, 2025):

even though I explicitly set the title to "Server (SSH)"

How are you setting the title to "Server (SSH)"? It doesn't look like any of your profiles have that as a name or title. Knowing the exact way you're setting this would help us debug this.


My theory was:

  • you're using your zsh profile
  • you're ssh'ing to the server
  • then manually renaming the tab in the tab context menu
  • then some VT sequence for setting the title (or a settings reload or something) was causing us to forget to the tab's title override

But we couldn't ever get that to work right.

@zadjii-msft commented on GitHub (Oct 29, 2025): > even though I explicitly set the title to "Server (SSH)" How are you setting the title to "Server (SSH)"? It doesn't look like any of your profiles have that as a name or title. Knowing the exact way you're setting this would help us debug this. ---- My theory was: * you're using your `zsh` profile * you're ssh'ing to the server * then manually renaming the tab in the tab context menu * then some VT sequence for setting the title (or a settings reload or something) was causing us to forget to the tab's title override But we couldn't ever get that to work right.
Author
Owner

@DHowett commented on GitHub (Oct 29, 2025):

But we couldn't ever get that to work right.

Well, we couldn't get it to repro that way. 🙂

@DHowett commented on GitHub (Oct 29, 2025): > But we couldn't ever get that to work right. Well, we couldn't get it to _repro_ that way. 🙂
Author
Owner

@cool-RR commented on GitHub (Oct 29, 2025):

I've got this AutoHotKey line:

Run, "%A_Home%\AppData\Local\Microsoft\WindowsApps\wt.exe" new-tab --profile zsh --title "%title% (SSH)" --startingDirectory "%A_Home%" --suppressApplicationTitle ssh %jumpParam% %target%
@cool-RR commented on GitHub (Oct 29, 2025): I've got this AutoHotKey line: ``` Run, "%A_Home%\AppData\Local\Microsoft\WindowsApps\wt.exe" new-tab --profile zsh --title "%title% (SSH)" --startingDirectory "%A_Home%" --suppressApplicationTitle ssh %jumpParam% %target% ```
Author
Owner

@DHowett commented on GitHub (Oct 29, 2025):

When the settings reloads we blow away both of these overrides. That's not ideal.

@DHowett commented on GitHub (Oct 29, 2025): When the settings reloads we blow away both of these overrides. That's not ideal.
Author
Owner

@cool-RR commented on GitHub (Oct 29, 2025):

I don't understand what you're saying at all. Can you explain?

@cool-RR commented on GitHub (Oct 29, 2025): I don't understand what you're saying at all. Can you explain?
Author
Owner

@DHowett commented on GitHub (Oct 29, 2025):

Oh, sorry. This is a bug on our end - I'm just explaining how it happens.

There are a few things that cause the settings file to reload even when it has not changed. When we reload the settings file, sometimes we forget things you specify on the command line (like --title!)

@DHowett commented on GitHub (Oct 29, 2025): Oh, sorry. This is a bug on our end - I'm just explaining how it happens. There are a few things that cause the settings file to reload even when it has not changed. When we reload the settings file, sometimes we forget things you specify on the command line (like `--title`!)
Author
Owner

@cool-RR commented on GitHub (Oct 29, 2025):

Gotcha. Is there an existing issue for that?

@cool-RR commented on GitHub (Oct 29, 2025): Gotcha. Is there an existing issue for that?
Author
Owner

@zadjii-msft commented on GitHub (Nov 5, 2025):

Huh. I cannot for the life of me figure out the dupe for this!

Pretty sure it was somewhere between:

But I'm not sure there's a more correct one for "when the settings reload, we blow away the args that are passed on the commandline, and because suppressApplicationTitle is something that's checked as needed, the all of a sudden we start allowing apps to set the title"

(I suppose passing the scheme on the CLI would be a more visual demo)

@zadjii-msft commented on GitHub (Nov 5, 2025): Huh. I cannot for the life of me figure out the dupe for this! Pretty sure it was somewhere between: * #11913 * #14350 * #5047 * This is the most promising dupe? But I'm not sure there's a more correct one for "when the settings reload, we blow away the args that are passed on the commandline, and because `suppressApplicationTitle` is something that's checked as needed, the all of a sudden we start allowing apps to set the title" (I suppose passing the scheme on the CLI would be a more visual demo)
Author
Owner

@cool-RR commented on GitHub (Dec 7, 2025):

Hey guys. Below is an analysis by Claude Code. I don't know whether this is helpful so attaching it here in case it is.

Analysis with Claude Code

I traced through the codebase and found the exact root cause of this bug. Here's the complete chain:

Initial Tab Creation (works correctly)

When you create a tab with command-line args like --title "Server (SSH)" --suppressApplicationTitle:

  1. TabManagement.cpp:76 calls:

    const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs) };
    
  2. TerminalSettings.cpp:116-197 - CreateWithNewTerminalArgs applies command-line overrides on top of profile settings:

    if (newTerminalArgs.SuppressApplicationTitle())
    {
        defaultSettings->_SuppressApplicationTitle = newTerminalArgs.SuppressApplicationTitle().Value();
    }
    if (!newTerminalArgs.TabTitle().empty())
    {
        defaultSettings->_StartingTitle = newTerminalArgs.TabTitle();
    }
    

Settings Reload (bug happens here)

When settings reload (dock/undock, settings file change, etc.):

  1. TerminalPage.cpp:3778 resets the settings cache:

    _terminalSettingsCache->Reset(_settings);
    
  2. TerminalSettingsCache.cpp:46-65 - Reset() rebuilds the cache using only profiles (no NewTerminalArgs):

    for (const auto& newProfile : allProfiles)
    {
        profileGuidSettingsMap.insert_or_assign(newProfile.Guid(), std::pair{ newProfile, std::nullopt });
    }
    
  3. TerminalPaneContent.cpp:336-346 - UpdateSettings looks up settings from the cache:

    if (const auto settings{ _cache->TryLookup(_profile) })
    {
        _control.UpdateControlSettings(settings->DefaultSettings(), settings->UnfocusedSettings());
    }
    
  4. TerminalSettingsCache.cpp:38 - TryLookup creates settings using CreateWithProfile (NOT CreateWithNewTerminalArgs):

    pair.second = winrt::Microsoft::Terminal::Settings::TerminalSettings::CreateWithProfile(_settings, pair.first);
    

Why the args are lost

The NewTerminalArgs (containing --title, --suppressApplicationTitle, etc.) are never persisted. They're used once during initial tab creation, then discarded.

Looking at TerminalPaneContent.h, the pane only stores:

  • _profile - the profile object
  • _cache - the shared settings cache

There's no _newTerminalArgs member to preserve the original command-line overrides.

Suggested Fix

The fix would involve:

  1. Store the original NewTerminalArgs in TerminalPaneContent (add a _newTerminalArgs member)

  2. Modify UpdateSettings to use CreateWithNewTerminalArgs instead of CreateWithProfile:

    void TerminalPaneContent::UpdateSettings(const CascadiaSettings& settings)
    {
        const auto profile{ settings.FindProfile(_profile.Guid()) };
        _profile = profile ? profile : settings.ProfileDefaults();
    
        // Use stored newTerminalArgs to preserve command-line overrides
        auto newSettings = Settings::TerminalSettings::CreateWithNewTerminalArgs(settings, _newTerminalArgs);
        _control.UpdateControlSettings(newSettings.DefaultSettings(), newSettings.UnfocusedSettings());
    }
    
  3. Alternatively, extend TerminalSettingsCache to key by both profile GUID and NewTerminalArgs so each unique combination gets its own cached settings.

This would ensure that command-line overrides like --title and --suppressApplicationTitle survive settings reloads.


@cool-RR commented on GitHub (Dec 7, 2025): Hey guys. Below is an analysis by Claude Code. I don't know whether this is helpful so attaching it here in case it is. ## Analysis with Claude Code I traced through the codebase and found the exact root cause of this bug. Here's the complete chain: ### Initial Tab Creation (works correctly) When you create a tab with command-line args like `--title "Server (SSH)" --suppressApplicationTitle`: 1. **`TabManagement.cpp:76`** calls: ```cpp const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs) }; ``` 2. **`TerminalSettings.cpp:116-197`** - `CreateWithNewTerminalArgs` applies command-line overrides on top of profile settings: ```cpp if (newTerminalArgs.SuppressApplicationTitle()) { defaultSettings->_SuppressApplicationTitle = newTerminalArgs.SuppressApplicationTitle().Value(); } if (!newTerminalArgs.TabTitle().empty()) { defaultSettings->_StartingTitle = newTerminalArgs.TabTitle(); } ``` ### Settings Reload (bug happens here) When settings reload (dock/undock, settings file change, etc.): 1. **`TerminalPage.cpp:3778`** resets the settings cache: ```cpp _terminalSettingsCache->Reset(_settings); ``` 2. **`TerminalSettingsCache.cpp:46-65`** - `Reset()` rebuilds the cache using **only profiles** (no NewTerminalArgs): ```cpp for (const auto& newProfile : allProfiles) { profileGuidSettingsMap.insert_or_assign(newProfile.Guid(), std::pair{ newProfile, std::nullopt }); } ``` 3. **`TerminalPaneContent.cpp:336-346`** - `UpdateSettings` looks up settings from the cache: ```cpp if (const auto settings{ _cache->TryLookup(_profile) }) { _control.UpdateControlSettings(settings->DefaultSettings(), settings->UnfocusedSettings()); } ``` 4. **`TerminalSettingsCache.cpp:38`** - `TryLookup` creates settings using **`CreateWithProfile`** (NOT `CreateWithNewTerminalArgs`): ```cpp pair.second = winrt::Microsoft::Terminal::Settings::TerminalSettings::CreateWithProfile(_settings, pair.first); ``` ### Why the args are lost The **`NewTerminalArgs`** (containing `--title`, `--suppressApplicationTitle`, etc.) are never persisted. They're used once during initial tab creation, then discarded. Looking at **`TerminalPaneContent.h`**, the pane only stores: - `_profile` - the profile object - `_cache` - the shared settings cache There's no `_newTerminalArgs` member to preserve the original command-line overrides. ### Suggested Fix The fix would involve: 1. **Store the original `NewTerminalArgs`** in `TerminalPaneContent` (add a `_newTerminalArgs` member) 2. **Modify `UpdateSettings`** to use `CreateWithNewTerminalArgs` instead of `CreateWithProfile`: ```cpp void TerminalPaneContent::UpdateSettings(const CascadiaSettings& settings) { const auto profile{ settings.FindProfile(_profile.Guid()) }; _profile = profile ? profile : settings.ProfileDefaults(); // Use stored newTerminalArgs to preserve command-line overrides auto newSettings = Settings::TerminalSettings::CreateWithNewTerminalArgs(settings, _newTerminalArgs); _control.UpdateControlSettings(newSettings.DefaultSettings(), newSettings.UnfocusedSettings()); } ``` 3. **Alternatively**, extend `TerminalSettingsCache` to key by both profile GUID **and** `NewTerminalArgs` so each unique combination gets its own cached settings. This would ensure that command-line overrides like `--title` and `--suppressApplicationTitle` survive settings reloads. ---
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#23746