JDK-8271398 : GTK3 drag view image swaps red and blue color channels
  • Type: Bug
  • Component: javafx
  • Sub-Component: window-toolkit
  • Affected Version: jfx14,jfx16,jfx17
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86_64
  • Submitted: 2021-07-27
  • Updated: 2024-03-06
  • Resolved: 2021-09-17
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.

To download the current JDK release, click here.
Other
jfx17.0.11Fixed
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Tested with JavaFX 16, JDK 16 on Ubuntu 20.04 and Fedora 34.

A DESCRIPTION OF THE PROBLEM :
When setting an image as drag view during drag and drop it will be shown with incorrect colors. The red and blue color channels will be swapped.
Does not happen in JavaFX 13, happens in 14 and later. Most likely related to this change: https://bugs.openjdk.java.net/browse/JDK-8225571 - "Port Linux glass drag source (DND) to use gtk instead of gdk".

REGRESSION : Last worked in version 13

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a draggable control.
2. At drag start, set an image as drag view.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Drag view image displayed with correct colors.
ACTUAL -
Drag view image displayed with incorrect colors, red and blue channels are swapped.

---------- BEGIN SOURCE ----------
package com.example.bug;

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.awt.image.BufferedImage;

/**
 * Example code for JavaFX bug "GTK3 drag view image swaps red and blue color channels".
 *
 * Does not happen in JavaFX 13, happens in 14 and later.
 * Most likely related to this change: https://bugs.openjdk.java.net/browse/JDK-8225571 - "Port Linux glass drag source
 * (DND) to use gtk instead of gdk".
 *
 * Workaround:
 * #1: Swap red and blue color channels before setting drag view image, see code.
 * #2: Use JavaFX 13.
 * #3: Use GTK2 at runtime with JVM argument "-Djdk.gtk.version=2".
 *
 * Tested with JavaFX 16, JDK 16 on Ubuntu 20.04 and Fedora 34.
 */
public class Main extends Application {
    Image image = createImage(240, 240);
    CheckBox workaround = new CheckBox("Workaround");

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        ImageView imageView = new ImageView(image);
        imageView.setOnDragDetected(event -> {
            ClipboardContent content = new ClipboardContent();
            content.putImage(image);
            Dragboard dragboard = imageView.startDragAndDrop(TransferMode.ANY);
            dragboard.setContent(content);
            if (workaround.isSelected()) {
                dragboard.setDragView(swapRedAndBlueColorChannels(image));
            } else {
                dragboard.setDragView(image);
            }
        });

        VBox vBox = new VBox(new Label("Drag image"), imageView, workaround);
        vBox.setSpacing(5.0);
        vBox.setAlignment(Pos.CENTER);
        stage.setScene(new Scene(vBox, 480, 480));
        stage.setTitle("GTK3 Drag View Image Wrong Colors");
        stage.show();
    }

    private static Image createImage(int width, int height) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int y=0; y<height; y++) {
            for (int x=0; x<width; x++) {
                if (x < width * 0.33) {
                    image.setRGB(x, y, 0xFF0000);
                } else if (x < width * 0.66) {
                    image.setRGB(x, y, 0x00FF00);
                } else {
                    image.setRGB(x, y, 0x0000FF);
                }
            }
        }
        return SwingFXUtils.toFXImage(image, null);
    }

    private static Image swapRedAndBlueColorChannels(Image image) {
        BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null);
        int width = bufferedImage.getWidth();
        int height = bufferedImage.getHeight();
        for (int y=0; y<height; y++) {
            for (int x=0; x<width; x++) {
                int p = bufferedImage.getRGB(x, y);
                int a = (p>>24) & 0xFF;
                int r = (p>>16) & 0xFF;
                int g = (p>>8) & 0xFF;
                int b = p & 0xFF;
                p = (a<<24) | (b<<16) | (g<<8) | r; // Swap red and blue values.
                bufferedImage.setRGB(x, y, p);
            }
        }
        return SwingFXUtils.toFXImage(bufferedImage, null);
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
#1: Swap red and blue color channels before setting drag view image, see code.
#2: Use JavaFX 13.
#3: Use GTK2 at runtime with JVM argument "-Djdk.gtk.version=2".

FREQUENCY : always



Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jfx17u/pull/180 Date: 2024-03-06 12:20:12 +0000
06-03-2024

Changeset: b2ecfacf Author: Thiago Milczarek Sayao <tsayao@openjdk.org> Committer: Kevin Rushforth <kcr@openjdk.org> Date: 2021-09-17 15:02:08 +0000 URL: https://git.openjdk.java.net/jfx/commit/b2ecfacf0d8c9512d0b4cc13c1ac6c104a20f396
17-09-2021

I can confirm that this is a regression of JDK-8225571
05-08-2021

I am able to reproduce the issue with latest OpenJFX code with JDK18
03-08-2021

Checked with attached Testcase in Ubuntu 20.04, Issue is reproducible<Attached screenshot for reference> $ gtk-launch --version 3.24.20 Test Result: ========= openjfx11: Pass openjfx15: Fail openjfx16: Fail openjfx17ea: Fail Issue is not reproducible in Windows 10.
28-07-2021