JBR-5316 Fix fractional scaling HIDPI.

(cherry picked from commit acb62617d7)
This commit is contained in:
ngubarkov
2023-03-22 22:45:52 +02:00
committed by jbrbot
parent 4e6dd040f3
commit e867c5e0b4
3 changed files with 43 additions and 12 deletions

View File

@@ -143,6 +143,32 @@ static void* get_schema_value(char *name, char *key) {
return NULL;
}
// When monitor framebuffer scaling enabled, compositor scales down monitor resolutions according to their scales,
// so that we're working in logical, not device pixels, just like in macOS. This approach is used for implementing
// fractional scaling, so basically this function tells you whether fractional scaling is enabled or not.
int isMonitorFramebufferScalingEnabled() {
int result = 0;
void* features = get_schema_value("org.gnome.mutter", "experimental-features");
if (features) {
if (fp_g_variant_is_of_type(features, "as")) {
int numFeatures = fp_g_variant_n_children(features);
for (int i = 0; i < numFeatures; i++) {
void* feature = fp_g_variant_get_child_value(features, i);
if (feature) {
char* name = fp_g_variant_get_string(feature, NULL);
if (name && strcmp(name, "scale-monitor-framebuffer") == 0) {
result = 1;
}
fp_g_variant_unref(feature);
if (result) break;
}
}
}
fp_g_variant_unref(features);
}
return result;
}
static double getDesktopScale(char *output_name) {
double result = -1;

View File

@@ -30,6 +30,7 @@
double getNativeScaleFactor(char *output_name, double default_value);
double getScaleEnvVar(const char* var_name, double default_value);
int isMonitorFramebufferScalingEnabled();
#endif

View File

@@ -801,24 +801,28 @@ Java_sun_awt_X11GraphicsEnvironment_updateWaylandMonitorScaling(JNIEnv *env, jcl
if (!usingXinerama || !wlLibHandle) return;
struct UpdateWaylandMonitorsData monData;
monData.xinInfo = (*XineramaQueryScreens)(awt_display, &monData.xinScreens);
if (monData.xinInfo == NULL) return;
wl_display* display = wl_display_connect(NULL);
if (display == NULL) return;
monData.waylandMonitorScales = calloc(monData.xinScreens, sizeof(int32_t));
monData.currentWaylandMonitor = -1;
monData.currentWaylandScale = 1;
monData.waylandMonitorScales = NULL;
if (!isMonitorFramebufferScalingEnabled()) {
monData.xinInfo = (*XineramaQueryScreens)(awt_display, &monData.xinScreens);
if (monData.xinInfo == NULL) return;
wl_display* display = wl_display_connect(NULL);
if (display == NULL) return;
monData.waylandMonitorScales = calloc(monData.xinScreens, sizeof(int32_t));
wl_registry* registry = wl_proxy_marshal_constructor(display, 1, wl_registry_interface, NULL); // wl_display_get_registry
wl_proxy_add_listener(registry, (void (**)(void)) &wlRegistryListener, &monData); // wl_registry_add_listener
wl_display_roundtrip(display); // Get globals (wl_outputs)
wl_display_roundtrip(display); // Get outputs info
wl_registry* registry = wl_proxy_marshal_constructor(display, 1, wl_registry_interface, NULL); // wl_display_get_registry
wl_proxy_add_listener(registry, (void (**)(void)) &wlRegistryListener, &monData); // wl_registry_add_listener
wl_display_roundtrip(display); // Get globals (wl_outputs)
wl_display_roundtrip(display); // Get outputs info
XFree(monData.xinInfo);
wl_display_disconnect(display);
XFree(monData.xinInfo);
}
int32_t* oldScales = waylandMonitorScales;
waylandMonitorScales = monData.waylandMonitorScales;
free(oldScales);
wl_display_disconnect(display);
}
/*