2

New windows from other processes open behind a focused JDialog child but in front of the JDialog parent. I would expect new windows to appear in front of the child. None of these windows are declared always on top.

Picture

  • See that app 3 is between app 2 windows
  • Does not matter that it is behind app 1 - always on top, this is expected

3 between app 2 windows

Actual order

JDialog (App 1 - always on top)
JFrame (App 2 non modal dialog child of app 2 main)
JDialog (App 3) <=== new window should appear on top of app 2
JFrame (App 2 - main window)

Expected order

JDialog (App 1 - always on top)
JDialog (App 3) <=== new window should appear on top of app 2
JFrame (App 2 non modal dialog child of app 2 main)
JFrame (App 2 - main window)

This problem only happens if

  • there is an existing window from another process that is declared always-on-top, this doesn't have to be Java, I just used Java in the sample below - but issue also happens if you select always on top for say Firefox, gnome-terminal etc.
  • The new window that is opened in a position that is behind the always on top application. Again, doesn't have to be Java application, repeated with Firefox, gnome-terminal.
  • Redhat Linux 6. Not repeatable on Ubuntu 16.04 or Windows 7

If the window is opened slightly to the right (change to newWindow.setBounds(**370**, 20, 0, 200)) in the sample below, so that it is not behind the always on top window then it appears in front of child.

3 opens above 2

To be clear, this problem occurs between three separate applications, however for simplicity I've recreated it below as a single Java application.

public class Combined {
    public static void main(String[] args) throws Exception {

        JFrame aot = new JFrame("App 1 - always on top");
        aot.setAlwaysOnTop(true);
        aot.setBounds(50, 50, 300, 40);
        aot.setVisible(true);

        JFrame frame = new JFrame("App 2 - main window");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 300, 200);
        frame.setVisible(true);

        JDialog child = new JDialog(frame, "App 2 - non-modal child dialog (child)");
        child.setBounds(150, 150, 300, 200);
        child.setVisible(true);

        Thread.sleep(1000);
        JFrame newWindow = new JFrame("App 3");
        newWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        newWindow.setBounds(200, 20, 300, 200);
        // newWindow.setBounds(370, 20, 300, 200);

        newWindow.setVisible(true);
    }
}

Is there any option that can be applied to the JDialog child such that it allows Windows appear above it. The background is that I'm developing the "app 2" application, all the other parts and the Redhat Linux installation are all managed by other third-parties, so cannot be changed easily.

Tried using strict/smart window manager options, but no difference in behaviour

gconftool-2 --set /schemas/apps/metacity/general/focus_new_windows --type string smart
gconftool-2 --set /schemas/apps/metacity/general/focus_new_windows --type string strict

Hacky solutions

  • Show, hide and then show the App 3 window again. In this case it appears above "App 2 child" correctly, although this causes a noticable flicker

Code

newWindow.setVisible(true);
newWindow.setVisible(false);
newWindow.setVisible(true);
Adam
  • 35,919
  • 9
  • 100
  • 137
  • 1) *"there is an existing frame from another process that is declared always-on-top, this can be Java or some other application"* There's really no way of fixing that. Some 'always on top' apps. will go to insane lengths to achieve being always on top, whereas Oracle is only prepared to go to certain lengths to ensure an app. is always on top. 2) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) It is likely the app. will work if the 'other frames' are in fact modal dialogs wich specify the always on top app. as the parent or owner of the dialog. – Andrew Thompson Aug 29 '16 at 05:56
  • 1
    Thanks for you input. To be clear there is only one JFrame in the application. The other JFrames are in separate processes and are for purpose of demonstrating the problem only... – Adam Aug 29 '16 at 06:00
  • It is the fact that the always on top application being there has the side effect of meaning that two other windows in two other applications are not ordered correctly... it is as if gnome window manager has some code saying "if window being opended is behind an always on top window then ... " – Adam Aug 29 '16 at 06:05
  • 1
    *"To be clear there is only one JFrame in the application. The other JFrames are in separate processes and are for purpose of demonstrating the problem only..."* OK cool. Could you retitle the windows along the lines of "My AOT App.", "Other non AOT app. what should be behind my app..". I find the 'parent' / 'child' titling to be confusing. Also, can you manage to express that problem in a single source code with a single `main(String[])` method? That way it's easier for other people to compile (& run) and test. Even add number to the other windows as to which should be back most to front most – Andrew Thompson Aug 29 '16 at 06:16
  • @AndrewThompson Thanks again, I apologise this is such a difficult problem to explain. I had originally done three separate apps to narrow problem to window manager issue or not. Recreated as combined example and updated screenshots. Hope this is clearer. – Adam Aug 29 '16 at 06:47

1 Answers1

0

In summary there are no nice solutions to this Linux windows management specific issue. All that can be done is to banish always-on-top windows from your application. This is best practice anyway, but difficult when dealing with legacy codebases.

The only other solution of desparation is to do the setVisible() dance.

newWindow.setVisible(true);
newWindow.setVisible(false);
newWindow.setVisible(true);
Adam
  • 35,919
  • 9
  • 100
  • 137