Compare commits

...

4 Commits

Author SHA1 Message Date
Nikita Gubarkov
c268a422d4 JBR-9856 Handle missing display configuration in CGraphicsDevice 2026-02-05 13:13:28 +01:00
Nikita Gubarkov
8aef93f914 JBR-9942 Vulkan: Glyph position rounding errors 2026-02-02 16:47:28 +01:00
Nikita Provotorov
18cd61aeac JBR-9534 Wayland: text-input-unstable-v3: don't bind to zwp_text_input_manager_v3 if IM support is disabled
* Introducing a new WLToolkit method isNativeInputMethodSupportEnabled
* Deciding whether to bind to a zwp_text_input_manager_v3 based on the value returned by the new method
2026-02-02 14:27:51 +01:00
Nikita Provotorov
e50f535947 fixup! JBR-9817 Wayland: text-input-unstable-v3: Japanese input text partially highlighted in search
Removing AccessController from the new code.
2026-01-31 02:59:16 +01:00
6 changed files with 101 additions and 38 deletions

View File

@@ -391,7 +391,7 @@ public final class CGraphicsDevice extends GraphicsDevice
map.put(displayID, new Descriptor(new Insets(top, left, bottom, right), scale));
}
public Descriptor getDescriptor(int displayID) {
return map.get(displayID);
return map.getOrDefault(displayID, Descriptor.DEFAULT);
}
public static DisplayConfiguration get() {
try {
@@ -407,6 +407,7 @@ public final class CGraphicsDevice extends GraphicsDevice
}
private static final class Descriptor {
private static final Descriptor DEFAULT = new Descriptor(new Insets(0, 0, 0, 0), 1.0);
private final Insets screenInsets;
private final double scale;
private Descriptor(Insets screenInsets, double scale) {

View File

@@ -24,6 +24,7 @@
* questions.
*/
#include <math.h>
#include "sun_font_StrikeCache.h"
#include "sun_java2d_pipe_BufferedOpCodes.h"
#include "sun_java2d_pipe_BufferedRenderPipe.h"
@@ -315,11 +316,23 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
}
if (ginfo->format != sun_font_StrikeCache_PIXEL_FORMAT_GREYSCALE) continue;
if (ginfo->height*ginfo->rowBytes == 0) continue;
VKRenderer_MaskFill((int) glyphx, (int) glyphy,
// Calculate subpixel offset.
int rx = ginfo->subpixelResolutionX, ry = ginfo->subpixelResolutionY;
int x = floor(glyphx), y = floor(glyphy);
int xOffset, yOffset;
if ((rx == 1 && ry == 1) || rx <= 0 || ry <= 0) {
xOffset = yOffset = 0;
} else {
xOffset = (int) ((glyphx - (float) x) * (float) rx);
yOffset = (int) ((glyphy - (float) y) * (float) ry);
}
VKRenderer_MaskFill(x, y,
ginfo->width, ginfo->height,
0, ginfo->rowBytes,
ginfo->height * ginfo->rowBytes,
ginfo->image);
ginfo->image + (ginfo->rowBytes * ginfo->height) * (xOffset + yOffset * rx));
}
SKIP_BYTES(b, numGlyphs * bytesPerGlyph);
}

View File

@@ -151,6 +151,9 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
private static native void initIDs(long displayPtr);
static {
// This field must be initialized BEFORE initIDs is called because it'll be read there
ENABLE_NATIVE_IM_SUPPORT = obtainWhetherToEnableNativeIMSupport();
if (!GraphicsEnvironment.isHeadless()) {
keyboard = new WLKeyboard();
long display = WLDisplay.getInstance().getDisplayPtr();
@@ -256,6 +259,39 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
return peer;
}
// This method is directly used by native code at the class loading stage, be careful with changing it in any way.
public static boolean isNativeInputMethodSupportEnabled() {
return ENABLE_NATIVE_IM_SUPPORT;
}
/**
* This flag allows disabling ALL integrations with native IMs. The idea is to allow users to disable
* unnecessary for them functionality if they face any problems because of it.
* Therefore, if it's {@code false}, the Toolkit code shouldn't use (directly or indirectly)
* any of Wayland's input methods-related APIs (e.g. the "text-input" protocol).
*/
private final static boolean ENABLE_NATIVE_IM_SUPPORT;
private static boolean obtainWhetherToEnableNativeIMSupport() {
// NB: make sure this default value is synchronized with the one used in the native function
// isNativeInputMethodSupportEnabled() in WLToolkit.c
boolean result = true;
try {
result = Boolean.parseBoolean(System.getProperty("sun.awt.wl.im.enabled", "true"));
} catch (Exception err) {
log.severe(
String.format(
"Failed to read the value of the system property \"sun.awt.wl.im.enabled\". Assuming the default value(=%b).",
result
),
err
);
}
return result;
}
/**
* Wayland events coming to queues other that the default are handled here.
* The code is executed on a separate thread and must not call any user code.
@@ -893,7 +929,15 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
*/
@Override
public InputMethodDescriptor getInputMethodAdapterDescriptor() {
return WLInputMethodMetaDescriptor.getInstanceIfAvailableOnPlatform();
final InputMethodDescriptor result = ENABLE_NATIVE_IM_SUPPORT
? WLInputMethodMetaDescriptor.getInstanceIfAvailableOnPlatform()
: null;
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("getInputMethodAdapterDescriptor(): ENABLE_NATIVE_IM_SUPPORT={0}, result={1}.", ENABLE_NATIVE_IM_SUPPORT, result);
}
return result;
}
/**

View File

@@ -25,6 +25,7 @@
package sun.awt.wl.im;
import sun.awt.wl.WLToolkit;
import sun.awt.wl.im.text_input_unstable_v3.WLInputMethodDescriptorZwpTextInputV3;
import sun.util.logging.PlatformLogger;
@@ -88,8 +89,9 @@ public final class WLInputMethodMetaDescriptor implements InputMethodDescriptor
public static WLInputMethodMetaDescriptor getInstanceIfAvailableOnPlatform() {
final WLInputMethodMetaDescriptor result;
final boolean enableNativeImSupport = WLToolkit.isNativeInputMethodSupportEnabled();
if (!ENABLE_NATIVE_IM_SUPPORT) {
if (!enableNativeImSupport) {
result = null;
} else {
// For now there's only 1 possible implementation of IM,
@@ -104,10 +106,6 @@ public final class WLInputMethodMetaDescriptor implements InputMethodDescriptor
}
}
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("getInstanceIfAvailableOnPlatform(): result={0}, ENABLE_NATIVE_IM_SUPPORT={1}.", result, ENABLE_NATIVE_IM_SUPPORT);
}
return result;
}
@@ -186,25 +184,6 @@ public final class WLInputMethodMetaDescriptor implements InputMethodDescriptor
TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON
);
/**
* This flag allows disabling ALL integrations with native IMs. The idea is to allow users to disable
* unnecessary for them functionality if they face any problems because of it.
* Therefore, if it's {@code false}, the Toolkit code shouldn't use (directly or indirectly)
* any of Wayland's input methods-related APIs (e.g. the "text-input" protocol).
*/
private final static boolean ENABLE_NATIVE_IM_SUPPORT;
static {
boolean enableNativeImSupportInitializer = true;
try {
enableNativeImSupportInitializer = Boolean.parseBoolean(System.getProperty("sun.awt.wl.im.enabled", "true"));
} catch (Exception err) {
log.severe("Failed to read the value of the system property \"sun.awt.wl.im.enabled\". Assuming the default value(=true).", err);
}
ENABLE_NATIVE_IM_SUPPORT = enableNativeImSupportInitializer;
}
private final InputMethodDescriptor realImDescriptor;

View File

@@ -28,8 +28,6 @@ package sun.awt.wl.im.text_input_unstable_v3;
import sun.awt.UNIXToolkit;
import java.awt.Toolkit;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
@@ -70,12 +68,7 @@ final class CurrentDesktopInfo {
result = -1;
} else if (Toolkit.getDefaultToolkit() instanceof UNIXToolkit unixToolkit) {
try {
@SuppressWarnings("removal")
final Integer version = AccessController.doPrivileged(
(PrivilegedAction<Integer>)unixToolkit::getGnomeShellMajorVersion
);
result = Objects.requireNonNullElse(version, -1);
result = Objects.requireNonNullElse(unixToolkit.getGnomeShellMajorVersion(), -1);
} catch (Exception ignored) {
result = -1;
}

View File

@@ -139,6 +139,8 @@ static jmethodID dispatchKeyboardLeaveEventMID;
static jmethodID dispatchRelativePointerEventMID;
static jmethodID handleToplevelIconSizeMID;
static jmethodID isNativeInputMethodSupportEnabledMID;
JNIEnv *getEnv() {
JNIEnv *env;
// assuming we're always called from a Java thread
@@ -602,6 +604,29 @@ static const struct xdg_toplevel_icon_manager_v1_listener xdg_toplevel_icon_mana
.done = xdg_toplevel_icon_manager_icon_size_done,
};
static bool isNativeInputMethodSupportEnabled(void) {
// NB: make sure this default value is synchronized with the one used in
// sun.awt.wl.WLToolkit#obtainWhetherToEnableNativeIMSupport
const bool deflt = true;
JNIEnv * const env = getEnv();
jboolean upcallResult;
if (env == NULL) {
return deflt;
}
upcallResult = (*env)->CallStaticBooleanMethod(env, tkClass, isNativeInputMethodSupportEnabledMID);
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return deflt;
}
return (upcallResult == JNI_TRUE) ? true : false;
}
static void
registry_global(void *data, struct wl_registry *wl_registry,
uint32_t name, const char *interface, uint32_t version)
@@ -663,8 +688,11 @@ registry_global(void *data, struct wl_registry *wl_registry,
// the event loop may shut down as soon as it gets launched (wl_display_dispatch will return -1),
// so let's protect from this since the component being obtained is not vital for work.
const uint32_t versionToBind = 1;
if (versionToBind <= version) {
zwp_text_input_manager = wl_registry_bind(wl_registry, name, &zwp_text_input_manager_v3_interface, versionToBind);
if (isNativeInputMethodSupportEnabled()) {
if (versionToBind <= version) {
zwp_text_input_manager = wl_registry_bind(wl_registry, name, &zwp_text_input_manager_v3_interface, versionToBind);
}
}
} else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) {
xdg_decoration_manager = wl_registry_bind(wl_registry, name, &zxdg_decoration_manager_v1_interface, 1);
@@ -817,6 +845,11 @@ initJavaRefs(JNIEnv *env, jclass clazz)
"(DD)V"),
JNI_FALSE);
CHECK_NULL_RETURN(isNativeInputMethodSupportEnabledMID = (*env)->GetStaticMethodID(env, tkClass,
"isNativeInputMethodSupportEnabled",
"()Z"),
JNI_FALSE);
jclass wlgeClass = (*env)->FindClass(env, "sun/awt/wl/WLGraphicsEnvironment");
CHECK_NULL_RETURN(wlgeClass, JNI_FALSE);