7
$\begingroup$

Link to Wolfram Community version


Calling getDefaultToolkit() through J/Link causes the Front End to lose focus. This is specific to OS X. Here is a minimal example (it needs to be run in a fresh kernel):

Needs["JLink`"]
InstallJava[];

JLink`LoadJavaClass["java.awt.Toolkit", AllowShortContext -> False];

CreatePalette@Button["Press", java`awt`Toolkit`getDefaultToolkit[]]

This opens a palette with one button. Pressing this button for the first time causes all Front End windows to lose focus. As a side effect, the palette itself disappears. Note that palettes are only shown when the Front End is the foreground application.

The Mathematica application itself does not lose focus. It is still the active application, as evidenced by the text "Mathematica" in the OS X menu bar. However, the Front End behaves as if I had switched to a different application.

Since effectively it is the entire Front End that loses focus, and not just one notebook, SetSelectedNotebook is of no help here.

Pressing the button (or calling getDefaultToolkit()) a second time does not cause this behaviour.

The problem also occurs when evaluating java`awt`Toolkit`getDefaultToolkit[] in a normal notebook. I showed it with a palette, because the fact the the palette disappears is very striking (and it is really this behaviour that I consider to be a problem for my application).

Is there a workaround for this problem?

I need to fix this for a palette I am working on. Due to this problem, the palette effectively disappears either immediately when it is opened from the Palettes menu or as soon as a button is used (depending on where this code is called). This is not harmful, but it would be confusing to the users of the palette.

$\endgroup$
7
  • $\begingroup$ Hmm, I can't reproduce it on Windows 10. You could use (java`awt`Toolkit`getDefaultToolkit[]; SetSelectedNotebook[#]) &@ SelectedNotebook[] as a fix. $\endgroup$
    – Kuba
    Apr 4, 2017 at 9:56
  • $\begingroup$ @Kuba That was the first thing I tried, but it does not work. The reason is that it is not one notebook that loses the focus. The whole front end loses focus. Within the front end, the selected notebook does not change. It is good to know that Windows is not affected though. $\endgroup$
    – Szabolcs
    Apr 4, 2017 at 10:20
  • $\begingroup$ @Szabolcs Linux (Debian) has no problem either. MacOSX was always troublesome with Java ... $\endgroup$ Apr 4, 2017 at 10:30
  • $\begingroup$ Thanks for confirming that this is Mac-only. I rephrased the question accordingly. $\endgroup$
    – Szabolcs
    Apr 4, 2017 at 10:39
  • $\begingroup$ You might try launching the Java runtime manually and adding -Djava.awt.headless=true as an additional argument to the CommandLine option. $\endgroup$
    – WReach
    Apr 4, 2017 at 14:31

1 Answer 1

6
$\begingroup$

You can prevent the focus from being lost by setting certain system properties to true before calling any awt functionality:

LoadJavaClass["java.lang.System", AllowShortContext -> False]; 

java`lang`System`setProperty["apple.awt.UIElement", "true"];

(* or use the property "java.awt.headless"  instead *)

These properties can also be specified in the CommandLine option passed to InstallJava or ReinstallJava.

Potentially unwelcome side-effects of these settings are discussed below.

Discussion

The problem seems to be caused by the initialization of the Java GUI package, awt. When the first awt method is called, the UI event pump thread is started. On MacOSX this immediately creates a dock icon and a global menu bar, stealing focus away from the Mathematica front-end.

java.awt.headless and apple.awt.UIElement are two system properties that can affect this behaviour. These properties must be set before any calls to awt in order to take effect.

If the cross-platform property java.awt.headless is set to true, then most of the awt UI facilities will be disabled. This means that no Java windows, dialogs, etc. can be created. Only off-screen operations can be performed. This is a fairly draconian measure and will interfere with any Mathematica packages that want to interact with the user through on-screen UI elements.

The MacOSX-specific property apple.awt.UIElement is a less radical option (scroll down to Radar #5754483). The scant documentation for this property says:

Set the Java system property "apple.awt.UIElement" to "true" to start your command-line application in UIElement mode. This suppresses creation of a Dock icon and menu bar, and is only appropriate for modeless transient utility applications.

This could potentially interfere with the operation of a Mathematica package that relies upon the dock icon or customizes the menu bar. I dare say that most use of Java UI functionality within a Mathematica session would qualify as a "modeless transient utility application". But the possibility of a full-on Java application invoked from within Mathematica must be admitted.

If an awt-based package were already loaded prior to the creation of the palette in question, setting these properties will be harmless. Presumably that other package will already have ignored or dealt with the focus loss in its own way. Furthermore, the property apple.awt.UIElement is harmless on non-Mac systems.

Update

As Szabolcs notes in a comment, this work-around is currently (circa V11) incompatible with RLink.

$\endgroup$
5
  • $\begingroup$ It is good to note that the simple J/Link examples from the documentation do not create a dock icon anyway. I do not recall seeing dock icons created by J/Link code run from within Mathematica (and not externally, as e.g. with LinkSnooper). It sounds like it is safe enough. $\endgroup$
    – Szabolcs
    Apr 5, 2017 at 11:15
  • $\begingroup$ It turns out that this breaks RLink (which is based on J/Link). I think it is better if I do not push this. The focus loss is a very minor issue. It is not worth risking breaking other packages. But please do keep this answer, with this caveat, it is still useful. $\endgroup$
    – Szabolcs
    Apr 5, 2017 at 12:14
  • $\begingroup$ What a shame. The messages are fairly non sequitur so perhaps there is hope, however faint, that the dependency is incidental and can be fixed at some point. I will update my response to note the problem. $\endgroup$
    – WReach
    Apr 5, 2017 at 14:17
  • $\begingroup$ @Szabolcs - do you still get the error messages from InstallR[]? Also, would there be any issue with first saving the current value of the UIElement property, then running getDefaultToolkit, and finally resetting the UIElement property value? $\endgroup$
    – Jason B.
    Aug 28, 2019 at 21:10
  • $\begingroup$ @JasonB. I haven't use RLink for a long time ... it's not that easy to set it up anymore ... $\endgroup$
    – Szabolcs
    Aug 29, 2019 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.