cider-nrepl
cider-nrepl copied to clipboard
cider-debug side effect breaks macos window focusing behaviour when using java UI components
Expected behavior
$ clj -Sdeps '{:deps {cider/cider-nrepl {:mvn/version "0.21.1"}}}' -m nrepl.cmdline --middleware "[cider.nrepl/wrap-debug]" -i
nREPL server started on port 58662 on host localhost - nrepl://localhost:58662
nREPL 0.6.0
Clojure 1.10.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_191-b12
Interrupt: Control+C
Exit: Control+D or (exit) or (quit)
user=> (require 'clojure.inspector)
nil
user=> (clojure.inspector/inspect {:a :b})
#object[javax.swing.JFrame 0x17a01b0c "javax.swing.JFrame[frame0,0,23,400x400,invalid,layout=java.awt.BorderLayout,title=Clojure Inspector,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,22,400x378,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777675,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]"]
Actual behavior
The above runs the clojure inspector SWING UI widget as you'd expect, however the window can't be switched to with cmd-tab. It also does not have any presence in the application menu bar.
Steps to reproduce the problem
Run the above command on macos (I'm using macos Mojave). If you run the above without the cider middleware you will get the expected macos windowing behaviour e.g. this works:
clj
Clojure 1.10.0
user=> (require 'clojure.inspector)
user=> (clojure.inspector/inspect {:a :b})
Environment & Version information
cider-nrepl version
E.g. 0.11.2
Java version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
Operating system
- macos mojave 10.14.3
I have done some work to track where this is occuring.
I suspect the following middlewares may also cause this:
cider.nrepl/wrap-debug
cider.nrepl/wrap-tracker
cider.nrepl/wrap-enlighten
I did some additional work to try and track this down, and it appears you can also recreate it by requiring orchard.classpath doing:
clj -Sdeps '{:deps {cider/orchard {:mvn/version "0.4.0"}}}'
Clojure 1.10.0
user=> (require 'orchard.classpath)
nil
user=> (require 'clojure.inspector)
nil
user=> (clojure.inspector/inspect 1)
#object[javax.swing.JFrame 0x56f2bbea "javax.swing.JFrame[frame0,0,23,400x400,invalid,layout=java.awt.BorderLayout,title=Clojure Inspector,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,22,400x378,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]"]
orchard.classpath
is required by wrap-debug.
I believe there may be a side effect ordering issue here too, as if you do this, and load up a swing UI before requiring orchard...
(require 'clojure.inspector)
(clojure.inspector 1)
;; now close the swing window
;; next...
(require 'orchard.classpath)
(clojure.inspector 1) ;; works
It seems to work, as macos creates the menubar for the java process and reuses it.
This appears to affect Java 8.
Updating your Java dependency to JDK 12 appears to fix this. Not sure why.
I could track this down to two lines of code in orchard and opened an issue there: https://github.com/clojure-emacs/orchard/issues/162
As a consequence, the quickfix is to set the apple.awt.UIElement
property to false
when running clojure.