@@ -44,7 +44,8 @@ import { ILanguageService } from '../../../../editor/common/languages/language.j
4444import { mainWindow } from '../../../../base/browser/window.js' ;
4545import { generateColorThemeCSS } from './colorThemeCss.js' ;
4646import { INotificationService , Severity } from '../../../../platform/notification/common/notification.js' ;
47- import { ICommandService } from '../../../../platform/commands/common/commands.js' ;
47+ import { IHostService } from '../../host/browser/host.js' ;
48+ import { toAction } from '../../../../base/common/actions.js' ;
4849
4950// implementation
5051
@@ -114,12 +115,11 @@ export class WorkbenchThemeService extends Disposable implements IWorkbenchTheme
114115 @IUserDataInitializationService private readonly userDataInitializationService : IUserDataInitializationService ,
115116 @ILanguageService private readonly languageService : ILanguageService ,
116117 @INotificationService private readonly notificationService : INotificationService ,
117- @ICommandService private readonly commandService : ICommandService
118+ @IHostService private readonly hostService : IHostService
118119 ) {
119120 super ( ) ;
120121 this . container = layoutService . mainContainer ;
121- const isNewUser = this . storageService . isNew ( StorageScope . APPLICATION ) ;
122- this . settings = new ThemeConfiguration ( configurationService , hostColorService , isNewUser ) ;
122+ this . settings = new ThemeConfiguration ( configurationService , hostColorService ) ;
123123
124124 this . colorThemeRegistry = this . _register ( new ThemeRegistry ( colorThemesExtPoint , ColorThemeData . fromExtensionTheme ) ) ;
125125 this . colorThemeWatcher = this . _register ( new ThemeFileWatcher ( fileService , environmentService , this . reloadCurrentColorTheme . bind ( this ) ) ) ;
@@ -146,6 +146,7 @@ export class WorkbenchThemeService extends Disposable implements IWorkbenchTheme
146146 // themes are loaded asynchronously, we need to initialize
147147 // a color theme document with good defaults until the theme is loaded
148148 let themeData : ColorThemeData | undefined = ColorThemeData . fromStorageData ( this . storageService ) ;
149+ const previousColorThemeSetting = themeData ?. settingsId ;
149150 const colorThemeSetting = this . settings . colorTheme ;
150151 if ( themeData && colorThemeSetting !== themeData . settingsId ) {
151152 themeData = undefined ;
@@ -179,7 +180,7 @@ export class WorkbenchThemeService extends Disposable implements IWorkbenchTheme
179180 this . installConfigurationListener ( ) ;
180181 this . installPreferredSchemeListener ( ) ;
181182 this . installRegistryListeners ( ) ;
182- this . initialize ( ) . catch ( errors . onUnexpectedError ) ;
183+ this . initialize ( previousColorThemeSetting ) . catch ( errors . onUnexpectedError ) ;
183184 } ) ;
184185
185186 const codiconStyleSheet = createStyleSheet ( ) ;
@@ -195,7 +196,7 @@ export class WorkbenchThemeService extends Disposable implements IWorkbenchTheme
195196 delayer . schedule ( ) ;
196197 }
197198
198- private async initialize ( ) : Promise < [ IWorkbenchColorTheme | null , IWorkbenchFileIconTheme | null , IWorkbenchProductIconTheme | null ] > {
199+ private async initialize ( themePreviousSettingsId : string | undefined ) : Promise < [ IWorkbenchColorTheme | null , IWorkbenchFileIconTheme | null , IWorkbenchProductIconTheme | null ] > {
199200 const extDevLocs = this . environmentService . extensionDevelopmentLocationURI ;
200201 const extDevLoc = extDevLocs && extDevLocs . length === 1 ? extDevLocs [ 0 ] : undefined ; // in dev mode, switch to a theme provided by the extension under dev.
201202
@@ -246,34 +247,64 @@ export class WorkbenchThemeService extends Disposable implements IWorkbenchTheme
246247
247248
248249 this . migrateColorThemeSettings ( ) ;
249- await this . migrateAutoDetectColorScheme ( ) ;
250250 const result = await Promise . all ( [ initializeColorTheme ( ) , initializeFileIconTheme ( ) , initializeProductIconTheme ( ) ] ) ;
251- this . showNewDefaultThemeNotification ( ) ;
251+ await this . showNewDefaultThemeNotification ( themePreviousSettingsId ) ;
252252 return result ;
253253 }
254254
255255 private static readonly NEW_THEME_NOTIFICATION_KEY = 'workbench.newDefaultThemeNotification' ;
256256
257- private showNewDefaultThemeNotification ( ) : void {
258- const newDefaultThemes = new Set ( [ ThemeSettingDefaults . COLOR_THEME_DARK , ThemeSettingDefaults . COLOR_THEME_LIGHT ] ) ;
259- if ( newDefaultThemes . has ( this . currentColorTheme . settingsId ) ) {
260- return ; // already using a new default theme
261- }
257+ private async showNewDefaultThemeNotification ( previousSettingsId : string | undefined ) : Promise < void > {
262258 if ( this . storageService . getBoolean ( WorkbenchThemeService . NEW_THEME_NOTIFICATION_KEY , StorageScope . APPLICATION ) ) {
263259 return ; // already shown
264260 }
265-
266- const handle = this . notificationService . prompt (
267- Severity . Info ,
268- nls . localize ( 'newDefaultTheme' , "New default themes are available for VS Code." ) ,
269- [ {
270- label : nls . localize ( 'tryNewTheme' , "Try Them Out" ) ,
271- run : ( ) => this . commandService . executeCommand ( 'workbench.action.tryNewDefaultThemes' )
272- } ]
273- ) ;
274- this . _register ( Event . once ( handle . onDidClose ) ( ( ) => {
261+ if ( ! ( await this . hostService . hadLastFocus ( ) ) || this . environmentService . isSessionsWindow ) {
262+ return ;
263+ }
264+ try {
265+ if ( ! this . settings . isDefaultColorTheme ( ) || ! previousSettingsId ) {
266+ return ;
267+ }
268+ previousSettingsId = migrateThemeSettingsId ( previousSettingsId ) ;
269+ if ( ! [ 'Dark Modern' , 'Light Modern' ] . includes ( previousSettingsId ) ) {
270+ return ;
271+ }
272+ if ( ! [ ThemeSettingDefaults . COLOR_THEME_DARK , ThemeSettingDefaults . COLOR_THEME_LIGHT ] . includes ( this . settings . colorTheme ) ) {
273+ return ;
274+ }
275+ } finally {
276+ // remeber to not show the dialog again
275277 this . storageService . store ( WorkbenchThemeService . NEW_THEME_NOTIFICATION_KEY , true , StorageScope . APPLICATION , StorageTarget . USER ) ;
276- } ) ) ;
278+ }
279+
280+ const keepTheme = await new Promise ( resolve => {
281+ this . notificationService . prompt (
282+ Severity . Info ,
283+ nls . localize ( { key : 'themeUpdatedNotification' , comment : [ '{0} is the name of the new default theme' ] } , "VS Code has a new default theme: '{0}'." , this . getColorTheme ( ) . label ) ,
284+ [
285+ toAction ( {
286+ id : 'themeUpdated.tryItOut' ,
287+ label : nls . localize ( 'tryNewTheme' , "Keep It" ) ,
288+ run : ( ) => resolve ( true )
289+ } ) ,
290+ toAction ( {
291+ id : 'themeUpdated.noThanks' ,
292+ label : nls . localize ( 'noThanks' , "No Thanks" ) ,
293+ run : ( ) => resolve ( false )
294+ } )
295+ ] ,
296+ {
297+ onCancel : ( ) => resolve ( false )
298+ }
299+ ) ;
300+ } ) ;
301+
302+ if ( ! keepTheme ) {
303+ const previousTheme = this . colorThemeRegistry . findThemeBySettingsId ( previousSettingsId ) ;
304+ if ( previousTheme ) {
305+ this . setColorTheme ( previousTheme . id , 'auto' ) ;
306+ }
307+ }
277308 }
278309
279310 /**
@@ -305,29 +336,6 @@ export class WorkbenchThemeService extends Disposable implements IWorkbenchTheme
305336 }
306337 }
307338
308- /**
309- * For new users who haven't explicitly configured `window.autoDetectColorScheme`,
310- * persist `true` so that auto-detect becomes the default going forward.
311- */
312- private async migrateAutoDetectColorScheme ( ) : Promise < void > {
313- if ( ! this . storageService . isNew ( StorageScope . APPLICATION ) ) {
314- return ;
315- }
316-
317- // Ensure that user data (including synced settings) has finished initializing
318- // so we do not overwrite values that arrive via settings sync.
319- await this . userDataInitializationService . whenInitializationFinished ( ) ;
320-
321- const inspection = this . configurationService . inspect < boolean > ( ThemeSettings . DETECT_COLOR_SCHEME ) ;
322-
323- // Treat any of userValue, userLocalValue, or userRemoteValue as an explicit configuration.
324- if ( inspection . userValue === undefined
325- && inspection . userLocalValue === undefined
326- && inspection . userRemoteValue === undefined ) {
327- await this . configurationService . updateValue ( ThemeSettings . DETECT_COLOR_SCHEME , true , ConfigurationTarget . USER ) ;
328- }
329- }
330-
331339 private installConfigurationListener ( ) {
332340 this . _register ( this . configurationService . onDidChangeConfiguration ( e => {
333341 if ( e . affectsConfiguration ( ThemeSettings . COLOR_THEME )
0 commit comments