IJPL-189307 Windows scrollbars: update shape

GitOrigin-RevId: ef47dcc6b4584e9fa6eb3cd3a91354749a95a6cc
This commit is contained in:
Alexander Lobas
2025-09-08 15:47:40 +00:00
committed by intellij-monorepo-bot
parent 4085f77da5
commit f9bd233810
14 changed files with 89 additions and 18 deletions
@@ -8,6 +8,7 @@ import com.intellij.openapi.wm.IdeGlassPane.TopComponent;
import com.intellij.ui.ClientProperty;
import com.intellij.ui.scale.JBUIScale;
import com.intellij.ui.scroll.TouchScrollUtil;
import com.intellij.ui.tabs.impl.IslandsPainterProvider;
import com.intellij.util.ui.RegionPainter;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NotNull;
@@ -111,7 +112,8 @@ public class JBScrollBar extends JScrollBar implements TopComponent, Interpolabl
*/
@SuppressWarnings("UnusedParameters")
public static @NotNull ScrollBarUI createUI(JComponent c, boolean isThin) {
if (SystemInfo.isMac) {
IslandsPainterProvider provider = IslandsPainterProvider.getInstance();
if (SystemInfo.isMac || (provider != null && provider.useMacScrollBar())) {
return isThin ? new ThinMacScrollBarUI() : new MacScrollBarUI();
}
else {
@@ -12,6 +12,7 @@ import com.intellij.ui.scroll.LatchingScroll;
import com.intellij.ui.scroll.MouseWheelSmoothScroll;
import com.intellij.ui.scroll.TouchScroll;
import com.intellij.ui.scroll.TouchScrollUtil;
import com.intellij.ui.tabs.impl.IslandsPainterProvider;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.ui.JBInsets;
@@ -1039,6 +1040,7 @@ public class JBScrollPane extends JScrollPane {
@ApiStatus.Internal
public static RegionPainter<Float> getThumbPainter(@NotNull Supplier<? extends Component> supplier, @NotNull CoroutineScope coroutineScope) {
return new ScrollBarPainter.Thumb(supplier, SystemInfoRt.isMac, coroutineScope);
IslandsPainterProvider provider = IslandsPainterProvider.getInstance();
return new ScrollBarPainter.Thumb(supplier, SystemInfoRt.isMac || (provider != null && provider.useMacScrollBar()), coroutineScope);
}
}
@@ -36,8 +36,12 @@ internal open class MacScrollBarUI : DefaultScrollBarUI {
companion object {
private val CURRENT_STYLE = object : MacScrollbarNative<MacScrollbarStyle>() {
override fun run() {
if (!SystemInfoRt.isMac) {
return
}
val oldStyle = invoke()
if (SystemInfoRt.isMac && !Registry.`is`("ide.mac.disableMacScrollbars", false)) {
if (!Registry.`is`("ide.mac.disableMacScrollbars", false)) {
super.run()
}
@@ -61,6 +65,9 @@ internal open class MacScrollBarUI : DefaultScrollBarUI {
override fun toString(): String = "scroll bar style"
override fun initialize(): ID {
if (!SystemInfoRt.isMac) {
return ID.NIL
}
return Foundation.invoke(Foundation.invoke("NSNotificationCenter", "defaultCenter"),
"addObserver:selector:name:object:",
createDelegate("JBScrollBarStyleObserver", Foundation.createSelector("handleScrollerStyleChanged:"),
@@ -143,7 +150,12 @@ internal open class MacScrollBarUI : DefaultScrollBarUI {
override fun installUI(c: JComponent) {
super.installUI(c)
updateStyle(CURRENT_STYLE())
if (SystemInfoRt.isMac) {
updateStyle(CURRENT_STYLE())
}
else {
updateStyle(MacScrollbarStyle.Overlay)
}
processReferences(toAdd = this, toRemove = null, list = null)
val listener = MOVEMENT_LISTENER.getAndSet(null)
if (listener != null) {
@@ -11,6 +11,7 @@ import com.intellij.ui.ColorUtil;
import com.intellij.ui.JBColor;
import com.intellij.ui.MixedColorProducer;
import com.intellij.ui.paint.RectanglePainter;
import com.intellij.ui.tabs.impl.IslandsPainterProvider;
import com.intellij.util.ui.RegionPainter;
import kotlinx.coroutines.CoroutineScope;
import org.jetbrains.annotations.ApiStatus;
@@ -128,9 +129,6 @@ public abstract class ScrollBarPainter implements RegionPainter<Float> {
THUMB_HOVERED_BACKGROUND
);
private static final int LIGHT_ALPHA = SystemInfoRt.isMac ? 120 : 160;
private static final int DARK_ALPHA = SystemInfoRt.isMac ? 255 : 180;
ScrollBarPainter(@NotNull Supplier<? extends Component> supplier, @NotNull CoroutineScope coroutineScope) {
animator = new TwoWayAnimator(getClass().getName(), 11, 150, 125, 300, 125, coroutineScope) {
@Override
@@ -168,6 +166,11 @@ public abstract class ScrollBarPainter implements RegionPainter<Float> {
alpha = Integer.min(alpha, 255);
}
else {
IslandsPainterProvider provider = IslandsPainterProvider.getInstance();
boolean isMac = SystemInfoRt.isMac || (provider != null && provider.useMacScrollBar());
int LIGHT_ALPHA = isMac ? 120 : 160;
int DARK_ALPHA = isMac ? 255 : 180;
alpha = JBColor.isBright() ? LIGHT_ALPHA : DARK_ALPHA;
}
@@ -242,7 +245,8 @@ public abstract class ScrollBarPainter implements RegionPainter<Float> {
if (ignoreBorder() || fill.getRGB() == draw.getRGB()) draw = null; // without border
int arc = 0;
if (SystemInfoRt.isMac) {
IslandsPainterProvider provider = IslandsPainterProvider.getInstance();
if (SystemInfoRt.isMac || (provider != null && provider.useMacScrollBar())) {
int margin = macMargin(draw != null);
x += margin;
y += margin;
@@ -7,11 +7,13 @@ import org.jetbrains.annotations.ApiStatus
@ApiStatus.Experimental
@ApiStatus.Internal
open class TabsPainterProvider {
open class IslandsPainterProvider {
companion object {
@JvmStatic
fun getInstance(): TabsPainterProvider? = ApplicationManager.getApplication()?.serviceOrNull()
fun getInstance(): IslandsPainterProvider? = ApplicationManager.getApplication()?.serviceOrNull()
}
open fun createCommonTabPainter(): TabPainterAdapter? = null
open fun useMacScrollBar(): Boolean = false
}
@@ -348,7 +348,7 @@ open class JBTabsImpl internal constructor(
protected open fun createTabBorder(): JBTabsBorder = JBDefaultTabsBorder(this)
protected open fun createTabPainterAdapter(): TabPainterAdapter = TabsPainterProvider.getInstance()?.createCommonTabPainter() ?: DefaultTabPainterAdapter(DEFAULT)
protected open fun createTabPainterAdapter(): TabPainterAdapter = IslandsPainterProvider.getInstance()?.createCommonTabPainter() ?: DefaultTabPainterAdapter(DEFAULT)
private var tabLabelAtMouse: TabLabel? = null
private val scrollBar: JBScrollBar
@@ -116,8 +116,8 @@ public final class NSScrollerHelper {
}
@ApiStatus.Internal
public static @Nullable Style getScrollerStyle() {
if (!isOverlayScrollbarSupported()) return null;
public static @NotNull Style getScrollerStyle() {
if (!isOverlayScrollbarSupported()) return Style.Overlay;
Foundation.NSAutoreleasePool pool = new Foundation.NSAutoreleasePool();
try {
@@ -113,6 +113,8 @@ open class InternalUICustomization {
open val isCustomPaintersAllowed: Boolean = false
open val isMacScrollBar: Boolean = false
open fun attachIdeFrameBackgroundPainter(frame: IdeFrame, glassPane: IdeGlassPane): Unit = Unit
open fun paintFrameBackground(frame: Window, component: Component, g: Graphics2D) {}
@@ -2,11 +2,15 @@
package com.intellij.openapi.application.impl.islands
import com.intellij.openapi.application.impl.InternalUICustomization
import com.intellij.ui.tabs.impl.IslandsPainterProvider
import com.intellij.ui.tabs.impl.TabPainterAdapter
import com.intellij.ui.tabs.impl.TabsPainterProvider
internal class IslandsTabsPainterProvider : TabsPainterProvider() {
internal class IslandsInternalPainterProvider : IslandsPainterProvider() {
override fun createCommonTabPainter(): TabPainterAdapter? {
return InternalUICustomization.getInstance()?.commonTabPainterAdapter
}
override fun useMacScrollBar(): Boolean {
return InternalUICustomization.getInstance()?.isMacScrollBar == true
}
}
@@ -5,6 +5,7 @@ import com.intellij.ide.ProjectWindowCustomizerService
import com.intellij.ide.impl.ProjectUtil
import com.intellij.ide.ui.LafManagerListener
import com.intellij.ide.ui.UISettings
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil.doPaint
import com.intellij.openapi.actionSystem.ex.ActionButtonLook
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.impl.InternalUICustomization
@@ -16,6 +17,7 @@ import com.intellij.openapi.ui.Divider
import com.intellij.openapi.ui.OnePixelDivider
import com.intellij.openapi.ui.Splittable
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.SystemInfoRt
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.wm.*
import com.intellij.openapi.wm.ex.ToolWindowManagerEx
@@ -613,6 +615,11 @@ internal class IslandsUICustomization : InternalUICustomization() {
return graphics
}
override val isMacScrollBar: Boolean
get() {
return !SystemInfoRt.isMac && isManyIslandEnabled
}
private fun updateToolStripesVisibility(toolWindowManager: ToolWindowManager) {
if (toolWindowManager is ToolWindowManagerImpl) {
for (pane in toolWindowManager.getToolWindowPanes()) {
@@ -4,6 +4,7 @@ package com.intellij.util.ui;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.CoroutineSupport.UiDispatcherKind;
import com.intellij.openapi.application.impl.InternalUICustomization;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
@@ -232,7 +233,8 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
}
public static boolean isMacOverlayScrollbarSupported() {
return SystemInfo.isMac && !Registry.is("ide.mac.disableMacScrollbars");
InternalUICustomization customization = InternalUICustomization.getInstance();
return (SystemInfo.isMac && !Registry.is("ide.mac.disableMacScrollbars")) || (customization != null && customization.isMacScrollBar());
}
private void updateMacScrollbarStyle() {
@@ -191,8 +191,8 @@
<applicationService serviceInterface="com.intellij.openapi.application.impl.InternalUICustomization"
serviceImplementation="com.intellij.openapi.application.impl.islands.IslandsUICustomization"/>
<applicationService serviceInterface="com.intellij.ui.tabs.impl.TabsPainterProvider"
serviceImplementation="com.intellij.openapi.application.impl.islands.IslandsTabsPainterProvider"/>
<applicationService serviceInterface="com.intellij.ui.tabs.impl.IslandsPainterProvider"
serviceImplementation="com.intellij.openapi.application.impl.islands.IslandsInternalPainterProvider"/>
<!---->
<adEntityProvider implementation="com.intellij.openapi.editor.impl.ad.document.DefaultAdEntityProvider" />
@@ -331,6 +331,23 @@
}
},
"ScrollBar": {
"hoverThumbBorderColor": "#2626268C",
"hoverThumbColor": "#8080808C",
"hoverTrackColor": "#80808000",
"thumbBorderColor": "#26262659",
"thumbColor": "#80808059",
"trackColor": "#80808000",
"Transparent": {
"hoverThumbBorderColor": "#2626268C",
"hoverThumbColor": "#8080808C",
"hoverTrackColor": "#8080801A",
"thumbBorderColor": "#26262600",
"thumbColor": "#80808000",
"trackColor": "#80808000"
}
},
"VersionControl.MarkerPopup.borderColor": "Gray4"
}
}
@@ -140,6 +140,23 @@
"borderColor": "Blue6"
},
"ScrollBar": {
"hoverThumbBorderColor": "#00000080",
"hoverThumbColor": "#00000080",
"hoverTrackColor": "#80808000",
"thumbBorderColor": "#00000033",
"thumbColor": "#00000033",
"trackColor": "#80808000",
"Transparent": {
"hoverThumbBorderColor": "#00000080",
"hoverThumbColor": "#00000080",
"hoverTrackColor": "#8080801A",
"thumbBorderColor": "#00000000",
"thumbColor": "#00000000",
"trackColor": "#80808000"
}
},
"HelpBrowser.UserMessage.background": "#DFE1E5CC",
"RecentProject.Color1.MainToolbarGradientStart": "#f7d7cb",