IJPL-194950 Get rid of restart when switching island themes

GitOrigin-RevId: a3e60a4ef67bd3b1d2699512279a52affd1dc761
This commit is contained in:
Alexander Lobas
2025-07-16 13:11:27 +00:00
committed by intellij-monorepo-bot
parent 37aae16170
commit 168ff042b7
15 changed files with 304 additions and 54 deletions
@@ -523,6 +523,7 @@ private class ProjectWindowCustomizerListener : ProjectActivity, UISettingsListe
}
override fun uiSettingsChanged(uiSettings: UISettings) {
InternalUICustomization.getInstance()?.updateBackgroundPainter()
ProjectWindowCustomizerService.getInstance().update(uiSettings.differentiateProjects)
}
}
@@ -5,6 +5,7 @@ import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.LafManagerListener;
import com.intellij.ide.ui.TargetUIType;
import com.intellij.ide.ui.ThemeListProvider;
import com.intellij.ide.ui.laf.UIThemeLookAndFeelInfo;
import com.intellij.ide.ui.laf.UiThemeProviderListManager;
@@ -43,6 +44,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Collections;
import java.util.List;
public final class QuickChangeLookAndFeel extends QuickSwitchSchemeAction implements ActionRemoteBehaviorSpecification.Frontend {
@@ -72,9 +74,13 @@ public final class QuickChangeLookAndFeel extends QuickSwitchSchemeAction implem
@Override
protected @NotNull ListPopup createPopup(AnActionEvent e, DefaultActionGroup group, JBPopupFactory.ActionSelectionAid aid) {
UiThemeProviderListManager themeManager = UiThemeProviderListManager.Companion.getInstance();
List<UIThemeLookAndFeelInfo> islandThemes = themeManager.getBundledThemeListForTargetUI(TargetUIType.ISLANDS);
if (WelcomeFrame.getInstance() == null &&
ContainerUtil.exists(group.getChildren(e),
action -> action instanceof LafChangeAction lafAction && lafAction.myLookAndFeelInfo.isRestartRequired())) {
ContainerUtil.exists(group.getChildren(e), action -> action instanceof LafChangeAction lafAction &&
(lafAction.myLookAndFeelInfo.isRestartRequired() ||
islandThemes.contains(lafAction.myLookAndFeelInfo)))) {
return new PopupFactoryImpl.ActionGroupPopup(null, getPopupTitle(e), group, e.getDataContext(),
myActionPlace == null ? ActionPlaces.POPUP : myActionPlace, new PresentationFactory(),
ActionPopupOptions.forAid(aid, true, -1, preselectAction()), null) {
@@ -113,7 +119,7 @@ public final class QuickChangeLookAndFeel extends QuickSwitchSchemeAction implem
if (value instanceof PopupFactoryImpl.ActionItem item) {
AnAction action = item.getAction();
if (action instanceof LafChangeAction lafAction) {
checkRestartRequired(lafAction, infos, isSelected, icon1, icon2);
checkRestartRequired(lafAction, infos, islandThemes, isSelected, icon1, icon2);
}
}
}
@@ -126,6 +132,7 @@ public final class QuickChangeLookAndFeel extends QuickSwitchSchemeAction implem
private static boolean checkRestartRequired(@NotNull LafChangeAction lafAction,
@NotNull List<Groups.GroupInfo<UIThemeLookAndFeelInfo>> infos,
@NotNull List<UIThemeLookAndFeelInfo> islandThemes,
boolean isSelected,
@Nullable JLabel icon1,
@Nullable JLabel icon2) {
@@ -154,6 +161,9 @@ public final class QuickChangeLookAndFeel extends QuickSwitchSchemeAction implem
}
return true;
}
if (icon1 != null && islandThemes.contains(lafAction.myLookAndFeelInfo)) {
icon1.setIcon(AllIcons.General.Beta);
}
return false;
}
@@ -232,7 +242,8 @@ public final class QuickChangeLookAndFeel extends QuickSwitchSchemeAction implem
Object item = ((JList<?>)event.getSource()).getSelectedValue();
if (item instanceof AnActionHolder) {
AnAction anAction = ((AnActionHolder)item).getAction();
if (anAction instanceof LafChangeAction action && !checkRestartRequired(action, infos, false, null, null)) {
if (anAction instanceof LafChangeAction action &&
!checkRestartRequired(action, infos, Collections.emptyList(), false, null, null)) {
switchAlarm.cancelAllRequests();
switchAlarm.addRequest(() -> {
switchLafAndUpdateUI(LafManager.getInstance(), action.myLookAndFeelInfo);
@@ -64,7 +64,6 @@ import com.intellij.util.IJSwingUtilities
import com.intellij.util.SVGLoader.colorPatcherProvider
import com.intellij.util.concurrency.SynchronizedClearableLazy
import com.intellij.util.ui.*
import com.intellij.util.ui.StartupUiUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
@@ -499,7 +498,10 @@ class LafManagerImpl(private val coroutineScope: CoroutineScope) : LafManager(),
}
override fun getLookAndFeelCellRenderer(component: JComponent): ListCellRenderer<LafReference> {
val themeManager = UiThemeProviderListManager.getInstance()
val islandThemes = themeManager.getBundledThemeListForTargetUI(TargetUIType.ISLANDS)
val welcomeMode = WelcomeFrame.getInstance() != null
return listCellRenderer {
toolTipText = null
text(value.name)
@@ -521,6 +523,9 @@ class LafManagerImpl(private val coroutineScope: CoroutineScope) : LafManager(),
icon(getDisabledIcon(AllIcons.Actions.Restart, null))
toolTipText = IdeBundle.message("ide.restart.required.comment")
}
else if (islandThemes.contains(theme)) {
icon(AllIcons.General.Beta)
}
break
}
}
@@ -115,6 +115,14 @@ class UiThemeProviderListManager {
.mapNotNull { it.theme.get() }
}
fun getBundledThemeListForTargetUI(targetUI: TargetUIType): List<UIThemeLookAndFeelInfo> {
val themes = mutableListOf<UIThemeLookAndFeelInfo>()
getThemeListForTargetUI(targetUI).forEach { info ->
if (!info.isThemeFromPlugin) themes.add(info)
}
return themes
}
internal fun themeProviderAdded(provider: UIThemeProvider, pluginDescriptor: PluginDescriptor): LafEntry? {
if (findLaFByProviderId(provider) != null) {
// provider is already registered
@@ -105,6 +105,8 @@ open class InternalUICustomization {
open fun attachIdeFrameBackgroundPainter(frame: IdeFrame, glassPane: IdeGlassPane): Unit = Unit
open fun updateBackgroundPainter() {}
open fun attachIdeFallbackBackgroundPainter(glassPane: IdeGlassPane): Unit = Unit
open fun attachDialogFallbackBackgroundPainter(glassPane: IdeGlassPane): Unit = Unit
@@ -4,10 +4,11 @@ package com.intellij.openapi.application.impl
import org.jetbrains.annotations.ApiStatus
import javax.swing.JComponent
import javax.swing.JPanel
import javax.swing.border.Border
@ApiStatus.Internal
open class ToolWindowUIDecorator() {
open fun decorateAndReturnHolder(divider: JComponent, child: JComponent): JComponent? = null
open fun decorateAndReturnHolder(divider: JComponent, child: JComponent, originalBorderBuilder: () -> Border): JComponent? = null
open fun createCustomToolWindowPaneHolder(): JPanel = JPanel()
}
@@ -18,7 +18,7 @@ import com.intellij.ui.scale.ScaleContext
import com.intellij.util.ui.JBUI
import java.awt.*
internal class IslandsGradientPainter(private val frame: IdeFrame, private val mainColor: Color) : AbstractPainter() {
internal class IslandsGradientPainter(private val frame: IdeFrame, private val mainColor: Color, private val enabled: () -> Boolean) : AbstractPainter() {
private val leftGradientCache: GradientTextureCache = GradientTextureCache()
private val rightGradientCache: GradientTextureCache = GradientTextureCache()
@@ -26,7 +26,7 @@ internal class IslandsGradientPainter(private val frame: IdeFrame, private val m
private var doPaint = true
override fun needsRepaint(): Boolean = true
override fun needsRepaint(): Boolean = enabled()
override fun executePaint(component: Component, g: Graphics2D) {
if (doPaint) {
@@ -1,6 +1,7 @@
// 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.openapi.application.impl.islands
import com.intellij.openapi.fileEditor.impl.EditorTabPainterAdapter
import com.intellij.ui.ColorUtil
import com.intellij.ui.JBColor
import com.intellij.ui.paint.RectanglePainter2D
@@ -16,10 +17,21 @@ import com.intellij.util.ui.JBUI
import java.awt.*
import java.awt.geom.RoundRectangle2D
internal class ManyIslandsTabPainterAdapter : TabPainterAdapter {
override val tabPainter: JBTabPainter = ManyIslandsTabPainter()
internal class IslandsTabPainterAdapter(var isEnabled: Boolean) : TabPainterAdapter {
private val editorAdapter = EditorTabPainterAdapter()
private val islandsAdapter = IslandsTabPainter()
override val tabPainter: JBTabPainter
get() {
return if (isEnabled) islandsAdapter else editorAdapter.tabPainter
}
override fun paintBackground(label: TabLabel, g: Graphics, tabs: JBTabsImpl) {
if (!isEnabled) {
editorAdapter.paintBackground(label, g, tabs)
return
}
val info = label.info
val selected = info == tabs.selectedInfo
val active = tabs.isActiveTabs(info)
@@ -36,7 +48,7 @@ internal class ManyIslandsTabPainterAdapter : TabPainterAdapter {
val accentedRect = Rectangle(rect.x, rect.y, rect.width, rect.height)
JBInsets.removeFrom(accentedRect, JBInsets(5, 3, 5, 3))
(tabPainter as ManyIslandsTabPainter).paintTab(g2, accentedRect, info.tabColor, active, hovered, selected)
(tabPainter as IslandsTabPainter).paintTab(g2, accentedRect, info.tabColor, active, hovered, selected)
}
finally {
g2.dispose()
@@ -44,7 +56,7 @@ internal class ManyIslandsTabPainterAdapter : TabPainterAdapter {
}
}
private class ManyIslandsTabTheme : TabTheme {
private class IslandsTabTheme : TabTheme {
override val background: Color
get() = JBUI.CurrentTheme.EditorTabs.background()
@@ -74,8 +86,8 @@ private class ManyIslandsTabTheme : TabTheme {
get() = JBColor.namedColor("EditorTabs.underlinedTabInactiveForeground", JBColor(0x000000, 0xFFFFFF))
}
private class ManyIslandsTabPainter : JBTabPainter {
private val myTheme = ManyIslandsTabTheme()
private class IslandsTabPainter : JBTabPainter {
private val myTheme = IslandsTabTheme()
override fun getTabTheme(): TabTheme = myTheme
@@ -2,6 +2,7 @@
package com.intellij.openapi.application.impl.islands
import com.intellij.ide.ui.LafManagerListener
import com.intellij.ide.ui.UISettings
import com.intellij.openapi.actionSystem.ex.ActionButtonLook
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.impl.InternalUICustomization
@@ -13,16 +14,20 @@ import com.intellij.openapi.ui.Splittable
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.wm.IdeFrame
import com.intellij.openapi.wm.IdeGlassPane
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.openapi.wm.WindowManager
import com.intellij.openapi.wm.ex.ToolWindowManagerEx
import com.intellij.openapi.wm.impl.IdeBackgroundUtil
import com.intellij.openapi.wm.impl.IdeGlassPaneImpl
import com.intellij.openapi.wm.impl.SquareStripeButtonLook
import com.intellij.openapi.wm.impl.ToolWindowImpl
import com.intellij.toolWindow.ToolWindowButtonManager
import com.intellij.toolWindow.ToolWindowPaneNewButtonManager
import com.intellij.toolWindow.xNext.island.XNextIslandHolder
import com.intellij.ui.ClientProperty
import com.intellij.ui.ExperimentalUI
import com.intellij.ui.JBColor
import com.intellij.ui.tabs.impl.TabPainterAdapter
import com.intellij.ui.tabs.impl.JBEditorTabs
import com.intellij.util.ui.JBSwingUtilities
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
@@ -30,31 +35,60 @@ import java.awt.*
import java.awt.event.AWTEventListener
import java.awt.event.HierarchyEvent
import javax.swing.JComponent
import javax.swing.border.Border
internal class IslandsUICustomization : InternalUICustomization() {
private val isIslandsAvailable = !Registry.`is`("llm.riderNext.enabled", false) && ExperimentalUI.isNewUI()
private var isManyIslandEnabledCache: Boolean? = null
private val isManyIslandEnabled: Boolean
get() {
return isIslandsAvailable && JBUI.getInt("Islands", 0) == 1
var value = isManyIslandEnabledCache
if (value == null) {
value = isIslandsAvailable && JBUI.getInt("Islands", 0) == 1
isManyIslandEnabledCache = value
}
return value
}
private val isIslandsGradientEnabled: Boolean = Registry.`is`("idea.islands.gradient.enabled", true)
private var isIslandsGradientEnabledCache: Boolean? = null
private val isIslandsGradientEnabled: Boolean
get() {
var value = isIslandsGradientEnabledCache
if (value == null) {
value = Registry.`is`("idea.islands.gradient.enabled", true) && UISettings.getInstance().differentiateProjects
isIslandsGradientEnabledCache = value
}
return value
}
override fun updateBackgroundPainter() {
isIslandsGradientEnabledCache = null
}
override val isProjectCustomDecorationGradientPaint: Boolean = !isManyIslandEnabled || !isIslandsGradientEnabled
override val shouldPaintEditorFadeout: Boolean = !isManyIslandEnabled
private val toolWindowDecorator = object : ToolWindowUIDecorator() {
override fun decorateAndReturnHolder(divider: JComponent, child: JComponent): JComponent {
override val toolWindowUIDecorator: ToolWindowUIDecorator = object : ToolWindowUIDecorator() {
override fun decorateAndReturnHolder(divider: JComponent, child: JComponent, originalBorderBuilder: () -> Border): JComponent {
return XNextIslandHolder().apply {
layout = BorderLayout()
background = JBUI.CurrentTheme.ToolWindow.background()
add(divider, BorderLayout.NORTH)
add(child, BorderLayout.CENTER)
IslandsRoundedBorder.createToolWindowBorder(this)
child.putClientProperty(IdeBackgroundUtil.NO_BACKGROUND, true)
putClientProperty("originalBorderBuilder", originalBorderBuilder)
if (isManyIslandEnabled) {
background = JBUI.CurrentTheme.ToolWindow.background()
IslandsRoundedBorder.createToolWindowBorder(this)
child.putClientProperty(IdeBackgroundUtil.NO_BACKGROUND, true)
}
else {
border = originalBorderBuilder()
}
}
}
}
@@ -77,27 +111,160 @@ internal class IslandsUICustomization : InternalUICustomization() {
Toolkit.getDefaultToolkit().addAWTEventListener(awtListener, AWTEvent.HIERARCHY_EVENT_MASK)
}
var oldManyIsland = isManyIslandEnabled
val connection = ApplicationManager.getApplication().messageBus.connect()
connection.subscribe(LafManagerListener.TOPIC, LafManagerListener {
val toolkit = Toolkit.getDefaultToolkit()
toolkit.removeAWTEventListener(awtListener)
isManyIslandEnabledCache = null
if (isManyIslandEnabled && JBColor.isBright()) {
val newManyIsland = isManyIslandEnabled
if (newManyIsland && JBColor.isBright()) {
toolkit.addAWTEventListener(awtListener, AWTEvent.HIERARCHY_EVENT_MASK)
}
if (oldManyIsland == newManyIsland) {
return@LafManagerListener
}
if (newManyIsland) {
enableManyIslands()
}
else {
disableManyIslands()
}
oldManyIsland = newManyIsland
})
}
private val tabPainterAdapter = ManyIslandsTabPainterAdapter()
private fun enableManyIslands() {
editorTabPainterAdapter.isEnabled = true
override val toolWindowUIDecorator: ToolWindowUIDecorator
get() {
if (isManyIslandEnabled) {
return toolWindowDecorator
// XXX: dialogs
for (frame in WindowManager.getInstance().allProjectFrames) {
val toolwindows = mutableSetOf<String>()
UIUtil.forEachComponentInHierarchy(frame.component) {
when (it) {
is XNextIslandHolder -> {
setToolWindowManyBorder(it)
val id = it.getClientProperty("ToolWindow.ID")
if (id is String) {
toolwindows.add(id)
}
}
is EditorsSplitters -> {
IslandsRoundedBorder.createEditorBorder(it, editorTabPainterAdapter)
clearParentNoBackground(it)
}
is JBEditorTabs -> {
if (it.parent is EditorsSplitters) {
ClientProperty.putRecursive(it, IdeBackgroundUtil.NO_BACKGROUND, true)
}
}
is ManyIslandDivider -> {
it.configure(true)
}
}
}
val project = frame.project
if (project != null) {
val manager = ToolWindowManager.getInstance(project) as ToolWindowManagerEx
for (toolwindow in manager.toolWindows) {
if (!toolwindows.contains(toolwindow.id) && toolwindow is ToolWindowImpl) {
toolwindow.getNullableDecorator()?.also {
UIUtil.findComponentOfType(it, XNextIslandHolder::class.java)?.also { holder ->
setToolWindowManyBorder(holder)
}
}
}
}
}
return super.toolWindowUIDecorator
}
}
private fun disableManyIslands() {
editorTabPainterAdapter.isEnabled = false
// XXX: dialogs
for (frame in WindowManager.getInstance().allProjectFrames) {
val toolwindows = mutableSetOf<String>()
UIUtil.forEachComponentInHierarchy(frame.component) {
if (it is JComponent) {
ClientProperty.removeRecursive(it, IdeBackgroundUtil.NO_BACKGROUND)
}
when (it) {
is XNextIslandHolder -> {
setOriginalToolWindowBorder(it)
val id = it.getClientProperty("ToolWindow.ID")
if (id is String) {
toolwindows.add(id)
}
}
is EditorsSplitters -> {
it.border = null
}
is ManyIslandDivider -> {
it.configure(false)
}
}
}
val project = frame.project
if (project != null) {
val manager = ToolWindowManager.getInstance(project) as ToolWindowManagerEx
for (toolwindow in manager.toolWindows) {
if (!toolwindows.contains(toolwindow.id) && toolwindow is ToolWindowImpl) {
toolwindow.getNullableDecorator()?.also {
UIUtil.findComponentOfType(it, XNextIslandHolder::class.java)?.also { holder ->
setOriginalToolWindowBorder(holder)
}
}
}
}
}
}
}
private fun setOriginalToolWindowBorder(holder: XNextIslandHolder) {
val builder = holder.getClientProperty("originalBorderBuilder")
if (builder is Function0<*>) {
val border = builder()
if (border is Border) {
holder.setSuperBorder(border)
}
}
holder.background = JBColor.PanelBackground
}
private fun setToolWindowManyBorder(holder: XNextIslandHolder) {
holder.background = JBUI.CurrentTheme.ToolWindow.background()
IslandsRoundedBorder.createToolWindowBorder(holder)
clearParentNoBackground(holder)
for (child in holder.components) {
ClientProperty.putRecursive(child as JComponent, IdeBackgroundUtil.NO_BACKGROUND, true)
}
}
private fun clearParentNoBackground(component: JComponent) {
var nextComponent: JComponent? = component
while (nextComponent != null && ClientProperty.get(nextComponent, IdeBackgroundUtil.NO_BACKGROUND) != null) {
ClientProperty.removeRecursive(nextComponent, IdeBackgroundUtil.NO_BACKGROUND)
nextComponent = nextComponent.parent as JComponent?
}
}
override fun configureToolWindowPane(toolWindowPaneParent: JComponent, buttonManager: ToolWindowButtonManager) {
if (isManyIslandEnabled && buttonManager is ToolWindowPaneNewButtonManager) {
@@ -129,15 +296,9 @@ internal class IslandsUICustomization : InternalUICustomization() {
}
override fun createCustomDivider(isVertical: Boolean, splitter: Splittable): Divider? {
if (isManyIslandEnabled) {
return object : OnePixelDivider(isVertical, splitter) {
override fun paint(g: Graphics) {
}
}.also {
it.putClientProperty("DividerWidth", 0)
}
return ManyIslandDivider(isVertical, splitter).also {
it.configure(isManyIslandEnabled)
}
return null
}
override fun configureRendererComponent(component: JComponent) {
@@ -154,34 +315,34 @@ internal class IslandsUICustomization : InternalUICustomization() {
override fun configureEditorsSplitters(component: EditorsSplitters) {
if (isManyIslandEnabled) {
IslandsRoundedBorder.createEditorBorder(component, tabPainterAdapter)
IslandsRoundedBorder.createEditorBorder(component, editorTabPainterAdapter)
}
}
override fun paintBeforeEditorEmptyText(component: JComponent, graphics: Graphics) {
if (isManyIslandEnabled) {
IslandsRoundedBorder.paintBeforeEditorEmptyText(component, graphics, tabPainterAdapter)
IslandsRoundedBorder.paintBeforeEditorEmptyText(component, graphics, editorTabPainterAdapter)
}
}
override val editorTabPainterAdapter: TabPainterAdapter
get() {
if (isManyIslandEnabled) {
return tabPainterAdapter
}
return super.editorTabPainterAdapter
}
override val editorTabPainterAdapter: IslandsTabPainterAdapter = IslandsTabPainterAdapter(isManyIslandEnabled)
private fun getMainBackgroundColor(): Color {
return JBColor.namedColor("MainWindow.background", JBColor.PanelBackground)
}
override fun getCustomMainBackgroundColor(): Color? {
if (isManyIslandEnabled) {
return JBColor.namedColor("MainWindow.background", JBColor.PanelBackground)
return getMainBackgroundColor()
}
return super.getCustomMainBackgroundColor()
return null
}
override fun attachIdeFrameBackgroundPainter(frame: IdeFrame, glassPane: IdeGlassPane) {
if (isManyIslandEnabled && isIslandsGradientEnabled && glassPane is IdeGlassPaneImpl) {
glassPane.addFallbackBackgroundPainter(IslandsGradientPainter(frame, getCustomMainBackgroundColor()!!))
if (glassPane is IdeGlassPaneImpl) {
glassPane.addFallbackBackgroundPainter(IslandsGradientPainter(frame, getMainBackgroundColor()) {
isManyIslandEnabled && isIslandsGradientEnabled
})
}
}
@@ -209,4 +370,25 @@ internal class IslandsUICustomization : InternalUICustomization() {
}
return graphics
}
}
private class ManyIslandDivider(isVertical: Boolean, splitter: Splittable) : OnePixelDivider(isVertical, splitter) {
private var doPaint = true
fun configure(manyIsland: Boolean) {
doPaint = !manyIsland
if (manyIsland) {
putClientProperty("DividerWidth", 0)
}
else {
putClientProperty("DividerWidth", null)
}
}
override fun paint(g: Graphics) {
if (doPaint) {
super.paint(g)
}
}
}
@@ -486,6 +486,8 @@ internal class ToolWindowImpl(
toolWindowManager.stretchHeight(this, value)
}
internal fun getNullableDecorator() = decorator
override fun getDecorator(): InternalDecoratorImpl = decorator!!
override fun setAdditionalGearActions(value: ActionGroup?) {
@@ -279,8 +279,12 @@ class InternalDecoratorImpl internal constructor(
Mode.SINGLE, Mode.CELL -> {
layout = BorderLayout()
InternalUICustomization.getInstance()?.toolWindowUIDecorator?.decorateAndReturnHolder(dividerAndHeader, myDecoratorChild)?.let {
val decorator = InternalUICustomization.getInstance()?.toolWindowUIDecorator
?.decorateAndReturnHolder(dividerAndHeader, myDecoratorChild) { InnerPanelBorder(toolWindow) }
decorator?.let {
add(it, BorderLayout.CENTER)
putClientProperty("ToolWindow.ID", toolWindowId)
} ?: run {
add(dividerAndHeader, BorderLayout.NORTH)
add(myDecoratorChild, BorderLayout.CENTER)
@@ -617,7 +617,7 @@ class ToolWindowPane private constructor(
}
override fun createDivider(): Divider {
return InternalUICustomization.getInstance()?.createCustomDivider(isVisible, this)
return InternalUICustomization.getInstance()?.createCustomDivider(isVertical, this)
?: super.createDivider().also { it.background = JBUI.CurrentTheme.ToolWindow.mainBorderColor() }
}
@@ -48,6 +48,10 @@ class XNextIslandHolder : JPanel() {
super.setBorder(border)
}
fun setSuperBorder(border: Border?) {
super.setBorder(border)
}
override fun isOpaque(): Boolean {
return true
}
@@ -690,8 +690,8 @@
<bundledColorScheme id="Island Dark" path="/themes/islands/IslandSchemeDark.xml"/>
<themeProvider id="Many Islands Dark" path="/themes/islands/ManyIslandsDark.theme.json" targetUi="islands" restartRequired="true"/>
<themeProvider id="Many Islands Light" path="/themes/islands/ManyIslandsLight.theme.json" targetUi="islands" restartRequired="true"/>
<themeProvider id="Many Islands Dark" path="/themes/islands/ManyIslandsDark.theme.json" targetUi="islands"/>
<themeProvider id="Many Islands Light" path="/themes/islands/ManyIslandsLight.theme.json" targetUi="islands"/>
<themeMetadataProvider path="/themes/metadata/IntelliJPlatform.themeMetadata.json"/>
<themeMetadataProvider path="/themes/metadata/JDK.themeMetadata.json"/>
@@ -116,6 +116,24 @@ public final class ClientProperty {
}
}
@ApiStatus.Internal
public static <T> void removeRecursive(@NotNull JComponent component, @NotNull Key<T> key) {
Map<Key<?>, ContainerListener> listeners = get(component, RECURSIVE_LISTENERS);
if (listeners != null) {
ContainerListener existingListener = listeners.remove(key);
if (existingListener != null) {
component.removeContainerListener(existingListener);
if (listeners.isEmpty()) {
put(component, RECURSIVE_LISTENERS, null);
}
}
}
put(component, key, null);
}
@Contract("null -> null")
private static @Nullable JComponent getPropertiesHolder(@Nullable Component component) {
if (component instanceof JComponent) return (JComponent)component;