Skip to content

Commit

Permalink
JBR-6213 Wayland: removed blurring on cursor on multiple monitors wit…
Browse files Browse the repository at this point in the history
…h different scales
  • Loading branch information
dmitriimorskii authored and jbrbot committed Nov 8, 2024
1 parent e946179 commit fa7844d
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 23 deletions.
13 changes: 13 additions & 0 deletions src/java.desktop/share/classes/java/awt/Cursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
Expand Down Expand Up @@ -192,11 +193,23 @@ public class Cursor implements java.io.Serializable {

AWTAccessor.setCursorAccessor(
new AWTAccessor.CursorAccessor() {
private final HashMap<Integer, Integer> actualCursorScale = new HashMap<>();

public long getPData(Cursor cursor, int scale) {
return (actualCursorScale.getOrDefault(cursor.getType(), 0) == scale) ? cursor.pData : 0;
}

public long getPData(Cursor cursor) {
return cursor.pData;
}

public void setPData(Cursor cursor, int scale, long pData) {
actualCursorScale.put(cursor.getType(), scale);
cursor.pData = pData;
}

public void setPData(Cursor cursor, long pData) {
actualCursorScale.remove(cursor.getType());
cursor.pData = pData;
}

Expand Down
10 changes: 10 additions & 0 deletions src/java.desktop/share/classes/sun/awt/AWTAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -639,11 +639,21 @@ public interface CheckboxMenuItemAccessor {
* An accessor for the Cursor class
*/
public interface CursorAccessor {
/**
* Returns pData of the Cursor class according to scale or 0 otherwise
*/
long getPData(Cursor cursor, int scale);

/**
* Returns pData of the Cursor class
*/
long getPData(Cursor cursor);

/**
* Sets pData to the Cursor class according to scale
*/
void setPData(Cursor cursor, int scale, long pData);

/**
* Sets pData to the Cursor class
*/
Expand Down
29 changes: 18 additions & 11 deletions src/java.desktop/unix/classes/sun/awt/wl/WLComponentPeer.java
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ private void updateCursorImmediately(WLInputState inputState) {
WLComponentPeer peer = inputState.getPeer();
if (peer == null) return;
Cursor cursor = peer.getCursor(inputState.getPointerX(), inputState.getPointerY());
setCursor(cursor);
setCursor(cursor, getGraphicsDevice() != null ? getGraphicsDevice().getScale() : 1);
}

Cursor getCursor(int x, int y) {
Expand All @@ -780,35 +780,41 @@ Cursor getCursor(int x, int y) {
return AWTAccessor.getComponentAccessor().getCursor(target);
}

private static void setCursor(Cursor c) {
private static void setCursor(Cursor c, int scale) {
Cursor cursor;
if (c.getType() == Cursor.CUSTOM_CURSOR && !(c instanceof WLCustomCursor)) {
cursor = Cursor.getDefaultCursor();
} else {
cursor = c;
}
performLockedGlobal(() -> {
long pData = AWTAccessor.getCursorAccessor().getPData(cursor);
long pData = AWTAccessor.getCursorAccessor().getPData(cursor, scale);
if (pData == 0) {
pData = createNativeCursor(cursor.getType());
// instead of destroying and creating new cursor after changing scale could be used caching
long oldPData = AWTAccessor.getCursorAccessor().getPData(cursor);
if (oldPData != 0) {
nativeDestroyPredefinedCursor(oldPData);
}

pData = createNativeCursor(cursor.getType(), scale);
if (pData == 0) {
pData = createNativeCursor(Cursor.DEFAULT_CURSOR);
pData = createNativeCursor(Cursor.DEFAULT_CURSOR, scale);
}
if (pData == 0) {
pData = -1; // mark as unavailable
}
AWTAccessor.getCursorAccessor().setPData(cursor, pData);
AWTAccessor.getCursorAccessor().setPData(cursor, scale, pData);
}
nativeSetCursor(pData);
nativeSetCursor(pData, scale);
});
}

private static long createNativeCursor(int type) {
private static long createNativeCursor(int type, int scale) {
if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
type = Cursor.DEFAULT_CURSOR;
}
for (String name : CURSOR_NAMES[type]) {
long pData = nativeGetPredefinedCursor(name);
long pData = nativeGetPredefinedCursor(name, scale);
if (pData != 0) {
return pData;
}
Expand Down Expand Up @@ -962,8 +968,9 @@ protected native void nativeRepositionWLPopup(long ptr,
private native void nativeSetWindowGeometry(long ptr, int x, int y, int width, int height);
private native void nativeSetMinimumSize(long ptr, int width, int height);
private native void nativeSetMaximumSize(long ptr, int width, int height);
private static native void nativeSetCursor(long pData);
private static native long nativeGetPredefinedCursor(String name);
private static native void nativeSetCursor(long pData, int scale);
private static native long nativeGetPredefinedCursor(String name, int scale);
private static native long nativeDestroyPredefinedCursor(long pData);
private native void nativeShowWindowMenu(long ptr, int x, int y);
private native void nativeActivate(long ptr);

Expand Down
21 changes: 16 additions & 5 deletions src/java.desktop/unix/native/libawt_wlawt/WLCursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <jni_util.h>

#include "WLToolkit.h"
#include "WLGraphicsEnvironment.h"

struct WLCursor {
struct wl_buffer *buffer;
Expand Down Expand Up @@ -58,16 +59,18 @@ Java_java_awt_Cursor_finalizeImpl
}

JNIEXPORT jlong JNICALL Java_sun_awt_wl_WLComponentPeer_nativeGetPredefinedCursor
(JNIEnv *env, jclass cls, jstring name)
(JNIEnv *env, jclass cls, jstring name, jint scale)
{
if (!wl_cursor_theme)
struct wl_cursor_theme *cursor_theme = getCursorTheme(scale);

if (!cursor_theme)
return 0;

jboolean isCopy = JNI_FALSE;
const char *name_c_str = JNU_GetStringPlatformChars(env, name, &isCopy);
if (!name_c_str)
return 0;
struct wl_cursor *wl_cursor = wl_cursor_theme_get_cursor(wl_cursor_theme, name_c_str);
struct wl_cursor *wl_cursor = wl_cursor_theme_get_cursor(cursor_theme, name_c_str);
if (isCopy) {
JNU_ReleaseStringPlatformChars(env, name, name_c_str);
}
Expand All @@ -88,6 +91,12 @@ JNIEXPORT jlong JNICALL Java_sun_awt_wl_WLComponentPeer_nativeGetPredefinedCurso
return ptr_to_jlong(cursor);
}

JNIEXPORT void JNICALL Java_sun_awt_wl_WLComponentPeer_nativeDestroyPredefinedCursor
(JNIEnv *env, jclass cls, struct WLCursor *cursor)
{
free(cursor);
}

JNIEXPORT jlong JNICALL Java_sun_awt_wl_WLCustomCursor_nativeCreateCustomCursor
(JNIEnv *env, jclass cls, jintArray pixels, jint width, jint height, jint xHotSpot, jint yHotSpot)
{
Expand Down Expand Up @@ -131,7 +140,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_wl_WLCustomCursor_nativeCreateCustomCursor
}

JNIEXPORT void JNICALL Java_sun_awt_wl_WLComponentPeer_nativeSetCursor
(JNIEnv *env, jclass cls, jlong pData)
(JNIEnv *env, jclass cls, jlong pData, jint scale)
{
struct wl_buffer *buffer = NULL;
int32_t width = 0;
Expand Down Expand Up @@ -161,6 +170,7 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_WLComponentPeer_nativeSetCursor
if (buffer != last_buffer) {
last_buffer = buffer;
wl_surface_attach(wl_cursor_surface, buffer, 0, 0);
wl_surface_set_buffer_scale(wl_cursor_surface, scale);
wl_surface_damage_buffer(wl_cursor_surface, 0, 0, width, height);
wl_surface_commit(wl_cursor_surface);
}
Expand All @@ -169,7 +179,8 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_WLComponentPeer_nativeSetCursor
last_serial = last_pointer_enter_serial;
last_hotspot_x = hotspot_x;
last_hotspot_y = hotspot_y;
wl_pointer_set_cursor(wl_pointer, last_pointer_enter_serial, wl_cursor_surface, hotspot_x, hotspot_y);
wl_pointer_set_cursor(wl_pointer, last_pointer_enter_serial, wl_cursor_surface,
hotspot_x / scale, hotspot_y / scale);
wlFlushToServer(env);
}
}
24 changes: 17 additions & 7 deletions src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ struct wl_seat *wl_seat = NULL;
struct wl_keyboard *wl_keyboard;
struct wl_pointer *wl_pointer;

struct wl_cursor_theme *wl_cursor_theme = NULL;
#define MAX_CURSOR_SCALE 100
struct wl_cursor_theme *cursor_themes[MAX_CURSOR_SCALE] = {NULL};

struct wl_surface *wl_surface_in_focus = NULL;
struct wl_data_device_manager *wl_ddm = NULL;
Expand Down Expand Up @@ -673,8 +674,12 @@ readDesktopProperty(const char* name, char *output, int outputSize) {
return pclose(fd) ? NULL : res;
}

static void
initCursors() {
struct wl_cursor_theme*
getCursorTheme(int scale) {
if (cursor_themes[scale]) {
return cursor_themes[scale];
}

char *theme_name;
int theme_size = 0;
char buffer[256];
Expand Down Expand Up @@ -702,10 +707,17 @@ initCursors() {
}
}

wl_cursor_theme = wl_cursor_theme_load(theme_name, theme_size, wl_shm);
if (!wl_cursor_theme) {
if (scale >= MAX_CURSOR_SCALE) {
J2dTrace(J2D_TRACE_ERROR, "WLToolkit: Reach the maximum scale for cursor theme\n");
return NULL;
}

cursor_themes[scale] = wl_cursor_theme_load(theme_name, theme_size * scale, wl_shm);
if (!cursor_themes[scale]) {
J2dTrace(J2D_TRACE_ERROR, "WLToolkit: Failed to load cursor theme\n");
}

return cursor_themes[scale];
}

static void
Expand Down Expand Up @@ -756,8 +768,6 @@ Java_sun_awt_wl_WLToolkit_initIDs

J2dTrace1(J2D_TRACE_INFO, "WLToolkit: Connection to display(%p) established\n", wl_display);

initCursors();

finalizeInit(env);
}

Expand Down
1 change: 1 addition & 0 deletions src/java.desktop/unix/native/libawt_wlawt/WLToolkit.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,6 @@ extern uint32_t last_input_or_focus_serial;
JNIEnv *getEnv();

int wlFlushToServer(JNIEnv* env);
struct wl_cursor_theme *getCursorTheme(int scale);

struct wl_shm_pool *CreateShmPool(size_t size, const char *name, void **data);

0 comments on commit fa7844d

Please sign in to comment.