4

When I try to request focus (I'm on macOS Mojave 10.14.2) when the user clicks a 'show' button from the tray icon menu, it doesn't change the menu bar on the top left corner (e.g. Chrome -> java), but at least it brings to front. It doesn't appear at all when in a fullscreen app (e.g. clicking tray icon from Sublime Text in fullscreen) and instead shows it in the main Desktop space without moving to it.


Menu Bar Example:

About to show window should become this is what should happen but is instead fail: it brings to top but doesn't actually gain focus

Fullscreen Example:

About to show window when in a fullscreen app When clicking on 'Show'...

Nothing happens?!! Seemingly nothing happens! It gets opened without taking focus or appearing on top and instead on the main 'Desktop' space.


I've tried doing a combination of doing either toFront() or requestFocus() first or doing just one or the other, but it doesn't seem to work.

Does anyone have any fixes/workarounds to this problem?

Here is the simple application used above to demonstrate the problem:

package me.matetoes.dockvisibility;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.stage.Stage;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;

public class DockVisibilityTester extends Application {

    public javafx.scene.control.Button hideButton;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        hideButton = new javafx.scene.control.Button("Hide");
        hideButton.setOnAction(e -> handleHide());
        Scene scene = new Scene(hideButton, 200, 100);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Testing");
        Platform.setImplicitExit(false);
        createTrayIcon(primaryStage);
        primaryStage.show();
    }

    private void createTrayIcon(final Stage stage) {
        if (SystemTray.isSupported()) {
            SystemTray tray = SystemTray.getSystemTray(); // get the SystemTray instance

            Image icon = null;
            try { // load an image
                URL url = new URL("http://www.digitalphotoartistry.com/rose1.jpg");
                icon = ImageIO.read(url);
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            stage.setOnCloseRequest(e -> hide(stage)); //hide instead of close

            // to be added on "show" MenuItem and trayIcon itself
            ActionListener showListener = e -> show(stage);

            PopupMenu popup = new PopupMenu(); // create a popup menu

            MenuItem showItem = new MenuItem("Show");
            showItem.addActionListener(showListener);

            MenuItem closeItem = new MenuItem("Close");
            closeItem.addActionListener(e -> System.exit(0));

            popup.add(showItem);
            popup.addSeparator();
            popup.add(closeItem);

            assert icon != null;
            TrayIcon trayIcon = new TrayIcon(icon, "Test", popup); // construct a TrayIcon
            trayIcon.setImageAutoSize(true);
            trayIcon.addActionListener(showListener);

            try { // add the tray image
                tray.add(trayIcon);
            } catch (AWTException e) {
                e.printStackTrace();
            }
        }
    }

    private void hide(final Stage stage) {
        Platform.runLater(() -> {
            if (SystemTray.isSupported()) {
                stage.hide();
            } else {
                System.exit(0);
            }
        });
    }

    private void show(final Stage stage) {
        Platform.runLater(() -> {
            stage.show();

            // doesn't work!
            stage.requestFocus();
            stage.toFront();
        });
    }

    public void handleHide() {
        Stage stage = (Stage) hideButton.getScene().getWindow();
        hide(stage);
    }
}

Thanks! :)

Matias
  • 459
  • 1
  • 4
  • 14

1 Answers1

0

You could try using useSystemMenuBar()

Something like

MenuBar mnuBar;
mnuBar.useSystemMenuBar();
Camtensor
  • 38
  • 1
  • 7
  • Although `useSystemMenuBar()` will let me use the macOS menu bar, but it doesn't fix the issue at hand which is that it won't change focus to the java app. [Here](https://snipplr.com/view/330810/requesting-focus-on-javafx-stage/) is the same example except with a sample menu bar, and it still has the focus issue. – Matias Jan 25 '19 at 16:39
  • 1
    I was doing some researching and it might be a feature of macOS [See here.](https://bugs.openjdk.java.net/browse/JDK-8120102?focusedCommentId=13755491&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-13755491) I believe it only happens on background applications, can you try to requestFocus a second time from the shown window? – Camtensor Jan 26 '19 at 17:38
  • I've seen that already, and I don't think that it's true, because I was able to write a JNA library with Objective-C code to show and hide the macOS dock icon, and sometimes it would change the macOS menu bar in the top left, sometimes not. Either that "security feature" is not so secure, or there is supposed to be some way to take focus of the macOS menu bar. – Matias Jan 27 '19 at 06:11