Enable native GTK Look and Feel for non-gnome desktops

Bug #1581835 reported by Yanpas
14
This bug affects 3 people
Affects Status Importance Assigned to Milestone
openjdk-7 (Ubuntu)
Confirmed
Wishlist
Unassigned
openjdk-8 (Ubuntu)
Opinion
Wishlist
Unassigned

Bug Description

The default System LAF - ie. UIManager.getSystemLookAndFeelClassName() - on Linux is set to GTK for gnome desktop - ie. sun.desktop returns gnome - and to Metal for non-gnome desktops.

This prevents the majority of Java applications to use the native GTK LAF when running.

Also, UIManager.getSystemLookAndFeelClassName() ignores the default LAF set by the user through swing.defaultlaf (either as a system property or in swing.properties), relying instead on it's own simplified OS/Desktop based heuristics and defaulting to the Cross Platform LAF when those heuristics fail.

While the Default LAF can be set either as a system property or in swing.properties, the System LAF can only be set as as system property, thus there is no way to assign it system-wide.

Historically the GTK LAF was a source of bugs and errors. It is unclear if the situation has improved at all in the past few years.

= Workaround =

Currently there are only 2 alternatives to set GTK LAF system wide, both rely on editing the swing.properties file, depending on whether the Java application calls UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()):

1) For applications that *don't* use it then add swing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel to swing.properties

2) For applications that use it then add swing.installedlafs=com.sun.java.swing.plaf.gtk.GTKLookAndFeel to swing.properties

Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote :

Thank you for taking the time to report this bug and helping to make Ubuntu better.

The GTK L&F has a few known issues and is not enabled by default. Please see bug #183139.

You might try adding those properties to either /etc/java-7-openjdk/swing.properties /etc/java-8-openjdk/swing.properties, one per line without the "-D", as in:

awt.useSystemAAFontSettings=on
swing.aatext=true
swing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel
swing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel

Be aware that the application you are trying to run might override those settings on its own, if so that would require you to edit the application configuration files.

Revision history for this message
Yanpas (yanpaso) wrote :

unfortunately this configuration file doesn't work. I am still to use _JAVA_OPTIONS which is annoying, cause every time I start anything written in Java I face a message "Picked up _JAVA_OPTIONS ...".
Fix at least this conf file!

Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote :

"_JAVA_OPTIONS trumps command-line arguments, which in turn trump JAVA_TOOL_OPTIONS" (see http://stackoverflow.com/a/30305597/1153136)

If the Java application is not using the default LAF as defined by /etc/java-X-openjdk/swing.properties and its LAF can only be changed through _JAVA_OPTIONS then it means the application is setting LAF by itself. This is not related to OpenJDK and there is nothing we can do on OpenJDK packaging to change that.

If relying on _JAVA_OPTIONS is not a solution for you, then you need to open a bug against each Java application and request that they provide a way to load the default LAF set by the user instead of overwriting it on its own.

As this is not an OpenJDK bug I will be closing it as invalid.

Changed in openjdk-7 (Ubuntu):
status: New → Invalid
Changed in openjdk-8 (Ubuntu):
status: New → Invalid
Revision history for this message
Yanpas (yanpaso) wrote :

>If the Java application is not using the default LAF as defined by /etc/java-X-openjdk/swing.properties and its LAF can only be changed through _JAVA_OPTIONS then it means the application is setting LAF by itself.

I have my own application (https://github.com/Yanpas/PdfMerger), which manually sets System style! And openjdk still sets crossplatform blue style! It's definetely a bug. There should be no difference between _JAVA_OPTIONS and swing.properties!

Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote :
Download full text (4.2 KiB)

tl;dr Drop the UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) call if you want to use the swing.defaultlaf as the System LAF is hardcoded and selected by heuristics and swing.properties can't do anything about it.

I took a look at the UIManager.java yesterday to get a picture of what is going on and there are a few misunderstandings going on with how UIManager deals with LAF selection.

The file in question is http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/tip/src/share/classes/javax/swing/UIManager.java

Before we go ahead, let me just even the field with a few LAF concepts and heuristics.

= The Cross Platform LAF =
It is not possible to change the cross platform LAF through swing.properties, UIManager will either use what is set through system properties (-D in command line or _JAVA_OPTIONS) or the hardcoded setting (Metal for both JDK7u and JDK8u as of Today).
References:
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/tip/src/share/classes/javax/swing/UIManager.java#l642
http://hg.openjdk.java.net/jdk7u/jdk7u-dev/jdk/file/tip/src/share/classes/javax/swing/UIManager.java#l639

= How OpenJDK decides the right default LAF =
1. Non-null swing.defaultlaf system property
2. swing.defaultlaf set in swing.properties
3. the cross platform LAF

References, see section "Default look and feel":
https://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html
https://docs.oracle.com/javase/7/docs/api/javax/swing/UIManager.html

= UIManager.getSystemLookAndFeelClassName() =
Javadoc states "Returns the name of the LookAndFeel class that implements the native system look and feel if there is one, otherwise the name of the default cross platform LookAndFeel class."

This call will actually try to:
1. Read the system property swing.systemlaf if set, or
2. Select a *hardcoded* value according to running OS and desktop, or
3. Defaults to the *cross platform LAF* if nothing matches.

Yes, it ignores the default LAF altogether.

On Linux it will return GTK LAF if and only if the property "sun.desktop" is set to "gnome" and the internal SunToolkit detects GTK as being available, otherwise it will default to the Metal cross platform LAF.

Again: *System LAF completely ignores the Default LAF settings.*

References:
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/tip/src/share/classes/javax/swing/UIManager.java#l600
http://hg.openjdk.java.net/jdk7u/jdk7u-dev/jdk/file/tip/src/share/classes/javax/swing/UIManager.java#l597

= PDF Merger LAF issues =
PDFMerger is forcing the usage of the System LAF through the call to UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()).

In order for swing to actually use the default LAF, that call must be removed.

There are 4 other alternatives to get the GTK LAF while still keeping that call:
1. Set the system property swing.systemlaf (through -D on command line or _JAVA_OPTIONS)
1. Set the system property swing.crossplatformlaf (-D as above)
2. Set the system property sun.desktop=gnome (-D as above), will only work if GTK is detected by SunToolkit
3. Set the property swing.installedlafs as a system property or in swing.properties (this forces UIManager to use GTK as no other LAF wi...

Read more...

Revision history for this message
Yanpas (yanpaso) wrote :

Thanks for an answer!

I've got the principle of work. You've marked my bug as invalid - Is it possible to see gtk laf on non-gnome DEs by default ? (I guess this question should be adressed to openjdk developers). When will ubuntu packages of openjdk be shiped with gtk laf by default? (which bugs should I follow to track the status). And what will be the rules when the bugs will be fixed? I imagine like this:

On Gnome DE (Gnome and Unity7): default LAF is gtk, using UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) will make LAF "GTK"

On non-gnome DE (Xfce e. g.): default LAF is gtk, using UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) will make LAF "SilverBlue".

The last one seems to be controversial. Avoiding of usage setLookAndFeel will cause my app to look SilverBlue on Win/OSX and Native on Linux :)

I am able to rewrite my code, but there are apps like Yed, Logisim which use setLookAndFeel, they look native everywhere except Ubuntu :(

Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote : Re: [Bug 1581835] Re: Native Look and Feel for Swing does not work

On Mon, May 16, 2016 at 3:40 PM, Yanpas <email address hidden> wrote:
> Thanks for an answer!
>
> I've got the principle of work. You've marked my bug as invalid - Is it
> possible to see gtk laf on non-gnome DEs by default ? (I guess this
> question should be adressed to openjdk developers). When will ubuntu
> packages of openjdk be shiped with gtk laf by default? (which bugs
> should I follow to track the status).

It is possible, but it requires changes on OpenJDK itself. The best
way to resolve this is to discuss the issue directly on the OpenJDK
mailing list. Still, there are a lot of bug reports everywhere when
GTK LAF is used by default due to applications mixing GTK2 and GTK3
calls. I'm not aware if this has been fixed recently or is still an
issue, again it is something to be discussed on the OpenJDK side.

Unless it is clear that GTK is safe to be used and we have good
heuristics in place to know when we must avoid it, we will not enable
GTK by default. There are no bugs tracking this on Ubuntu AFAIK, I
have put this bug back as a confirmed for now and will ask someone to
set its priority to Wishlist. We can track progress that way.

> And what will be the rules when
> the bugs will be fixed? I imagine like this:
>
> On Gnome DE (Gnome and Unity7): default LAF is gtk, using
> UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) will
> make LAF "GTK"
>
> On non-gnome DE (Xfce e. g.): default LAF is gtk, using
> UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) will
> make LAF "SilverBlue".

The SilverBlue is called Metal LAF.

> The last one seems to be controversial. Avoiding of usage setLookAndFeel
> will cause my app to look SilverBlue on Win/OSX and Native on Linux :)

This is weird, the systemlaf is set to
com.sun.java.swing.plaf.windows.WindowsLookAndFeel on Windows and
com.apple.laf.AquaLookAndFeel on OSX. Apart from a systemlaf being set
I have no idea why it would be using Metal instead on Windows and OSX.

> I am able to rewrite my code, but there are apps like Yed, Logisim which
> use setLookAndFeel, they look native everywhere except Ubuntu :(

Again, the best way would be for OpenJDK to allow us to set that on
the swing.properties file. This way users could edit the file to set
what LAF to use when
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())
gets called.

Changed in openjdk-7 (Ubuntu):
status: Invalid → Confirmed
Changed in openjdk-8 (Ubuntu):
status: Invalid → Confirmed
summary: - Native Look and Feel for Swing does not work
+ Enable native GTK Look and Feel for non-gnome desktops
description: updated
Thomas Ward (teward)
Changed in openjdk-7 (Ubuntu):
importance: Undecided → Wishlist
Changed in openjdk-8 (Ubuntu):
importance: Undecided → Wishlist
Revision history for this message
Thorsten Glaser (mirabilos) wrote :

Metal is also a very nice look.

We’re not going to deviate here.

Changed in openjdk-8 (Ubuntu):
status: Confirmed → Opinion
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.