diff --git a/platform/core-api/src/com/intellij/DynamicBundle.java b/platform/core-api/src/com/intellij/DynamicBundle.java index 1e37224ce10e..e3a7ed13289a 100644 --- a/platform/core-api/src/com/intellij/DynamicBundle.java +++ b/platform/core-api/src/com/intellij/DynamicBundle.java @@ -78,7 +78,7 @@ public class DynamicBundle extends AbstractBundle { @NotNull Locale locale, @NotNull BiFunction bundleResolver) { Path bundlePath = FileSystems.getDefault().getPath(FileUtil.toCanonicalPath(defaultPath, '.')); - ClassLoader pluginClassLoader = DefaultBundleService.isDefaultBundle() ? null: LocalizationUtil.INSTANCE.getPluginClassLoader(bundleClassLoader); + ClassLoader pluginClassLoader = DefaultBundleService.isDefaultBundle() ? null: LocalizationUtil.INSTANCE.getPluginClassLoader(bundleClassLoader, locale); List paths = LocalizationUtil.INSTANCE.getLocalizedPaths(bundlePath, locale); Map bundleOrderMap = new HashMap<>(); if (pluginClassLoader != null) { @@ -267,6 +267,17 @@ public class DynamicBundle extends AbstractBundle { .computeIfAbsent(pathToBundle, __ -> resolveResourceBundle(loader, pathToBundle, locale)); } + @ApiStatus.Internal + public static @NotNull ResourceBundle getResourceBundleLocalized(@NotNull ClassLoader loader, @NotNull @NonNls String pathToBundle, @NotNull Locale locale) { + ResourceBundle bundle = (DefaultBundleService.isDefaultBundle() ? ourDefaultCache : ourCache) + .computeIfAbsent(loader, __ -> CollectionFactory.createConcurrentSoftValueMap()) + .get(pathToBundle); + if (bundle != null && bundle.getLocale().equals(locale)) { + return bundle; + } + return resolveResourceBundle(loader, pathToBundle, locale); + } + public static @Nullable ResourceBundle getPluginBundle(@NotNull PluginDescriptor pluginDescriptor) { ClassLoader classLoader = pluginDescriptor.getPluginClassLoader(); String baseName = pluginDescriptor.getResourceBundleBaseName(); diff --git a/platform/core-api/src/com/intellij/l10n/LocalizationStateService.kt b/platform/core-api/src/com/intellij/l10n/LocalizationStateService.kt index 27b0d21cd832..5d3ec6168279 100644 --- a/platform/core-api/src/com/intellij/l10n/LocalizationStateService.kt +++ b/platform/core-api/src/com/intellij/l10n/LocalizationStateService.kt @@ -18,4 +18,5 @@ interface LocalizationStateService { fun getSelectedLocale(): String fun setSelectedLocale(locale: String) + fun getLastSelectedLocale(): String } \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/l10n/LocalizationUtil.kt b/platform/core-api/src/com/intellij/l10n/LocalizationUtil.kt index 141c26f0a552..fdaad1d9949e 100644 --- a/platform/core-api/src/com/intellij/l10n/LocalizationUtil.kt +++ b/platform/core-api/src/com/intellij/l10n/LocalizationUtil.kt @@ -54,8 +54,9 @@ object LocalizationUtil { @Internal @JvmOverloads - fun getPluginClassLoader(defaultLoader: ClassLoader? = null): ClassLoader? { - val langBundle = findLanguageBundle() ?: return null + fun getPluginClassLoader(defaultLoader: ClassLoader? = null, locale: Locale = getLocale()): ClassLoader? { + if (locale == Locale.ENGLISH || locale == Locale.ROOT) return null + val langBundle = findLanguageBundle(locale) ?: return null return langBundle.pluginDescriptor?.classLoader ?: defaultLoader } diff --git a/platform/lang-impl/src/com/intellij/lang/LocalizationStateServiceImpl.kt b/platform/lang-impl/src/com/intellij/lang/LocalizationStateServiceImpl.kt index 03beeb455e31..b02dd3d7a698 100644 --- a/platform/lang-impl/src/com/intellij/lang/LocalizationStateServiceImpl.kt +++ b/platform/lang-impl/src/com/intellij/lang/LocalizationStateServiceImpl.kt @@ -45,6 +45,10 @@ internal class LocalizationStateServiceImpl : LocalizationStateService, Persiste return localizationState.selectedLocale } + override fun getLastSelectedLocale(): String { + return localizationState.lastSelectedLocale + } + override fun setSelectedLocale(locale: String) { localizationState.lastSelectedLocale = localizationState.selectedLocale localizationState.selectedLocale = locale diff --git a/platform/platform-api/api-dump-unreviewed.txt b/platform/platform-api/api-dump-unreviewed.txt index 8bc1c3af24c8..51de168f1d2e 100644 --- a/platform/platform-api/api-dump-unreviewed.txt +++ b/platform/platform-api/api-dump-unreviewed.txt @@ -655,6 +655,7 @@ f:com.intellij.ide.Prefs - sf:NOT_SET:com.intellij.ide.Region - externalName():java.lang.String - s:fromExternalName(java.lang.String):com.intellij.ide.Region +- getDisplayKey():java.lang.String - getDisplayName():java.lang.String - getDisplayOrdinal():I - s:valueOf(java.lang.String):com.intellij.ide.Region diff --git a/platform/platform-api/resources/messages/LanguageAndRegionBundle.properties b/platform/platform-api/resources/messages/LanguageAndRegionBundle.properties new file mode 100644 index 000000000000..738db5fc03dd --- /dev/null +++ b/platform/platform-api/resources/messages/LanguageAndRegionBundle.properties @@ -0,0 +1,17 @@ +title.language.and.region=Language and Region +description.language.and.region=

Select a region to ensure that licensing, JetBrains Marketplace, and other region-specific features and links work correctly. See the documentation for details

+ +language.en=English +language.zhCN=Chinese (Simplified) \u4E2D\u6587\u8BED\u8A00\u5305 +language.ja=Japanese \u65E5\u672C\u8A9E +language.ko=Korean \uD55C\uAD6D\uC778 + +title.region.africa=Africa +title.region.america=Americas +title.region.asia=Asia Pacific (except for China Mainland) +title.region.china=China Mainland +title.region.europe=Europe +title.region.not_set=Not specified +title.region.not.set.label=Region is not specified + +button.next=Next \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ide/LanguageAndRegionBundle.java b/platform/platform-api/src/com/intellij/ide/LanguageAndRegionBundle.java new file mode 100644 index 000000000000..16acec3ef929 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/LanguageAndRegionBundle.java @@ -0,0 +1,26 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.ide; + +import com.intellij.DynamicBundle; +import org.jetbrains.annotations.*; + +import java.util.function.Supplier; + +@ApiStatus.Internal +public final class LanguageAndRegionBundle { + + public static final @NonNls String BUNDLE_FQN = "messages.LanguageAndRegionBundle"; + private static final DynamicBundle BUNDLE = new DynamicBundle(LanguageAndRegionBundle.class, BUNDLE_FQN); + + private LanguageAndRegionBundle() { } + + public static @Nls @NotNull String message(@PropertyKey(resourceBundle = BUNDLE_FQN) @NotNull String key, + @Nullable Object @NotNull ... params) { + return BUNDLE.getMessage(key, params); + } + + public static @NotNull Supplier<@Nls @NotNull String> messagePointer(@PropertyKey(resourceBundle = BUNDLE_FQN) @NotNull String key, + @Nullable Object @NotNull ... params) { + return BUNDLE.getLazyMessage(key, params); + } +} diff --git a/platform/platform-api/src/com/intellij/ide/Region.java b/platform/platform-api/src/com/intellij/ide/Region.java index 923ba4ddd3de..660d5b96f9ea 100644 --- a/platform/platform-api/src/com/intellij/ide/Region.java +++ b/platform/platform-api/src/com/intellij/ide/Region.java @@ -35,6 +35,10 @@ public enum Region { return IdeBundle.message(displayKey); } + public String getDisplayKey() { + return displayKey; + } + public int getDisplayOrdinal() { return displayOrdinal; } diff --git a/platform/platform-impl/api-dump-unreviewed.txt b/platform/platform-impl/api-dump-unreviewed.txt index 4daf35d10982..f38ee3816222 100644 --- a/platform/platform-impl/api-dump-unreviewed.txt +++ b/platform/platform-impl/api-dump-unreviewed.txt @@ -8781,6 +8781,10 @@ f:com.intellij.ide.trustedProjects.impl.UntrustedProjectNotificationProvider - com.intellij.ui.EditorNotificationProvider - ():V - collectNotificationData(com.intellij.openapi.project.Project,com.intellij.openapi.vfs.VirtualFile):java.util.function.Function +f:com.intellij.ide.ui.ButtonPanel +- javax.swing.JPanel +- (javax.swing.JButton):V +- f:getButton():javax.swing.JButton f:com.intellij.ide.ui.ColorBlindnessInternalAction - com.intellij.openapi.project.DumbAwareAction - ():V diff --git a/platform/platform-impl/src/com/intellij/ide/ui/ButtonPanel.kt b/platform/platform-impl/src/com/intellij/ide/ui/ButtonPanel.kt new file mode 100644 index 000000000000..20308aad363c --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/ButtonPanel.kt @@ -0,0 +1,61 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.ide.ui + +import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI +import com.intellij.ide.ui.laf.darcula.ui.OnboardingDialogButtons.BUTTON_HOVER_BORDER_COLOR +import com.intellij.ide.ui.laf.darcula.ui.OnboardingDialogButtons.DEFAULT_BUTTON_HOVER_BORDER_COLOR +import com.intellij.util.ui.JBDimension +import com.intellij.util.ui.JBSwingUtilities +import com.intellij.util.ui.JBUI +import org.jetbrains.annotations.ApiStatus +import org.jetbrains.annotations.Nls +import java.awt.BorderLayout +import java.awt.Graphics +import java.awt.event.ActionEvent +import java.awt.event.MouseAdapter +import java.awt.event.MouseEvent +import javax.swing.* + + +class ButtonPanel(val button: JButton) : JPanel(BorderLayout(0, 0)) { + init { + val buttonGap = 4 + preferredSize = JBDimension(280, 40 + (buttonGap * 2)) + isOpaque = false + add(button) + border = JBUI.Borders.empty(buttonGap, 0) + } +} + +@ApiStatus.Internal +internal fun createButton(isDefault: Boolean, @Nls text: String, icon: Icon? = null, onClick: (JButton) -> Unit): JButton { + val btn = object : JButton() { + override fun getComponentGraphics(g: Graphics?): Graphics { + return JBSwingUtilities.runGlobalCGTransform(this, super.getComponentGraphics(g)) + } + } + btn.putClientProperty("ActionToolbar.smallVariant", true) + btn.putClientProperty(DarculaButtonUI.DEFAULT_STYLE_KEY, isDefault) + btn.putClientProperty(DarculaButtonUI.AVOID_EXTENDING_BORDER_GRAPHICS, true) + val listener: MouseAdapter = object : MouseAdapter() { + override fun mouseEntered(e: MouseEvent) { + btn.putClientProperty("JButton.borderColor", if (isDefault) DEFAULT_BUTTON_HOVER_BORDER_COLOR else BUTTON_HOVER_BORDER_COLOR) + btn.repaint() + } + + override fun mouseExited(e: MouseEvent) { + btn.putClientProperty("JButton.borderColor", null) + btn.repaint() + } + } + btn.addMouseMotionListener(listener) + btn.addMouseListener(listener) + btn.action = object : AbstractAction(text, null) { + override fun actionPerformed(e: ActionEvent) { + onClick.invoke(btn) + } + } + btn.icon = icon + btn.horizontalTextPosition = SwingConstants.LEFT + return btn +} diff --git a/platform/platform-impl/src/com/intellij/ide/ui/LanguageAndRegionDialog.kt b/platform/platform-impl/src/com/intellij/ide/ui/LanguageAndRegionDialog.kt new file mode 100644 index 000000000000..e1ab1b6b6ecc --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/LanguageAndRegionDialog.kt @@ -0,0 +1,176 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.ide.ui + +import com.intellij.DynamicBundle +import com.intellij.icons.AllIcons +import com.intellij.ide.LanguageAndRegionBundle +import com.intellij.ide.Region +import com.intellij.ide.RegionSettings +import com.intellij.l10n.LocalizationStateService +import com.intellij.openapi.application.impl.RawSwingDispatcher +import com.intellij.openapi.ui.DialogWrapper +import com.intellij.openapi.ui.popup.JBPopupFactory +import com.intellij.ui.awt.RelativePoint +import com.intellij.ui.components.JBLabel +import com.intellij.ui.components.panels.VerticalLayout +import com.intellij.ui.dsl.builder.Align +import com.intellij.ui.dsl.builder.panel +import com.intellij.util.ui.JBDimension +import com.intellij.util.ui.JBFont +import com.intellij.util.ui.JBSwingUtilities +import com.intellij.util.ui.JBUI +import kotlinx.coroutines.withContext +import org.jetbrains.annotations.Nls +import java.awt.Dimension +import java.awt.Graphics +import java.util.* +import javax.swing.* +import javax.swing.border.Border + +private val localeMappings = mapOf(Locale.CHINA to listOf("zh-CN", "CN"), Locale.JAPANESE to listOf("ja", "JP"), + Locale.KOREAN to listOf("ko", "KR", "KP")) + +private class LanguageAndRegionDialog(private var selectedLanguage: Locale) : DialogWrapper(null, null, true, IdeModalityType.IDE, false) { + private var region = getRegionForLocale(selectedLanguage) + private val TOP_BOTTOM_BORDERS = 4 + private val LEFT_RIGHT_BORDERS = 16 + init { + isResizable = false + init() + } + + override fun createCenterPanel(): JComponent { + val centerPanel = object : JPanel(VerticalLayout(JBUI.scale(10), SwingConstants.CENTER)) { + override fun getComponentGraphics(g: Graphics?): Graphics { + return JBSwingUtilities.runGlobalCGTransform(this, super.getComponentGraphics(g)) + } + }.apply { + isOpaque = false + border = JBUI.Borders.empty() + } + centerPanel.preferredSize = JBDimension(640, 470) + val header = JLabel(getMessageBundle().getString("title.language.and.region")).apply { + font = JBFont.h1() + alignmentX = JLabel.CENTER_ALIGNMENT + } + + centerPanel.add(panel { + row { + cell(header).align(Align.CENTER) + } + row { + text(getMessageBundle().getString("description.language.and.region")) + } + }.withPreferredWidth(350), VerticalLayout.CENTER) + + val buttonsPanel = JPanel(VerticalLayout(JBUI.scale(3), SwingConstants.CENTER)) + buttonsPanel.add(getLanguageButton()) + buttonsPanel.add(getRegionButton()) + buttonsPanel.add(getNextButton()) + centerPanel.add(buttonsPanel, VerticalLayout.CENTER) + return centerPanel + } + + private fun getLanguageButton() = + ButtonPanel(createButton(false, getLocaleName(selectedLanguage), AllIcons.General.ChevronDown) { createLanguagePopup(it) }) + + private fun getRegionButton() = ButtonPanel( + createButton(false, getRegionName(region), AllIcons.General.ChevronDown) { createRegionPopup(it) }) + + private fun getNextButton() = ButtonPanel(createButton(true, getMessageBundle().getString("button.next"), null) { this.doOKAction() }) + + override fun createContentPaneBorder(): Border { + return JBUI.Borders.empty() + } + + private fun createRegionPopup(button: JButton) { + val regions = Region.entries.sortedBy { it.displayOrdinal } + val popup = JBPopupFactory.getInstance() + .createPopupChooserBuilder(regions) + .setRequestFocus(true) + .setRenderer { _, value, _, _, _ -> + if (value == null) return@setRenderer JLabel() + val label = JBLabel(getRegionName(value), null, SwingConstants.LEFT) + label.border = JBUI.Borders.empty(TOP_BOTTOM_BORDERS, LEFT_RIGHT_BORDERS) + return@setRenderer label + } + .setMinSize(Dimension(280, 100)) + .setResizable(false) + .setCancelOnClickOutside(true) + .setItemChosenCallback { + region = it + button.text = getRegionLabel(it) + } + .createPopup() + popup.show(RelativePoint.getSouthWestOf(button)) + } + + private fun createLanguagePopup(button: JButton) { + val locales = mutableListOf(Locale.ENGLISH) + localeMappings.keys + val popup = JBPopupFactory.getInstance() + .createPopupChooserBuilder(locales) + .setRequestFocus(true) + .setRenderer { _, value, _, _, _ -> + if (value == null) return@setRenderer JLabel() + val label = JBLabel(getLocaleName(value), null, SwingConstants.LEFT) + label.border = JBUI.Borders.empty(TOP_BOTTOM_BORDERS, LEFT_RIGHT_BORDERS) + return@setRenderer label + } + .setMinSize(Dimension(280, 100)) + .setResizable(false) + .setCancelOnClickOutside(true) + .setItemChosenCallback { + selectedLanguage = it + contentPanel.removeAll() + init() + contentPanel.revalidate() + contentPanel.repaint() + } + .createPopup() + popup.show(RelativePoint.getSouthWestOf(button)) + } + + private fun getRegionForLocale(locale: Locale): Region { + return when (locale) { + Locale.CHINA -> Region.CHINA + Locale.JAPANESE, Locale.KOREAN -> Region.APAC + else -> Region.NOT_SET + } + } + + @Nls + private fun getLocaleName(locale: Locale): String { + return getMessageBundle().getString("language." + locale.toLanguageTag().replace("-", "")) + } + + @Nls + private fun getRegionName(region: Region): String { + return getMessageBundle().getString(region.displayKey) + } + + private fun getRegionLabel(region: Region): String { + return getMessageBundle().getString(if (region == Region.NOT_SET) "title.region.not.set.label" else region.displayKey) + } + + + override fun doOKAction() { + LocalizationStateService.getInstance()?.setSelectedLocale(selectedLanguage.toLanguageTag()) + RegionSettings.setRegion(region) + super.doOKAction() + } + + private fun getMessageBundle() = DynamicBundle.getResourceBundleLocalized(this::class.java.classLoader, LanguageAndRegionBundle.BUNDLE_FQN, selectedLanguage) +} + + +internal fun getLanguageAndRegionDialogIfNeeded(): (suspend () -> Boolean)? { + val locale = Locale.getDefault() + val matchingLanguage = localeMappings.values.flatten().find { locale.toLanguageTag().contains(it) } + if (matchingLanguage == null) return null + return suspend { + withContext(RawSwingDispatcher) { + val matchingLocale = localeMappings.entries.find { it.value.contains(matchingLanguage) }!!.key + LanguageAndRegionDialog(matchingLocale).showAndGet() + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/PreCachedDataContext.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/PreCachedDataContext.java index a191d467eac8..2f0036cf6e13 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/PreCachedDataContext.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/PreCachedDataContext.java @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.actionSystem.impl; +import com.intellij.diagnostic.LoadingState; import com.intellij.ide.ActivityTracker; import com.intellij.ide.DataManager; import com.intellij.ide.ProhibitAWTEvents; @@ -183,7 +184,7 @@ class PreCachedDataContext implements AsyncDataContext, UserDataHolder, AnAction boolean isEDT = EDT.isCurrentThreadEdt(); boolean noRulesSection = isEDT && ActionUpdater.Companion.isNoRulesInEDTSection(); - boolean rulesSuppressed = isEDT && Registry.is("actionSystem.update.actions.suppress.dataRules.on.edt"); + boolean rulesSuppressed = isEDT && LoadingState.COMPONENTS_LOADED.isOccurred() && Registry.is("actionSystem.update.actions.suppress.dataRules.on.edt"); boolean rulesAllowed = !CommonDataKeys.PROJECT.is(dataId) && !rulesSuppressed && !noRulesSection; Object answer = getDataInner(dataId, rulesAllowed, !noRulesSection); diff --git a/platform/platform-impl/src/com/intellij/platform/ide/bootstrap/ApplicationLoader.kt b/platform/platform-impl/src/com/intellij/platform/ide/bootstrap/ApplicationLoader.kt index b5a31a10cf62..75df44f34aa5 100644 --- a/platform/platform-impl/src/com/intellij/platform/ide/bootstrap/ApplicationLoader.kt +++ b/platform/platform-impl/src/com/intellij/platform/ide/bootstrap/ApplicationLoader.kt @@ -16,16 +16,14 @@ import com.intellij.ide.plugins.PluginSet import com.intellij.ide.plugins.marketplace.statistics.PluginManagerUsageCollector import com.intellij.ide.plugins.marketplace.statistics.enums.DialogAcceptanceResultEnum import com.intellij.ide.plugins.saveBundledPluginsState -import com.intellij.ide.ui.IconMapLoader -import com.intellij.ide.ui.LafManager -import com.intellij.ide.ui.NotRoamableUiSettings -import com.intellij.ide.ui.UISettings +import com.intellij.ide.ui.* import com.intellij.ide.ui.customization.CustomActionsSchema import com.intellij.ide.ui.html.initGlobalStyleSheet import com.intellij.ide.ui.laf.LafManagerImpl import com.intellij.idea.AppExitCodes import com.intellij.idea.AppMode import com.intellij.idea.IdeStarter +import com.intellij.l10n.LocalizationStateService import com.intellij.openapi.actionSystem.ActionManager import com.intellij.openapi.actionSystem.impl.ActionConfigurationCustomizer import com.intellij.openapi.application.* @@ -117,6 +115,15 @@ internal suspend fun loadApp( } } + val languageAndRegionTaskDeferred: Deferred<(suspend () -> Boolean)?>? = if (AppMode.isHeadless() || euaDocumentDeferred.await() == null) { + null + } + else { + async(CoroutineName("language and region")) { + getLanguageAndRegionDialogIfNeeded() + } + } + initServiceContainerJob.join() val initTelemetryJob = launch(CoroutineName("opentelemetry configuration")) { @@ -187,9 +194,20 @@ internal suspend fun loadApp( ) if (!app.isHeadlessEnvironment) { - euaTaskDeferred?.await()?.let { + languageAndRegionTaskDeferred?.await()?.let { cssInit?.join() - it() + val languageOkPressed = it() + euaTaskDeferred?.await()?.let { + it() + if (languageOkPressed) { + val localizationStateService = LocalizationStateService.getInstance() ?: return@let + if (localizationStateService.getLastSelectedLocale() != localizationStateService.getSelectedLocale()) { + preloadJob.cancel() + applicationStarter.cancel() + ApplicationManager.getApplication().restart() + } + } + } } } diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java index 431de4ba6170..ffb9f77f3570 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ui; +import com.intellij.diagnostic.LoadingState; import com.intellij.idea.AppMode; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; @@ -62,7 +63,7 @@ public abstract class AbstractExpandableItemsHandler bar.setOpaque(true)); } @@ -1650,7 +1650,7 @@ public class AbstractPopup implements JBPopup, ScreenAreaConsumer, AlignedPopup private PopupComponentFactory.PopupType getMostSuitablePopupType() { boolean forceDialog = myMayBeParent || SystemInfo.isMac && !(myOwner instanceof IdeFrame) && myOwner.isShowing(); - if (Registry.is("allow.dialog.based.popups")) { + if (LoadingState.COMPONENTS_LOADED.isOccurred() && Registry.is("allow.dialog.based.popups")) { boolean noFocus = !myFocusable || !myRequestFocus; boolean cannotBeDialog = noFocus; // && SystemInfo.isXWindow