RFR: 8280861: Robot color picker broken on Linux with scaling above 100%

Sergey Bylokhov serb at openjdk.java.net
Fri Feb 11 07:32:12 UTC 2022


On Thu, 10 Feb 2022 14:08:48 GMT, Maxim Kartashev <duke at openjdk.java.net> wrote:

> The primary API for image capture on modern Linuxes is `gdk_pixbuf_get_from_window()` that expects both coordinates and the size unscaled (i.e. not multiplied by the current desktop scale). At the same time, `gtk3_interface.c:gtk3_get_drawable_data()` gets the coordinates from `Robot` that pre-scales them (multiplying by the scale known to Java, however, not necessarily the current desktop scale). The problem with the size had been partly taken care of in [JDK-8225118](https://bugs.openjdk.java.net/browse/JDK-8225118), but coordinates are still passed to `gdk_pixbuf_get_from_window()` pre-scaled.
> 
> The idea of the fix is to capture a possibly larger area that is guaranteed to contain the one that is interesting to the caller and then only copy the interesting pixels to the output image. As a positive side effect, the size of the captured area cannot be less than 1x1 (provided the correct input, of course). This solves the problem of zero size passed to  `(*fp_gdk_pixbuf_get_from_drawable)` when the desktop scale is 3 and we're asked to capture just one pixel. In that case, the previous formula (`width / (float) win_scale + 0.5`) would have yielded `0`. 
> 
> A related issue would be that tests written specifically for this general area (`java/awt/Robot`) didn't catch this problem and only somewhat unrelated tests (`javax/swing/...`) were affected.
> 
> This one is solved by adding pixel-sized areas to the test image in `HiDPIRobotScreenCaptureTest.java`, which precise colors are then verified to match the expected ones. In addition to that, instead of verifying just the color of the center of a large area, 4 more pixels close to the area's border are checked. This helps to make sure that captured area coordinates aren't way off.
> 
> The tests under `javax/swing/...` that originally helped to identify this problem were modified to provide more screen space for painting their components as extreme desktop scaling (300%) on Ubuntu doesn't leave much room due to a humongous title bar.
> 
> The fix was tested by running all the modified tests on Ubuntu with desktop scaling set to 100%, 200%, and 300%. The `Robot` tests were also executed on Windows (300% scaling) and MacOS.

src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c line 2876:

> 2874: static gboolean gtk3_get_drawable_data(JNIEnv *env, jintArray pixelArray,
> 2875:      int x, jint y, jint width, jint height, jint jwidth, int dx, int dy,
> 2876:                                                                    jint scale) {

Is this scale parameter is simply ignored? If the passed parameters are always in the device space and the array is allocated properly then we should not care about this scale(especially in case of gtk2)?

-------------

PR: https://git.openjdk.java.net/jdk/pull/7425



More information about the client-libs-dev mailing list