Repositioning of frames from top to bottom does not work on OSX

Repositioning the docking frames from top to bottom does not work correctly on OSX. The error can be seen in the Hello World demo in version ‚Preview 10‘ (8 Nov 2013) on OSX 10.9 with Java 1.7.0.45.

Reproduction

  1. Open Hello World demo
  2. Notice the Red frame is on top and the green frame is at the bottom
  3. Drag the red frame to right side of the green frame
    That is: try to have the green and red frames positioned next to each other instead of on top of each other
  4. Notice that the red frame stays on top and a blue rectangle is shown next to the green frame (see screenshot)

I’m not certain if this is an issue of the OS, the Java Version, or something else - in any case I could not reproduce this issue on my machine. And since I cannot reproduce, I cannot fix…

Did you see any exceptions? Or are the other strange things happening, e.g. like the mouse no longer working after trying to move a Dockable?

Thanks for looking into this! I did some extra investigation and what I found is the following:

  • The problem only occurs when running the jar! Debugging with Eclipse or using the JNLP works fine.
  • The problem occurs with different JDKs. I tried with 1.7.0.45, 1.7.0.13 and 1.6.0.45 and all showed the same problem.
  • The problem seems to occur only when you drag something from the top to the bottom right. In the example if I drag the red panel to the left of the green panel, everything works correctly.
  • When I am in the state as shown in the screenshot, I can click the red frame again to get back to the original state (as in: to a working state).
  • I don’t see any other strange behavior when this happens; my mouse works fine. I also don’t see any exceptions being thrown (or any logging, for that matter).

If you need any other information, please let me know :slight_smile:

Well… I have no idea at all where to start looking for this bug. And I still cannot reproduce it. The fact that it depends on whether you start the app from the JAR files or from Eclipse is even more confusing, after all it is the same code…

I’ll have to ask some collegues if I can borrow their OSX machine for a little testing.

But right now I really do not have any kind of solution for this issue.

I found some time to do some debugging on my Mac and noticed that I am now able to reproduce it in debug mode also. I have no idea why this didn’t work before, but I am still positive that it was the actual behavior I observed. (Running Java 7 update 45, OSX 10.9.1, Eclipse)

What I found with debugging was that the problem seems to be solved when no drag icon/moving image is used. If I set showMovingImage to false in the calls to dragMouseDragged(…) in DefaultDockRelocator.java, then it all seems to work fine for me. Some further digging in the dispatching of the mouse events and most notably the mouseReleased event, revealed that in the cases where it goes wrong the mouseReleased event is not dispatched properly. The correct cases dispatch the mouseReleased event to listeners in ActionPopup.java and DefaultDockRelocator.java (which is also what you would expect, I guess), but when it goes wrong the dispatching is done only to DefaultSplitDividerStrategy.

Since I am not really familiar with the code, I am not sure what all these classes do or are supposed to do and in which cases they should appear. I might have some spare time next week to do some additional debugging, so if you could give me some tips on where to look, that would be great.

When dragging a Dockable usually you grab the title. So the source of the MouseEvents should be something like AbstractMultiDockTitle$1, or some other child-Component of the title.

Both the ActionPopup and the DefaultDockRelactor have a MouseListener added to the title, so it’s perfectly fine and expected that both these classes receive the mouse-released event.

The DefaultSplitDividerStrategy globally listens to all AWTEvents. It is also correct that it gets the MouseEvent.

If you would like to continue debugging (I would appreciate that), then I think as next step you should add a global AWTListener, and analyze the MouseEvents:

			public void eventDispatched( AWTEvent event ) {
				System.out.println(event);
			}
		}, AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK );```

The output of this code should be something like this:

java.awt.event.MouseEvent[MOUSE_MOVED,(537,8),absolute(601,506),button=0,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]

*** java.awt.event.MouseEvent[MOUSE_PRESSED,(537,8),absolute(601,506),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]

java.awt.event.MouseEvent[MOUSE_DRAGGED,(536,8),absolute(600,506),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_DRAGGED,(536,7),absolute(600,505),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_DRAGGED,(536,6),absolute(600,504),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
[…]
java.awt.event.MouseEvent[MOUSE_DRAGGED,(539,-6),absolute(603,492),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_DRAGGED,(539,-7),absolute(603,491),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_DRAGGED,(540,-8),absolute(604,490),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_EXITED,(559,420),absolute(604,489),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.SplitDockStation$Content[,0,0,790x566,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_ENTERED,(557,396),absolute(604,489),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.util.ConfiguredBackgroundPanel[,0,22,786x397,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777225,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_DRAGGED,(540,-9),absolute(604,489),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
[…]
java.awt.event.MouseEvent[MOUSE_DRAGGED,(629,-174),absolute(693,324),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_DRAGGED,(630,-174),absolute(694,324),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_EXITED,(647,231),absolute(694,324),button=1,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.util.ConfiguredBackgroundPanel[,0,22,645x397,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777225,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_ENTERED,(649,255),absolute(694,324),button=1,modifiers=Button1,extModifiers=Button1,clickCount=0] on bibliothek.gui.dock.SplitDockStation$Content[,0,0,790x566,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]

*** java.awt.event.MouseEvent[MOUSE_RELEASED,(630,-174),absolute(694,324),button=1,modifiers=Button1,clickCount=0] on bibliothek.gui.dock.title.AbstractMultiDockTitle$1[,17,0,746x22,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]

java.awt.event.MouseEvent[MOUSE_MOVED,(651,257),absolute(696,326),button=0,clickCount=0] on bibliothek.gui.dock.SplitDockStation$Content[,0,0,790x566,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_EXITED,(655,267),absolute(700,336),button=0,clickCount=0] on bibliothek.gui.dock.SplitDockStation$Content[,0,0,790x566,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_ENTERED,(3,243),absolute(700,336),button=0,clickCount=0] on bibliothek.gui.dock.util.ConfiguredBackgroundPanel[,0,22,136x540,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777225,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_MOVED,(3,243),absolute(700,336),button=0,clickCount=0] on bibliothek.gui.dock.util.ConfiguredBackgroundPanel[,0,22,136x540,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777225,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_MOVED,(8,250),absolute(705,343),button=0,clickCount=0] on bibliothek.gui.dock.util.ConfiguredBackgroundPanel[,0,22,136x540,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777225,maximumSize=,minimumSize=,preferredSize=]



I marked the two events that are really interesting with "***" - the mousePressed and the mouseReleased-Event. They way you describe the bug I would suspect that these two MouseEvents do not match up. For example, do both events have the same source? If they do not match: then it is a bug in the JRE, and I cannot do anything against those. If it does match up... well then my guess was wrong and I do still not have a good idea.

There are some known bugs in the JDK regarding focus when new Windows are opened (google "java 6 focus bug"). This could be related, because the icon that shows up during a drag and drop operation is a Window as well.

By the way, you can disable the moving image:

// if you have only a DockController:
controller.getProperties().set( DockTheme.DOCKABLE_MOVING_IMAGE_FACTORY, new DockableMovingImageFactory() {
public MovingImage create( DockController controller, Dockable dockable ) {
// show no image
return null;
}

public MovingImage create( DockController controller, DockTitle snatched ) {
	// show no image
	return null;
}

});

// … or if using a CControl:
// CControl control = … ;
// control.putProperty( DockTheme.DOCKABLE_MOVING_IMAGE_FACTORY, new … );