Fix "hidpi" property

- When disabled, it should suppress JRE-HiDPI mode
- New test
- New run config for a standalone (fork) test run mode
This commit is contained in:
Anton Tarasov
2018-03-01 18:29:05 +03:00
parent 955c6ed94e
commit fcfc61cf24
5 changed files with 135 additions and 34 deletions
@@ -27,6 +27,7 @@ import com.intellij.ui.AppUIUtil;
import com.intellij.util.Consumer;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.PlatformUtils;
import com.intellij.util.SystemProperties;
import com.intellij.util.ui.UIUtil;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
@@ -82,6 +83,8 @@ public class StartupUtil {
IdeaForkJoinWorkerThreadFactory.setupForkJoinCommonPool(Main.isHeadless(args));
boolean newConfigFolder = false;
checkHiDPISettings();
if (!Main.isHeadless()) {
AppUIUtil.updateFrameClass();
newConfigFolder = !new File(PathManager.getConfigPath()).exists();
@@ -180,6 +183,14 @@ public class StartupUtil {
return true;
}
// called via reflection from com.intellij.util.ui.HidpiPropTest
private static void checkHiDPISettings() {
if (SystemProperties.has("hidpi") && !SystemProperties.is("hidpi")) {
// suppress JRE-HiDPI mode
System.setProperty("sun.java2d.uiScale.enabled", "false");
}
}
private static synchronized boolean checkSystemFolders() {
String configPath = PathManager.getConfigPath();
PathManager.ensureConfigFolderExists();
@@ -8,6 +8,7 @@ import com.intellij.internal.IconsLoadTime.StatData;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.registry.RegistryValue;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.ui.TestScaleHelper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -32,13 +33,11 @@ public class IconsLoadTimeTest {
// a list of icons for which we have SVG versions
private static final String ICONS_LIST_PATH = PlatformTestUtil.getPlatformTestDataPath() + "icons/icons_list.txt";
private static String initialInternalProp;
private static boolean initialSvgProp;
@Before
public void setState() {
initialInternalProp = System.getProperty("idea.is.internal");
System.setProperty("idea.is.internal", "true");
TestScaleHelper.setProperty("idea.is.internal", "true");
RegistryValue rv = Registry.get("ide.svg.icon");
initialSvgProp = rv.asBoolean();
rv.setValue(true);
@@ -68,12 +67,7 @@ public class IconsLoadTimeTest {
@After
public void restoreState() {
if (initialInternalProp == null) {
System.clearProperty("idea.is.internal");
}
else {
System.setProperty("idea.is.internal", initialInternalProp);
}
TestScaleHelper.restoreProperties();
Registry.get("ide.svg.icon").setValue(initialSvgProp);
}
}
@@ -0,0 +1,49 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.ui;
import com.intellij.idea.StartupUtil;
import com.intellij.util.MethodInvocator;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.SystemProperties;
import org.junit.*;
import javax.swing.*;
import java.awt.*;
/**
* Tests "hidpi" system property.
*
* @author tav
*/
public class HidpiPropTest {
static final String HIDPI_PROP = "hidpi";
static final String UI_SCALE_PROP = "sun.java2d.uiScale.enabled";
static final String STANDALONE_PROP = "intellij.test.standalone";
@Before
public void checkStandalone() {
Assume.assumeTrue("not in " + STANDALONE_PROP + " mode", SystemProperties.is(STANDALONE_PROP));
}
@Before
public void setState() {
TestScaleHelper.setProperty(HIDPI_PROP, "false");
MethodInvocator m = new MethodInvocator(StartupUtil.class, "checkHiDPISettings");
Assume.assumeTrue("StartupUtil.checkHiDPISettings method not available", m.isAvailable());
m.invoke(null);
}
@After
public void restoreState() {
TestScaleHelper.restoreProperties();
}
@Test
public void test() {
Graphics2D g = TestScaleHelper.createGraphics(2);
Assert.assertFalse(UI_SCALE_PROP + " should be disabled", SystemProperties.is(UI_SCALE_PROP));
Assert.assertFalse("hidpi should be disabled", UIUtil.isJreHiDPI());
Assert.assertFalse("hidpi should be disabled", UIUtil.isJreHiDPI(g));
}
}
@@ -2,14 +2,26 @@
package com.intellij.util.ui;
import com.intellij.util.FieldAccessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.After;
import org.junit.Before;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
/**
* @author tav
*/
@SuppressWarnings("JUnitTestCaseWithNoTests")
public class TestScaleHelper {
private static final FieldAccessor<UIUtil, Boolean> JRE_HIDPI_ACCESSOR = new FieldAccessor<>(UIUtil.class, "jreHiDPI");
private static final FieldAccessor<UIUtil, AtomicReference<Boolean>> JRE_HIDPI_ACCESSOR =
new FieldAccessor<>(UIUtil.class, "jreHiDPI");
private static final Map<String, String> origProps = new HashMap<>();
private float originalUserScale;
private boolean originalJreHiDPIEnabled;
@@ -24,9 +36,37 @@ public class TestScaleHelper {
public void restoreState() {
JBUI.setUserScaleFactor(originalUserScale);
overrideJreHiDPIEnabled(originalJreHiDPIEnabled);
restoreProperties();
}
public static void setProperty(@NotNull String name, @Nullable String value) {
origProps.put(name, System.getProperty(name));
_setProperty(name, value);
}
private static void _setProperty(String name, String value) {
if (value != null) {
System.setProperty(name, value);
}
else {
System.clearProperty(name);
}
}
public static void restoreProperties() {
for (Map.Entry<String, String> entry : origProps.entrySet()) {
_setProperty(entry.getKey(), entry.getValue());
}
}
public static void overrideJreHiDPIEnabled(boolean enabled) {
JRE_HIDPI_ACCESSOR.set(null, enabled);
JRE_HIDPI_ACCESSOR.get(null).set(enabled);
}
public static Graphics2D createGraphics(double scale) {
//noinspection UndesirableClassUsage
Graphics2D g = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).createGraphics();
g.scale(scale, scale);
return g;
}
}
@@ -78,6 +78,7 @@ import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
/**
@@ -387,9 +388,9 @@ public class UIUtil {
return isJreHiDPIEnabled() && JBUI.isHiDPI(JBUI.sysScale(ctx));
}
// accessed from com.intellij.util.ui.paint.AbstractPainter2D via reflect
private static Boolean jreHiDPI;
private static boolean jreHiDPI_earlierVersion;
// accessed from com.intellij.util.ui.TestScaleHelper via reflect
private static final AtomicReference<Boolean> jreHiDPI = new AtomicReference<Boolean>();
private static volatile boolean jreHiDPI_earlierVersion;
/**
* Returns whether the JRE-managed HiDPI mode is enabled.
@@ -398,30 +399,36 @@ public class UIUtil {
* @see JBUI.ScaleType
*/
public static boolean isJreHiDPIEnabled() {
if (jreHiDPI != null) {
return jreHiDPI;
}
jreHiDPI = false;
jreHiDPI_earlierVersion = true;
if (SystemInfo.isLinux) {
return false; // pending support
}
if (SystemInfo.isJetBrainsJvm) {
try {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (ge instanceof SunGraphicsEnvironment) {
Method m = ReflectionUtil.getDeclaredMethod(SunGraphicsEnvironment.class, "isUIScaleOn");
jreHiDPI = (Boolean)m.invoke(ge);
jreHiDPI_earlierVersion = false;
if (jreHiDPI.get() != null) return jreHiDPI.get();
synchronized (jreHiDPI) {
if (jreHiDPI.get() != null) return jreHiDPI.get();
jreHiDPI.set(false);
if (SystemProperties.has("hidpi") && !SystemProperties.is("hidpi")) {
return false;
}
jreHiDPI_earlierVersion = true;
if (SystemInfo.isLinux) {
return false; // pending support
}
if (SystemInfo.isJetBrainsJvm) {
try {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (ge instanceof SunGraphicsEnvironment) {
Method m = ReflectionUtil.getDeclaredMethod(SunGraphicsEnvironment.class, "isUIScaleOn");
jreHiDPI.set(m != null && (Boolean)m.invoke(ge));
jreHiDPI_earlierVersion = false;
}
}
catch (Throwable ignore) {
}
}
catch (Throwable ignore) {
if (SystemInfo.isMac) {
jreHiDPI.set(true);
}
return jreHiDPI.get();
}
if (SystemInfo.isMac) {
jreHiDPI = true;
}
return jreHiDPI;
}
/**