diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 2e2a0313f8..dcd381e335 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -18285,6 +18285,23 @@ - (NSDictionary *)automaticProfileSwitcherCurrentProfile { - (void)automaticProfileSwitcherLoadProfile:(iTermSavedProfile *)savedProfile { Profile *underlyingProfile = [[ProfileModel sharedInstance] bookmarkWithGuid:savedProfile.originalProfile[KEY_GUID]]; Profile *replacementProfile = underlyingProfile ?: savedProfile.originalProfile; + + // Compute the font zoom delta before switching profiles so we can preserve it. + // The zoom delta is the difference between the current font size and the + // profile\u2019s base font size. + CGFloat fontZoomDelta = 0; + NSRect savedWindowFrame = NSZeroRect; + NSWindow *window = [[_delegate realParentWindow] window]; + if ([iTermAdvancedSettingsModel preserveFontSizeOnAutomaticProfileSwitch]) { + iTermFontTable *originalFontTable = [iTermFontTable fontTableForProfile:_originalProfile]; + CGFloat currentPointSize = _textview.fontTable.asciiFont.font.pointSize; + CGFloat originalPointSize = originalFontTable.asciiFont.font.pointSize; + fontZoomDelta = currentPointSize - originalPointSize; + if (fontZoomDelta != 0 && window) { + savedWindowFrame = window.frame; + } + } + if (![self setProfile:replacementProfile preservingName:NO adjustWindow:NO]) { [_view showUnobtrusiveMessage:[NSString stringWithFormat:@"Can’t switch to profile “%@”—wrong profile type.", underlyingProfile[KEY_NAME]]]; return; @@ -18297,8 +18314,29 @@ - (void)automaticProfileSwitcherLoadProfile:(iTermSavedProfile *)savedProfile { } overrides[key] = savedProfile.profile[key]; } + _windowAdjustmentDisabled = YES; [self setSessionSpecificProfileValues:overrides]; + _windowAdjustmentDisabled = NO; } + + // Re-apply the font zoom delta after the profile switch, but only when + // switching to a new profile. When restoring a divorced profile from the + // stack, the saved overrides already include the zoomed font. + if (fontZoomDelta != 0 && !savedProfile.isDivorced) { + _windowAdjustmentDisabled = YES; + iTermFontTable *zoomedTable = [_textview.fontTable fontTableGrownBy:fontZoomDelta]; + [self setFontTable:zoomedTable + horizontalSpacing:_textview.horizontalSpacing + verticalSpacing:_textview.verticalSpacing]; + _windowAdjustmentDisabled = NO; + } + + // Restore the window frame to eliminate any rounding glitches from + // intermediate font size changes during the profile switch. + if (!NSIsEmptyRect(savedWindowFrame) && window) { + [window setFrame:savedWindowFrame display:YES]; + } + if ([iTermAdvancedSettingsModel showAutomaticProfileSwitchingBanner]) { [_view showUnobtrusiveMessage:[NSString stringWithFormat:@"Switched to profile “%@”.", underlyingProfile[KEY_NAME]]]; } diff --git a/sources/iTermAdvancedSettingsModel.h b/sources/iTermAdvancedSettingsModel.h index 085d85a2dc..e95717fecc 100644 --- a/sources/iTermAdvancedSettingsModel.h +++ b/sources/iTermAdvancedSettingsModel.h @@ -404,6 +404,7 @@ extern NSString *const iTermAdvancedSettingsDidChange; + (BOOL)shouldSetLCTerminal; + (BOOL)shouldSetTerminfoDirs; + (BOOL)showAutomaticProfileSwitchingBanner; ++ (BOOL)preserveFontSizeOnAutomaticProfileSwitch; + (BOOL)showBlockBoundaries; + (BOOL)showButtonsForSelectedCommand; + (BOOL)showHintsInSplitPaneMenuItems; diff --git a/sources/iTermAdvancedSettingsModel.m b/sources/iTermAdvancedSettingsModel.m index 9d5ec8fb8d..877def767b 100644 --- a/sources/iTermAdvancedSettingsModel.m +++ b/sources/iTermAdvancedSettingsModel.m @@ -621,6 +621,7 @@ + (BOOL)settingIsDeprecated:(NSString *)name { DEFINE_BOOL(focusNewSplitPaneWithFocusFollowsMouse, YES, SECTION_SESSION @"When focus follows mouse is enabled, should new split panes automatically be focused?"); DEFINE_BOOL(NoSyncSuppressRestartSessionConfirmationAlert, NO, SECTION_SESSION @"Suppress restart session confirmation alert.\nDon't ask for a confirmation when manually restarting a session."); DEFINE_BOOL(showAutomaticProfileSwitchingBanner, YES, SECTION_SESSION @"Show a “Switched to profile” message when Automatic Profile Switching activates."); +DEFINE_BOOL(preserveFontSizeOnAutomaticProfileSwitch, YES, SECTION_SESSION @"Preserve font zoom level when Automatic Profile Switching changes profiles."); DEFINE_BOOL(autoLockSessionNameOnEdit, YES, SECTION_SESSION @"Auto-lock session name after editing it."); DEFINE_FLOAT(timeoutForDaemonAttachment, 10, SECTION_SESSION @"How long to wait when trying to attach to an iTerm daemon at startup when restoring windows (in seconds)?"); DEFINE_BOOL(logTimestampsWithPlainText, YES, SECTION_SESSION @"When logging plain text, include timestamps for each line?");