JDK-8225118 : Robot.createScreenCapture() returns black image on HiDPI linux with gtk3
Type:Bug
Component:client-libs
Sub-Component:java.awt
Affected Version:11,12,13
Priority:P3
Status:Resolved
Resolution:Fixed
OS:linux
Submitted:2019-05-31
Updated:2022-01-28
Resolved:2019-06-06
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
Linux Ubuntu 18.04 with gtk3 available. 4k screen set to 200% scale.
Robot.createScreenCapture() returns a black screenshot, and so does Robot.createMultiResolutionScreenCapture().
Comments
This fix caused a regression here : https://bugs.openjdk.java.net/browse/JDK-8226654
webrev: http://cr.openjdk.java.net/~ant/JDK-8225118/webrev.0
The problem with Robot.createScreenCapture() on gtk3 is in the following function call (quoting from gtk3_interface.h):
fp_gdk_pixbuf_get_from_drawable = dl_symbol("gdk_pixbuf_get_from_window")
which, as you can see, is resolved to another function in gtk3 (unlike gtk2) due to its deprecation.
The spec [1] states that the passed size is scaled:
"the width and height arguments scaled by the scale factor of window"
however this fact is not taken into account and so the returned pixbuf has wrong size and is then ignored.
To meet the spec, I retrieve the root window scale and downscale the size, ceiling the result. Also, I weaken the condition where the pixbuf size is compared to the passed size, from "==" to ">=". My reasoning is this:
1) The original passed size (of the screen) may appear to be lossy due to downscaling/upscaling ops.
2) The weakened condition is enough for the valid pixbuf copying.
The test (which I've modified to allow its run on Linux) reproduces the issue.
[1] https://developer.gnome.org/gdk3/stable/gdk3-Pixbufs.html#gdk-pixbuf-get-from-window