use smooth scrolling on Mac only by default

This commit is contained in:
Sergey Malenkov
2017-02-10 21:59:09 +03:00
parent 31e1b5a8e4
commit baf60259c2
4 changed files with 27 additions and 58 deletions
@@ -16,6 +16,7 @@
package com.intellij.ui;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.registry.RegistryValue;
import com.intellij.util.SystemProperties;
@@ -27,6 +28,9 @@ import java.awt.*;
* IDE-agnostic component settings.
*/
public class ComponentSettings {
private static final boolean SUPPORTED_JAVA = SystemInfo.isJetbrainsJvm || SystemInfo.isJavaVersionAtLeast("1.9");
private static final RegistryValue SUPPORTED = Registry.get("ide.scroll.precise");
private static final RegistryValue HIGH_PRECISION_SCROLLING = Registry.get("idea.true.smooth.scrolling.high.precision");
private static final RegistryValue PIXEL_PERFECT_SCROLLING = Registry.get("idea.true.smooth.scrolling.pixel.perfect");
@@ -57,7 +61,8 @@ public class ComponentSettings {
// Returns whether "true smooth scrolling" is applicable to the particular component
public boolean isTrueSmoothScrollingEligibleFor(Component component) {
return !ApplicationManager.getApplication().isUnitTestMode() &&
return isSmoothScrollingSupported() &&
!ApplicationManager.getApplication().isUnitTestMode() &&
mySmoothScrollingEnabled &&
!myRemoteDesktopConnected &&
!myPowerSaveModeEnabled &&
@@ -65,6 +70,11 @@ public class ComponentSettings {
component.isShowing();
}
// Returns whether smooth scrolling supported
public boolean isSmoothScrollingSupported() {
return SUPPORTED.asBoolean() || (SUPPORTED_JAVA && SystemInfo.isMac);
}
// Returns whether high-precision scrolling events are enabled
public boolean isHighPrecisionScrollingEnabled() {
return HIGH_PRECISION_SCROLLING.asBoolean();
@@ -17,7 +17,6 @@ package com.intellij.ui.components;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.IdeGlassPane.TopComponent;
import com.intellij.ui.ComponentSettings;
import com.intellij.ui.InputSource;
@@ -54,7 +53,6 @@ public class JBScrollBar extends JScrollBar implements TopComponent, Interpolabl
public static final Key<RegionPainter<Object>> TRACK = Key.create("JB_SCROLL_BAR_TRACK");
private static final double THRESHOLD = 1D + 1E-5D;
private static final boolean SUPPORTED_JAVA = SystemInfo.isJetbrainsJvm || SystemInfo.isJavaVersionAtLeast("1.9");
private final Interpolator myInterpolator = new Interpolator(this::getValue, this::setCurrentValue);
private final Adjuster myAdjuster = new Adjuster(delta -> setValue(getTargetValue() + delta));
private boolean isUnitIncrementSet;
@@ -245,44 +243,26 @@ public class JBScrollBar extends JScrollBar implements TopComponent, Interpolabl
return Math.max(minDelta, Math.min(maxDelta, delta));
}
/**
* Indicates whether MouseWheelEvent#getPreciseWheelRotation can be used to calculate an absolute scrolling delta.
*
* @return {@code true} if an absolute scrolling delta is supported, {@code false} otherwise
* @see #getPreciseDelta(MouseWheelEvent)
*/
static boolean isAbsoluteDeltaSupported() {
ComponentSettings settings = ComponentSettings.getInstance();
if (SUPPORTED_JAVA && settings.isPixelPerfectScrollingEnabled()) {
if (SystemInfo.isMac && Registry.is("ide.scroll.precise.rotation.mac")) return true;
if (SystemInfo.isWindows && Registry.is("ide.scroll.precise.rotation.windows")) return true;
}
return false;
}
/**
* Calculates a scrolling delta from the specified event.
*
* @param event the mouse wheel event
* @return a scrolling delta for this scrollbar
* @see #isAbsoluteDeltaSupported
*/
private double getPreciseDelta(MouseWheelEvent event) {
double rotation = event.getPreciseWheelRotation();
ComponentSettings settings = ComponentSettings.getInstance();
if (SUPPORTED_JAVA && settings.isPixelPerfectScrollingEnabled()) {
if (settings.isPixelPerfectScrollingEnabled()) {
// calculate an absolute delta if possible
if (SystemInfo.isMac && Registry.is("ide.scroll.precise.rotation.mac")) {
if (SystemInfo.isMac) {
// Native code in our JDK for Mac uses 0.1 to convert pixels to units,
// so we use 10 to restore amount of pixels to scroll.
return 10 * rotation;
}
if (SystemInfo.isWindows && Registry.is("ide.scroll.precise.rotation.windows")) {
JViewport viewport = getViewport();
Font font = viewport == null ? null : getViewFont(viewport);
int size = font == null ? JBUI.scale(10) : font.getSize(); // assume an unit size
return size * rotation * event.getScrollAmount();
}
JViewport viewport = getViewport();
Font font = viewport == null ? null : getViewFont(viewport);
int size = font == null ? JBUI.scale(10) : font.getSize(); // assume an unit size
return size * rotation * event.getScrollAmount();
}
if (settings.isHighPrecisionScrollingEnabled()) {
// calculate a relative delta if possible
@@ -713,36 +713,18 @@ public class JBScrollPane extends JScrollPane {
if (event.isConsumed()) return false;
// any rotation expected (forward or backward)
boolean ignore = event.getWheelRotation() == 0;
if (ignore && (JBScrollBar.isAbsoluteDeltaSupported() || ComponentSettings.getInstance().isHighPrecisionScrollingEnabled())) {
double rotation = event.getPreciseWheelRotation();
ignore = rotation == 0.0D || !Double.isFinite(rotation);
if (ignore) {
ComponentSettings settings = ComponentSettings.getInstance();
if (settings.isSmoothScrollingSupported()) {
if (settings.isPixelPerfectScrollingEnabled() || settings.isHighPrecisionScrollingEnabled()) {
double rotation = event.getPreciseWheelRotation();
ignore = rotation == 0.0D || !Double.isFinite(rotation);
}
}
}
return !ignore && 0 == (SCROLL_MODIFIERS & event.getModifiers());
}
/**
* Indicates whether we can use MouseWheelEvent#getPreciseWheelRotation to scroll.
*
* @deprecated will be removed after fixing a blit-scrolling
*/
@Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
public static boolean isPreciseRotationSupported() {
if (PRECISE_ROTATION_SUPPORTED) {
if (SystemInfo.isMac) return Registry.is("ide.scroll.precise.rotation.mac");
if (SystemInfo.isWindows) return Registry.is("ide.scroll.precise.rotation.windows");
}
return false;
}
/**
* Indicates whether the system property "idea.true.smooth.scrolling" is not set to "true"
* (it is needed to avoid possible conflicts with another scrolling implementation)
* and the current JVM contains our fixes for MouseWheelEvent#getPreciseWheelRotation.
*/
private static final boolean PRECISE_ROTATION_SUPPORTED = !isTrueSmoothScrollingEnabled() &&
(SystemInfo.isJetbrainsJvm || SystemInfo.isJavaVersionAtLeast("1.9"));
private static final int SCROLL_MODIFIERS = // event modifiers allowed during scrolling
~InputEvent.SHIFT_MASK & ~InputEvent.SHIFT_DOWN_MASK & // for horizontal scrolling
~InputEvent.BUTTON1_MASK & ~InputEvent.BUTTON1_DOWN_MASK; // for selection
@@ -118,11 +118,8 @@ ide.splitter.mouseZone=6
ide.autoscroll.from.source.delay=100
ide.autoscroll.from.source.delay.description=Delay before performing the AutoscrollFromSource action
ide.scroll.precise.rotation.mac=true
ide.scroll.precise.rotation.mac.description=Use precise wheel rotation on Mac (may decrease scrolling performance).
ide.scroll.precise.rotation.windows=false
ide.scroll.precise.rotation.windows.description=Use precise wheel rotation on Windows (may decrease scrolling performance).
ide.scroll.precise=false
ide.scroll.precise.description=Use precise wheel rotation (may decrease scrolling performance).
ide.scroll.default.unit.increment=false
ide.scroll.default.unit.increment.description=Use default unit increment from Java (may decrease scrolling performance).