FlatLaf icon indicating copy to clipboard operation
FlatLaf copied to clipboard

Add Hostname to Title Bar when X11 Forwarding

Open IanKrL opened this issue 1 year ago • 10 comments

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.

IanKrL avatar Mar 25 '24 13:03 IanKrL

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?

DevCharly avatar Mar 28 '24 16:03 DevCharly

Yes, JFrame.setDefaultLookAndFeelDecorated( true ) is key. With true: Screenshot from 2024-03-29 09-37-18 With false (or, default): Screenshot from 2024-03-29 09-34-45 These samples just have dark theme enabled to prove FlatLaf is loaded correctly.

IanKrL avatar Mar 29 '24 13:03 IanKrL

Thanks.

Is the hostname shown in each window? In JFrames and in JDialogs? Or just in JFrames?

DevCharly avatar Mar 29 '24 13:03 DevCharly

All 3: Screenshot from 2024-03-29 10-05-21

IanKrL avatar Mar 29 '24 14:03 IanKrL

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")?

DevCharly avatar Mar 29 '24 14:03 DevCharly

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:' it's likely X11 forwarding is happening?

Sorry, I'm not entirely clear on the exact meanings of all these variables.

IanKrL avatar Mar 29 '24 15:03 IanKrL

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
}

DevCharly avatar Mar 29 '24 16:03 DevCharly

That seems promising to me.

I get the same value for DISPLAY from within the java code using System.getenv("DISPLAY"):

localhost:10.0

IanKrL avatar Mar 29 '24 16:03 IanKrL

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

DevCharly avatar Mar 29 '24 16:03 DevCharly

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.

IanKrL avatar Mar 29 '24 16:03 IanKrL