imagej / imagej2

Open scientific N-dimensional image processing :microscope: :sparkler:
https://imagej.net/
BSD 2-Clause "Simplified" License
1.2k stars 337 forks source link

Channels Tool seems broken on MacOS FIJI/ImageJ #240

Closed hyungsongnam closed 5 years ago

hyungsongnam commented 5 years ago

Hello,

I recently noticed that the "Channels Tool" seems to be broken when running FIJI/ImageJ on mac OS with Java 8.

The behavior is as follows: (1) open an image (2) open channels tool - Can change from the dropdown menu from composite, color, etc (3) zoom in zoom out - Now, the dropdown menu in the channels tool becomes unresponsive - it cannot be changed.

If I quit and restart ImageJ, the channels tool works again, but only on the first image - if I close the first image and open another image, the tool becomes unresponsive again.

When running the FIJI/ImageJ on Ubuntu Linux, and opening the same image files, I don't see the same behavior with the channels tool, so this behavior might be mac OS specific.

Thank you.

Sincerely,

Hyung-song Nam, PhD

ctrueden commented 5 years ago

Thanks for the report, @hyungsongnam. I was able to reproduce this issue on my system with ImageJ 1.52o and 1.52p. I believe the patch which causes the issue is here:

https://github.com/imagej/ImageJA/commit/7ecb3e177e30744cb0b3e65ce9d877f7ec702e7c#diff-6eeb9bb47ee5d78fdba73066706c99cdL49

@rasband It seems dangerous to me to force the ImageJ main window to have the focus while the user is trying to manipulate a plugin dialog. Are you able to reproduce the issue? If not, I can grab a video and post it here, to illustrate what goes wrong.

rasband commented 5 years ago

I was not able to reproduce this problem using the Mitosis, Organ of Corti and Neuron sample images. The menu bar would disappear if ImageJ did not force the main window to have the focus.

hyungsongnam commented 5 years ago

I have looked for this behavior with additional images. I can add that this is sporadic. However, it does occur, and I have attached a movie from my mac. Sorry for the long movie, but the issue I'm describing occurs at the end of the movie. Thank you. Sincerely, Hyung-song Nam, PhD

Hyung-song's FIJI-ImageJ movie.zip

hyungsongnam commented 5 years ago

I've done more testing of this. It is indeed sporadic, and finding a reproducible trigger was difficult. The behavior appears to be associated with changing focus of the windows. Thank you. Sincerely, Hyung-song Nam, PhD

rasband commented 5 years ago

I was not able to reproduce this problem but it should be fixed in the latest ImageJ daily build (1.52q42). To upgrade, use the Help>Update ImageJ command and select "daily build" from the drop down menu. ImageJ no longer forces the main window to have the focus when activating the Channels window on macOS. As a result, the menu bar disappears when you switch from an image window to the Channels window.

hyungsongnam commented 5 years ago

Thank you.

Sincerely, Hyung-song Nam, PhD

hyungsongnam commented 5 years ago

In an attempt to reconcile the different findings, I re-installed the no-jre version of FIJI downloaded today, and repeated the testing. Strangely, I cannot reproduce the behavior at all today, even after trying for some time. Since there is a video of the behavior from yesterday, I observed it yesterday. Maybe my installation of FIJI simply needed an update. I can't say for sure whether today's change to the code will be necessary, the developers can decide.

Thank you.

Sincerely, Hyung-song Nam, PhD

rasband commented 5 years ago

The problem my be related to Java. What version of Java are you using now and what version were you using when you were having the problem? I am using Java 1.8.0_172 and I do not see the problem.

ctrueden commented 5 years ago

I used AdoptOpenJDK 1.8.0_202 in my tests, where I did see the problem.

The reason I called stealing the focus from the Channels window "dangerous" is because it goes against typical windowing assumptions: the user manipulates the active window, not background windows. There may be environments where manipulating an inactive window with the mouse does not work at all—as we've seen, in at least some macOS-based environments it is not guaranteed to work. It also precludes keyboard-based manipulation of the dialog. Therefore, I support the decision to keep the dialog in focus, even if the menu bar must disappear as a consequence.

But I was wondering: why does the menu disappear for the Channels tool? The PlugInDialog constructor uses IJ.getInstance() as the parent frame on macOS:

https://github.com/imagej/ImageJA/blob/v1.52p/src/main/java/ij/plugin/frame/PlugInDialog.java#L13-L14

This should preserve the menu bar from the main window, no? It seems to work for both Swing and plain AWT:

Menu_Test_AWT.groovy ```groovy import java.awt.* import java.awt.event.* disposer = new WindowAdapter() { public void windowClosing(WindowEvent e) { frame.dispose() } } frame = new Frame("Test Frame") menubar = new MenuBar() file = new Menu("File") menubar.add(file) file.add(new MenuItem("Test")) frame.setMenuBar(menubar) frame.addWindowListener(disposer) frame.setBounds(100, 100, 400, 300) frame.setVisible(true) //dialog = new Dialog(frame) // the menu bar will be that of "Test Frame" //dialog = new Dialog(null) // there will be no menu bar dialog = new Dialog(ij.IJ.getInstance()) // the menu bar will be that of ImageJ dialog.add(new Button("Test")) dialog.setModal(false) dialog.addWindowListener(disposer) dialog.pack() dialog.setVisible(true) ```
Menu_Test_Swing.groovy ```groovy import java.awt.* import javax.swing.* frame = new JFrame("Test Frame") menubar = new JMenuBar() file = new JMenu("File") menubar.add(file) file.add(new JMenuItem("Test")) frame.setJMenuBar(menubar) frame.setBounds(100, 100, 400, 300) frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE) frame.setVisible(true) //dialog = new JDialog(frame) // the menu bar will be that of "Test Frame" //dialog = new JDialog(null) // there will be no menu bar dialog = new JDialog(ij.IJ.getInstance()) // the menu bar will be that of ImageJ dialog.getContentPane().add(new JButton("Test")) dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE) dialog.setModal(false) dialog.pack() dialog.setVisible(true) ```

I'll dig a little more right now to see if I can narrow down the issue.

hyungsongnam commented 5 years ago

I'm using Oracle Java 1.8.0_221.

ctrueden commented 5 years ago

@rasband Here is what I have learned so far:

  1. The windowActivated method of ImageWindow steals the main ImageJ window's menu bar (1, 2).
  2. Internally, when the ImageWindow sets its MenuBar to ImageJ's menu bar, that menu bar is removed from its previous parent, which in this case is the main ImageJ window (1).
  3. To combat this wrinkle, the main ImageJ window grabs the menu bar again any time it is reactivated (1). In general, whenever a Frame is activated on macOS, it assigns the menu bar to itself, which ensures that from the user's perspective (apart from a brief flash), the menu bar remains available.
  4. Unfortunately, when the Channel window (or any PlugInDialog) is activated directly from an ImageWindow, its parent (the main ImageJ window) has a null menu bar, so the menu blanks out.
  5. So the natural conclusion is that we need the same hack in the windowActivated method of PlugInDialog: reset the main ImageJ window's menu bar there, so that the dialog's menu bar is correct. Unfortunately, it does not work: even though we can reset the main ImageJ window's menu bar, it does not cause the screen menu bar to refresh afterward.
  6. I also tried resetting the main ImageJ window's menu bar from the windowDeactivated method of ImageWindow, hoping that that would be early enough for the dialog activation to pick up its parent's menu bar successfully. But alas not.

Now I am looking for some other invocation that could be used from the windowActivated method of PlugInDialog to force the screen menu bar to refresh/repaint.

ctrueden commented 5 years ago

Unfortunately, I am out of time, and did not find a solution yet. One idea I had was to "bounce back"—i.e. activate the main window and immediately reactivate the dialog, to refresh the menu bar—but I think that approach is very hacky and my intuition is that it could create more bugs than it solves.

My next idea was/is to dig into the Apple-specific Java code (e.g. here) and try to understand it a bit better, to see if there is an API hook (even a private one) that could be called to force a screen menu bar refresh.

rasband commented 5 years ago

Hi Curtis,

In the latest ImageJ daily build (1.52q43), I changed the code in PlugInDialog that restores the Mac menu bar to

   if (IJ.isMacOSX() && ij!=null) {
      ij.requestFocus();
      this.requestFocus();
   }

Does this also fix the problem you saw with the Channels dialog on AdoptOpenJDK 1.8.0_202?

ctrueden commented 5 years ago

In the latest ImageJ daily build (1.52q43)

Are these changes pushed to GitHub anywhere? I am not seeing any updates to the imagej/imagej1 repository since August 3.

rasband commented 5 years ago

The changes are at https://github.com/imagej/imagej1/commit/cd8d54632601e9ee1476e40e01b21a629f581905

hyungsongnam commented 5 years ago

Hello, I have upgraded to the daily build of today Aug 26 2019. I still observe the same issue. The dropdown menu in Channels Tool works for some time, then it gets stuck, and becomes unresponsive.

FIJI-ImageJ movie.zip

rasband commented 5 years ago

The latest daily build (1.52q44) has a different fix for this problem that should work better. ImageJ no longer attempts to restore the Mac menu bar when the user switches from an image window to a PlugInDialog, such as the Channels tool. Source code changes are at https://github.com/imagej/imagej1/commit/bf9a36dea66add6c2b6ed3a2732917613722816f

rasband commented 5 years ago

This 1.52o regression is fixed in the ImageJ 1.52q44 daily build.