terminal icon indicating copy to clipboard operation
terminal copied to clipboard

suppressApplicationTitle doesn't work

Open cool-RR opened this issue 4 months ago • 9 comments

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.

cool-RR avatar Oct 23 '25 07:10 cool-RR

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 avatar Oct 29 '25 19:10 zadjii-msft

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

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

DHowett avatar Oct 29 '25 19:10 DHowett

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 avatar Oct 29 '25 19:10 cool-RR

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

DHowett avatar Oct 29 '25 19:10 DHowett

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

cool-RR avatar Oct 29 '25 19:10 cool-RR

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 avatar Oct 29 '25 20:10 DHowett

Gotcha. Is there an existing issue for that?

cool-RR avatar Oct 29 '25 20:10 cool-RR

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)

zadjii-msft avatar Nov 05 '25 20:11 zadjii-msft

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 avatar Dec 07 '25 20:12 cool-RR