On Mon, 10 Aug 2026 21:44:08 GMT, Thiago Milczarek Sayao <[email protected]> 
wrote:

>> This is a continuation to 
>> [JDK-8236651](https://bugs.openjdk.org/browse/JDK-8236651) and it aims to 
>> stabilize the linux glass gtk backend.
>> 
>> It refactors the Glass GTK implementation with a primary focus on window 
>> sizing, positioning, and state management, addressing a number of 
>> long-standing issues.
>> 
>> Previously, three separate context classes existed, two of which were used 
>> for Java Web Start and Applets. These have been unified, as they are no 
>> longer required.
>> 
>> Additional tests have been introduced to improve coverage. Some tests 
>> produced different results depending on the StageStyle, so they have been 
>> converted to use `@ParameterizedTest` to exercise multiple styles.
>> 
>> Although the primary focus is XWayland, the changes have also been verified 
>> to work correctly on Xorg.
>> 
>> This replaces #1789. It removes the use of GdkWindow in favor of GtkWindow, 
>> reducing risk and simplifying the review process while preserving the same 
>> set of bug fixes. Additionally, #2025 requires a `GtkWindow` to be used when 
>> setting the parent of the file chooser dialog.
>> 
>> To show debug messages,  build with `-PCONF=DebugNative`  and run with 
>> `-Djdk.gtk.verbose=true`. Log categories can be passed with 
>> `-Dglass.gtk.logCategories=CATEGORY` 
>> 
>> `CATEGORY` can be one or more of:
>> - all
>> - size
>> - position
>> - focus
>> - state
>> - lifecycle
>> - input
>> - dialog
>> 
>> Multiple categories can be specified by separating them with commas (e.g. 
>> size,focus,input).
>> 
>> A manual test is provided:
>> `java @build/run.args tests/manual/stage/TestStage.java`
>> 
>> When a window property is set, it is reported immediately. However, once it 
>> reaches the native Glass layer, it may be adjusted or rejected, causing the 
>> property to be updated again. Introducing a delay helps ensure the final 
>> state has been applied before it is verified.
>> 
>> ---------
>> - [x] I confirm that I make this contribution in accordance with the 
>> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai).
>
> Thiago Milczarek Sayao has updated the pull request with a new target base 
> due to a merge or a rebase. The pull request now contains 43 commits:
> 
>  - Merge branch 'master' into 8354943_v2
>  - mapped = true for popups
>  - Do not block sent configure events, as doing so breaks screen-change 
> detection.
>  - - Restore gdk_event_request_motions (it's needed even without event 
> compression)
>    - Remove cursor unref (it's aready de-referenced on gdk_window_set_cursor)
>    - Improve XComposite message
>  - Remove configurable delays
>  - Fix test
>  - Xorg fixes
>  - Revert "Rewrite WrongStageFocusWithApplicationModalityTest because it 
> fails intermittently"
>    
>    This reverts commit c6b9dd745e5d762adb89a3b596e53b0d8a790d7f.
>  - Rewrite WrongStageFocusWithApplicationModalityTest because it fails 
> intermittently
>  - Use existing verbose flag for GTK
>  - ... and 33 more: https://git.openjdk.org/jfx/compare/58a7bea2...969ed5f3

modules/javafx.graphics/src/main/native-glass/gtk/GlassApplication.cpp line 549:

> 547:                 case GDK_MAP:
> 548:                     ctx->process_map();
> 549:                     break;

Is this really intended? The previous implementation passed `GDK_MAP` to 
`gtk_main_do_event()`. Other GTK-managed events in the new implementation still 
do so, but map events are now intercepted completely. This suppresses the 
widget’s `map-event` signal and the default `GtkWindow` map handler.

Maybe we should dispatch to GTK:

case GDK_MAP:
    gtk_main_do_event(event);
    ctx->process_map();
    break;

modules/javafx.graphics/src/main/native-glass/gtk/glass_window.cpp line 940:

> 938:     if (xSet && gravity_x > 0 && dx != 0) {
> 939:         x -= gravity_x * static_cast<float>(dx);
> 940:         if (x < 0) x = 0;

Why is `x` (and `y`) clamped to zero? Couldn't a monitor to the left of the 
primary monitor have negative coordinates?

modules/javafx.graphics/src/main/native-glass/gtk/glass_window.cpp line 1206:

> 1204: 
> 1205:     gtk_window_set_geometry_hints(GTK_WINDOW(gtk_widget), nullptr, 
> nullptr,
> 1206:         (GdkWindowHints) (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE));

What does this function do? The 
[set_geometry_hints](https://docs.gtk.org/gtk3/method.Window.set_geometry_hints.html)
 documentation say that `geom_mask` is a "bitmask indicating which struct 
fields should be paid attention to", but `geometry` is null.

modules/javafx.graphics/src/main/native-glass/gtk/glass_window.cpp line 1261:

> 1259:     }
> 1260: 
> 1261:      gtk_window_set_geometry_hints(GTK_WINDOW(gtk_widget), nullptr, 
> &hints, (GdkWindowHints) flags);

After queueing `gtk_window_resize()`, `move_resize()` calls this method. At 
that moment `view_size` still contains the old configured size, so the code 
reinstalls min == max == old size before GTK processes the queued resize.

Maybe the temporary removal should use a zero mask:

gtk_window_set_geometry_hints(
    GTK_WINDOW(gtk_widget),
    nullptr,
    nullptr,
    static_cast<GdkWindowHints>(0));


The fixed constraints should then be reapplied after the corresponding 
`GDK_CONFIGURE` updates `view_size`, not immediately after 
`gtk_window_resize()`. Maybe a "pending programmatic resize" flag would make 
that sequencing explicit.

modules/javafx.graphics/src/main/native-glass/gtk/glass_window.cpp line 1472:

> 1470:     if (frame_type == TITLED && (initial_wmf & GDK_FUNC_MINIMIZE)) {
> 1471:         if (!enabled) {
> 1472:             remove_wmf(GDK_FUNC_MINIMIZE);

If we are here, it means that `initial_wmf` contains `GDK_FUNC_MINIMIZE`. 
However, both `remove_wmf()` and `add_wmf()` check `initial_wmf`, which makes 
this entire operation a no-op:

if (initial_wmf & wmf) return;


Maybe we need a different approach here, for example:

if (!enabled) {
    current_wmf = static_cast<GdkWMFunction>(
        static_cast<int>(current_wmf) & ~static_cast<int>(GDK_FUNC_MINIMIZE));
} else {
    current_wmf = static_cast<GdkWMFunction>(
        static_cast<int>(current_wmf) | static_cast<int>(initial_wmf & 
GDK_FUNC_MINIMIZE));
}

gdk_window_set_functions(gdk_window, current_wmf);

tests/system/src/test/java/test/javafx/stage/StageSizingTest.java line 511:

> 509:         runAndWait(() -> {
> 510:             getStage().setWidth(NEW_WIDTH);
> 511:             getStage().setHeight(NEW_HEIGHT);

`Window.setWidth()` and `Window.setHeight()` update the Java properties 
immediately, before native confirmation. If GTK rejects the resize without 
emitting a configure event, the Java property assertions can still report the 
requested values while the native window remains at the old size.

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

PR Review Comment: https://git.openjdk.org/jfx/pull/2139#discussion_r3871806943
PR Review Comment: https://git.openjdk.org/jfx/pull/2139#discussion_r3871870715
PR Review Comment: https://git.openjdk.org/jfx/pull/2139#discussion_r3871697604
PR Review Comment: https://git.openjdk.org/jfx/pull/2139#discussion_r3871757644
PR Review Comment: https://git.openjdk.org/jfx/pull/2139#discussion_r3871847082
PR Review Comment: https://git.openjdk.org/jfx/pull/2139#discussion_r3871767869

Reply via email to