Add Hostname to Title Bar when X11 Forwarding
When running via X11 forwarding, the application is run on a remote host but the UI is forwarded to a client machine and displayed there. The standard title bar adds the remote hostname to the titlebar so the user knows which machine the application is actually running on.
Since we switched to FlatLaf, our users miss this information. It would be nice if FlatLaf added the hostname to the title (or failing that, a tooltip of the titlebar) when running via X11 forwarding.
Are you using FlatLaf window decorations, enabled with JFrame.setDefaultLookAndFeelDecorated( true )?
Does it show hostname if you use JFrame.setDefaultLookAndFeelDecorated( false )?
Could you post a screenshot that shows a title bar with a host name?
Yes, JFrame.setDefaultLookAndFeelDecorated( true ) is key.
With true:
With false (or, default):
These samples just have dark theme enabled to prove FlatLaf is loaded correctly.
Thanks.
Is the hostname shown in each window? In JFrames and in JDialogs? Or just in JFrames?
All 3:
So the last question is: where to get the hostname from?
Is it best to get it from the DISPLAY environment variable?
Using System.getenv("DISPLAY")?
On the remote machine, via ssh -X
DISPLAY=localhost:10.0
That doesn't seem right. I know very little of X but I think what's happening is ssh is faking out the server (remote) system to make it think X is running directly on it even though it's really running on my local (client) machine.
I had thought I'd get a different value in the titlebar depending on how I connected, but I tried using the IP instead of the hostname, and the titlebar still shows the hostname, not the IP I expected.
So, I think the right value will be one of:
- System.getenv("HOST")
- System.getenv("HOSTNAME")
- InetAddress.getLocalHost().getHostName()
The real trick will be determining that X11 forwarding is happening. I think the DISPLAY variable might tell you that? Normally it says DISPLAY=:1 which I think means no forwarding is happening. But if it's set to 'localhost:
Sorry, I'm not entirely clear on the exact meanings of all these variables.
What's the value of DISPLAY in the Java app?
You could find out with a label added to the frame. E.g. new JLable(System.getenv("DISPLAY"))
I think following could work:
String display = System.getenv("DISPLAY");
if( !display.startsWith( ":" ) && !display.startsWith( "localhost:" ) ) {
// X11 forwarding
// append System.getenv("HOSTNAME") to title
}
That seems promising to me.
I get the same value for DISPLAY from within the java code using System.getenv("DISPLAY"):
localhost:10.0
Hmm, I'm still confused a little bit... Need to set up an environment to try this out...
In the meantime, I've found the source code in window manager Mutter, which seems to be the default for GNOME, where the remote host name is added to title: https://gitlab.gnome.org/GNOME/mutter/-/blob/main/src/x11/window-props.c#L524-531
The window->is_remote flag seems to be set here:
https://gitlab.gnome.org/GNOME/mutter/-/blob/main/src/x11/window-props.c#L225-236
In case it helps, here is my test code as it currently stands:
import java.awt.Dialog.ModalityType;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.swing.JDialog;
import javax.swing.JFrame;
import com.formdev.flatlaf.FlatDarkLaf;
public class SimpleLaf {
public static void main(String[] args) throws UnknownHostException {
FlatDarkLaf.setup();
// JFrame.setDefaultLookAndFeelDecorated(true);
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("String Title");
frame.setSize(500,200);
frame.setVisible(true);
final JFrame small = new JFrame();
small.setSize(500, 150);
small.setTitle("Small Frame");
small.setVisible(false);
small.setVisible(true);
JDialog dialog = new JDialog(frame, "Dialog Title");
dialog.setSize(250,90);
dialog.setModalityType(ModalityType.MODELESS);
dialog.setVisible(true);
System.out.println(System.getenv("DISPLAY"));
System.out.println(InetAddress.getLocalHost().getHostName());
}
}
Just uncomment that one line to see the hostname text go away.
Put the Java application on machineA and then from machineB run "ssh -X machineA" and run the Java application over that connection.