JDK-8225571 : Port Linux glass drag source (DND) to use gtk instead of gdk
  • Type: Enhancement
  • Component: javafx
  • Sub-Component: window-toolkit
  • Affected Version: openjfx11,openjfx12,openjfx13
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • Submitted: 2019-06-11
  • Updated: 2021-09-06
  • Resolved: 2020-01-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.

To download the current JDK release, click here.
Other
openjfx14Fixed
Related Reports
Blocks :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Rationale:

While working on JDK-8211302 I have stumbled on many differences between gdk versions. On the gdk3 line, I have found many backends (X11, Wayland) code differences on the GTK side. While the fix works (refering to  JDK-8211302), it's not perfect. For example, the dragview (the window that follows the mouse showing image/icon) does not work well on scenebuilder, because it sets it to be under the cursor and it ends up stealing the events.  This does not happen with the gtk port because gtk handles it well, as it does with many other systems/versions differences.

The JDK-8211302 patch has this code:
#ifdef GLASS_GTK3
    if (gtk_get_minor_version() >= 20) {
        // according to GDK docs, this is only fired on managed mode, but
        // on 3.20+ the GDK_DROP_FINISHED event stopped working and this signal
        // works (even when not managed).
        g_signal_connect(ctx, "dnd-finished",
            G_CALLBACK(dnd_finished_callback), NULL);
    }

I don't feel this is secure because it uses something that docs says otherwise.

UI Consistency:

Gtk shows an default icon while dragging which is consistent with the gnome desktop and desktop theme. It also shows an animation when drag fails, where the dragview comes back to the origin. (Can change some behaviors if they go against javafx UI policies).

Conclusion:
In essence, this change makes the code easier to maintain, adds UI consistency and works better (as gtk handles systems differences internally)

PR:
https://github.com/javafxports/openjdk-jfx/pull/490

This PR is well tested on Ubuntu 16.04, 18.04 and 19.04 with gtk2 fallback and gtk3. Scenebuilder also works well with the patch and gtk3. On 19.04 it works with wayland.

Code changes are restricted to drag source (destination is untouched) and some minor necessary changes on other places.


Comments
This has caused a regression JDK-8271398
05-08-2021

Changeset: 3bbcbfb4 Author: Thiago Milczarek Sayao <tsayao@openjdk.org> Committer: Kevin Rushforth <kcr@openjdk.org> Date: 2020-01-02 17:06:21 +0000 URL: https://git.openjdk.java.net/jfx/commit/3bbcbfb4
06-01-2020

Fixed by the following commit: https://github.com/openjdk/jfx/commit/3bbcbfb4dea09ba9b4686b11b49e0643afb79bc3 The resolution of this issue by the Skara bot is pending.
02-01-2020

Here is another reported failure: https://github.com/javafxports/openjdk-jfx/issues/589 ---------------------------------------------------------------------------------- The code below works correctly on Windows 7. On Ubuntu 19.04 the drag starts but the method Node.setOnDragDropped is not called and the cursor indicates that it is not possible to drop although DragEvent.acceptTransferModes is set. public class DNDApp extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { Label label = new Label("Test"); label.setOnDragDetected(event -> { Dragboard db = label.startDragAndDrop(TransferMode.MOVE); SnapshotParameters parameters = new SnapshotParameters(); parameters.setFill(Color.TRANSPARENT); Image snapshot = label.snapshot(parameters, null); db.setDragView(snapshot, event.getX(), event.getY()); ClipboardContent content = new ClipboardContent(); content.putString(label.getText()); db.setContent(content); event.consume(); }); Pane root = new Pane(); root.setOnDragOver(event -> { if (event.getDragboard().hasString() && event.getGestureSource() instanceof Label) { event.acceptTransferModes(TransferMode.COPY_OR_MOVE); } event.consume(); }); root.setOnDragDropped(event -> { Dragboard db = event.getDragboard(); boolean success = false; if (db.hasString() && event.getGestureSource() instanceof Label) { Label shortcutViewSource = (Label) event.getGestureSource(); shortcutViewSource.relocate(event.getX(), event.getY()); success = true; } event.setDropCompleted(success); event.consume(); }); root.getChildren().add(label); Scene scene = new Scene(root, 500, 500); stage.setScene(scene); stage.show(); } }
30-09-2019

To run tests (on the root of the source tree): ./gradlew apps java @build/run.args -cp apps/toys/DragDrop/dist/DragDrop.jar dragdrop.DragDropWithControls java @build/run.args -cp apps/toys/DragDrop/dist/DragDrop.jar dragdrop.DragDropColor java -Djdk.gtk.version=2 @build/run.args -cp apps/toys/DragDrop/dist/DragDrop.jar dragdrop.DragDropWithControls java -Djdk.gtk.version=2 @build/run.args -cp apps/toys/DragDrop/dist/DragDrop.jar dragdrop.DragDropColor Scenebuilder git clone https://github.com/gluonhq/scenebuilder.git ./gradlew build java --module-path ~/Repos/openjdk-jfx/build/sdk/lib --add-modules javafx.web,javafx.fxml,javafx.swing,javafx.media --add-opens=javafx.fxml/javafx.fxml=ALL-UNNAMED -cp app/build/libs/scenebuilder-11.0.0-SNAPSHOT.jar com.oracle.javafx.scenebuilder.app.SceneBuilderApp Replace module path with your openjdk-jfx path.
12-06-2019