Discussion on adding a new gtk glass backend

Kevin Rushforth kevin.rushforth at oracle.com
Mon Apr 6 21:34:03 UTC 2020

Hi Thiago,

Nice summary!

As I mentioned offline, I am generally supportive of this, since I know 
how fragile the existing Linux Glass implementation is. Unsurprisingly, 
this has effectively turned into a rewrite of the Linux GTK glass port. 
It's going to need a very thorough review, including a security review, 
and that will take some time.

Thank you for adding my offline suggestion of making this new 
implementation an optional library where the old and new versions of the 
glass library for Linux can coexist. This will allow making separate 
decisions about when it is ready to go in versus when it is ready to 
become the default; this is the only way it even has a chance of getting 
in for JavaFX 15 (and even then it's not a given). Since this is JavaFX 
only, the command line option should probably be "javafx.gtk..." rather 
than "jdk.gtk....", or at least something with "javafx" in the name, but 
that's a detail that can be worked out later.

I have a couple high-level questions:

1. In the goals you mention "Update to gtk3 (it was originally a port 
from gtk2)" I presume that this preserves compatibility with older gtk2 
libraries as well?

2. How much of the reliance on GDK were you able to eliminate?

I'd like to also hear from Johan and others -- especially other Linux 
app developers.

-- Kevin

On 4/4/2020 5:13 PM, Thiago Milczarek Sayao wrote:
> Summary
> -------
> * Simplify and update the Gtk glass backend, making Linux a first-class OpenJFX platform.
> PR: https://github.com/openjdk/jfx/pull/77
> Goals
> -----
> * Make Linux a first-class OpenJFX platform (see Motivation);
> * Simplify the code and reduce it's size;
> * Update to gtk3 (it was originally a port from gtk2);
> * Remove unused code (such as applets and web start);
> * Prepare the ground for a possible future Wayland support.
> Non-Goals
> ---------
> * Make Wayland work now.
> Success Metrics
> ---------------
> * Reduced code size (999 lines removed);
> * Pass robot tests on Ubuntu 16.04, 18.04 and 20.04, except some of them that always fails;
> * Pass manual testing using the Drag and Drop app (java @build/run.args -cp apps/toys/DragDrop/dist/DragDrop.jar dragdrop.DragDropWithControls) with gtk2 and gtk3 backends;
> * Pass manual testing using Ensemble 8 with either gtk2 and gtk3 backends.
> Motivation
> ----------
> While working with OpenJFX on Linux, I have fixed some of it's bugs:
> * Wrong stage gets focused after modal stage creation: https://bugs.openjdk.java.net/browse/JDK-8227366
> * Multi-level Stage::initOwner can crash gnome-shell or X.org server: https://bugs.openjdk.java.net/browse/JDK-8226537
> * DragAndDrop no longer works with GTK3: https://bugs.openjdk.java.net/browse/JDK-8211302
> * [Linux] Dialog height switches between correct and too small when showing and hiding a Dialog repeatedly: https://bugs.openjdk.java.net/browse/JDK-8193502
> * Focus goes to wrong Window when dismissing an Alert: https://bugs.openjdk.java.net/browse/JDK-8210973
> * [GTK3] Stage sometimes shown at top-left before moving to correct position: https://bugs.openjdk.java.net/browse/JDK-8212060
> * Window order is not correct when Modality.WINDOW_MODAL: https://bugs.openjdk.java.net/browse/JDK-8220272
> * Port Linux glass drag source (DND) to use gtk instead of gdk: https://bugs.openjdk.java.net/browse/JDK-8225571
> * Dialog's preferred size no longer accommodates multi-line strings: https://bugs.openjdk.java.net/browse/JDK-8232811
> While fixing those bugs I got familiar with the code and saw many opportunities to make it better (as the goal lists).
> One special case is that X.org needs a window manager to decorate windows (such as Unity, Metacity, Mutter, and many others), so the toolkit does not know about decoration sizes - it must ask to the window manager trough an extension (https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html). OpenJFX can set sizes by content size and window size - so there is a complexity on the "window size" option - it must know decoration sizes. I could not fully understand the current code because it had a high cyclomatic complexity - this was the main motivation to make it simplier (see JBS https://bugs.openjdk.java.net/browse/JDK-8232811 - it fixes the bug, but it's not very "clean").
> I refer to "make Linux a first-class platform" on the goal because the PR makes room for more improvements (such as easier to fix bugs).
> Description
> -----------
> This glass gtk replacement will be active if passing -Djdk.gtk.new=true to the jvm. The proposal is to have this side by side with current Linux glass so people can test and eventually it may become the default glass implementation on Linux.
> * Note: No public API was modified;
> * Specific Code Changes
>      * glass_window.cpp / glass_window.h
> - Removed WindowContextPlug and WindowContextChild (that were used for applets / web start) and moved everything to one class named WindowContext (since inheritance was no required anymore);
> - Changed set_enabled() to use gtk_widget_set_sensitive instead of custom code;
> - Moved to gtk signals instead of gdk events (to use gtk_widget_set_sensitive and gtk_grab_add);
> - Frame Extents: Removed the code to request extents and gtk already does it by default;
> - Size calculation: Reworked size calculation code. In general, X windows are content size instead of whole window size (considering extents - frame decorations). OpenJFX uses "whole window size" as window sizes, so it requires a "hack" to recalculate sizes when set_bounds() is called with window sizes instead of content sizes. The rework was to simplify code paths and make it more straightforward.
> - Other Size calculation changes:
>      - Use gtk_window_set_default_size() for initial size which is the appropriate function;
>      - Gravity is now ignored as it is on Windows glass impl;
>      - Avoid sending same sizes to Java (duplicated events);
>      - Introduced calculate_adjustments() which is a fallback when frame extents is not present (it's optional to window managers to implement it);
>      - Geometry: Min / Max sizes - reworked it to simplify / Concentrated geometry changes on
> apply_geometry().
> - Mouse grab: Reworked it to use to correct functions according to gtk+ version;
> - Draw: Reworked it to use the correct calls accord to gtk+ version changes;
> - Fixed JDK-8237491;
> - Moved background code to paint() as gtk3 uses styles to set the background and other functions were deprecated;
> - Reorganized function order on glass_window.cpp to match glass_window.h
> - Only work-around Unity bug if window manager is Unity
>      * GlassCursor.cpp
> - Gtk+3 uses a name-like-css approach - so it was properly ported to gtk3 way;
> - Reworked Gtk+2 to use a function instead of manual calls to find the cursor;
>      * GtkWindow.java
> - Moved the extents special case to native glass;
>      * GlassApplication.cpp
> - Removed Gdk events where possible (it's now on glass_window as signals);
> - Removed applet/web start code;
>      * GlassView.cpp
> - Changes to reflect frame extents rework on glass_window
>      * GlassWindow.cpp
> - WindowContextTop -> WindowContext
> - Removed applet / web start code;
> - Removed frame extents (which is not called anymore due to GtkWindow.java change);
>      * glass_general.cpp
> - Removed functions that became unused;
> - Added is_grab_disabled() that is used on glass_window
>      * glass_window_ime.cpp
> - WindowContextTop -> WindowContext;
>      * glass_dnd.cpp / glass_dnd.h
> - Ported to Gtk signals;
> - Use all possible image formats (supported by GdkPixbuf / OpenJFX) - .gif is now possible (for ex.);
> - Do not request content while dragging;
> - Reduce overall code size.
> Testing
> -------
> While fixing the bugs listed on "Motivation" I have developed some robot tests that must pass along with the previosly existing ones.
> Note: Non-robot tests do not apply since the changes are glass specific.
> Note2: Must pass -PEXTRA_TEST_ARGS='-Djdk.gtk.new=true' to gradle.
> Risks and Assumptions
> ---------------------
> * Testing were done since Ubuntu 16.04 (released 4 years ago) on x64 machines;
> * Tested with Mutter (default gnome) and Unity (default on 16.04) - should work on other window managers that follows the specs;
> * It's a big change - well tested but might still break something.
> Dependencies
> -----------
> * Simplify and update glass gtk backend: https://bugs.openjdk.java.net/browse/JDK-8236651
> * Maximized undecorated stage behaves inconsistently on different platforms
> : https://bugs.openjdk.java.net/browse/JDK-8237491

More information about the openjfx-dev mailing list