diff --git a/platform/ide-core/api-dump.txt b/platform/ide-core/api-dump.txt index 52b707118dd6..82ba62836bbc 100644 --- a/platform/ide-core/api-dump.txt +++ b/platform/ide-core/api-dump.txt @@ -844,6 +844,7 @@ c:com.intellij.openapi.options.ConfigurationException - setQuickFix(com.intellij.openapi.options.ConfigurationQuickFix):V - setQuickFix(java.lang.Runnable):V - withHtmlMessage():com.intellij.openapi.options.ConfigurationException +com.intellij.openapi.options.NoAutomaticReset f:com.intellij.openapi.options.OptionsBundle - com.intellij.DynamicBundle com.intellij.openapi.options.SearchableConfigurable diff --git a/platform/ide-core/src/com/intellij/openapi/options/NoAutomaticReset.kt b/platform/ide-core/src/com/intellij/openapi/options/NoAutomaticReset.kt new file mode 100644 index 000000000000..cd085d193910 --- /dev/null +++ b/platform/ide-core/src/com/intellij/openapi/options/NoAutomaticReset.kt @@ -0,0 +1,16 @@ +// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.openapi.options + +import org.jetbrains.annotations.ApiStatus + +/** + * A marker interface for [Configurable]s that require an explicit user action outside the IDE + * (such as browser-based authorization or a native file picker) before their state can be reset. + * + * When a settings window regains focus, the Settings editor normally resets any configurable that + * was unmodified when focus was lost but now reports `isModified() == true` (e.g. due to a + * background/external change). Implementing this interface opts the configurable out of that + * automatic reset, ensuring that ongoing external interactions are not interrupted. + */ +@ApiStatus.OverrideOnly +interface NoAutomaticReset diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java index 55f91ff22b49..67a8b4e9b1e8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.UiDataProvider; import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.BackedByPersistentState; +import com.intellij.openapi.options.NoAutomaticReset; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; import com.intellij.openapi.options.ConfigurationException; @@ -72,7 +73,6 @@ import javax.swing.JPanel; import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Component; -import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -704,9 +704,14 @@ public final class SettingsEditor extends AbstractEditor implements UiDataProvid if (isModified == null) return; LOG.debug("resetUnmodifiedOnWindowFocus: current=" + current.getDisplayName() + ", leaveState=" + leaveState + ", isModified=" + isModified); if (leaveState == Boolean.FALSE && isModified) { - LOG.warn("resetUnmodifiedOnWindowFocus: resetting " + current.getDisplayName()); - current.reset(); - filter.context.fireReset(current); + if (ConfigurableWrapper.cast(NoAutomaticReset.class, current) != null) { + LOG.debug("resetUnmodifiedOnWindowFocus: skipping reset for " + current.getDisplayName() + " (NoAutomaticReset)"); + } + else { + LOG.warn("resetUnmodifiedOnWindowFocus: resetting " + current.getDisplayName()); + current.reset(); + filter.context.fireReset(current); + } } detectExternalChangesOnFocusGain(); }