Findings on JDK-8211302

Thiago Milczarek Sayao thiago.sayao at clamed.com.br
Wed May 15 01:38:34 UTC 2019


Fix in progress:

https://github.com/tsayao/openjdk-jfx/pull/5
________________________________
De: openjfx-dev <openjfx-dev-bounces at openjdk.java.net> em nome de Thiago Milczarek Sayao <thiago.sayao at clamed.com.br>
Enviado: terça-feira, 14 de maio de 2019 13:25
Para: openjfx-dev at openjdk.java.net
Assunto: RE: Findings on JDK-8211302

Found the problem!
Managed to get it partially working, will do a proper fix when I get time.

The problem lies on glass_general.cpp. To properly get the device and keep receiving mouse move events (required while dragging) gdk_event_get_device(event) must be used. For that, GdkEvent must be in the function arguments.


Partially fixed:

void
glass_gdk_master_pointer_grab(GdkEvent *event, GdkWindow *window, GdkCursor *cursor) {
    if (disableGrab) {
        gdk_window_set_cursor(window, cursor);
        return;
    }
#ifdef GLASS_GTK3
        gdk_device_grab(gdk_event_get_device(event), window, GDK_OWNERSHIP_NONE, FALSE, GDK_ALL_EVENTS_MASK,
                    cursor, GDK_CURRENT_TIME);
#else
        gdk_pointer_grab(window, FALSE, (GdkEventMask)
                         (GDK_POINTER_MOTION_MASK
                             | GDK_BUTTON_MOTION_MASK
                             | GDK_BUTTON1_MOTION_MASK
                             | GDK_BUTTON2_MOTION_MASK
                             | GDK_BUTTON3_MOTION_MASK
                             | GDK_BUTTON_RELEASE_MASK),
                         NULL, cursor, GDK_CURRENT_TIME);
#endif
}


Original:
void
glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor) {
    if (disableGrab) {
        gdk_window_set_cursor(window, cursor);
        return;
    }
#ifdef GLASS_GTK3
        gdk_device_grab(gdk_device_manager_get_client_pointer(
                    gdk_display_get_device_manager(
                        gdk_display_get_default())),
                    window, GDK_OWNERSHIP_NONE, FALSE, GDK_ALL_EVENTS_MASK,
                    cursor, GDK_CURRENT_TIME);
#else
        gdk_pointer_grab(window, FALSE, (GdkEventMask)
                         (GDK_POINTER_MOTION_MASK
                             | GDK_BUTTON_MOTION_MASK
                             | GDK_BUTTON1_MOTION_MASK
                             | GDK_BUTTON2_MOTION_MASK
                             | GDK_BUTTON3_MOTION_MASK
                             | GDK_BUTTON_RELEASE_MASK),
                         NULL, cursor, GDK_CURRENT_TIME);
#endif
}


________________________________
De: openjfx-dev <openjfx-dev-bounces at openjdk.java.net> em nome de Thiago Milczarek Sayao <thiago.sayao at clamed.com.br>
Enviado: segunda-feira, 13 de maio de 2019 22:28
Para: Pankaj Bansal; openjfx-dev at openjdk.java.net
Assunto: RE: Findings on JDK-8211302

Did further investigation...

I think the problem lies on Gdk mouse motion events not being fired. On gdk2 the GDK_DRAG_STATUS and GDK_MOTION_NOTIFY events fires many times, including when the drag operation leaves the root window. On gdk3 it fires a few times and does not keep firing when the cursor leaves the root window.

It's on GlassApplication.cpp -> around line 419

static void process_events(GdkEvent* event, gpointer data)

on gdk2 this keeps firing:

    if (is_in_drag()) {
        process_dnd_source(window, event);
    }

on gdk3 it does not.

Cheers.

________________________________
De: Pankaj Bansal <pankaj.b.bansal at oracle.com>
Enviado: segunda-feira, 13 de maio de 2019 10:59
Para: Thiago Milczarek Sayao; openjfx-dev at openjdk.java.net
Assunto: RE: Findings on JDK-8211302

I think problem starts even before this as process_dnd_source_mouse_release is called when we release the mouse after drag and drop. But there we are not even able to initiate the dnd. If gdk_drag_context_get_selected_action(event->context) returning ZERO was the main issue, we should be able to start the drag and drop successfully. What do you think?

-Pankaj

-----Original Message-----
From: Thiago Milczarek Sayao [mailto:thiago.sayao at clamed.com.br]
Sent: Monday, May 13, 2019 7:17 PM
To: openjfx-dev at openjdk.java.net
Subject: RE: Findings on JDK-8211302

It does not work because the problem happens before.

But I suspect when the  gdk_drag_context_get_selected_action(event->context) returning ZERO problem is fixed, the need of gdk_drag_drop_done() will be the problem.

Cheers.
________________________________
De: Pankaj Bansal <pankaj.b.bansal at oracle.com>
Enviado: segunda-feira, 13 de maio de 2019 10:38
Para: Thiago Milczarek Sayao; openjfx-dev at openjdk.java.net
Assunto: RE: Findings on JDK-8211302

Hello Thiago,

This solution was proposed by one of the engineers in Oracle sometime back and we have tested it. This does not seem to solve the issue. If you wish to try this, please take the patch [1], which is attached in the bug JDK-8211302. This patch neatly defines the function depending upon the gtk version. You can test this patch and let us know if you could make this work.

[1] https://bugs.openjdk.java.net/secure/attachment/82098/8211302-drag-drop-done.patch


-Pankaj

-----Original Message-----
From: Thiago Milczarek Sayao [mailto:thiago.sayao at clamed.com.br]
Sent: Monday, May 13, 2019 6:59 PM
To: openjfx-dev at openjdk.java.net
Subject: Findings on JDK-8211302

Hello,

I have been looking into JDK-8211302.

https://bugs.openjdk.java.net/browse/JDK-8211302

Did not find a solution, but the problem is because gdk_drag_context_get_selected_action(event->context) is returning ZERO. That's also why the cursor does not update on the drop location. Subsequent events do not get fired to complete the drop, because it falls on the abort code below:

static void process_dnd_source_mouse_release(GdkWindow *window, GdkEventButton *event) {
    (void)window;
    (void)event;

    glass_gdk_master_pointer_ungrab();

    if (gdk_drag_context_get_selected_action(get_drag_context())) {
        gdk_drag_drop(get_drag_context(), GDK_CURRENT_TIME);
    } else {
        gdk_drag_abort(get_drag_context(), GDK_CURRENT_TIME);
        /* let the gdk_drag_abort messages handled before finish */
        gdk_threads_add_idle((GSourceFunc) dnd_finish_callback, NULL);
    }
}


I also suspect this will be needed, and it was introduced in GDK 3.20:

gdk_drag_drop_done(get_drag_context(), TRUE)

One solution is to check the version on build, other is to bundle the GTK lib (which makes it more safe to GDK changes).

Cheers.


More information about the openjfx-dev mailing list