mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-1429 Scale is huge due to GDK_SCALE
(cherry picked from commit 1c3477df2e)
This commit is contained in:
committed by
alexey.ushakov@jetbrains.com
parent
b581a10ce9
commit
dd8712b550
@@ -1457,7 +1457,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
|
||||
if (dpi < 50) {
|
||||
dpi = 50;
|
||||
}
|
||||
X11GraphicsDevice.setGlobalDPI(dpi);
|
||||
X11GraphicsDevice.setXftDpi(dpi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import sun.awt.util.ThreadGroupUtils;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
@@ -68,12 +69,27 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
private DisplayMode origDisplayMode;
|
||||
private boolean shutdownHookRegistered;
|
||||
private int scale;
|
||||
private volatile boolean isNativeScaleDefault;
|
||||
private static int globalScale; // derived from Xft.dpi
|
||||
private final AtomicBoolean isScaleFactorDefault = new AtomicBoolean(false);
|
||||
private static final int XRM_XFT_DPI;
|
||||
private static volatile int XFT_DPI;
|
||||
private static final int GDK_SCALE;
|
||||
private static final double GDK_DPI_SCALE;
|
||||
private static final double GDK_SCALE_MULTIPLIER;
|
||||
|
||||
public X11GraphicsDevice(int screennum) {
|
||||
this.screen = screennum;
|
||||
this.scale = initScaleFactor();
|
||||
int scaleFactor = initScaleFactor(-1);
|
||||
synchronized (isScaleFactorDefault) {
|
||||
isScaleFactorDefault.set(scaleFactor == -1);
|
||||
this.scale = isScaleFactorDefault.get() ? 1 : scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
xrmXftDpi = getXrmXftDpi(-1);
|
||||
GDK_SCALE = (int)getGdkScale("GDK_SCALE", -1);
|
||||
GDK_DPI_SCALE = getGdkScale("GDK_DPI_SCALE", -1);
|
||||
GDK_SCALE_MULTIPLIER = GDK_SCALE != -1 ? GDK_SCALE * (GDK_DPI_SCALE != -1 ? GDK_DPI_SCALE : 1) : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,8 +313,11 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
private static native void configDisplayMode(int screen,
|
||||
int width, int height,
|
||||
int displayMode);
|
||||
private static native double getNativeScaleFactor(int screen);
|
||||
private static native void resetNativeData(int screen);
|
||||
private native Rectangle pGetBounds(int screenNum);
|
||||
private static native double getNativeScaleFactor(int screen, double defValue);
|
||||
private static native double getGdkScale(String name, double defValue);
|
||||
private static native int getXrmXftDpi(int defValue);
|
||||
|
||||
/**
|
||||
* Returns true only if:
|
||||
@@ -506,7 +525,7 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
*/
|
||||
@Override
|
||||
public synchronized void displayChanged() {
|
||||
scale = initScaleFactor();
|
||||
scale = initScaleFactor(1);
|
||||
// On X11 the visuals do not change, and therefore we don't need
|
||||
// to reset the defaultConfig, config, doubleBufferVisuals,
|
||||
// neither do we need to reset the native data.
|
||||
@@ -536,39 +555,66 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
return scale;
|
||||
}
|
||||
|
||||
public int getNativeScale() {
|
||||
return (int)Math.round(getNativeScaleFactor(screen));
|
||||
private double getNativeScale() {
|
||||
isXrandrExtensionSupported();
|
||||
return getNativeScaleFactor(screen, -1);
|
||||
}
|
||||
|
||||
public static void setGlobalDPI(int dpi) {
|
||||
public static void setXftDpi(int dpi) {
|
||||
XFT_DPI = dpi;
|
||||
boolean uiScaleEnabled = SunGraphicsEnvironment.isUIScaleEnabled(dpi);
|
||||
globalScale = uiScaleEnabled ? (int)Math.round(dpi / 96.0) : 1;
|
||||
double xftDpiScale = uiScaleEnabled ? XFT_DPI / 96.0 : 1.0;
|
||||
for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
|
||||
X11GraphicsDevice x11gd = (X11GraphicsDevice)gd;
|
||||
if (x11gd.isNativeScaleDefault || !uiScaleEnabled) {
|
||||
x11gd.scale = globalScale;
|
||||
x11gd.isNativeScaleDefault = false;
|
||||
synchronized (x11gd.isScaleFactorDefault) {
|
||||
if (x11gd.isScaleFactorDefault.get() || !uiScaleEnabled) {
|
||||
x11gd.scale = (int)Math.round(xftDpiScale * (uiScaleEnabled ? GDK_SCALE_MULTIPLIER : 1));
|
||||
x11gd.isScaleFactorDefault.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int initScaleFactor() {
|
||||
|
||||
if (SunGraphicsEnvironment.isUIScaleEnabled()) {
|
||||
|
||||
private int initScaleFactor(int defValue) {
|
||||
boolean uiScaleEnabled = SunGraphicsEnvironment.isUIScaleEnabled();
|
||||
if (uiScaleEnabled) {
|
||||
double debugScale = SunGraphicsEnvironment.getDebugScale();
|
||||
|
||||
if (debugScale >= 1) {
|
||||
return (int) debugScale;
|
||||
}
|
||||
int nativeScale = getNativeScale();
|
||||
if (nativeScale > 0) return nativeScale;
|
||||
if (globalScale > 0) return globalScale;
|
||||
isNativeScaleDefault = true;
|
||||
return 1;
|
||||
double gdkScaleMult = uiScaleEnabled ? GDK_SCALE_MULTIPLIER : 1;
|
||||
double nativeScale = getNativeScale();
|
||||
if (nativeScale > 0) {
|
||||
return (int)Math.round(nativeScale * gdkScaleMult);
|
||||
}
|
||||
if (XRM_XFT_DPI > 0) {
|
||||
return (int)Math.round((XRM_XFT_DPI / 96.0) * gdkScaleMult);
|
||||
}
|
||||
if (XFT_DPI > 0) {
|
||||
return (int)Math.round((XFT_DPI / 96.0) * gdkScaleMult);
|
||||
}
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
return 1;
|
||||
/**
|
||||
* Used externally for diagnostic purpose.
|
||||
*/
|
||||
public String[][] getDpiInfo() {
|
||||
int xftDpi = XRM_XFT_DPI != -1 ? XRM_XFT_DPI : XFT_DPI;
|
||||
String xftDpiStr = xftDpi != -1 ? String.valueOf(xftDpi) : "undefined";
|
||||
double gsettingsScale = getNativeScaleFactor(screen, -1);
|
||||
String gsettingsScaleStr = gsettingsScale != -1 ? String.valueOf(gsettingsScale) : "undefined";
|
||||
String gdkScaleStr = GDK_SCALE != -1 ? String.valueOf(GDK_SCALE) : "undefined";
|
||||
String gdkDpiScaleStr = GDK_DPI_SCALE != -1 ? String.valueOf(GDK_DPI_SCALE) : "undefined";
|
||||
|
||||
return new String[][] {
|
||||
{"Xft.DPI", xftDpiStr, "Font DPI (X resources value)"},
|
||||
{"GSettings scale factor", gsettingsScaleStr, "http://wiki.archlinux.org/index.php/HiDPI"},
|
||||
{"GDK_SCALE", gdkScaleStr, "http://developer.gnome.org/gtk3/stable/gtk-x11.html"},
|
||||
{"GDK_DPI_SCALE", gdkDpiScaleStr, "http://developer.gnome.org/gtk3/stable/gtk-x11.html"}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <xlocale.h>
|
||||
#endif
|
||||
|
||||
typedef void* g_settings_schema_source_get_default();
|
||||
typedef void* g_settings_schema_source_ref(void *);
|
||||
@@ -204,16 +209,17 @@ static double getDesktopScale(char *output_name) {
|
||||
|
||||
}
|
||||
|
||||
static int getScale(const char *name) {
|
||||
double getScaleEnvVar(const char *name, double default_value) {
|
||||
char *uiScale = getenv(name);
|
||||
if (uiScale != NULL) {
|
||||
double scale = strtod(uiScale, NULL);
|
||||
if (scale < 1) {
|
||||
return -1;
|
||||
locale_t c_locale = newlocale(LC_NUMERIC_MASK, "C", NULL);
|
||||
double scale = strtod_l(uiScale, NULL, c_locale);
|
||||
freelocale(c_locale);
|
||||
if (scale > 0) {
|
||||
return scale;
|
||||
}
|
||||
return (int) scale;
|
||||
}
|
||||
return -1;
|
||||
return default_value;
|
||||
}
|
||||
|
||||
double getNativeScaleFactor(char *output_name, double default_value) {
|
||||
@@ -222,7 +228,7 @@ double getNativeScaleFactor(char *output_name, double default_value) {
|
||||
int gdk_scale = 0;
|
||||
|
||||
if (scale == -2) {
|
||||
scale = getScale("J2D_UISCALE");
|
||||
scale = (int)getScaleEnvVar("J2D_UISCALE", -1);
|
||||
}
|
||||
|
||||
if (scale > 0) {
|
||||
@@ -235,7 +241,5 @@ double getNativeScaleFactor(char *output_name, double default_value) {
|
||||
native_scale = default_value;
|
||||
}
|
||||
|
||||
gdk_scale = getScale("GDK_SCALE");
|
||||
|
||||
return gdk_scale > 0 ? (native_scale <= 0 ? 1 : native_scale) * gdk_scale : native_scale;
|
||||
return native_scale;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
double getNativeScaleFactor(char *output_name, double default_value);
|
||||
double getScaleEnvVar(const char* var_name, double default_value);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2057,40 +2057,64 @@ static char *get_output_screen_name(JNIEnv *env, int screen) {
|
||||
/*
|
||||
* Class: sun_awt_X11GraphicsDevice
|
||||
* Method: getNativeScaleFactor
|
||||
* Signature: (I)D
|
||||
* Signature: (ID)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor
|
||||
(JNIEnv *env, jobject this, jint screen) {
|
||||
(JNIEnv *env, jobject this, jint screen, jdouble defValue) {
|
||||
// in case of Xinerama individual screen scales are not supported
|
||||
char *name = get_output_screen_name(env, usingXinerama ? 0 : screen);
|
||||
double scale = getNativeScaleFactor(name, -1);
|
||||
|
||||
#ifndef HEADLESS
|
||||
// Ubuntu 18.04 introduced a new settings for a scale factor: Settings > Devices > Displays > Scale.
|
||||
// It is propagated to Xresource (and is read fine with 'xrdb' util) but is not propagated to GSettings
|
||||
// (gtk3 doesn't see it in 'gtk-xft-dpi'). So, retrieve "Xft.dpi" from Xresource via X11 API call.
|
||||
if (scale <= 0) {
|
||||
Display *display = XOpenDisplay(NULL); // need to open new display to get up-to-date XResource value
|
||||
if (display) {
|
||||
char *resource_manager = XResourceManagerString(display);
|
||||
if (resource_manager) {
|
||||
XrmDatabase db = XrmGetStringDatabase(resource_manager);
|
||||
if (db) {
|
||||
XrmValue value;
|
||||
char *type;
|
||||
if (XrmGetResource(db, "Xft.dpi", "Xft.dpi", &type, &value)) {
|
||||
scale = (double)atoi(value.addr) / 96;
|
||||
}
|
||||
}
|
||||
}
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
double scale = getNativeScaleFactor(name, defValue);
|
||||
if (name) {
|
||||
free(name);
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_X11GraphicsDevice
|
||||
* Method: getGdkScale
|
||||
* Signature: (Ljava/lang/String;D)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_sun_awt_X11GraphicsDevice_getGdkScale
|
||||
(JNIEnv *env, jobject this, jstring envVarName, jdouble defValue)
|
||||
{
|
||||
const char* name = (*env)->GetStringUTFChars(env, envVarName, 0);
|
||||
double value = getScaleEnvVar(name, defValue);
|
||||
(*env)->ReleaseStringUTFChars(env, envVarName, name);
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_X11GraphicsDevice
|
||||
* Method: getXrmXftDpi
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_awt_X11GraphicsDevice_getXrmXftDpi
|
||||
(JNIEnv *env, jobject this, jint defValue)
|
||||
{
|
||||
int dpi = defValue;
|
||||
#ifndef HEADLESS
|
||||
// Ubuntu 18.04 introduced a new settings for a scale factor: Settings > Devices > Displays > Scale.
|
||||
// It is propagated to Xresource (and is read fine with 'xrdb' util) but is not propagated to GSettings
|
||||
// (gtk3 doesn't see it in 'gtk-xft-dpi'). So, retrieve "Xft.dpi" from Xresource via X11 API call.
|
||||
Display *display = XOpenDisplay(NULL); // need to open new display to get up-to-date XResource value
|
||||
if (display) {
|
||||
char *resource_manager = XResourceManagerString(display);
|
||||
if (resource_manager) {
|
||||
XrmDatabase db = XrmGetStringDatabase(resource_manager);
|
||||
if (db) {
|
||||
XrmValue value;
|
||||
char *type;
|
||||
if (XrmGetResource(db, "Xft.dpi", "Xft.dpi", &type, &value)) {
|
||||
dpi = atoi(value.addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
#endif
|
||||
return dpi;
|
||||
}
|
||||
Reference in New Issue
Block a user