IJPL-217011 rdct: Restore default settings on frontend and backend simultaneously

The "Restore Default Settings..." action is no longer duplicated in remote development. Instead, a custom implementation of the logic restores the default settings on the frontend and backend simultaneously. This applies to a real remote development environment but not Code With Me where the default settings are restored only on the frontend.

GitOrigin-RevId: 5858bc3459efb5395112116c935b08c891538235
This commit is contained in:
Nikita Zaytsev
2025-12-03 12:15:40 +00:00
committed by intellij-monorepo-bot
parent ca0d2bca29
commit a891fa1237
8 changed files with 173 additions and 47 deletions
@@ -23,6 +23,7 @@ title.select.components.to.import=Select Components to Import
restore.default.settings.confirmation.title=Restore Default IDE Settings?
restore.default.settings.confirmation.message=The current settings will be backed up to {0}
restore.default.settings.confirmation.message.controller=The current settings will be backed up to {0} on the frontend and {1} on the backend
restore.default.settings.confirmation.button.restart=Restore and Restart
restore.default.settings.confirmation.button.shutdown=Restore and Shutdown
import.settings.confirmation.button.restart=Import and Restart
@@ -1,46 +0,0 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.configurationStore
import com.intellij.CommonBundle
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.*
import com.intellij.openapi.application.ex.ApplicationEx
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.ui.Messages
import com.intellij.platform.backend.workspace.GlobalWorkspaceModelCache
import java.nio.file.Path
private class RestoreDefaultSettingsAction : DumbAwareAction() {
override fun actionPerformed(e: AnActionEvent) {
if (!confirmRestoreSettings(e, ConfigBackup.getNextBackupPath(PathManager.getConfigDir()))) {
return
}
CustomConfigMigrationOption.StartWithCleanConfig.writeConfigMarkerFile()
GlobalWorkspaceModelCache.getInstance()?.invalidateCaches()
invokeLater {
(ApplicationManager.getApplication() as ApplicationEx).restart(true)
}
}
private fun confirmRestoreSettings(e: AnActionEvent, backupPath: Path?): Boolean {
val restartButtonText =
if (ApplicationManager.getApplication().isRestartCapable)
ConfigurationStoreBundle.message("restore.default.settings.confirmation.button.restart")
else ConfigurationStoreBundle.message("restore.default.settings.confirmation.button.shutdown")
return Messages.YES == Messages.showYesNoDialog(
e.project,
ConfigurationStoreBundle.message("restore.default.settings.confirmation.message", backupPath),
ConfigurationStoreBundle.message("restore.default.settings.confirmation.title"),
restartButtonText,
CommonBundle.getCancelButtonText(), Messages.getWarningIcon()
)
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
}
@@ -0,0 +1,106 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.configurationStore.defaults
import com.intellij.CommonBundle
import com.intellij.configurationStore.ConfigurationStoreBundle
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ConfigBackup
import com.intellij.openapi.application.CustomConfigMigrationOption
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.application.ex.ApplicationEx
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.NlsContexts
import com.intellij.platform.backend.workspace.GlobalWorkspaceModelCache
import com.intellij.util.application
import org.jetbrains.annotations.ApiStatus
/**
* Contains common logic used in the monolith and remote development for restoring the default settings
*/
@ApiStatus.Internal
object DefaultSettingsHelper {
/**
* Performs all the actions necessary to restore the default settings:
*
* - Shows a confirmation dialog
* - Initiates restoring the default settings
* - Restarts the IDE
*
* @param project the project where the confirmation dialog should be shown
*/
fun restoreDefaultSettings(project: Project?) {
if (confirmRestoringDefaultSettings(project)) {
initiateRestoringDefaultSettings()
restart()
}
}
/**
* Shows a confirmation dialog for restoring the default settings
*
* @param project the project where the confirmation dialog should be shown
*/
fun confirmRestoringDefaultSettings(project: Project?): Boolean {
return confirmRestoringDefaultSettingsImpl(
project,
ConfigurationStoreBundle.message("restore.default.settings.confirmation.message", getNextBackupPath())
)
}
/**
* Shows a confirmation dialog for restoring the default settings on the frontend and backend
*
* @param project the project where the confirmation dialog should be shown
* @param remoteBackupPath the path on the backend where a backup will be created
*/
fun confirmRestoringDefaultSettingsOnFrontendAndBackend(project: Project?, remoteBackupPath: String): Boolean {
return confirmRestoringDefaultSettingsImpl(
project,
ConfigurationStoreBundle.message("restore.default.settings.confirmation.message.controller", getNextBackupPath(), remoteBackupPath)
)
}
/**
* Initiates restoring the default settings by creating a marker file and invalidates caches
*/
fun initiateRestoringDefaultSettings() {
CustomConfigMigrationOption.StartWithCleanConfig.writeConfigMarkerFile()
GlobalWorkspaceModelCache.getInstance()?.invalidateCaches()
}
/**
* Restarts the IDE
*
* @param modalityState the modality state in which the IDE will be restarted
*/
fun restart(modalityState: ModalityState = ModalityState.defaultModalityState()) {
application.invokeLater(
{ (ApplicationManager.getApplication() as ApplicationEx).restart(true) },
modalityState
)
}
private fun confirmRestoringDefaultSettingsImpl(project: Project?, @NlsContexts.DialogMessage message: String): Boolean {
val restartButtonText =
if (ApplicationManager.getApplication().isRestartCapable)
ConfigurationStoreBundle.message("restore.default.settings.confirmation.button.restart")
else ConfigurationStoreBundle.message("restore.default.settings.confirmation.button.shutdown")
return Messages.YES == Messages.showYesNoDialog(
project,
message,
ConfigurationStoreBundle.message("restore.default.settings.confirmation.title"),
restartButtonText,
CommonBundle.getCancelButtonText(), Messages.getWarningIcon()
)
}
private fun getNextBackupPath(): String {
return ConfigBackup.getNextBackupPath(PathManager.getOriginalConfigDir()).toString()
}
}
@@ -0,0 +1,25 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.configurationStore.defaults
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.ApiStatus
/**
* Provides an implementation of restoring the default settings
*/
@ApiStatus.Internal
interface DefaultSettingsService {
companion object {
fun getInstance(): DefaultSettingsService = service()
}
/**
* Restores the default settings
*
* @param project the project where the confirmation dialog should be shown
*/
fun restoreDefaultSettings(project: Project?)
}
@@ -0,0 +1,17 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.configurationStore.defaults
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.ApiStatus
/**
* Restores the default settings on the calling side
*/
@ApiStatus.Internal
class DefaultSettingsServiceImpl : DefaultSettingsService {
override fun restoreDefaultSettings(project: Project?) {
DefaultSettingsHelper.restoreDefaultSettings(project)
}
}
@@ -0,0 +1,20 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.configurationStore.defaults
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.remoting.ActionRemoteBehaviorSpecification
import com.intellij.openapi.project.DumbAwareAction
/**
* Restores the default settings. In remote development, this action is updated and performed on the frontend.
*/
private class RestoreDefaultSettingsAction : DumbAwareAction(), ActionRemoteBehaviorSpecification.Frontend {
override fun actionPerformed(e: AnActionEvent) {
DefaultSettingsService.getInstance().restoreDefaultSettings(e.project)
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
}
@@ -2029,6 +2029,9 @@
<registryKey key="ide.suppress.low.memory.notifications.when.dumb" defaultValue="false"
description="Disables Low Memory notifications during indexing for the sake of less false-positive detection for users" />
<configFolderChangedListener implementation="com.intellij.configurationStore.ComponentStoreImplReloadListener"/>
<applicationService serviceInterface="com.intellij.configurationStore.defaults.DefaultSettingsService"
serviceImplementation="com.intellij.configurationStore.defaults.DefaultSettingsServiceImpl" />
</extensions>
<applicationListeners>
@@ -516,7 +516,7 @@
<action id="ImportSettings" class="com.intellij.configurationStore.ImportSettingsAction"/>
<action id="ExportSettings" class="com.intellij.configurationStore.ExportSettingsAction"/>
<separator/>
<action id="RestoreDefaultSettings" class="com.intellij.configurationStore.RestoreDefaultSettingsAction"/>
<action id="RestoreDefaultSettings" class="com.intellij.configurationStore.defaults.RestoreDefaultSettingsAction"/>
</group>
<group id="FileOtherSettingsGroup" class="com.intellij.ide.actions.SmartPopupActionGroup">
<action id="TemplateProjectProperties" class="com.intellij.ide.actions.TemplateProjectPropertiesAction"/>