RFR: 8271054: [REDO] Wrong stage gets focused after modal stage creation

Thiago Milczarek Sayao tsayao at openjdk.java.net
Tue Sep 21 21:18:56 UTC 2021


On Thu, 5 Aug 2021 23:38:06 GMT, Thiago Milczarek Sayao <tsayao at openjdk.org> wrote:

> Found the problem thru this path:
> 
> **WindowStage.java**
> 
>     final void handleFocusDisabled() {
>         if (activeWindows.isEmpty()) {
>             return;
>         }
>         WindowStage window = activeWindows.get(activeWindows.size() - 1);
>         window.setIconified(false);
>         window.requestToFront();
>         window.requestFocus();
>     }
> 
> 
> **glass_window.cpp**
> 
> void WindowContextBase::process_focus(GdkEventFocus* event) {
>    ...
> 
>     if (jwindow) {
>         if (!event->in || isEnabled()) {
>             mainEnv->CallVoidMethod(jwindow, jWindowNotifyFocus,
>                     event->in ? com_sun_glass_events_WindowEvent_FOCUS_GAINED : com_sun_glass_events_WindowEvent_FOCUS_LOST);
>             CHECK_JNI_EXCEPTION(mainEnv)
>         } else {
>             mainEnv->CallVoidMethod(jwindow, jWindowNotifyFocusDisabled);
>             CHECK_JNI_EXCEPTION(mainEnv)
>         }
>     }
> }
> 
> 
> So `glass_window.cpp` was triggering `jWindowNotifyFocusDisabled` which triggered the java code on the Primary Stage (on the bug reproduce code).
> 
> The docs states:
> 
>     /**
>      * Enables or disables the window.
>      *
>      * A disabled window is unfocusable by definition.
>      * Also, key or mouse events aren't generated for disabled windows.
>      *
>      * When a user tries to activate a disabled window, or the window gets
>      * accidentally brought to the top of the stacking order, the window
>      * generates the FOCUS_DISABLED window event. A Glass client should react
>      * to this event and bring the currently active modal blocker of the
>      * disabled window to top by calling blocker's minimize(false), toFront(),
>      * and requestFocus() methods. It may also 'blink' the blocker window to
>      * further attract user's attention.
>      *
>      .....
> 
> 
> So I guess the C++ side looks ok, java side on `handleFocusDisabled` I did not understand why it `requestToFront` and `requestFocus` on the latest window.
> 
> The solution makes disabled windows unfocusable and prevents mouse and keyboard events as the docs states, making it compatible with other platforms.

Docs states:

        /*
         * When a user tries to activate a disabled window, or the window gets
         * accidentally brought to the top of the stacking order, the window
         * generates the FOCUS_DISABLED window event. A Glass client should react
         * to this event and bring the currently active modal blocker of the
         * disabled window to top by calling blocker's minimize(false), toFront(),
         * and requestFocus() methods. It may also 'blink' the blocker window to
         * further attract user's attention.
         */


But `WindowStage.java` actually does:


    final void handleFocusDisabled() {
        if (activeWindows.isEmpty()) {
            return;
        }
        WindowStage window = activeWindows.get(activeWindows.size() - 1);
        window.setIconified(false);
        window.requestToFront();
        window.requestFocus();
    }

It brings up current activeWindows.size() - 1, not actually the MODAL blocker. Seems wrong to me.

The event is born on `glass_window.cpp`:

```c++
mainEnv->CallVoidMethod(jwindow, jWindowNotifyFocusDisabled);


The current proposed code (which I will redo) blocks this line from being sent (on non-virtual machines apparently). But commenting the `jWindowNotifyFocusDisabled` should make the problem disappear (just to test the theory).

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

PR: https://git.openjdk.java.net/jfx/pull/598


More information about the openjfx-dev mailing list