-
Bug
-
Resolution: Incomplete
-
P4
-
None
-
8u112
-
x86
-
other
FULL PRODUCT VERSION :
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
2.6.32-573.12.1.el6.x86_64
A DESCRIPTION OF THE PROBLEM :
This attached programme demonstrates an issue with closing a dialog using the native "x" on Red Hat 6 OS. The issue does not occur on Windows 7.
Once a dialog is opened (using the "Open Dialog (Broken)" menuitem), click outside the dialog but within the primary stage area and then click the "x" icon. Focus should be returned to the primary stage. On Red Hat this does not happen, on Windows it does.
Once in this state, the menubar is no longer usable (you will see that the content of the primary stage shows "Has focus? false" at this point). The only way to regain focus is to move the application window around or switch focus to another application and then back again. In my runtime scenario neither of these is possible as the application runs full screen and the user can't switch to any other applications.
The "Open Dialog (Workaround)" menuitem shows a workaround that I am using in order to filter the WINDOW_CLOSE_REQUEST if the dialog does not currently have focus, and reissue this event once focus is gained.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
On Red Hat Enterprise Linux, ssing the programme in the attached source code:
1. Open the "Dialog Menu"
2. Click "Open Dialog (Broken)
3. Click in an area outside the dialog but within the bounds of the primary stage
4. Click on the "X" button on the dialog
5. Observe that focus has not returned to the owning stage. You can no longer use the menu.
This is not reproducable on Windows 7..
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Focus should be returned to the owning stage upon the dialog being closed with the 'X' button, as per operation when following the reproduction steps in Windows 7.
ACTUAL -
Focus is not returned to primary stage. In the example application that I have attached the result of this is that the menu can no longer be used until focus is regained (by dragging application / switching away then back to application etc).
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package application;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.StringExpression;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
/**
* This small programme demonstrates an issue with closing a dialog using the
* native "x" on Red Hat 6 OS. The issue does not occur on Windows 7.
*
* Once a dialog is opened (using the "Open Dialog (Broken)" menuitem), click
* outside the dialog but within the primary stage area and then click the "x"
* icon. Focus should be returned to the primary stage. On Red Hat this does not
* happen, on Windows it does.
*
* Once in this state, the menubar is no longer usable (you will see that the
* content of the primary stage shows "Has focus? false" at this point). The
* only way to regain focus is to move the application window around or switch
* focus to another application and then back again. In my runtime scenario
* neither of these is possible as the application runs full screen and the user
* can't switch to any other applications.
*
* The "Open Dialog (Workaround)" menuitem shows a workaround that I am using in
* order to filter the WINDOW_CLOSE_REQUEST if the dialog does not currently
* have focus, and reissue this event once focus is gained.
*
*/
public class Main extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) {
try {
final BorderPane root = new BorderPane();
root.setTop(createMenu(primaryStage));
root.setCenter(createContent(primaryStage));
primaryStage.setScene(new Scene(root, 400, 300));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
private Pane createContent(final Stage primaryStage) {
final HBox pane = new HBox();
pane.setPadding(new Insets(15, 12, 15, 12));
pane.setSpacing(10);
pane.getChildren().add(new Label("Has focus?"));
final Label focusLabel = new Label();
focusLabel.textProperty().bind(StringExpression.stringExpression(primaryStage.focusedProperty()));
pane.getChildren().add(focusLabel);
return pane;
}
private MenuBar createMenu(final Stage primaryStage) {
final Menu menu = new Menu("Dialog Menu");
final MenuItem menuItem = new MenuItem("Open Dialog (Broken)");
menuItem.setOnAction(ae -> {
final Alert alert = createAlert(primaryStage);
alert.showAndWait();
});
menu.getItems().add(menuItem);
final MenuItem workaroundMenuItem = new MenuItem("Open Dialog (Workaround)");
workaroundMenuItem.setOnAction(ae -> {
final Alert alert = createAlert(primaryStage);
// This method contains the workaround code
applyWorkaround(alert.getDialogPane().getScene().getWindow());
alert.showAndWait();
});
menu.getItems().add(workaroundMenuItem);
return new MenuBar(menu);
}
private Alert createAlert(final Stage stage) {
final Alert alert = new Alert(AlertType.CONFIRMATION, "some content");
alert.initOwner(stage);
return alert;
}
/**
* On Red Hat OS, If the dialog window is not currently focused when closing
* the window via a native window close event (WINDOW_CLOSE_REQUEST) then
* the main stage will no longer be focused correctly upon closing the
* dialog. This doesn't occur when running on Windows.
*
* In order to work around this, if the dialog does not have focus upon the
* WINDOW_CLOSE_REQUEST, then request focus and add a listener to fire the
* WINDOW_CLOSE_REQUEST event upon receiving the focus again. Finally,
* consume the original WINDOW_CLOSE_REQUEST so that the Dialog is not
* closed without focus.
*/
public void applyWorkaround(final Window window) {
if (window == null) {
return;
}
window.addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST, event -> {
if (event.getSource() instanceof Window) {
final Window source = (Window) event.getSource();
if (!source.isFocused()) {
Platform.runLater(() -> {
source.focusedProperty()
.addListener((ChangeListener<Boolean>) (observable, oldValue, newValue) -> {
if (newValue) {
source.fireEvent(new WindowEvent(source, WindowEvent.WINDOW_CLOSE_REQUEST));
}
});
source.requestFocus();
});
event.consume();
}
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
See the attached sourcecode in applyWorkaround(Window window) method.
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
2.6.32-573.12.1.el6.x86_64
A DESCRIPTION OF THE PROBLEM :
This attached programme demonstrates an issue with closing a dialog using the native "x" on Red Hat 6 OS. The issue does not occur on Windows 7.
Once a dialog is opened (using the "Open Dialog (Broken)" menuitem), click outside the dialog but within the primary stage area and then click the "x" icon. Focus should be returned to the primary stage. On Red Hat this does not happen, on Windows it does.
Once in this state, the menubar is no longer usable (you will see that the content of the primary stage shows "Has focus? false" at this point). The only way to regain focus is to move the application window around or switch focus to another application and then back again. In my runtime scenario neither of these is possible as the application runs full screen and the user can't switch to any other applications.
The "Open Dialog (Workaround)" menuitem shows a workaround that I am using in order to filter the WINDOW_CLOSE_REQUEST if the dialog does not currently have focus, and reissue this event once focus is gained.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
On Red Hat Enterprise Linux, ssing the programme in the attached source code:
1. Open the "Dialog Menu"
2. Click "Open Dialog (Broken)
3. Click in an area outside the dialog but within the bounds of the primary stage
4. Click on the "X" button on the dialog
5. Observe that focus has not returned to the owning stage. You can no longer use the menu.
This is not reproducable on Windows 7..
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Focus should be returned to the owning stage upon the dialog being closed with the 'X' button, as per operation when following the reproduction steps in Windows 7.
ACTUAL -
Focus is not returned to primary stage. In the example application that I have attached the result of this is that the menu can no longer be used until focus is regained (by dragging application / switching away then back to application etc).
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package application;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.StringExpression;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
/**
* This small programme demonstrates an issue with closing a dialog using the
* native "x" on Red Hat 6 OS. The issue does not occur on Windows 7.
*
* Once a dialog is opened (using the "Open Dialog (Broken)" menuitem), click
* outside the dialog but within the primary stage area and then click the "x"
* icon. Focus should be returned to the primary stage. On Red Hat this does not
* happen, on Windows it does.
*
* Once in this state, the menubar is no longer usable (you will see that the
* content of the primary stage shows "Has focus? false" at this point). The
* only way to regain focus is to move the application window around or switch
* focus to another application and then back again. In my runtime scenario
* neither of these is possible as the application runs full screen and the user
* can't switch to any other applications.
*
* The "Open Dialog (Workaround)" menuitem shows a workaround that I am using in
* order to filter the WINDOW_CLOSE_REQUEST if the dialog does not currently
* have focus, and reissue this event once focus is gained.
*
*/
public class Main extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) {
try {
final BorderPane root = new BorderPane();
root.setTop(createMenu(primaryStage));
root.setCenter(createContent(primaryStage));
primaryStage.setScene(new Scene(root, 400, 300));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
private Pane createContent(final Stage primaryStage) {
final HBox pane = new HBox();
pane.setPadding(new Insets(15, 12, 15, 12));
pane.setSpacing(10);
pane.getChildren().add(new Label("Has focus?"));
final Label focusLabel = new Label();
focusLabel.textProperty().bind(StringExpression.stringExpression(primaryStage.focusedProperty()));
pane.getChildren().add(focusLabel);
return pane;
}
private MenuBar createMenu(final Stage primaryStage) {
final Menu menu = new Menu("Dialog Menu");
final MenuItem menuItem = new MenuItem("Open Dialog (Broken)");
menuItem.setOnAction(ae -> {
final Alert alert = createAlert(primaryStage);
alert.showAndWait();
});
menu.getItems().add(menuItem);
final MenuItem workaroundMenuItem = new MenuItem("Open Dialog (Workaround)");
workaroundMenuItem.setOnAction(ae -> {
final Alert alert = createAlert(primaryStage);
// This method contains the workaround code
applyWorkaround(alert.getDialogPane().getScene().getWindow());
alert.showAndWait();
});
menu.getItems().add(workaroundMenuItem);
return new MenuBar(menu);
}
private Alert createAlert(final Stage stage) {
final Alert alert = new Alert(AlertType.CONFIRMATION, "some content");
alert.initOwner(stage);
return alert;
}
/**
* On Red Hat OS, If the dialog window is not currently focused when closing
* the window via a native window close event (WINDOW_CLOSE_REQUEST) then
* the main stage will no longer be focused correctly upon closing the
* dialog. This doesn't occur when running on Windows.
*
* In order to work around this, if the dialog does not have focus upon the
* WINDOW_CLOSE_REQUEST, then request focus and add a listener to fire the
* WINDOW_CLOSE_REQUEST event upon receiving the focus again. Finally,
* consume the original WINDOW_CLOSE_REQUEST so that the Dialog is not
* closed without focus.
*/
public void applyWorkaround(final Window window) {
if (window == null) {
return;
}
window.addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST, event -> {
if (event.getSource() instanceof Window) {
final Window source = (Window) event.getSource();
if (!source.isFocused()) {
Platform.runLater(() -> {
source.focusedProperty()
.addListener((ChangeListener<Boolean>) (observable, oldValue, newValue) -> {
if (newValue) {
source.fireEvent(new WindowEvent(source, WindowEvent.WINDOW_CLOSE_REQUEST));
}
});
source.requestFocus();
});
event.consume();
}
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
See the attached sourcecode in applyWorkaround(Window window) method.