Skip to content

8354943: [Linux] Simplify and update glass gtk backend: window sizing, positioning, and state management issues#2139

Open
tsayao wants to merge 42 commits into
openjdk:masterfrom
tsayao:8354943_v2
Open

8354943: [Linux] Simplify and update glass gtk backend: window sizing, positioning, and state management issues#2139
tsayao wants to merge 42 commits into
openjdk:masterfrom
tsayao:8354943_v2

Conversation

@tsayao

@tsayao tsayao commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator

This is a continuation to 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.



Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed (2 reviews required, with at least 2 Reviewers)

Issues

  • JDK-8354943: [Linux] Simplify and update glass gtk backend: window sizing, positioning, and state management issues (Enhancement - P4)
  • JDK-8316425: [Linux] Stage.setMaximized() before show() does not persist (Bug - P4)
  • JDK-8316891: [Linux] Intermittent test failure in IconifyTest.canIconifyDecoratedStage (Bug - P4)
  • JDK-8337400: [Linux] Initial window position is not centered on Ubuntu 24.04 / Xorg (Bug - P4)
  • JDK-8353612: [Linux] Some of the SizeToSceneTest fail in Ubuntu 24.04 (Bug - P4)
  • JDK-8355073: [Linux] View size glitch when resizing past max window size (Bug - P4)
  • JDK-8353556: RestoreSceneSizeTest fails in Ubuntu 24.04 (Bug - P4)
  • JDK-8321624: DualWindowTest fails intermittently on Linux (Bug - P4)
  • JDK-8367893: StageFocusTest fails on some Linux systems (Bug - P4)
  • JDK-8366009: Stage does not always enter full screen when shown with fullScreen set to true on Ubuntu 24.04 (Bug - P4)
  • JDK-8365201: [Linux] Restoring the maximized state of a window makes it exceed the screen's bounds (Bug - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/2139/head:pull/2139
$ git checkout pull/2139

Update a local copy of the PR:
$ git checkout pull/2139
$ git pull https://git.openjdk.org/jfx.git pull/2139/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 2139

View PR using the GUI difftool:
$ git pr show -t 2139

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/2139.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper

bridgekeeper Bot commented Apr 6, 2026

Copy link
Copy Markdown

👋 Welcome back tsayao! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk

openjdk Bot commented Apr 6, 2026

Copy link
Copy Markdown

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@tsayao tsayao marked this pull request as ready for review April 6, 2026 18:11
@openjdk openjdk Bot added the rfr Ready for review label Apr 6, 2026
@mlbridge

mlbridge Bot commented Apr 6, 2026

Copy link
Copy Markdown

@kevinrushforth

Copy link
Copy Markdown
Member

We'll need to evaluate this approach vs that of #1789 and choose one or the other.

It is accurate to say that the main difference between the two approaches is that PR #1789 replaces GtkWindow with GdkWindow whereas this PR sticks with GtkWindow? What other differences will help guide the reviewers?

Does this PR address the same set of issues that PR #1789 does? That one lists 10 additional bugs as also being resolved by that PR.

/reviewers 2 reviewers

@openjdk

openjdk Bot commented Apr 6, 2026

Copy link
Copy Markdown

@kevinrushforth
The total number of required reviews for this PR (including the jcheck configuration and the last /reviewers command) is now set to 2 (with at least 2 Reviewers).

@tsayao

tsayao commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator Author

We'll need to evaluate this approach vs that of #1789 and choose one or the other.

It is accurate to say that the main difference between the two approaches is that PR #1789 replaces GtkWindow with GdkWindow whereas this PR sticks with GtkWindow? What other differences will help guide the reviewers?

With the introduction of #2025, a GtkWindow became required for the FileChooser. As a result, PR #1789 needed a relatively large change to work directly with the portal (with a fallback to the GTK FileChooser), enabling the use of a GdkWindow as the parent.

By reverting to GtkWindow instead of GdkWindow, this additional FileChooser-related change is no longer necessary.

Experience shows that such changes can introduce regressions. Since this PR preserves the use of GtkWindow and changes less, it is likely lower risk compared to #1789. A final conclusion depends on further testing of this PR.

Does this PR address the same set of issues that PR #1789 does? That one lists 10 additional bugs as also being resolved by that PR.

At this time, the answer is likely yes, as all tests are passing on Ubuntu 24.04 with XWayland. I will follow up with additional validation and explicitly list the confirmed fixes.

The decision between #1789 and this PR will ultimately depend on the outcome of these tests.

/reviewers 2 reviewers

@tsayao

tsayao commented Apr 7, 2026

Copy link
Copy Markdown
Collaborator Author

/issue add 8354943,8316425,8316891,8337400,8353612,8355073,8353556,8321624,8367893,8366009

@openjdk

openjdk Bot commented Apr 7, 2026

Copy link
Copy Markdown

@tsayao This issue is referenced in the PR title - it will now be updated.

Adding additional issue to issue list: 8316425: [Linux] Stage.setMaximized() before show() does not persist.

Adding additional issue to issue list: 8316891: [Linux] Intermittent test failure in IconifyTest.canIconifyDecoratedStage.

Adding additional issue to issue list: 8337400: [Linux] Initial window position is not centered on Ubuntu 24.04 / Xorg.

Adding additional issue to issue list: 8353612: [Linux] Some of the SizeToSceneTest fail in Ubuntu 24.04.

Adding additional issue to issue list: 8355073: [Linux] View size glitch when resizing past max window size.

Adding additional issue to issue list: 8353556: RestoreSceneSizeTest fails in Ubuntu 24.04.

Adding additional issue to issue list: 8321624: DualWindowTest fails intermittently on Linux.

Adding additional issue to issue list: 8367893: StageFocusTest fails on some Linux systems.

Adding additional issue to issue list: 8366009: Stage does not always enter full screen when shown with fullScreen set to true on Ubuntu 24.04.

tsayao added 6 commits April 8, 2026 06:52
- Improve tests to be more consistent
- GdkWindow -> GtkWindow related fixes
- Prevent repeated 'a' being typed
- Small fixes
# Conflicts:
#	modules/javafx.graphics/src/main/native-glass/gtk/glass_window.cpp
@openjdk

openjdk Bot commented Apr 9, 2026

Copy link
Copy Markdown

⚠️ @tsayao This pull request contains merges that bring in commits not present in the target repository. Since this is not a "merge style" pull request, these changes will be squashed when this pull request in integrated. If this is your intention, then please ignore this message. If you want to preserve the commit structure, you must change the title of this pull request to Merge <project>:<branch> where <project> is the name of another project in the OpenJDK organization (for example Merge jdk:master).

@openjdk openjdk Bot removed the rfr Ready for review label Apr 9, 2026
@palexdev

palexdev commented Apr 10, 2026

Copy link
Copy Markdown

@tsayao should you add JDK-8365201 to the list too?

Edit: oh sorry, I just read that this is an alternative to the other proposal. So the question is, does this fixes the above-mentioned issue too?

@tsayao

tsayao commented Apr 10, 2026

Copy link
Copy Markdown
Collaborator Author

@tsayao should you add JDK-8365201 to the list too?

Edit: oh sorry, I just read that this is an alternative to the other proposal. So the question is, does this fixes the above-mentioned issue too?

I still need to set up a multi-monitor environment to properly test it, but it will probably fix this issue as well.

@tsayao

tsayao commented Apr 10, 2026

Copy link
Copy Markdown
Collaborator Author

/template append

@tsayao

tsayao commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator Author

I’m finishing up the final details and expect to submit the last commit soon, aside from review changes.

@tsayao

tsayao commented May 21, 2026

Copy link
Copy Markdown
Collaborator Author

The pull request is almost ready. I'm just dealing with a few remaining failing tests.

@lukostyra

Copy link
Copy Markdown
Contributor

The pull request is almost ready. I'm just dealing with a few remaining failing tests.

Not a problem.

If you want you can turn this PR into a Draft and then once you're done remove the Draft status, that way we'll know what's the situation with this PR and Skara should be a bit more relaxed when it comes to timing it out.

@tsayao tsayao marked this pull request as draft May 21, 2026 11:48
@openjdk openjdk Bot removed the rfr Ready for review label May 21, 2026
@tsayao tsayao marked this pull request as ready for review May 31, 2026 13:42
@openjdk openjdk Bot added the rfr Ready for review label May 31, 2026
@tsayao

tsayao commented May 31, 2026

Copy link
Copy Markdown
Collaborator Author

All tests pass on Xorg and XWayland (primarily on Ubuntu 24.04). The new tests were also validated on macOS Tahoe. Additionally, extensive manual testing was conducted.

}

if (gdk_cursor) {
g_object_unref(gdk_cursor);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gdk_cursor field is unref'd here and in the destructor of WindowContext, but _setCustomCursor() passes in a cursor owned by com.sun.glass.ui.Cursor on the Java side. This may potentially destroy a cursor that is still used on the Java side. If WindowContext needs to participate in refcounting, it should probably take its own g_object_ref() for incoming cursors.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the GTK code, gdk_window_set_cursor() already unreferences the currently assigned cursor, so I removed the explicit unref. The custom cursor unref was causing a crash.

}

glong to_screen = getScreenPtrForLocation(geometry.x, geometry.y);
glong to_screen = getScreenPtrForLocation(event->x, event->y);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getScreenPtrForLocation(), which calls gdk_screen_get_monitor_at_point(), expects coordinates "in the virtual screen". You pass in coordinates specified "relative to its parent", can you verify that this is intended?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parent of a toplevel or a popup (override-redirect) window on X11 is the root window which covers the entire screen. But I've found some problems while testing it and fixed it.


#define ALPHA_CHANNEL_ERROR_MSG \
"Can't create transparent stage, because your screen doesn't support alpha channel. " \
"You need to enable XComposite extension.\n"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are touching this code, maybe you should consider improving the language. In particular, readers shouldn't be colloquially addressed with "you". Maybe something like:
"Cannot create a transparent stage because the screen does not support an alpha channel without enabling the XComposite extension."

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the error message (though it's very unlikely to ever be shown).

void invalidate() {
if (!onChange) return;
if (notifying) {
fprintf(stderr,"WARNING: Re-entrant call to Observable::invalidate() (possible cyclic dependency)\n");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this use the LOG macro, or alternatively be hidden behind the VERBOSE flag?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is closer to an error than a log message. On the other hand, it's something that should be caught during development.

view_size.set({boundsW, boundsH});
}

if (mapped) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit suspicious: move_resize() uses mapped to decide whether to call gtk_window_resize() or gtk_window_set_default_size(). The old code used gtk_widget_get_realized() and resized any realized window. Since the mapped field is always false for a POPUP window, the new code might not resize an already-realized popup.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Popups go through the same process of setting mapped to true. However, I'll do some testing to verify popup move and resize behavior.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only WindowContext::process_map() seems to set mapped = true, but not if window_type == POPUP.

@tsayao tsayao Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I'll fix it. That said, I'd still like to run some additional tests, as this slipped through unnoticed (at least on my end). There isn't any evident issue in the most common popup use cases, such as menus, tooltips, and dropdowns, but it may still affect less common scenarios.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed it and done some testing.

tsayao added 2 commits June 14, 2026 15:34
…ompression)

- Remove cursor unref (it's aready de-referenced on gdk_window_set_cursor)
- Improve XComposite message
@tsayao

tsayao commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

/issue add 8365201

@openjdk

openjdk Bot commented Jun 15, 2026

Copy link
Copy Markdown

@tsayao
Adding additional issue to issue list: 8365201: [Linux] Restoring the maximized state of a window makes it exceed the screen's bounds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rfr Ready for review

Development

Successfully merging this pull request may close these issues.

5 participants